[Parley-svn] r873 - / trunk/root/static/yui trunk/root/static/yui/animation trunk/root/static/yui/assets/skins/sam trunk/root/static/yui/autocomplete trunk/root/static/yui/autocomplete/assets trunk/root/static/yui/autocomplete/assets/skins/sam trunk/root/static/yui/base trunk/root/static/yui/button trunk/root/static/yui/button/assets trunk/root/static/yui/button/assets/skins/sam trunk/root/static/yui/calendar trunk/root/static/yui/calendar/assets trunk/root/static/yui/calendar/assets/skins/sam trunk/root/static/yui/charts trunk/root/static/yui/charts/assets trunk/root/static/yui/colorpicker trunk/root/static/yui/colorpicker/assets trunk/root/static/yui/colorpicker/assets/skins/sam trunk/root/static/yui/connection trunk/root/static/yui/container trunk/root/static/yui/container/assets trunk/root/static/yui/container/assets/skins/sam trunk/root/static/yui/cookie trunk/root/static/yui/datasource trunk/root/static/yui/datatable trunk/root/static/yui/datatable/assets trunk/root/static! /yui/datatable/assets/skins/sam trunk/root/static/yui/dom trunk/root/static/yui/dragdrop trunk/root/static/yui/editor trunk/root/static/yui/editor/assets trunk/root/static/yui/editor/assets/skins/sam trunk/root/static/yui/element trunk/root/static/yui/event trunk/root/static/yui/fonts trunk/root/static/yui/get trunk/root/static/yui/grids trunk/root/static/yui/history trunk/root/static/yui/imagecropper trunk/root/static/yui/imagecropper/assets trunk/root/static/yui/imagecropper/assets/skins trunk/root/static/yui/imagecropper/assets/skins/sam trunk/root/static/yui/imageloader trunk/root/static/yui/json trunk/root/static/yui/layout trunk/root/static/yui/layout/assets trunk/root/static/yui/layout/assets/skins trunk/root/static/yui/layout/assets/skins/sam trunk/root/static/yui/logger trunk/root/static/yui/logger/assets trunk/root/static/yui/logger/assets/skins/sam trunk/root/static/yui/menu trunk/root/static/yui/menu/assets trunk/root/static/yui/menu/assets/skins/sam trunk/root/! static/yui/profiler trunk/root/static/yui/profilerviewer trunk! /root/st

chiselwright at BerliOS chiselwright at mail.berlios.de
Fri Apr 11 11:59:50 CEST 2008


Author: chiselwright
Date: 2008-04-11 11:58:56 +0200 (Fri, 11 Apr 2008)
New Revision: 873

Added:
   trunk/root/static/yui/assets/skins/sam/asc.gif
   trunk/root/static/yui/assets/skins/sam/desc.gif
   trunk/root/static/yui/assets/skins/sam/header_background.png
   trunk/root/static/yui/assets/skins/sam/imagecropper.css
   trunk/root/static/yui/assets/skins/sam/layout.css
   trunk/root/static/yui/assets/skins/sam/layout_sprite.png
   trunk/root/static/yui/assets/skins/sam/profilerviewer.css
   trunk/root/static/yui/assets/skins/sam/resize.css
   trunk/root/static/yui/assets/skins/sam/wait.gif
   trunk/root/static/yui/colorpicker/colorpicker-debug.js
   trunk/root/static/yui/colorpicker/colorpicker-min.js
   trunk/root/static/yui/colorpicker/colorpicker.js
   trunk/root/static/yui/cookie/
   trunk/root/static/yui/cookie/README
   trunk/root/static/yui/cookie/cookie-beta-debug.js
   trunk/root/static/yui/cookie/cookie-beta-min.js
   trunk/root/static/yui/cookie/cookie-beta.js
   trunk/root/static/yui/get/get-debug.js
   trunk/root/static/yui/get/get-min.js
   trunk/root/static/yui/get/get.js
   trunk/root/static/yui/imagecropper/
   trunk/root/static/yui/imagecropper/README
   trunk/root/static/yui/imagecropper/assets/
   trunk/root/static/yui/imagecropper/assets/imagecropper-core.css
   trunk/root/static/yui/imagecropper/assets/skins/
   trunk/root/static/yui/imagecropper/assets/skins/sam/
   trunk/root/static/yui/imagecropper/assets/skins/sam/imagecropper-skin.css
   trunk/root/static/yui/imagecropper/assets/skins/sam/imagecropper.css
   trunk/root/static/yui/imagecropper/imagecropper-beta-debug.js
   trunk/root/static/yui/imagecropper/imagecropper-beta-min.js
   trunk/root/static/yui/imagecropper/imagecropper-beta.js
   trunk/root/static/yui/imageloader/imageloader-debug.js
   trunk/root/static/yui/imageloader/imageloader-min.js
   trunk/root/static/yui/imageloader/imageloader.js
   trunk/root/static/yui/json/json-debug.js
   trunk/root/static/yui/json/json-min.js
   trunk/root/static/yui/json/json.js
   trunk/root/static/yui/layout/
   trunk/root/static/yui/layout/README
   trunk/root/static/yui/layout/assets/
   trunk/root/static/yui/layout/assets/layout-core.css
   trunk/root/static/yui/layout/assets/skins/
   trunk/root/static/yui/layout/assets/skins/sam/
   trunk/root/static/yui/layout/assets/skins/sam/layout-skin.css
   trunk/root/static/yui/layout/assets/skins/sam/layout.css
   trunk/root/static/yui/layout/assets/skins/sam/layout_sprite.png
   trunk/root/static/yui/layout/layout-beta-debug.js
   trunk/root/static/yui/layout/layout-beta-min.js
   trunk/root/static/yui/layout/layout-beta.js
   trunk/root/static/yui/menu/assets/menuitem_checkbox.png
   trunk/root/static/yui/menu/assets/menuitem_checkbox_disabled.png
   trunk/root/static/yui/menu/assets/menuitem_checkbox_selected.png
   trunk/root/static/yui/profilerviewer/
   trunk/root/static/yui/profilerviewer/README
   trunk/root/static/yui/profilerviewer/assets/
   trunk/root/static/yui/profilerviewer/assets/skins/
   trunk/root/static/yui/profilerviewer/assets/skins/sam/
   trunk/root/static/yui/profilerviewer/assets/skins/sam/asc.gif
   trunk/root/static/yui/profilerviewer/assets/skins/sam/desc.gif
   trunk/root/static/yui/profilerviewer/assets/skins/sam/header_background.png
   trunk/root/static/yui/profilerviewer/assets/skins/sam/profilerviewer.css
   trunk/root/static/yui/profilerviewer/assets/skins/sam/wait.gif
   trunk/root/static/yui/profilerviewer/profilerviewer-beta-debug.js
   trunk/root/static/yui/profilerviewer/profilerviewer-beta-min.js
   trunk/root/static/yui/profilerviewer/profilerviewer-beta.js
   trunk/root/static/yui/resize/
   trunk/root/static/yui/resize/README
   trunk/root/static/yui/resize/assets/
   trunk/root/static/yui/resize/assets/resize-core.css
   trunk/root/static/yui/resize/assets/skins/
   trunk/root/static/yui/resize/assets/skins/sam/
   trunk/root/static/yui/resize/assets/skins/sam/layout_sprite.png
   trunk/root/static/yui/resize/assets/skins/sam/resize-skin.css
   trunk/root/static/yui/resize/assets/skins/sam/resize.css
   trunk/root/static/yui/resize/resize-beta-debug.js
   trunk/root/static/yui/resize/resize-beta-min.js
   trunk/root/static/yui/resize/resize-beta.js
   trunk/root/static/yui/uploader/
   trunk/root/static/yui/uploader/README
   trunk/root/static/yui/uploader/assets/
   trunk/root/static/yui/uploader/assets/uploader.swf
   trunk/root/static/yui/uploader/uploader-experimental-debug.js
   trunk/root/static/yui/uploader/uploader-experimental-min.js
   trunk/root/static/yui/uploader/uploader-experimental.js
   trunk/root/static/yui/yuiloader-dom-event/
   trunk/root/static/yui/yuiloader-dom-event/README
   trunk/root/static/yui/yuiloader-dom-event/yuiloader-dom-event.js
   trunk/root/static/yui/yuitest/yuitest-debug.js
   trunk/root/static/yui/yuitest/yuitest-min.js
   trunk/root/static/yui/yuitest/yuitest.js
   trunk/root/static/yui/yuitest/yuitest_core-debug.js
   trunk/root/static/yui/yuitest/yuitest_core-min.js
   trunk/root/static/yui/yuitest/yuitest_core.js
Removed:
   trunk/root/static/yui/colorpicker/colorpicker-beta-debug.js
   trunk/root/static/yui/colorpicker/colorpicker-beta-min.js
   trunk/root/static/yui/colorpicker/colorpicker-beta.js
   trunk/root/static/yui/get/get-beta-debug.js
   trunk/root/static/yui/get/get-beta-min.js
   trunk/root/static/yui/get/get-beta.js
   trunk/root/static/yui/imageloader/imageloader-beta-debug.js
   trunk/root/static/yui/imageloader/imageloader-beta-min.js
   trunk/root/static/yui/imageloader/imageloader-beta.js
   trunk/root/static/yui/json/json-beta-debug.js
   trunk/root/static/yui/json/json-beta-min.js
   trunk/root/static/yui/json/json-beta.js
   trunk/root/static/yui/menu/assets/menu_down_arrow_selected.png
   trunk/root/static/yui/menu/assets/menuitem_checked.png
   trunk/root/static/yui/menu/assets/menuitem_checked_disabled.png
   trunk/root/static/yui/menu/assets/menuitem_checked_selected.png
   trunk/root/static/yui/yuitest/yuitest-beta-debug.js
   trunk/root/static/yui/yuitest/yuitest-beta-min.js
   trunk/root/static/yui/yuitest/yuitest-beta.js
Modified:
   /
   trunk/root/static/yui/animation/README
   trunk/root/static/yui/animation/animation-debug.js
   trunk/root/static/yui/animation/animation-min.js
   trunk/root/static/yui/animation/animation.js
   trunk/root/static/yui/assets/skins/sam/autocomplete.css
   trunk/root/static/yui/assets/skins/sam/button.css
   trunk/root/static/yui/assets/skins/sam/calendar.css
   trunk/root/static/yui/assets/skins/sam/colorpicker.css
   trunk/root/static/yui/assets/skins/sam/container.css
   trunk/root/static/yui/assets/skins/sam/datatable.css
   trunk/root/static/yui/assets/skins/sam/dt-arrow-dn.png
   trunk/root/static/yui/assets/skins/sam/dt-arrow-up.png
   trunk/root/static/yui/assets/skins/sam/editor.css
   trunk/root/static/yui/assets/skins/sam/logger.css
   trunk/root/static/yui/assets/skins/sam/menu.css
   trunk/root/static/yui/assets/skins/sam/simpleeditor.css
   trunk/root/static/yui/assets/skins/sam/skin.css
   trunk/root/static/yui/assets/skins/sam/tabview.css
   trunk/root/static/yui/assets/skins/sam/treeview.css
   trunk/root/static/yui/assets/skins/sam/yuitest.css
   trunk/root/static/yui/autocomplete/README
   trunk/root/static/yui/autocomplete/assets/autocomplete-core.css
   trunk/root/static/yui/autocomplete/assets/skins/sam/autocomplete-skin.css
   trunk/root/static/yui/autocomplete/assets/skins/sam/autocomplete.css
   trunk/root/static/yui/autocomplete/autocomplete-debug.js
   trunk/root/static/yui/autocomplete/autocomplete-min.js
   trunk/root/static/yui/autocomplete/autocomplete.js
   trunk/root/static/yui/base/README
   trunk/root/static/yui/base/base-min.css
   trunk/root/static/yui/base/base.css
   trunk/root/static/yui/button/README
   trunk/root/static/yui/button/assets/button-core.css
   trunk/root/static/yui/button/assets/skins/sam/button-skin.css
   trunk/root/static/yui/button/assets/skins/sam/button.css
   trunk/root/static/yui/button/button-debug.js
   trunk/root/static/yui/button/button-min.js
   trunk/root/static/yui/button/button.js
   trunk/root/static/yui/calendar/README
   trunk/root/static/yui/calendar/assets/calendar-core.css
   trunk/root/static/yui/calendar/assets/calendar.css
   trunk/root/static/yui/calendar/assets/skins/sam/calendar-skin.css
   trunk/root/static/yui/calendar/assets/skins/sam/calendar.css
   trunk/root/static/yui/calendar/calendar-debug.js
   trunk/root/static/yui/calendar/calendar-min.js
   trunk/root/static/yui/calendar/calendar.js
   trunk/root/static/yui/charts/README
   trunk/root/static/yui/charts/assets/charts.swf
   trunk/root/static/yui/charts/charts-experimental-debug.js
   trunk/root/static/yui/charts/charts-experimental-min.js
   trunk/root/static/yui/charts/charts-experimental.js
   trunk/root/static/yui/colorpicker/README
   trunk/root/static/yui/colorpicker/assets/colorpicker_core.css
   trunk/root/static/yui/colorpicker/assets/skins/sam/colorpicker-skin.css
   trunk/root/static/yui/colorpicker/assets/skins/sam/colorpicker.css
   trunk/root/static/yui/connection/README
   trunk/root/static/yui/connection/connection-debug.js
   trunk/root/static/yui/connection/connection-min.js
   trunk/root/static/yui/connection/connection.js
   trunk/root/static/yui/container/README
   trunk/root/static/yui/container/assets/container-core.css
   trunk/root/static/yui/container/assets/container.css
   trunk/root/static/yui/container/assets/skins/sam/container-skin.css
   trunk/root/static/yui/container/assets/skins/sam/container.css
   trunk/root/static/yui/container/container-debug.js
   trunk/root/static/yui/container/container-min.js
   trunk/root/static/yui/container/container.js
   trunk/root/static/yui/container/container_core-debug.js
   trunk/root/static/yui/container/container_core-min.js
   trunk/root/static/yui/container/container_core.js
   trunk/root/static/yui/datasource/README
   trunk/root/static/yui/datasource/datasource-beta-debug.js
   trunk/root/static/yui/datasource/datasource-beta-min.js
   trunk/root/static/yui/datasource/datasource-beta.js
   trunk/root/static/yui/datatable/README
   trunk/root/static/yui/datatable/assets/datatable-core.css
   trunk/root/static/yui/datatable/assets/datatable.css
   trunk/root/static/yui/datatable/assets/skins/sam/datatable-skin.css
   trunk/root/static/yui/datatable/assets/skins/sam/datatable.css
   trunk/root/static/yui/datatable/assets/skins/sam/dt-arrow-dn.png
   trunk/root/static/yui/datatable/assets/skins/sam/dt-arrow-up.png
   trunk/root/static/yui/datatable/datatable-beta-debug.js
   trunk/root/static/yui/datatable/datatable-beta-min.js
   trunk/root/static/yui/datatable/datatable-beta.js
   trunk/root/static/yui/dom/README
   trunk/root/static/yui/dom/dom-debug.js
   trunk/root/static/yui/dom/dom-min.js
   trunk/root/static/yui/dom/dom.js
   trunk/root/static/yui/dragdrop/README
   trunk/root/static/yui/dragdrop/dragdrop-debug.js
   trunk/root/static/yui/dragdrop/dragdrop-min.js
   trunk/root/static/yui/dragdrop/dragdrop.js
   trunk/root/static/yui/editor/README
   trunk/root/static/yui/editor/assets/editor-core.css
   trunk/root/static/yui/editor/assets/simpleeditor-core.css
   trunk/root/static/yui/editor/assets/skins/sam/editor-skin.css
   trunk/root/static/yui/editor/assets/skins/sam/editor.css
   trunk/root/static/yui/editor/assets/skins/sam/simpleeditor-skin.css
   trunk/root/static/yui/editor/assets/skins/sam/simpleeditor.css
   trunk/root/static/yui/editor/editor-beta-debug.js
   trunk/root/static/yui/editor/editor-beta-min.js
   trunk/root/static/yui/editor/editor-beta.js
   trunk/root/static/yui/editor/simpleeditor-beta-debug.js
   trunk/root/static/yui/editor/simpleeditor-beta-min.js
   trunk/root/static/yui/editor/simpleeditor-beta.js
   trunk/root/static/yui/element/README
   trunk/root/static/yui/element/element-beta-debug.js
   trunk/root/static/yui/element/element-beta-min.js
   trunk/root/static/yui/element/element-beta.js
   trunk/root/static/yui/event/README
   trunk/root/static/yui/event/event-debug.js
   trunk/root/static/yui/event/event-min.js
   trunk/root/static/yui/event/event.js
   trunk/root/static/yui/fonts/README
   trunk/root/static/yui/fonts/fonts-min.css
   trunk/root/static/yui/fonts/fonts.css
   trunk/root/static/yui/get/README
   trunk/root/static/yui/grids/README
   trunk/root/static/yui/grids/grids-min.css
   trunk/root/static/yui/grids/grids.css
   trunk/root/static/yui/history/README
   trunk/root/static/yui/history/history-debug.js
   trunk/root/static/yui/history/history-min.js
   trunk/root/static/yui/history/history.js
   trunk/root/static/yui/imageloader/README
   trunk/root/static/yui/json/README
   trunk/root/static/yui/logger/README
   trunk/root/static/yui/logger/assets/logger-core.css
   trunk/root/static/yui/logger/assets/logger.css
   trunk/root/static/yui/logger/assets/skins/sam/logger-skin.css
   trunk/root/static/yui/logger/assets/skins/sam/logger.css
   trunk/root/static/yui/logger/logger-debug.js
   trunk/root/static/yui/logger/logger-min.js
   trunk/root/static/yui/logger/logger.js
   trunk/root/static/yui/menu/README
   trunk/root/static/yui/menu/assets/menu-core.css
   trunk/root/static/yui/menu/assets/menu.css
   trunk/root/static/yui/menu/assets/skins/sam/menu-skin.css
   trunk/root/static/yui/menu/assets/skins/sam/menu.css
   trunk/root/static/yui/menu/menu-debug.js
   trunk/root/static/yui/menu/menu-min.js
   trunk/root/static/yui/menu/menu.js
   trunk/root/static/yui/profiler/README
   trunk/root/static/yui/profiler/profiler-beta-debug.js
   trunk/root/static/yui/profiler/profiler-beta-min.js
   trunk/root/static/yui/profiler/profiler-beta.js
   trunk/root/static/yui/reset-fonts-grids/reset-fonts-grids.css
   trunk/root/static/yui/reset-fonts/reset-fonts.css
   trunk/root/static/yui/reset/README
   trunk/root/static/yui/reset/reset-min.css
   trunk/root/static/yui/reset/reset.css
   trunk/root/static/yui/selector/README
   trunk/root/static/yui/selector/selector-beta-debug.js
   trunk/root/static/yui/selector/selector-beta-min.js
   trunk/root/static/yui/selector/selector-beta.js
   trunk/root/static/yui/slider/README
   trunk/root/static/yui/slider/slider-debug.js
   trunk/root/static/yui/slider/slider-min.js
   trunk/root/static/yui/slider/slider.js
   trunk/root/static/yui/tabview/README
   trunk/root/static/yui/tabview/assets/border_tabs.css
   trunk/root/static/yui/tabview/assets/skin-sam.css
   trunk/root/static/yui/tabview/assets/skins/sam/tabview-skin.css
   trunk/root/static/yui/tabview/assets/skins/sam/tabview.css
   trunk/root/static/yui/tabview/assets/tabview-core.css
   trunk/root/static/yui/tabview/assets/tabview.css
   trunk/root/static/yui/tabview/tabview-debug.js
   trunk/root/static/yui/tabview/tabview-min.js
   trunk/root/static/yui/tabview/tabview.js
   trunk/root/static/yui/treeview/README
   trunk/root/static/yui/treeview/assets/skins/sam/treeview-skin.css
   trunk/root/static/yui/treeview/assets/skins/sam/treeview.css
   trunk/root/static/yui/treeview/assets/treeview-core.css
   trunk/root/static/yui/treeview/assets/treeview-menu.css
   trunk/root/static/yui/treeview/assets/treeview.css
   trunk/root/static/yui/treeview/treeview-debug.js
   trunk/root/static/yui/treeview/treeview-min.js
   trunk/root/static/yui/treeview/treeview.js
   trunk/root/static/yui/utilities/README
   trunk/root/static/yui/utilities/utilities.js
   trunk/root/static/yui/yahoo-dom-event/yahoo-dom-event.js
   trunk/root/static/yui/yahoo/README
   trunk/root/static/yui/yahoo/yahoo-debug.js
   trunk/root/static/yui/yahoo/yahoo-min.js
   trunk/root/static/yui/yahoo/yahoo.js
   trunk/root/static/yui/yuiloader/README
   trunk/root/static/yui/yuiloader/yuiloader-beta-debug.js
   trunk/root/static/yui/yuiloader/yuiloader-beta-min.js
   trunk/root/static/yui/yuiloader/yuiloader-beta.js
   trunk/root/static/yui/yuitest/README
   trunk/root/static/yui/yuitest/assets/skins/sam/yuitest-skin.css
   trunk/root/static/yui/yuitest/assets/skins/sam/yuitest.css
   trunk/root/static/yui/yuitest/assets/testlogger.css
   trunk/root/static/yui/yuitest/assets/yuitest-core.css
Log:
 r4929 at wiggin:  chisel | 2008-04-11 08:57:11 +0100
 / removed YUI 2.4.x
 / added YUI 2.5.1



Property changes on: 
___________________________________________________________________
Name: svk:merge
   - 6a361f96-f029-0410-94f8-848cdd0f6ccf:/local/parley:4927
6fba2e3f-c318-0410-85fa-910d1bc53201:/local/parley:5151
c0683b51-46fc-0310-adae-a083e7ee0929:/local/berlios/parley:15762
f1659af6-751b-0410-a472-c93ec2bf8afc:/local/parley:1222
   + 6a361f96-f029-0410-94f8-848cdd0f6ccf:/local/parley:4929
6fba2e3f-c318-0410-85fa-910d1bc53201:/local/parley:5151
c0683b51-46fc-0310-adae-a083e7ee0929:/local/berlios/parley:15762
f1659af6-751b-0410-a472-c93ec2bf8afc:/local/parley:1222

Modified: trunk/root/static/yui/animation/README
===================================================================
--- trunk/root/static/yui/animation/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/animation/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,11 @@
 Animation Release Notes
 
-*** version 2.4.1 ***
-* No change
+*** version 2.5.1 ***
+* no change
 
+*** version 2.5.0 ***
+* replace toString overrides with static NAME property
+
 *** version 2.4.0 ***
 * calling stop() on an non-animated Anim no longer fires onComplete
 

Modified: trunk/root/static/yui/animation/animation-debug.js
===================================================================
--- trunk/root/static/yui/animation/animation-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/animation/animation-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +1,13 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
+(function() {
+
+var Y = YAHOO.util;
+
 /*
 Copyright (c) 2006, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
@@ -37,23 +41,25 @@
  * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
  */
 
-YAHOO.util.Anim = function(el, attributes, duration, method) {
+var Anim = function(el, attributes, duration, method) {
     if (!el) {
         YAHOO.log('element required to create Anim instance', 'error', 'Anim');
     }
     this.init(el, attributes, duration, method); 
 };
 
-YAHOO.util.Anim.prototype = {
+Anim.NAME = 'Anim';
+
+Anim.prototype = {
     /**
      * Provides a readable name for the Anim instance.
      * @method toString
      * @return {String}
      */
     toString: function() {
-        var el = this.getEl();
-        var id = el.id || el.tagName || el;
-        return ("Anim " + id);
+        var el = this.getEl() || {};
+        var id = el.id || el.tagName;
+        return (this.constructor.NAME + ': ' + id);
     },
     
     patterns: { // cached for performance
@@ -87,7 +93,7 @@
             val = (val > 0) ? val : 0;
         }
 
-        YAHOO.util.Dom.setStyle(this.getEl(), attr, val + unit);
+        Y.Dom.setStyle(this.getEl(), attr, val + unit);
     },                        
     
     /**
@@ -98,7 +104,7 @@
      */
     getAttribute: function(attr) {
         var el = this.getEl();
-        var val = YAHOO.util.Dom.getStyle(el, attr);
+        var val = Y.Dom.getStyle(el, attr);
 
         if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
             return parseFloat(val);
@@ -109,7 +115,7 @@
         var box = !!( a[2] ); // width or height
         
         // use offsets for width/height and abs pos top/left
-        if ( box || (YAHOO.util.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
+        if ( box || (Y.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
             val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
         } else { // default to zero for other 'auto'
             val = 0;
@@ -220,7 +226,7 @@
          * @private
          * @type HTMLElement
          */
-        el = YAHOO.util.Dom.get(el);
+        el = Y.Dom.get(el);
         
         /**
          * The collection of attributes to be animated.  
@@ -247,7 +253,7 @@
          * @property method
          * @type Function
          */
-        this.method = method || YAHOO.util.Easing.easeNone;
+        this.method = method || Y.Easing.easeNone;
 
         /**
          * Whether or not the duration should be treated as seconds.
@@ -271,14 +277,14 @@
          * @property totalFrames
          * @type Int
          */
-        this.totalFrames = YAHOO.util.AnimMgr.fps;
+        this.totalFrames = Y.AnimMgr.fps;
         
         /**
          * Changes the animated element
          * @method setEl
          */
         this.setEl = function(element) {
-            el = YAHOO.util.Dom.get(element);
+            el = Y.Dom.get(element);
         };
         
         /**
@@ -324,12 +330,12 @@
             
             this.currentFrame = 0;
             
-            this.totalFrames = ( this.useSeconds ) ? Math.ceil(YAHOO.util.AnimMgr.fps * this.duration) : this.duration;
+            this.totalFrames = ( this.useSeconds ) ? Math.ceil(Y.AnimMgr.fps * this.duration) : this.duration;
     
             if (this.duration === 0 && this.useSeconds) { // jump to last frame if zero second duration 
                 this.totalFrames = 1; 
             }
-            YAHOO.util.AnimMgr.registerElement(this);
+            Y.AnimMgr.registerElement(this);
             return true;
         };
           
@@ -347,7 +353,7 @@
                  this.currentFrame = this.totalFrames;
                  this._onTween.fire();
             }
-            YAHOO.util.AnimMgr.stop(this);
+            Y.AnimMgr.stop(this);
         };
         
         var onStart = function() {            
@@ -418,39 +424,39 @@
          * Custom event that fires after onStart, useful in subclassing
          * @private
          */    
-        this._onStart = new YAHOO.util.CustomEvent('_start', this, true);
+        this._onStart = new Y.CustomEvent('_start', this, true);
 
         /**
          * Custom event that fires when animation begins
          * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)
          * @event onStart
          */    
-        this.onStart = new YAHOO.util.CustomEvent('start', this);
+        this.onStart = new Y.CustomEvent('start', this);
         
         /**
          * Custom event that fires between each frame
          * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)
          * @event onTween
          */
-        this.onTween = new YAHOO.util.CustomEvent('tween', this);
+        this.onTween = new Y.CustomEvent('tween', this);
         
         /**
          * Custom event that fires after onTween
          * @private
          */
-        this._onTween = new YAHOO.util.CustomEvent('_tween', this, true);
+        this._onTween = new Y.CustomEvent('_tween', this, true);
         
         /**
          * Custom event that fires when animation ends
          * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)
          * @event onComplete
          */
-        this.onComplete = new YAHOO.util.CustomEvent('complete', this);
+        this.onComplete = new Y.CustomEvent('complete', this);
         /**
          * Custom event that fires after onComplete
          * @private
          */
-        this._onComplete = new YAHOO.util.CustomEvent('_complete', this, true);
+        this._onComplete = new Y.CustomEvent('_complete', this, true);
 
         this._onStart.subscribe(onStart);
         this._onTween.subscribe(onTween);
@@ -458,6 +464,8 @@
     }
 };
 
+    Y.Anim = Anim;
+})();
 /**
  * Handles animation queueing and threading.
  * Used by Anim and subclasses.
@@ -696,23 +704,19 @@
  * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
  */
-    YAHOO.util.ColorAnim = function(el, attributes, duration,  method) {
-        YAHOO.util.ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
+    var ColorAnim = function(el, attributes, duration,  method) {
+        ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
     };
     
-    YAHOO.extend(YAHOO.util.ColorAnim, YAHOO.util.Anim);
-    
+    ColorAnim.NAME = 'ColorAnim';
+
     // shorthand
     var Y = YAHOO.util;
-    var superclass = Y.ColorAnim.superclass;
-    var proto = Y.ColorAnim.prototype;
+    YAHOO.extend(ColorAnim, Y.Anim);
+
+    var superclass = ColorAnim.superclass;
+    var proto = ColorAnim.prototype;
     
-    proto.toString = function() {
-        var el = this.getEl();
-        var id = el.id || el.tagName;
-        return ("ColorAnim " + id);
-    };
-
     proto.patterns.color = /color$/i;
     proto.patterns.rgb            = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
     proto.patterns.hex            = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
@@ -808,8 +812,10 @@
             this.runtimeAttributes[attr].end = end;
         }
     };
+
+    Y.ColorAnim = ColorAnim;
 })();
-/*
+/*!
 TERMS OF USE - EASING EQUATIONS
 Open source under the BSD License.
 Copyright 2001 Robert Penner All rights reserved.
@@ -1159,7 +1165,7 @@
  * @requires YAHOO.util.Event
  * @requires YAHOO.util.CustomEvent 
  * @constructor
- * @extends YAHOO.util.Anim
+ * @extends YAHOO.util.ColorAnim
  * @param {String | HTMLElement} el Reference to the element that will be animated
  * @param {Object} attributes The attribute(s) to be animated.  
  * Each attribute is an object with at minimum a "to" or "by" member defined.  
@@ -1168,25 +1174,22 @@
  * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
  */
-    YAHOO.util.Motion = function(el, attributes, duration,  method) {
+    var Motion = function(el, attributes, duration,  method) {
         if (el) { // dont break existing subclasses not using YAHOO.extend
-            YAHOO.util.Motion.superclass.constructor.call(this, el, attributes, duration, method);
+            Motion.superclass.constructor.call(this, el, attributes, duration, method);
         }
     };
 
-    YAHOO.extend(YAHOO.util.Motion, YAHOO.util.ColorAnim);
-    
+
+    Motion.NAME = 'Motion';
+
     // shorthand
     var Y = YAHOO.util;
-    var superclass = Y.Motion.superclass;
-    var proto = Y.Motion.prototype;
+    YAHOO.extend(Motion, Y.ColorAnim);
+    
+    var superclass = Motion.superclass;
+    var proto = Motion.prototype;
 
-    proto.toString = function() {
-        var el = this.getEl();
-        var id = el.id || el.tagName;
-        return ("Motion " + id);
-    };
-    
     proto.patterns.points = /^points$/i;
     
     proto.setAttribute = function(attr, val, unit) {
@@ -1295,6 +1298,8 @@
     var isset = function(prop) {
         return (typeof prop !== 'undefined');
     };
+
+    Y.Motion = Motion;
 })();
 (function() {
 /**
@@ -1310,7 +1315,7 @@
  * @requires YAHOO.util.Dom
  * @requires YAHOO.util.Event
  * @requires YAHOO.util.CustomEvent 
- * @extends YAHOO.util.Anim
+ * @extends YAHOO.util.ColorAnim
  * @constructor
  * @param {String or HTMLElement} el Reference to the element that will be animated
  * @param {Object} attributes The attribute(s) to be animated.  
@@ -1320,25 +1325,21 @@
  * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
  */
-    YAHOO.util.Scroll = function(el, attributes, duration,  method) {
+    var Scroll = function(el, attributes, duration,  method) {
         if (el) { // dont break existing subclasses not using YAHOO.extend
-            YAHOO.util.Scroll.superclass.constructor.call(this, el, attributes, duration, method);
+            Scroll.superclass.constructor.call(this, el, attributes, duration, method);
         }
     };
 
-    YAHOO.extend(YAHOO.util.Scroll, YAHOO.util.ColorAnim);
-    
+    Scroll.NAME = 'Scroll';
+
     // shorthand
     var Y = YAHOO.util;
-    var superclass = Y.Scroll.superclass;
-    var proto = Y.Scroll.prototype;
+    YAHOO.extend(Scroll, Y.ColorAnim);
+    
+    var superclass = Scroll.superclass;
+    var proto = Scroll.prototype;
 
-    proto.toString = function() {
-        var el = this.getEl();
-        var id = el.id || el.tagName;
-        return ("Scroll " + id);
-    };
-
     proto.doMethod = function(attr, start, end) {
         var val = null;
     
@@ -1377,5 +1378,7 @@
             superclass.setAttribute.call(this, attr, val, unit);
         }
     };
+
+    Y.Scroll = Scroll;
 })();
-YAHOO.register("animation", YAHOO.util.Anim, {version: "2.4.1", build: "742"});
+YAHOO.register("animation", YAHOO.util.Anim, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/animation/animation-min.js
===================================================================
--- trunk/root/static/yui/animation/animation-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/animation/animation-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +1,23 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-YAHOO.util.Anim=function(B,A,C,D){if(!B){}this.init(B,A,C,D);};YAHOO.util.Anim.prototype={toString:function(){var A=this.getEl();var B=A.id||A.tagName||A;return("Anim "+B);},patterns:{noNegatives:/width|height|opacity|padding/i,offsetAttribute:/^((width|height)|(top|left))$/,defaultUnit:/width|height|top$|bottom$|left$|right$/i,offsetUnit:/\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i},doMethod:function(A,C,B){return this.method(this.currentFrame,C,B-C,this.totalFrames);},setAttribute:function(A,C,B){if(this.patterns.noNegatives.test(A)){C=(C>0)?C:0;}YAHOO.util.Dom.setStyle(this.getEl(),A,C+B);},getAttribute:function(A){var C=this.getEl();var E=YAHOO.util.Dom.getStyle(C,A);if(E!=="auto"&&!this.patterns.offsetUnit.test(E)){return parseFloat(E);}var B=this.patterns.offsetAttribute.exec(A)||[];var F=!!(B[3]);var D=!!(B[2]);if(D||(YAHOO.util.Dom.getStyle(C,"position")=="absolute"&&F)){E=C["offset"+B[0].charAt(0).toUpperCase()+B[0].substr(1)];}else{E=0;}return E;},getDefaultUnit:function(A)!
 {if(this.patterns.defaultUnit.test(A)){return"px";}return"";},setRuntimeAttribute:function(B){var G;var C;var D=this.attributes;this.runtimeAttributes[B]={};var F=function(H){return(typeof H!=="undefined");};if(!F(D[B]["to"])&&!F(D[B]["by"])){return false;}G=(F(D[B]["from"]))?D[B]["from"]:this.getAttribute(B);if(F(D[B]["to"])){C=D[B]["to"];}else{if(F(D[B]["by"])){if(G.constructor==Array){C=[];for(var E=0,A=G.length;E<A;++E){C[E]=G[E]+D[B]["by"][E]*1;}}else{C=G+D[B]["by"]*1;}}}this.runtimeAttributes[B].start=G;this.runtimeAttributes[B].end=C;this.runtimeAttributes[B].unit=(F(D[B].unit))?D[B]["unit"]:this.getDefaultUnit(B);return true;},init:function(C,H,G,A){var B=false;var D=null;var F=0;C=YAHOO.util.Dom.get(C);this.attributes=H||{};this.duration=!YAHOO.lang.isUndefined(G)?G:1;this.method=A||YAHOO.util.Easing.easeNone;this.useSeconds=true;this.currentFrame=0;this.totalFrames=YAHOO.util.AnimMgr.fps;this.setEl=function(K){C=YAHOO.util.Dom.get(K);};this.getEl=function(){return!
  C;};this.isAnimated=function(){return B;};this.getStartTime=f!
 unction(
){return D;};this.runtimeAttributes={};this.animate=function(){if(this.isAnimated()){return false;}this.currentFrame=0;this.totalFrames=(this.useSeconds)?Math.ceil(YAHOO.util.AnimMgr.fps*this.duration):this.duration;if(this.duration===0&&this.useSeconds){this.totalFrames=1;}YAHOO.util.AnimMgr.registerElement(this);return true;};this.stop=function(K){if(!this.isAnimated()){return false;}if(K){this.currentFrame=this.totalFrames;this._onTween.fire();}YAHOO.util.AnimMgr.stop(this);};var J=function(){this.onStart.fire();this.runtimeAttributes={};for(var K in this.attributes){this.setRuntimeAttribute(K);}B=true;F=0;D=new Date();};var I=function(){var M={duration:new Date()-this.getStartTime(),currentFrame:this.currentFrame};M.toString=function(){return("duration: "+M.duration+", currentFrame: "+M.currentFrame);};this.onTween.fire(M);var L=this.runtimeAttributes;for(var K in L){this.setAttribute(K,this.doMethod(K,L[K].start,L[K].end),L[K].unit);}F+=1;};var E=function(){var K=(new D!
 ate()-D)/1000;var L={duration:K,frames:F,fps:F/K};L.toString=function(){return("duration: "+L.duration+", frames: "+L.frames+", fps: "+L.fps);};B=false;F=0;this.onComplete.fire(L);};this._onStart=new YAHOO.util.CustomEvent("_start",this,true);this.onStart=new YAHOO.util.CustomEvent("start",this);this.onTween=new YAHOO.util.CustomEvent("tween",this);this._onTween=new YAHOO.util.CustomEvent("_tween",this,true);this.onComplete=new YAHOO.util.CustomEvent("complete",this);this._onComplete=new YAHOO.util.CustomEvent("_complete",this,true);this._onStart.subscribe(J);this._onTween.subscribe(I);this._onComplete.subscribe(E);}};YAHOO.util.AnimMgr=new function(){var C=null;var B=[];var A=0;this.fps=1000;this.delay=1;this.registerElement=function(F){B[B.length]=F;A+=1;F._onStart.fire();this.start();};this.unRegister=function(G,F){F=F||E(G);if(!G.isAnimated()||F==-1){return false;}G._onComplete.fire();B.splice(F,1);A-=1;if(A<=0){this.stop();}return true;};this.start=function(){if(C===nu!
 ll){C=setInterval(this.run,this.delay);}};this.stop=function(H!
 ){if(!H)
{clearInterval(C);for(var G=0,F=B.length;G<F;++G){this.unRegister(B[0],0);}B=[];C=null;A=0;}else{this.unRegister(H);}};this.run=function(){for(var H=0,F=B.length;H<F;++H){var G=B[H];if(!G||!G.isAnimated()){continue;}if(G.currentFrame<G.totalFrames||G.totalFrames===null){G.currentFrame+=1;if(G.useSeconds){D(G);}G._onTween.fire();}else{YAHOO.util.AnimMgr.stop(G,H);}}};var E=function(H){for(var G=0,F=B.length;G<F;++G){if(B[G]==H){return G;}}return -1;};var D=function(G){var J=G.totalFrames;var I=G.currentFrame;var H=(G.currentFrame*G.duration*1000/G.totalFrames);var F=(new Date()-G.getStartTime());var K=0;if(F<G.duration*1000){K=Math.round((F/H-1)*G.currentFrame);}else{K=J-(I+1);}if(K>0&&isFinite(K)){if(G.currentFrame+K>=J){K=J-(I+1);}G.currentFrame+=K;}};};YAHOO.util.Bezier=new function(){this.getPosition=function(E,D){var F=E.length;var C=[];for(var B=0;B<F;++B){C[B]=[E[B][0],E[B][1]];}for(var A=1;A<F;++A){for(B=0;B<F-A;++B){C[B][0]=(1-D)*C[B][0]+D*C[parseInt(B+1,10)][0];C[B]!
 [1]=(1-D)*C[B][1]+D*C[parseInt(B+1,10)][1];}}return[C[0][0],C[0][1]];};};(function(){YAHOO.util.ColorAnim=function(E,D,F,G){YAHOO.util.ColorAnim.superclass.constructor.call(this,E,D,F,G);};YAHOO.extend(YAHOO.util.ColorAnim,YAHOO.util.Anim);var B=YAHOO.util;var C=B.ColorAnim.superclass;var A=B.ColorAnim.prototype;A.toString=function(){var D=this.getEl();var E=D.id||D.tagName;return("ColorAnim "+E);};A.patterns.color=/color$/i;A.patterns.rgb=/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;A.patterns.hex=/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;A.patterns.hex3=/^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;A.patterns.transparent=/^transparent|rgba\(0, 0, 0, 0\)$/;A.parseColor=function(D){if(D.length==3){return D;}var E=this.patterns.hex.exec(D);if(E&&E.length==4){return[parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16)];}E=this.patterns.rgb.exec(D);if(E&&E.length==4){return[parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10)];
-}E=this.patterns.hex3.exec(D);if(E&&E.length==4){return[parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16)];}return null;};A.getAttribute=function(D){var F=this.getEl();if(this.patterns.color.test(D)){var G=YAHOO.util.Dom.getStyle(F,D);if(this.patterns.transparent.test(G)){var E=F.parentNode;G=B.Dom.getStyle(E,D);while(E&&this.patterns.transparent.test(G)){E=E.parentNode;G=B.Dom.getStyle(E,D);if(E.tagName.toUpperCase()=="HTML"){G="#fff";}}}}else{G=C.getAttribute.call(this,D);}return G;};A.doMethod=function(E,I,F){var H;if(this.patterns.color.test(E)){H=[];for(var G=0,D=I.length;G<D;++G){H[G]=C.doMethod.call(this,E,I[G],F[G]);}H="rgb("+Math.floor(H[0])+","+Math.floor(H[1])+","+Math.floor(H[2])+")";}else{H=C.doMethod.call(this,E,I,F);}return H;};A.setRuntimeAttribute=function(E){C.setRuntimeAttribute.call(this,E);if(this.patterns.color.test(E)){var G=this.attributes;var I=this.parseColor(this.runtimeAttributes[E].start);var F=this.parseColor(this.runtimeAttr!
 ibutes[E].end);if(typeof G[E]["to"]==="undefined"&&typeof G[E]["by"]!=="undefined"){F=this.parseColor(G[E].by);for(var H=0,D=I.length;H<D;++H){F[H]=I[H]+F[H];}}this.runtimeAttributes[E].start=I;this.runtimeAttributes[E].end=F;}};})();YAHOO.util.Easing={easeNone:function(B,A,D,C){return D*B/C+A;},easeIn:function(B,A,D,C){return D*(B/=C)*B+A;},easeOut:function(B,A,D,C){return -D*(B/=C)*(B-2)+A;},easeBoth:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B+A;}return -D/2*((--B)*(B-2)-1)+A;},easeInStrong:function(B,A,D,C){return D*(B/=C)*B*B*B+A;},easeOutStrong:function(B,A,D,C){return -D*((B=B/C-1)*B*B*B-1)+A;},easeBothStrong:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B*B*B+A;}return -D/2*((B-=2)*B*B*B-2)+A;},elasticIn:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return -(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;},elasticOut:function(C,A,G,F,B,E)!
 {if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}!
 if(!B||B
<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return B*Math.pow(2,-10*C)*Math.sin((C*F-D)*(2*Math.PI)/E)+G+A;},elasticBoth:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F/2)==2){return A+G;}if(!E){E=F*(0.3*1.5);}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}if(C<1){return -0.5*(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;}return B*Math.pow(2,-10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E)*0.5+G+A;},backIn:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*(B/=D)*B*((C+1)*B-C)+A;},backOut:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*((B=B/D-1)*B*((C+1)*B+C)+1)+A;},backBoth:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}if((B/=D/2)<1){return E/2*(B*B*(((C*=(1.525))+1)*B-C))+A;}return E/2*((B-=2)*B*(((C*=(1.525))+1)*B+C)+2)+A;},bounceIn:function(B,A,D,C){return D-YAHOO.util.Easing.bounceOut(C-B,0,D,C)+A;},bounceOut:function(B,A,D,C){if((B/=C)<(1/2.75)){return D*(7.!
 5625*B*B)+A;}else{if(B<(2/2.75)){return D*(7.5625*(B-=(1.5/2.75))*B+0.75)+A;}else{if(B<(2.5/2.75)){return D*(7.5625*(B-=(2.25/2.75))*B+0.9375)+A;}}}return D*(7.5625*(B-=(2.625/2.75))*B+0.984375)+A;},bounceBoth:function(B,A,D,C){if(B<C/2){return YAHOO.util.Easing.bounceIn(B*2,0,D,C)*0.5+A;}return YAHOO.util.Easing.bounceOut(B*2-C,0,D,C)*0.5+D*0.5+A;}};(function(){YAHOO.util.Motion=function(G,F,H,I){if(G){YAHOO.util.Motion.superclass.constructor.call(this,G,F,H,I);}};YAHOO.extend(YAHOO.util.Motion,YAHOO.util.ColorAnim);var D=YAHOO.util;var E=D.Motion.superclass;var B=D.Motion.prototype;B.toString=function(){var F=this.getEl();var G=F.id||F.tagName;return("Motion "+G);};B.patterns.points=/^points$/i;B.setAttribute=function(F,H,G){if(this.patterns.points.test(F)){G=G||"px";E.setAttribute.call(this,"left",H[0],G);E.setAttribute.call(this,"top",H[1],G);}else{E.setAttribute.call(this,F,H,G);}};B.getAttribute=function(F){if(this.patterns.points.test(F)){var G=[E.getAttribute.call(t!
 his,"left"),E.getAttribute.call(this,"top")];}else{G=E.getAttr!
 ibute.ca
ll(this,F);}return G;};B.doMethod=function(F,J,G){var I=null;if(this.patterns.points.test(F)){var H=this.method(this.currentFrame,0,100,this.totalFrames)/100;I=D.Bezier.getPosition(this.runtimeAttributes[F],H);}else{I=E.doMethod.call(this,F,J,G);}return I;};B.setRuntimeAttribute=function(O){if(this.patterns.points.test(O)){var G=this.getEl();var I=this.attributes;var F;var K=I["points"]["control"]||[];var H;var L,N;if(K.length>0&&!(K[0] instanceof Array)){K=[K];}else{var J=[];for(L=0,N=K.length;L<N;++L){J[L]=K[L];}K=J;}if(D.Dom.getStyle(G,"position")=="static"){D.Dom.setStyle(G,"position","relative");}if(C(I["points"]["from"])){D.Dom.setXY(G,I["points"]["from"]);}else{D.Dom.setXY(G,D.Dom.getXY(G));}F=this.getAttribute("points");if(C(I["points"]["to"])){H=A.call(this,I["points"]["to"],F);var M=D.Dom.getXY(this.getEl());for(L=0,N=K.length;L<N;++L){K[L]=A.call(this,K[L],F);}}else{if(C(I["points"]["by"])){H=[F[0]+I["points"]["by"][0],F[1]+I["points"]["by"][1]];for(L=0,N=K.length!
 ;L<N;++L){K[L]=[F[0]+K[L][0],F[1]+K[L][1]];}}}this.runtimeAttributes[O]=[F];if(K.length>0){this.runtimeAttributes[O]=this.runtimeAttributes[O].concat(K);}this.runtimeAttributes[O][this.runtimeAttributes[O].length]=H;}else{E.setRuntimeAttribute.call(this,O);}};var A=function(F,H){var G=D.Dom.getXY(this.getEl());F=[F[0]-G[0]+H[0],F[1]-G[1]+H[1]];return F;};var C=function(F){return(typeof F!=="undefined");};})();(function(){YAHOO.util.Scroll=function(E,D,F,G){if(E){YAHOO.util.Scroll.superclass.constructor.call(this,E,D,F,G);}};YAHOO.extend(YAHOO.util.Scroll,YAHOO.util.ColorAnim);var B=YAHOO.util;var C=B.Scroll.superclass;var A=B.Scroll.prototype;A.toString=function(){var D=this.getEl();var E=D.id||D.tagName;return("Scroll "+E);};A.doMethod=function(D,G,E){var F=null;if(D=="scroll"){F=[this.method(this.currentFrame,G[0],E[0]-G[0],this.totalFrames),this.method(this.currentFrame,G[1],E[1]-G[1],this.totalFrames)];
-}else{F=C.doMethod.call(this,D,G,E);}return F;};A.getAttribute=function(D){var F=null;var E=this.getEl();if(D=="scroll"){F=[E.scrollLeft,E.scrollTop];}else{F=C.getAttribute.call(this,D);}return F;};A.setAttribute=function(D,G,F){var E=this.getEl();if(D=="scroll"){E.scrollLeft=G[0];E.scrollTop=G[1];}else{C.setAttribute.call(this,D,G,F);}};})();YAHOO.register("animation",YAHOO.util.Anim,{version:"2.4.1",build:"742"});
\ No newline at end of file
+(function(){var B=YAHOO.util;var A=function(D,C,E,F){if(!D){}this.init(D,C,E,F);};A.NAME="Anim";A.prototype={toString:function(){var C=this.getEl()||{};var D=C.id||C.tagName;return(this.constructor.NAME+": "+D);},patterns:{noNegatives:/width|height|opacity|padding/i,offsetAttribute:/^((width|height)|(top|left))$/,defaultUnit:/width|height|top$|bottom$|left$|right$/i,offsetUnit:/\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i},doMethod:function(C,E,D){return this.method(this.currentFrame,E,D-E,this.totalFrames);},setAttribute:function(C,E,D){if(this.patterns.noNegatives.test(C)){E=(E>0)?E:0;}B.Dom.setStyle(this.getEl(),C,E+D);},getAttribute:function(C){var E=this.getEl();var G=B.Dom.getStyle(E,C);if(G!=="auto"&&!this.patterns.offsetUnit.test(G)){return parseFloat(G);}var D=this.patterns.offsetAttribute.exec(C)||[];var H=!!(D[3]);var F=!!(D[2]);if(F||(B.Dom.getStyle(E,"position")=="absolute"&&H)){G=E["offset"+D[0].charAt(0).toUpperCase()+D[0].substr(1)];}else{G=0;}return G;},getDefaultUnit!
 :function(C){if(this.patterns.defaultUnit.test(C)){return"px";}return"";},setRuntimeAttribute:function(D){var I;var E;var F=this.attributes;this.runtimeAttributes[D]={};var H=function(J){return(typeof J!=="undefined");};if(!H(F[D]["to"])&&!H(F[D]["by"])){return false;}I=(H(F[D]["from"]))?F[D]["from"]:this.getAttribute(D);if(H(F[D]["to"])){E=F[D]["to"];}else{if(H(F[D]["by"])){if(I.constructor==Array){E=[];for(var G=0,C=I.length;G<C;++G){E[G]=I[G]+F[D]["by"][G]*1;}}else{E=I+F[D]["by"]*1;}}}this.runtimeAttributes[D].start=I;this.runtimeAttributes[D].end=E;this.runtimeAttributes[D].unit=(H(F[D].unit))?F[D]["unit"]:this.getDefaultUnit(D);return true;},init:function(E,J,I,C){var D=false;var F=null;var H=0;E=B.Dom.get(E);this.attributes=J||{};this.duration=!YAHOO.lang.isUndefined(I)?I:1;this.method=C||B.Easing.easeNone;this.useSeconds=true;this.currentFrame=0;this.totalFrames=B.AnimMgr.fps;this.setEl=function(M){E=B.Dom.get(M);};this.getEl=function(){return E;};this.isAnimated=fun!
 ction(){return D;};this.getStartTime=function(){return F;};thi!
 s.runtim
eAttributes={};this.animate=function(){if(this.isAnimated()){return false;}this.currentFrame=0;this.totalFrames=(this.useSeconds)?Math.ceil(B.AnimMgr.fps*this.duration):this.duration;if(this.duration===0&&this.useSeconds){this.totalFrames=1;}B.AnimMgr.registerElement(this);return true;};this.stop=function(M){if(!this.isAnimated()){return false;}if(M){this.currentFrame=this.totalFrames;this._onTween.fire();}B.AnimMgr.stop(this);};var L=function(){this.onStart.fire();this.runtimeAttributes={};for(var M in this.attributes){this.setRuntimeAttribute(M);}D=true;H=0;F=new Date();};var K=function(){var O={duration:new Date()-this.getStartTime(),currentFrame:this.currentFrame};O.toString=function(){return("duration: "+O.duration+", currentFrame: "+O.currentFrame);};this.onTween.fire(O);var N=this.runtimeAttributes;for(var M in N){this.setAttribute(M,this.doMethod(M,N[M].start,N[M].end),N[M].unit);}H+=1;};var G=function(){var M=(new Date()-F)/1000;var N={duration:M,frames:H,fps:H/M};N!
 .toString=function(){return("duration: "+N.duration+", frames: "+N.frames+", fps: "+N.fps);};D=false;H=0;this.onComplete.fire(N);};this._onStart=new B.CustomEvent("_start",this,true);this.onStart=new B.CustomEvent("start",this);this.onTween=new B.CustomEvent("tween",this);this._onTween=new B.CustomEvent("_tween",this,true);this.onComplete=new B.CustomEvent("complete",this);this._onComplete=new B.CustomEvent("_complete",this,true);this._onStart.subscribe(L);this._onTween.subscribe(K);this._onComplete.subscribe(G);}};B.Anim=A;})();YAHOO.util.AnimMgr=new function(){var C=null;var B=[];var A=0;this.fps=1000;this.delay=1;this.registerElement=function(F){B[B.length]=F;A+=1;F._onStart.fire();this.start();};this.unRegister=function(G,F){F=F||E(G);if(!G.isAnimated()||F==-1){return false;}G._onComplete.fire();B.splice(F,1);A-=1;if(A<=0){this.stop();}return true;};this.start=function(){if(C===null){C=setInterval(this.run,this.delay);}};this.stop=function(H){if(!H){clearInterval(C);for!
 (var G=0,F=B.length;G<F;++G){this.unRegister(B[0],0);}B=[];C=n!
 ull;A=0;
}else{this.unRegister(H);}};this.run=function(){for(var H=0,F=B.length;H<F;++H){var G=B[H];if(!G||!G.isAnimated()){continue;}if(G.currentFrame<G.totalFrames||G.totalFrames===null){G.currentFrame+=1;if(G.useSeconds){D(G);}G._onTween.fire();}else{YAHOO.util.AnimMgr.stop(G,H);}}};var E=function(H){for(var G=0,F=B.length;G<F;++G){if(B[G]==H){return G;}}return -1;};var D=function(G){var J=G.totalFrames;var I=G.currentFrame;var H=(G.currentFrame*G.duration*1000/G.totalFrames);var F=(new Date()-G.getStartTime());var K=0;if(F<G.duration*1000){K=Math.round((F/H-1)*G.currentFrame);}else{K=J-(I+1);}if(K>0&&isFinite(K)){if(G.currentFrame+K>=J){K=J-(I+1);}G.currentFrame+=K;}};};YAHOO.util.Bezier=new function(){this.getPosition=function(E,D){var F=E.length;var C=[];for(var B=0;B<F;++B){C[B]=[E[B][0],E[B][1]];}for(var A=1;A<F;++A){for(B=0;B<F-A;++B){C[B][0]=(1-D)*C[B][0]+D*C[parseInt(B+1,10)][0];C[B][1]=(1-D)*C[B][1]+D*C[parseInt(B+1,10)][1];}}return[C[0][0],C[0][1]];};};(function(){var A=!
 function(F,E,G,H){A.superclass.constructor.call(this,F,E,G,H);};A.NAME="ColorAnim";var C=YAHOO.util;YAHOO.extend(A,C.Anim);var D=A.superclass;var B=A.prototype;B.patterns.color=/color$/i;B.patterns.rgb=/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;B.patterns.hex=/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;B.patterns.hex3=/^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;B.patterns.transparent=/^transparent|rgba\(0, 0, 0, 0\)$/;B.parseColor=function(E){if(E.length==3){return E;}var F=this.patterns.hex.exec(E);if(F&&F.length==4){return[parseInt(F[1],16),parseInt(F[2],16),parseInt(F[3],16)];}F=this.patterns.rgb.exec(E);if(F&&F.length==4){return[parseInt(F[1],10),parseInt(F[2],10),parseInt(F[3],10)];}F=this.patterns.hex3.exec(E);if(F&&F.length==4){return[parseInt(F[1]+F[1],16),parseInt(F[2]+F[2],16),parseInt(F[3]+F[3],16)];}return null;};B.getAttribute=function(E){var G=this.getEl();if(this.patterns.color.test(E)){var H=YAHOO.util.Dom.getStyle(G,E);
+if(this.patterns.transparent.test(H)){var F=G.parentNode;H=C.Dom.getStyle(F,E);while(F&&this.patterns.transparent.test(H)){F=F.parentNode;H=C.Dom.getStyle(F,E);if(F.tagName.toUpperCase()=="HTML"){H="#fff";}}}}else{H=D.getAttribute.call(this,E);}return H;};B.doMethod=function(F,J,G){var I;if(this.patterns.color.test(F)){I=[];for(var H=0,E=J.length;H<E;++H){I[H]=D.doMethod.call(this,F,J[H],G[H]);}I="rgb("+Math.floor(I[0])+","+Math.floor(I[1])+","+Math.floor(I[2])+")";}else{I=D.doMethod.call(this,F,J,G);}return I;};B.setRuntimeAttribute=function(F){D.setRuntimeAttribute.call(this,F);if(this.patterns.color.test(F)){var H=this.attributes;var J=this.parseColor(this.runtimeAttributes[F].start);var G=this.parseColor(this.runtimeAttributes[F].end);if(typeof H[F]["to"]==="undefined"&&typeof H[F]["by"]!=="undefined"){G=this.parseColor(H[F].by);for(var I=0,E=J.length;I<E;++I){G[I]=J[I]+G[I];}}this.runtimeAttributes[F].start=J;this.runtimeAttributes[F].end=G;}};C.ColorAnim=A;})();
+/*
+TERMS OF USE - EASING EQUATIONS
+Open source under the BSD License.
+Copyright 2001 Robert Penner All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+YAHOO.util.Easing={easeNone:function(B,A,D,C){return D*B/C+A;},easeIn:function(B,A,D,C){return D*(B/=C)*B+A;},easeOut:function(B,A,D,C){return -D*(B/=C)*(B-2)+A;},easeBoth:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B+A;}return -D/2*((--B)*(B-2)-1)+A;},easeInStrong:function(B,A,D,C){return D*(B/=C)*B*B*B+A;},easeOutStrong:function(B,A,D,C){return -D*((B=B/C-1)*B*B*B-1)+A;},easeBothStrong:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B*B*B+A;}return -D/2*((B-=2)*B*B*B-2)+A;},elasticIn:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return -(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;},elasticOut:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return B*Math.pow(2,-10*C)*Math.sin((C*F-D)*(2*Math.PI)/E)+G+A;},elasticBoth:function(C,A,G,F,!
 B,E){if(C==0){return A;}if((C/=F/2)==2){return A+G;}if(!E){E=F*(0.3*1.5);}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}if(C<1){return -0.5*(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;}return B*Math.pow(2,-10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E)*0.5+G+A;},backIn:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*(B/=D)*B*((C+1)*B-C)+A;},backOut:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*((B=B/D-1)*B*((C+1)*B+C)+1)+A;},backBoth:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}if((B/=D/2)<1){return E/2*(B*B*(((C*=(1.525))+1)*B-C))+A;}return E/2*((B-=2)*B*(((C*=(1.525))+1)*B+C)+2)+A;},bounceIn:function(B,A,D,C){return D-YAHOO.util.Easing.bounceOut(C-B,0,D,C)+A;},bounceOut:function(B,A,D,C){if((B/=C)<(1/2.75)){return D*(7.5625*B*B)+A;}else{if(B<(2/2.75)){return D*(7.5625*(B-=(1.5/2.75))*B+0.75)+A;}else{if(B<(2.5/2.75)){return D*(7.5625*(B-=(2.25/2.75))*B+0.9375)+A;}}}return D*(7.562!
 5*(B-=(2.625/2.75))*B+0.984375)+A;},bounceBoth:function(B,A,D,!
 C){if(B<
C/2){return YAHOO.util.Easing.bounceIn(B*2,0,D,C)*0.5+A;}return YAHOO.util.Easing.bounceOut(B*2-C,0,D,C)*0.5+D*0.5+A;}};(function(){var A=function(H,G,I,J){if(H){A.superclass.constructor.call(this,H,G,I,J);}};A.NAME="Motion";var E=YAHOO.util;YAHOO.extend(A,E.ColorAnim);var F=A.superclass;var C=A.prototype;C.patterns.points=/^points$/i;C.setAttribute=function(G,I,H){if(this.patterns.points.test(G)){H=H||"px";F.setAttribute.call(this,"left",I[0],H);F.setAttribute.call(this,"top",I[1],H);}else{F.setAttribute.call(this,G,I,H);}};C.getAttribute=function(G){if(this.patterns.points.test(G)){var H=[F.getAttribute.call(this,"left"),F.getAttribute.call(this,"top")];}else{H=F.getAttribute.call(this,G);}return H;};C.doMethod=function(G,K,H){var J=null;if(this.patterns.points.test(G)){var I=this.method(this.currentFrame,0,100,this.totalFrames)/100;J=E.Bezier.getPosition(this.runtimeAttributes[G],I);}else{J=F.doMethod.call(this,G,K,H);}return J;};C.setRuntimeAttribute=function(P){if(this.!
 patterns.points.test(P)){var H=this.getEl();var J=this.attributes;var G;var L=J["points"]["control"]||[];var I;var M,O;if(L.length>0&&!(L[0] instanceof Array)){L=[L];}else{var K=[];for(M=0,O=L.length;M<O;++M){K[M]=L[M];}L=K;}if(E.Dom.getStyle(H,"position")=="static"){E.Dom.setStyle(H,"position","relative");}if(D(J["points"]["from"])){E.Dom.setXY(H,J["points"]["from"]);}else{E.Dom.setXY(H,E.Dom.getXY(H));}G=this.getAttribute("points");if(D(J["points"]["to"])){I=B.call(this,J["points"]["to"],G);
+var N=E.Dom.getXY(this.getEl());for(M=0,O=L.length;M<O;++M){L[M]=B.call(this,L[M],G);}}else{if(D(J["points"]["by"])){I=[G[0]+J["points"]["by"][0],G[1]+J["points"]["by"][1]];for(M=0,O=L.length;M<O;++M){L[M]=[G[0]+L[M][0],G[1]+L[M][1]];}}}this.runtimeAttributes[P]=[G];if(L.length>0){this.runtimeAttributes[P]=this.runtimeAttributes[P].concat(L);}this.runtimeAttributes[P][this.runtimeAttributes[P].length]=I;}else{F.setRuntimeAttribute.call(this,P);}};var B=function(G,I){var H=E.Dom.getXY(this.getEl());G=[G[0]-H[0]+I[0],G[1]-H[1]+I[1]];return G;};var D=function(G){return(typeof G!=="undefined");};E.Motion=A;})();(function(){var D=function(F,E,G,H){if(F){D.superclass.constructor.call(this,F,E,G,H);}};D.NAME="Scroll";var B=YAHOO.util;YAHOO.extend(D,B.ColorAnim);var C=D.superclass;var A=D.prototype;A.doMethod=function(E,H,F){var G=null;if(E=="scroll"){G=[this.method(this.currentFrame,H[0],F[0]-H[0],this.totalFrames),this.method(this.currentFrame,H[1],F[1]-H[1],this.totalFrames)];}e!
 lse{G=C.doMethod.call(this,E,H,F);}return G;};A.getAttribute=function(E){var G=null;var F=this.getEl();if(E=="scroll"){G=[F.scrollLeft,F.scrollTop];}else{G=C.getAttribute.call(this,E);}return G;};A.setAttribute=function(E,H,G){var F=this.getEl();if(E=="scroll"){F.scrollLeft=H[0];F.scrollTop=H[1];}else{C.setAttribute.call(this,E,H,G);}};B.Scroll=D;})();YAHOO.register("animation",YAHOO.util.Anim,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/animation/animation.js
===================================================================
--- trunk/root/static/yui/animation/animation.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/animation/animation.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +1,13 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
+(function() {
+
+var Y = YAHOO.util;
+
 /*
 Copyright (c) 2006, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
@@ -37,22 +41,24 @@
  * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
  */
 
-YAHOO.util.Anim = function(el, attributes, duration, method) {
+var Anim = function(el, attributes, duration, method) {
     if (!el) {
     }
     this.init(el, attributes, duration, method); 
 };
 
-YAHOO.util.Anim.prototype = {
+Anim.NAME = 'Anim';
+
+Anim.prototype = {
     /**
      * Provides a readable name for the Anim instance.
      * @method toString
      * @return {String}
      */
     toString: function() {
-        var el = this.getEl();
-        var id = el.id || el.tagName || el;
-        return ("Anim " + id);
+        var el = this.getEl() || {};
+        var id = el.id || el.tagName;
+        return (this.constructor.NAME + ': ' + id);
     },
     
     patterns: { // cached for performance
@@ -86,7 +92,7 @@
             val = (val > 0) ? val : 0;
         }
 
-        YAHOO.util.Dom.setStyle(this.getEl(), attr, val + unit);
+        Y.Dom.setStyle(this.getEl(), attr, val + unit);
     },                        
     
     /**
@@ -97,7 +103,7 @@
      */
     getAttribute: function(attr) {
         var el = this.getEl();
-        var val = YAHOO.util.Dom.getStyle(el, attr);
+        var val = Y.Dom.getStyle(el, attr);
 
         if (val !== 'auto' && !this.patterns.offsetUnit.test(val)) {
             return parseFloat(val);
@@ -108,7 +114,7 @@
         var box = !!( a[2] ); // width or height
         
         // use offsets for width/height and abs pos top/left
-        if ( box || (YAHOO.util.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
+        if ( box || (Y.Dom.getStyle(el, 'position') == 'absolute' && pos) ) {
             val = el['offset' + a[0].charAt(0).toUpperCase() + a[0].substr(1)];
         } else { // default to zero for other 'auto'
             val = 0;
@@ -219,7 +225,7 @@
          * @private
          * @type HTMLElement
          */
-        el = YAHOO.util.Dom.get(el);
+        el = Y.Dom.get(el);
         
         /**
          * The collection of attributes to be animated.  
@@ -246,7 +252,7 @@
          * @property method
          * @type Function
          */
-        this.method = method || YAHOO.util.Easing.easeNone;
+        this.method = method || Y.Easing.easeNone;
 
         /**
          * Whether or not the duration should be treated as seconds.
@@ -270,14 +276,14 @@
          * @property totalFrames
          * @type Int
          */
-        this.totalFrames = YAHOO.util.AnimMgr.fps;
+        this.totalFrames = Y.AnimMgr.fps;
         
         /**
          * Changes the animated element
          * @method setEl
          */
         this.setEl = function(element) {
-            el = YAHOO.util.Dom.get(element);
+            el = Y.Dom.get(element);
         };
         
         /**
@@ -320,12 +326,12 @@
             
             this.currentFrame = 0;
             
-            this.totalFrames = ( this.useSeconds ) ? Math.ceil(YAHOO.util.AnimMgr.fps * this.duration) : this.duration;
+            this.totalFrames = ( this.useSeconds ) ? Math.ceil(Y.AnimMgr.fps * this.duration) : this.duration;
     
             if (this.duration === 0 && this.useSeconds) { // jump to last frame if zero second duration 
                 this.totalFrames = 1; 
             }
-            YAHOO.util.AnimMgr.registerElement(this);
+            Y.AnimMgr.registerElement(this);
             return true;
         };
           
@@ -343,7 +349,7 @@
                  this.currentFrame = this.totalFrames;
                  this._onTween.fire();
             }
-            YAHOO.util.AnimMgr.stop(this);
+            Y.AnimMgr.stop(this);
         };
         
         var onStart = function() {            
@@ -414,39 +420,39 @@
          * Custom event that fires after onStart, useful in subclassing
          * @private
          */    
-        this._onStart = new YAHOO.util.CustomEvent('_start', this, true);
+        this._onStart = new Y.CustomEvent('_start', this, true);
 
         /**
          * Custom event that fires when animation begins
          * Listen via subscribe method (e.g. myAnim.onStart.subscribe(someFunction)
          * @event onStart
          */    
-        this.onStart = new YAHOO.util.CustomEvent('start', this);
+        this.onStart = new Y.CustomEvent('start', this);
         
         /**
          * Custom event that fires between each frame
          * Listen via subscribe method (e.g. myAnim.onTween.subscribe(someFunction)
          * @event onTween
          */
-        this.onTween = new YAHOO.util.CustomEvent('tween', this);
+        this.onTween = new Y.CustomEvent('tween', this);
         
         /**
          * Custom event that fires after onTween
          * @private
          */
-        this._onTween = new YAHOO.util.CustomEvent('_tween', this, true);
+        this._onTween = new Y.CustomEvent('_tween', this, true);
         
         /**
          * Custom event that fires when animation ends
          * Listen via subscribe method (e.g. myAnim.onComplete.subscribe(someFunction)
          * @event onComplete
          */
-        this.onComplete = new YAHOO.util.CustomEvent('complete', this);
+        this.onComplete = new Y.CustomEvent('complete', this);
         /**
          * Custom event that fires after onComplete
          * @private
          */
-        this._onComplete = new YAHOO.util.CustomEvent('_complete', this, true);
+        this._onComplete = new Y.CustomEvent('_complete', this, true);
 
         this._onStart.subscribe(onStart);
         this._onTween.subscribe(onTween);
@@ -454,6 +460,8 @@
     }
 };
 
+    Y.Anim = Anim;
+})();
 /**
  * Handles animation queueing and threading.
  * Used by Anim and subclasses.
@@ -692,23 +700,19 @@
  * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
  */
-    YAHOO.util.ColorAnim = function(el, attributes, duration,  method) {
-        YAHOO.util.ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
+    var ColorAnim = function(el, attributes, duration,  method) {
+        ColorAnim.superclass.constructor.call(this, el, attributes, duration, method);
     };
     
-    YAHOO.extend(YAHOO.util.ColorAnim, YAHOO.util.Anim);
-    
+    ColorAnim.NAME = 'ColorAnim';
+
     // shorthand
     var Y = YAHOO.util;
-    var superclass = Y.ColorAnim.superclass;
-    var proto = Y.ColorAnim.prototype;
+    YAHOO.extend(ColorAnim, Y.Anim);
+
+    var superclass = ColorAnim.superclass;
+    var proto = ColorAnim.prototype;
     
-    proto.toString = function() {
-        var el = this.getEl();
-        var id = el.id || el.tagName;
-        return ("ColorAnim " + id);
-    };
-
     proto.patterns.color = /color$/i;
     proto.patterns.rgb            = /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;
     proto.patterns.hex            = /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;
@@ -804,8 +808,10 @@
             this.runtimeAttributes[attr].end = end;
         }
     };
+
+    Y.ColorAnim = ColorAnim;
 })();
-/*
+/*!
 TERMS OF USE - EASING EQUATIONS
 Open source under the BSD License.
 Copyright 2001 Robert Penner All rights reserved.
@@ -1155,7 +1161,7 @@
  * @requires YAHOO.util.Event
  * @requires YAHOO.util.CustomEvent 
  * @constructor
- * @extends YAHOO.util.Anim
+ * @extends YAHOO.util.ColorAnim
  * @param {String | HTMLElement} el Reference to the element that will be animated
  * @param {Object} attributes The attribute(s) to be animated.  
  * Each attribute is an object with at minimum a "to" or "by" member defined.  
@@ -1164,25 +1170,22 @@
  * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
  */
-    YAHOO.util.Motion = function(el, attributes, duration,  method) {
+    var Motion = function(el, attributes, duration,  method) {
         if (el) { // dont break existing subclasses not using YAHOO.extend
-            YAHOO.util.Motion.superclass.constructor.call(this, el, attributes, duration, method);
+            Motion.superclass.constructor.call(this, el, attributes, duration, method);
         }
     };
 
-    YAHOO.extend(YAHOO.util.Motion, YAHOO.util.ColorAnim);
-    
+
+    Motion.NAME = 'Motion';
+
     // shorthand
     var Y = YAHOO.util;
-    var superclass = Y.Motion.superclass;
-    var proto = Y.Motion.prototype;
+    YAHOO.extend(Motion, Y.ColorAnim);
+    
+    var superclass = Motion.superclass;
+    var proto = Motion.prototype;
 
-    proto.toString = function() {
-        var el = this.getEl();
-        var id = el.id || el.tagName;
-        return ("Motion " + id);
-    };
-    
     proto.patterns.points = /^points$/i;
     
     proto.setAttribute = function(attr, val, unit) {
@@ -1291,6 +1294,8 @@
     var isset = function(prop) {
         return (typeof prop !== 'undefined');
     };
+
+    Y.Motion = Motion;
 })();
 (function() {
 /**
@@ -1306,7 +1311,7 @@
  * @requires YAHOO.util.Dom
  * @requires YAHOO.util.Event
  * @requires YAHOO.util.CustomEvent 
- * @extends YAHOO.util.Anim
+ * @extends YAHOO.util.ColorAnim
  * @constructor
  * @param {String or HTMLElement} el Reference to the element that will be animated
  * @param {Object} attributes The attribute(s) to be animated.  
@@ -1316,25 +1321,21 @@
  * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
  * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
  */
-    YAHOO.util.Scroll = function(el, attributes, duration,  method) {
+    var Scroll = function(el, attributes, duration,  method) {
         if (el) { // dont break existing subclasses not using YAHOO.extend
-            YAHOO.util.Scroll.superclass.constructor.call(this, el, attributes, duration, method);
+            Scroll.superclass.constructor.call(this, el, attributes, duration, method);
         }
     };
 
-    YAHOO.extend(YAHOO.util.Scroll, YAHOO.util.ColorAnim);
-    
+    Scroll.NAME = 'Scroll';
+
     // shorthand
     var Y = YAHOO.util;
-    var superclass = Y.Scroll.superclass;
-    var proto = Y.Scroll.prototype;
+    YAHOO.extend(Scroll, Y.ColorAnim);
+    
+    var superclass = Scroll.superclass;
+    var proto = Scroll.prototype;
 
-    proto.toString = function() {
-        var el = this.getEl();
-        var id = el.id || el.tagName;
-        return ("Scroll " + id);
-    };
-
     proto.doMethod = function(attr, start, end) {
         var val = null;
     
@@ -1373,5 +1374,7 @@
             superclass.setAttribute.call(this, attr, val, unit);
         }
     };
+
+    Y.Scroll = Scroll;
 })();
-YAHOO.register("animation", YAHOO.util.Anim, {version: "2.4.1", build: "742"});
+YAHOO.register("animation", YAHOO.util.Anim, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/assets/skins/sam/asc.gif
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/assets/skins/sam/asc.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: trunk/root/static/yui/assets/skins/sam/autocomplete.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/autocomplete.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/autocomplete.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-skin-sam .yui-ac{position:relative;font-family:arial;font-size:100%;}.yui-skin-sam .yui-ac-input{position:absolute;width:100%;}.yui-skin-sam .yui-ac-container{position:absolute;top:1.6em;width:100%;}.yui-skin-sam .yui-ac-content{position:absolute;width:100%;border:1px solid #808080;background:#fff;overflow:hidden;z-index:9050;}.yui-skin-sam .yui-ac-shadow{position:absolute;margin:.3em;width:100%;background:#000;-moz-opacity:0.10;opacity:.10;filter:alpha(opacity=10);z-index:9049;}.yui-skin-sam .yui-ac-content ul{margin:0;padding:0;width:100%;}.yui-skin-sam .yui-ac-content li{margin:0;padding:2px 5px;cursor:default;white-space:nowrap;}.yui-skin-sam .yui-ac-content li.yui-ac-prehighlight{background:#B3D4FF;}.yui-skin-sam .yui-ac-content li.yui-ac-highlight{background:#426FD9;color:#FFF;}

Modified: trunk/root/static/yui/assets/skins/sam/button.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/button.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/button.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-button{display:-moz-inline-box;display:inline-block;vertical-align:text-bottom;}.yui-button .first-child{display:block;*display:inline-block;}.yui-button button,.yui-button a{display:block;*display:inline-block;border:none;margin:0;}.yui-button button{background-color:transparent;*overflow:visible;cursor:pointer;}.yui-button a{text-decoration:none;}.yui-skin-sam .yui-button{border-width:1px 0;border-style:solid;border-color:#808080;background:url(sprite.png) repeat-x 0 0;margin:auto .25em;}.yui-skin-sam .yui-button .first-child{border-width:0 1px;border-style:solid;border-color:#808080;margin:0 -1px;*position:relative;*left:-1px;}.yui-skin-sam .yui-button button,.yui-skin-sam .yui-button a{padding:0 10px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-button a{*line-height:2;}.yui-skin-sam .yui-split-button button,.yui-skin-sam .yui-menu-button button{padding-right:20px;background-position:right center;backgro!
 und-repeat:no-repeat;}.yui-skin-sam .yui-menu-button button{background-image:url(menu-button-arrow.png);}.yui-skin-sam .yui-split-button button{background-image:url(split-button-arrow.png);}.yui-skin-sam .yui-button-focus{border-color:#7D98B8;background-position:0 -1300px;}.yui-skin-sam .yui-button-focus .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-button-focus button,.yui-skin-sam .yui-button-focus a{color:#000;}.yui-skin-sam .yui-split-button-focus button{background-image:url(split-button-arrow-focus.png);}.yui-skin-sam .yui-button-hover{border-color:#7D98B8;background-position:0 -1300px;}.yui-skin-sam .yui-button-hover .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-button-hover button,.yui-skin-sam .yui-button-hover a{color:#000;}.yui-skin-sam .yui-split-button-hover button{background-image:url(split-button-arrow-hover.png);}.yui-skin-sam .yui-button-active{border-color:#7D98B8;background-position:0 -1700px;}.yui-skin-sam .yui-button-active .first-child{b!
 order-color:#7D98B8;}.yui-skin-sam .yui-button-active button,.!
 yui-skin
-sam .yui-button-active a{color:#000;}.yui-skin-sam .yui-split-button-activeoption{border-color:#808080;background-position:0 0;}.yui-skin-sam .yui-split-button-activeoption .first-child{border-color:#808080;}.yui-skin-sam .yui-split-button-activeoption button{background-image:url(split-button-arrow-active.png);}.yui-skin-sam .yui-radio-button-checked,.yui-skin-sam .yui-checkbox-button-checked{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-radio-button-checked .first-child,.yui-skin-sam .yui-checkbox-button-checked .first-child{border-color:#304369;}.yui-skin-sam .yui-radio-button-checked button,.yui-skin-sam .yui-checkbox-button-checked button{color:#fff;}.yui-skin-sam .yui-button-disabled{border-color:#ccc;background-position:0 -1500px;}.yui-skin-sam .yui-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-button-disabled button,.yui-skin-sam .yui-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-menu-button-disabled !
 button{background-image:url(menu-button-arrow-disabled.png);}.yui-skin-sam .yui-split-button-disabled button{background-image:url(split-button-arrow-disabled.png);}

Modified: trunk/root/static/yui/assets/skins/sam/calendar.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/calendar.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/calendar.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-.yui-calcontainer{position:relative;float:left;_overflow:hidden;}.yui-calcontainer iframe{position:absolute;border:none;margin:0;padding:0;z-index:0;width:100%;height:100%;left:0px;top:0px;}.yui-calcontainer iframe.fixedsize{width:50em;height:50em;top:-1px;left:-1px;}.yui-calcontainer.multi .groupcal{z-index:1;float:left;position:relative;}.yui-calcontainer .title{position:relative;z-index:1;}.yui-calcontainer .close-icon{position:absolute;z-index:1;}.yui-calendar{position:relative;}.yui-calendar .calnavleft{position:absolute;z-index:1;}.yui-calendar .calnavright{position:absolute;z-index:1;}.yui-calendar .calheader{position:relative;width:100%;text-align:center;}.yui-calcontainer .yui-cal-nav-mask{position:absolute;z-index:2;margin:0;padding:0;width:100%;height:100%;_width:0;_height:0;left:0;top:0;display:none;}.yui-calcontainer .yui-cal-nav{position:absolute;z-index:3;top:0;display:none;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{display:-moz-inline-box;display:inlin!
 e-block;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{display:block;*display:inline-block;*overflow:visible;border:none;background-color:transparent;cursor:pointer;}.yui-calendar .calbody a:hover{background:inherit;}p#clear{clear:left;padding-top:10px;}.yui-skin-sam .yui-calcontainer{background-color:#f2f2f2;border:1px solid #808080;padding:10px;}.yui-skin-sam .yui-calcontainer.multi{padding:0 5px 0 5px;}.yui-skin-sam .yui-calcontainer.multi .groupcal{background-color:transparent;border:none;padding:10px 5px 10px 5px;margin:0;}.yui-skin-sam .yui-calcontainer .title{background:url(sprite.png) repeat-x 0 0;border-bottom:1px solid #cccccc;font:100% sans-serif;color:#000;font-weight:bold;height:auto;padding:.4em;margin:0 -10px 10px -10px;top:0;left:0;text-align:left;}.yui-skin-sam .yui-calcontainer.multi .title{margin:0 -5px 0 -5px;}.yui-skin-sam .yui-calcontainer.withtitle{padding-top:0;}.yui-skin-sam .yui-calcontainer .calclose{background:url(sprite.png) no-repeat 0!
  -300px;width:25px;height:15px;top:.4em;right:.4em;cursor:poin!
 ter;}.yu
i-skin-sam .yui-calendar{border-spacing:0;border-collapse:collapse;font:100% sans-serif;text-align:center;}.yui-skin-sam .yui-calendar .calhead{background:transparent;border:none;vertical-align:middle;}.yui-skin-sam .yui-calendar .calheader{background:transparent;font-weight:bold;padding:0 0 .6em 0;text-align:center;}.yui-skin-sam .yui-calendar .calheader img{border:none;}.yui-skin-sam .yui-calendar .calnavleft{background:url(sprite.png) no-repeat 0 -450px;width:25px;height:15px;top:0;bottom:0;left:-10px;margin-left:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calnavright{background:url(sprite.png) no-repeat 0 -500px;width:25px;height:15px;top:0;bottom:0;right:-10px;margin-right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calweekdayrow{height:2em;}.yui-skin-sam .yui-calendar .calweekdaycell{color:#000;font-weight:bold;text-align:center;width:2em;}.yui-skin-sam .yui-calendar .calfoot{background-color:#f2f2f2;}.yui-skin-sam .yui-calendar .calrowhead,.yui-skin-sam .y!
 ui-calendar .calrowfoot{color:#a6a6a6;font-size:85%;font-style:normal;font-weight:normal;}.yui-skin-sam .yui-calendar .calrowhead{text-align:right;padding-right:2px;}.yui-skin-sam .yui-calendar .calrowfoot{text-align:left;padding-left:2px;}.yui-skin-sam .yui-calendar td.calcell{border:1px solid #cccccc;background:#fff;padding:1px;height:1.6em;line-height:1.6em;text-align:center;white-space:nowrap;}.yui-skin-sam .yui-calendar td.calcell a{color:#0066cc;display:block;height:100%;text-decoration:none;}.yui-skin-sam .yui-calendar td.calcell.today{background-color:#000;}.yui-skin-sam .yui-calendar td.calcell.today a{background-color:#fff;}.yui-skin-sam .yui-calendar td.calcell.oom{background-color:#cccccc;color:#a6a6a6;cursor:default;}.yui-skin-sam .yui-calendar td.calcell.selected{background-color:#fff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.selected a{background-color:#b3d4ff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.calcellhover{background-color:#426fd9;co!
 lor:#fff;cursor:pointer;}.yui-skin-sam .yui-calendar td.calcel!
 l.calcel
lhover a{background-color:#426fd9;color:#fff;}.yui-skin-sam .yui-calendar td.calcell.previous{color:#e0e0e0;}.yui-skin-sam .yui-calendar td.calcell.restricted{text-decoration:line-through;}.yui-skin-sam .yui-calendar td.calcell.highlight1{background-color:#ccff99;}.yui-skin-sam .yui-calendar td.calcell.highlight2{background-color:#99ccff;}.yui-skin-sam .yui-calendar td.calcell.highlight3{background-color:#ffcccc;}.yui-skin-sam .yui-calendar td.calcell.highlight4{background-color:#ccff99;}.yui-skin-sam .yui-calendar a.calnav{border:1px solid #f2f2f2;padding:0 4px;text-decoration:none;color:#000;zoom:1;}.yui-skin-sam .yui-calendar a.calnav:hover{background:url(sprite.png) repeat-x 0 0;border-color:#A0A0A0;cursor:pointer;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mask{background-color:#000;opacity:0.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-calcontainer .yui-cal-nav{font-family:arial,helvetica,clean,sans-serif;font-size:93%;border:1px solid #808080;left:50%;margin-lef!
 t:-7em;width:14em;padding:0;top:2.5em;background-color:#f2f2f2;}.yui-skin-sam .yui-calcontainer.withtitle .yui-cal-nav{top:4.5em;}.yui-skin-sam .yui-calcontainer.multi .yui-cal-nav{width:16em;margin-left:-8em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y,.yui-skin-sam .yui-calcontainer .yui-cal-nav-m,.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{padding:5px 10px 5px 10px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{text-align:center;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-e{margin-top:5px;padding:5px;background-color:#EDF5FF;border-top:1px solid black;display:none;}.yui-skin-sam .yui-calcontainer .yui-cal-nav label{display:block;font-weight:bold;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mc{width:100%;_width:auto;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y input.yui-invalid{background-color:#FFEE69;border:1px solid #000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-yc{width:4em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{border:1px soli!
 d #808080;background:url(sprite.png) repeat-x 0 0;background-c!
 olor:#cc
c;margin:auto .15em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{padding:0 8px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default{border:1px solid #304369;background-color:#426fd9;background:url(sprite.png) repeat-x 0 -1400px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default button{color:#fff;}
+.yui-calcontainer{position:relative;float:left;_overflow:hidden;}.yui-calcontainer iframe{position:absolute;border:none;margin:0;padding:0;z-index:0;width:100%;height:100%;left:0px;top:0px;}.yui-calcontainer iframe.fixedsize{width:50em;height:50em;top:-1px;left:-1px;}.yui-calcontainer.multi .groupcal{z-index:1;float:left;position:relative;}.yui-calcontainer .title{position:relative;z-index:1;}.yui-calcontainer .close-icon{position:absolute;z-index:1;}.yui-calendar{position:relative;}.yui-calendar .calnavleft{position:absolute;z-index:1;}.yui-calendar .calnavright{position:absolute;z-index:1;}.yui-calendar .calheader{position:relative;width:100%;text-align:center;}.yui-calcontainer .yui-cal-nav-mask{position:absolute;z-index:2;margin:0;padding:0;width:100%;height:100%;_width:0;_height:0;left:0;top:0;display:none;}.yui-calcontainer .yui-cal-nav{position:absolute;z-index:3;top:0;display:none;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{display:-moz-inline-box;display:inlin!
 e-block;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{display:block;*display:inline-block;*overflow:visible;border:none;background-color:transparent;cursor:pointer;}.yui-calendar .calbody a:hover{background:inherit;}p#clear{clear:left;padding-top:10px;}.yui-skin-sam .yui-calcontainer{background-color:#f2f2f2;border:1px solid #808080;padding:10px;}.yui-skin-sam .yui-calcontainer.multi{padding:0 5px 0 5px;}.yui-skin-sam .yui-calcontainer.multi .groupcal{background-color:transparent;border:none;padding:10px 5px 10px 5px;margin:0;}.yui-skin-sam .yui-calcontainer .title{background:url(sprite.png) repeat-x 0 0;border-bottom:1px solid #cccccc;font:100% sans-serif;color:#000;font-weight:bold;height:auto;padding:.4em;margin:0 -10px 10px -10px;top:0;left:0;text-align:left;}.yui-skin-sam .yui-calcontainer.multi .title{margin:0 -5px 0 -5px;}.yui-skin-sam .yui-calcontainer.withtitle{padding-top:0;}.yui-skin-sam .yui-calcontainer .calclose{background:url(sprite.png) no-repeat 0!
  -300px;width:25px;height:15px;top:.4em;right:.4em;cursor:poin!
 ter;}.yu
i-skin-sam .yui-calendar{border-spacing:0;border-collapse:collapse;font:100% sans-serif;text-align:center;margin:0;}.yui-skin-sam .yui-calendar .calhead{background:transparent;border:none;vertical-align:middle;padding:0;}.yui-skin-sam .yui-calendar .calheader{background:transparent;font-weight:bold;padding:0 0 .6em 0;text-align:center;}.yui-skin-sam .yui-calendar .calheader img{border:none;}.yui-skin-sam .yui-calendar .calnavleft{background:url(sprite.png) no-repeat 0 -450px;width:25px;height:15px;top:0;bottom:0;left:-10px;margin-left:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calnavright{background:url(sprite.png) no-repeat 0 -500px;width:25px;height:15px;top:0;bottom:0;right:-10px;margin-right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calweekdayrow{height:2em;}.yui-skin-sam .yui-calendar .calweekdayrow th{padding:0;border:none;}.yui-skin-sam .yui-calendar .calweekdaycell{color:#000;font-weight:bold;text-align:center;width:2em;}.yui-skin-sam .yui-calendar .ca!
 lfoot{background-color:#f2f2f2;}.yui-skin-sam .yui-calendar .calrowhead,.yui-skin-sam .yui-calendar .calrowfoot{color:#a6a6a6;font-size:85%;font-style:normal;font-weight:normal;border:none;}.yui-skin-sam .yui-calendar .calrowhead{text-align:right;padding:0 2px 0 0;}.yui-skin-sam .yui-calendar .calrowfoot{text-align:left;padding:0 0 0 2px;}.yui-skin-sam .yui-calendar td.calcell{border:1px solid #cccccc;background:#fff;padding:1px;height:1.6em;line-height:1.6em;text-align:center;white-space:nowrap;}.yui-skin-sam .yui-calendar td.calcell a{color:#0066cc;display:block;height:100%;text-decoration:none;}.yui-skin-sam .yui-calendar td.calcell.today{background-color:#000;}.yui-skin-sam .yui-calendar td.calcell.today a{background-color:#fff;}.yui-skin-sam .yui-calendar td.calcell.oom{background-color:#cccccc;color:#a6a6a6;cursor:default;}.yui-skin-sam .yui-calendar td.calcell.selected{background-color:#fff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.selected a{background-colo!
 r:#b3d4ff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.c!
 alcellho
ver{background-color:#426fd9;color:#fff;cursor:pointer;}.yui-skin-sam .yui-calendar td.calcell.calcellhover a{background-color:#426fd9;color:#fff;}.yui-skin-sam .yui-calendar td.calcell.previous{color:#e0e0e0;}.yui-skin-sam .yui-calendar td.calcell.restricted{text-decoration:line-through;}.yui-skin-sam .yui-calendar td.calcell.highlight1{background-color:#ccff99;}.yui-skin-sam .yui-calendar td.calcell.highlight2{background-color:#99ccff;}.yui-skin-sam .yui-calendar td.calcell.highlight3{background-color:#ffcccc;}.yui-skin-sam .yui-calendar td.calcell.highlight4{background-color:#ccff99;}.yui-skin-sam .yui-calendar a.calnav{border:1px solid #f2f2f2;padding:0 4px;text-decoration:none;color:#000;zoom:1;}.yui-skin-sam .yui-calendar a.calnav:hover{background:url(sprite.png) repeat-x 0 0;border-color:#A0A0A0;cursor:pointer;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mask{background-color:#000;opacity:0.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-calcontainer .yui-cal-nav{fo!
 nt-family:arial,helvetica,clean,sans-serif;font-size:93%;border:1px solid #808080;left:50%;margin-left:-7em;width:14em;padding:0;top:2.5em;background-color:#f2f2f2;}.yui-skin-sam .yui-calcontainer.withtitle .yui-cal-nav{top:4.5em;}.yui-skin-sam .yui-calcontainer.multi .yui-cal-nav{width:16em;margin-left:-8em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y,.yui-skin-sam .yui-calcontainer .yui-cal-nav-m,.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{padding:5px 10px 5px 10px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{text-align:center;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-e{margin-top:5px;padding:5px;background-color:#EDF5FF;border-top:1px solid black;display:none;}.yui-skin-sam .yui-calcontainer .yui-cal-nav label{display:block;font-weight:bold;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mc{width:100%;_width:auto;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y input.yui-invalid{background-color:#FFEE69;border:1px solid #000;}.yui-skin-sam .yui-calcontainer .yu!
 i-cal-nav-yc{width:4em;}.yui-skin-sam .yui-calcontainer .yui-c!
 al-nav .
yui-cal-nav-btn{border:1px solid #808080;background:url(sprite.png) repeat-x 0 0;background-color:#ccc;margin:auto .15em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{padding:0 8px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default{border:1px solid #304369;background-color:#426fd9;background:url(sprite.png) repeat-x 0 -1400px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default button{color:#fff;}

Modified: trunk/root/static/yui/assets/skins/sam/colorpicker.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/colorpicker.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/colorpicker.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-picker-panel{background:#e3e3e3;border-color:#888;}.yui-picker-panel .hd{background-color:#ccc;font-size:100%;line-height:100%;border:1px solid #e3e3e3;font-weight:bold;overflow:hidden;padding:6px;color:#000;}.yui-picker-panel .bd{background:#e8e8e8;margin:1px;height:200px;}.yui-picker-panel .ft{background:#e8e8e8;margin:1px;padding:1px;}.yui-picker{position:relative;}.yui-picker-hue-thumb{cursor:default;width:18px;height:18px;top:-8px;left:-2px;z-index:9;position:absolute;}.yui-picker-hue-bg{-moz-outline:none;outline:0px none;position:absolute;left:200px;height:183px;width:14px;background:url(hue_bg.png) no-repeat;top:4px;}.yui-picker-bg{-moz-outline:none;outline:0px none;position:absolute;top:4px;left:4px;height:182px;width:182px;background-color:#F00;background-image:url(picker_mask.png);}*html .yui-picker-bg{background-image:none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../../build/colorpicker/assets/picker_mask.png',sizingMethod='scale');}.yu!
 i-picker-mask{position:absolute;z-index:1;top:0px;left:0px;}.yui-picker-thumb{cursor:default;width:11px;height:11px;z-index:9;position:absolute;top:-4px;left:-4px;}.yui-picker-swatch{position:absolute;left:240px;top:4px;height:60px;width:55px;border:1px solid #888;}.yui-picker-websafe-swatch{position:absolute;left:304px;top:4px;height:24px;width:24px;border:1px solid #888;}.yui-picker-controls{position:absolute;top:72px;left:226px;font:1em monospace;}.yui-picker-controls .hd{background:transparent;border-width:0px !important;}.yui-picker-controls .bd{height:100px;border-width:0px !important;}.yui-picker-controls ul{float:left;padding:0 2px 0 0;margin:0}.yui-picker-controls li{padding:2px;list-style:none;margin:0}.yui-picker-controls input{font-size:0.85em;width:2.4em;}.yui-picker-hex-controls{clear:both;padding:2px;}.yui-picker-hex-controls input{width:4.6em;}.yui-picker-controls a{font:1em arial,helvetica,clean,sans-serif;display:block;*display:inline-block;padding:0;color!
 :#000;}

Modified: trunk/root/static/yui/assets/skins/sam/container.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/container.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/container.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-.yui-overlay,.yui-panel-container{visibility:hidden;position:absolute;z-index:2;}.yui-panel-container form{margin:0;}.mask{z-index:1;display:none;position:absolute;top:0;left:0;right:0;bottom:0;overflow:auto;}.masked select,.drag select,.hide-select select{_visibility:hidden;}.yui-panel-container select{_visibility:inherit;}.hide-scrollbars,.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.show-scrollbars{overflow:auto;}.yui-panel-container.show-scrollbars,.yui-tt.show-scrollbars{overflow:visible;}.yui-panel-container.show-scrollbars .underlay,.yui-tt.show-scrollbars .yui-tt-shadow{overflow:auto;}.yui-panel-container.shadow .underlay.yui-force-redraw{padding-bottom:1px;}.yui-effect-fade .underlay{display:none;}.yui-tt-shadow{position:absolute;}.yui-skin-sam .mask{background-color:#000;opacity:.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-panel-container{padding:0 1px;*padding:2px 3px;}.yui-skin-sam .yui-panel{position:relative;*zoom:1;left:0;top!
 :0;border-style:solid;border-width:1px 0;border-color:#808080;z-index:1;}.yui-skin-sam .yui-panel .hd,.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{*zoom:1;*position:relative;border-style:solid;border-width:0 1px;border-color:#808080;margin:0 -1px;}.yui-skin-sam .yui-panel .hd{border-bottom:solid 1px #ccc;}.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{background-color:#F2F2F2;}.yui-skin-sam .yui-panel .hd{padding:0 10px;font-size:93%;line-height:2;*line-height:1.9;font-weight:bold;color:#000;background:url(sprite.png) repeat-x 0 -200px;}.yui-skin-sam .yui-panel .bd{padding:10px;}.yui-skin-sam .yui-panel .ft{border-top:solid 1px #808080;padding:5px 10px;font-size:77%;}.yui-skin-sam .yui-panel-container.focused .yui-panel .hd{}.yui-skin-sam .container-close{position:absolute;top:5px;right:6px;width:25px;height:15px;background:url(sprite.png) no-repeat 0 -300px;cursor:pointer;}.yui-skin-sam .yui-panel-container .underlay{right:-1px;left:-1px;}.yui-skin-!
 sam .yui-panel-container.matte{padding:9px 10px;background-col!
 or:#fff;
}.yui-skin-sam .yui-panel-container.shadow{_padding:2px 5px 0 3px;}.yui-skin-sam .yui-panel-container.shadow .underlay{position:absolute;top:2px;right:-3px;bottom:-3px;left:-3px;*top:3px;*left:-1px;*right:-1px;*bottom:-1px;_top:0;_right:0;_bottom:0;_left:0;_margin-top:3px;_margin-left:-1px;background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yui-dialog .ft{border-top:none;padding:0 10px 10px 10px;font-size:100%;}.yui-skin-sam .yui-dialog .ft .button-group{display:block;text-align:right;}.yui-skin-sam .yui-dialog .ft button.default{font-weight:bold;}.yui-skin-sam .yui-dialog .ft span.default{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-dialog .ft span.default .first-child{border-color:#304369;}.yui-skin-sam .yui-dialog .ft span.default button{color:#fff;}.yui-skin-sam .yui-simple-dialog .bd .yui-icon{background:url(sprite.png) no-repeat 0 0;width:16px;height:16px;margin-right:10px;float:left;}.yui-skin-sam .yui-simple-dialog .b!
 d span.blckicon{background-position:0 -1100px;}.yui-skin-sam .yui-simple-dialog .bd span.alrticon{background-position:0 -1050px;}.yui-skin-sam .yui-simple-dialog .bd span.hlpicon{background-position:0 -1150px;}.yui-skin-sam .yui-simple-dialog .bd span.infoicon{background-position:0 -1200px;}.yui-skin-sam .yui-simple-dialog .bd span.warnicon{background-position:0 -1900px;}.yui-skin-sam .yui-simple-dialog .bd span.tipicon{background-position:0 -1250px;}.yui-skin-sam .yui-tt .bd{position:relative;top:0;left:0;z-index:1;color:#000;padding:2px 5px;border-color:#D4C237 #A6982B #A6982B #A6982B;border-width:1px;border-style:solid;background-color:#FFEE69;}.yui-skin-sam .yui-tt.show-scrollbars .bd{overflow:auto;}.yui-skin-sam .yui-tt-shadow{top:2px;right:-3px;left:-3px;bottom:-3px;background-color:#000;}.yui-skin-sam .yui-tt-shadow-visible{opacity:.12;*filter:alpha(opacity=12);}
+.yui-overlay,.yui-panel-container{visibility:hidden;position:absolute;z-index:2;}.yui-panel-container form{margin:0;}.mask{z-index:1;display:none;position:absolute;top:0;left:0;right:0;bottom:0;}.mask.block-scrollbars{overflow:auto;}.masked select,.drag select,.hide-select select{_visibility:hidden;}.yui-panel-container select{_visibility:inherit;}.hide-scrollbars,.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.show-scrollbars{overflow:auto;}.yui-panel-container.show-scrollbars,.yui-tt.show-scrollbars{overflow:visible;}.yui-panel-container.show-scrollbars .underlay,.yui-tt.show-scrollbars .yui-tt-shadow{overflow:auto;}.yui-panel-container.shadow .underlay.yui-force-redraw{padding-bottom:1px;}.yui-effect-fade .underlay{display:none;}.yui-tt-shadow{position:absolute;}.yui-skin-sam .mask{background-color:#000;opacity:.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-panel-container{padding:0 1px;*padding:2px 3px;}.yui-skin-sam .yui-panel{position:rel!
 ative;*zoom:1;left:0;top:0;border-style:solid;border-width:1px 0;border-color:#808080;z-index:1;}.yui-skin-sam .yui-panel .hd,.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{*zoom:1;*position:relative;border-style:solid;border-width:0 1px;border-color:#808080;margin:0 -1px;}.yui-skin-sam .yui-panel .hd{border-bottom:solid 1px #ccc;}.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{background-color:#F2F2F2;}.yui-skin-sam .yui-panel .hd{padding:0 10px;font-size:93%;line-height:2;*line-height:1.9;font-weight:bold;color:#000;background:url(sprite.png) repeat-x 0 -200px;}.yui-skin-sam .yui-panel .bd{padding:10px;}.yui-skin-sam .yui-panel .ft{border-top:solid 1px #808080;padding:5px 10px;font-size:77%;}.yui-skin-sam .yui-panel-container.focused .yui-panel .hd{}.yui-skin-sam .container-close{position:absolute;top:5px;right:6px;width:25px;height:15px;background:url(sprite.png) no-repeat 0 -300px;cursor:pointer;}.yui-skin-sam .yui-panel-container .underlay{right:-1!
 px;left:-1px;}.yui-skin-sam .yui-panel-container.matte{padding!
 :9px 10p
x;background-color:#fff;}.yui-skin-sam .yui-panel-container.shadow{_padding:2px 5px 0 3px;}.yui-skin-sam .yui-panel-container.shadow .underlay{position:absolute;top:2px;right:-3px;bottom:-3px;left:-3px;*top:3px;*left:-1px;*right:-1px;*bottom:-1px;_top:0;_right:0;_bottom:0;_left:0;_margin-top:3px;_margin-left:-1px;background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yui-dialog .ft{border-top:none;padding:0 10px 10px 10px;font-size:100%;}.yui-skin-sam .yui-dialog .ft .button-group{display:block;text-align:right;}.yui-skin-sam .yui-dialog .ft button.default{font-weight:bold;}.yui-skin-sam .yui-dialog .ft span.default{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-dialog .ft span.default .first-child{border-color:#304369;}.yui-skin-sam .yui-dialog .ft span.default button{color:#fff;}.yui-skin-sam .yui-simple-dialog .bd .yui-icon{background:url(sprite.png) no-repeat 0 0;width:16px;height:16px;margin-right:10px;float:left;}.yui-skin-s!
 am .yui-simple-dialog .bd span.blckicon{background-position:0 -1100px;}.yui-skin-sam .yui-simple-dialog .bd span.alrticon{background-position:0 -1050px;}.yui-skin-sam .yui-simple-dialog .bd span.hlpicon{background-position:0 -1150px;}.yui-skin-sam .yui-simple-dialog .bd span.infoicon{background-position:0 -1200px;}.yui-skin-sam .yui-simple-dialog .bd span.warnicon{background-position:0 -1900px;}.yui-skin-sam .yui-simple-dialog .bd span.tipicon{background-position:0 -1250px;}.yui-skin-sam .yui-tt .bd{position:relative;top:0;left:0;z-index:1;color:#000;padding:2px 5px;border-color:#D4C237 #A6982B #A6982B #A6982B;border-width:1px;border-style:solid;background-color:#FFEE69;}.yui-skin-sam .yui-tt.show-scrollbars .bd{overflow:auto;}.yui-skin-sam .yui-tt-shadow{top:2px;right:-3px;left:-3px;bottom:-3px;background-color:#000;}.yui-skin-sam .yui-tt-shadow-visible{opacity:.12;*filter:alpha(opacity=12);}

Modified: trunk/root/static/yui/assets/skins/sam/datatable.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/datatable.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/datatable.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-table.yui-dt-table{table-layout:fixed;}th .yui-dt-header{position:relative;}th .yui-dt-label{position:relative;}th .yui-dt-resizer{position:absolute;margin-right:-6px;right:0;bottom:0;width:6px;height:100%;cursor:w-resize;cursor:col-resize;}.yui-dt-scrollable{*overflow-y:auto;}.yui-dt-scrollable thead{display:block;}.yui-dt-scrollable thead tr{position:relative;}.yui-dt-scrollbody{display:block;overflow:auto;}.yui-dt-editor{position:absolute;z-index:9000;}.yui-skin-sam .yui-dt-table{margin:0;padding:0;font-family:arial;font-size:inherit;border-collapse:collapse;border:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-table caption{padding-bottom:1em;text-align:left;}.yui-skin-sam .yui-dt-table th{background:url(sprite.png) repeat-x 0 0;}.yui-skin-sam .yui-dt-table th,.yui-skin-sam .yui-dt-table th a{font-weight:normal;text-decoration:none;color:#000;vertical-align:bottom;}.yui-skin-sam .yui-dt-table th,.yui-skin-sam .yui-dt-table td{padding:4px 10px 4px 10px;border-right:1px solid #!
 CBCBCB;}.yui-skin-sam .yui-dt-table td{text-align:left;}.yui-skin-sam .yui-dt-table th.yui-dt-last,.yui-skin-sam .yui-dt-table td.yui-dt-last{border-right:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-list td{border-right:none;}.yui-skin-sam .yui-dt-table thead{border:1px solid #989898;}.yui-skin-sam .yui-dt-table tbody{border-left:1px solid #7F7F7F;border-right:1px solid #7F7F7F;border-bottom:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-loading{background-color:#FFF;}.yui-skin-sam .yui-dt-loading{background-color:#FFF;}.yui-skin-sam .yui-dt-sortable{cursor:pointer;}.yui-skin-sam th.yui-dt-sortable{padding-right:5px;}.yui-skin-sam th.yui-dt-sortable .yui-dt-label{margin-right:15px;}.yui-skin-sam th.yui-dt-asc,.yui-skin-sam th.yui-dt-desc{background:url(sprite.png) repeat-x 0 -100px;}.yui-skin-sam th.yui-dt-asc .yui-dt-header{background:url(dt-arrow-up.png) no-repeat right;}.yui-skin-sam th.yui-dt-desc .yui-dt-header{background:url(dt-arrow-dn.png) no-repeat right;}.yui-dt-editable{c!
 ursor:pointer;}.yui-dt-editor{text-align:left;background-color!
 :#F2F2F2
;border:1px solid #808080;padding:6px;}.yui-dt-editor label{padding-left:4px;padding-right:6px;}.yui-dt-editor .yui-dt-button{padding-top:6px;text-align:right;}.yui-dt-editor .yui-dt-button button{background:url(sprite.png) repeat-x 0 0;border:1px solid #999;width:4em;height:1.8em;margin-left:6px;}.yui-dt-editor .yui-dt-button button.yui-dt-default{background:url(sprite.png) repeat-x 0 -1400px;background-color:#5584E0;border:1px solid #304369;color:#FFF}.yui-dt-editor .yui-dt-button button:hover{background:url(sprite.png) repeat-x 0 -1300px;color:#000;}.yui-dt-editor .yui-dt-button button:active{background:url(sprite.png) repeat-x 0 -1700px;color:#000;}.yui-skin-sam tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam tr.yui-dt-odd{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam tr.yui-dt-even td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam tr.yui-dt-odd td.yui-dt-desc{background-color:#DBEAFF!
 ;}.yui-skin-sam .yui-dt-list tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-odd{background-color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted!
 {cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam tr.yui!
 -dt-sele
cted td,.yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam tr.yui-dt-selected td.yui-dt-desc{background-color:#426FD9;color:#FFF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam tr.yui-dt-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-selected td,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc{background-color:#426FD9;color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}.yui-skin-sam .yui-dt-paginator{display:block;margin:6px 0;white-space:nowrap;}.yui-skin-sam .yui-dt-paginator .yui-dt-first,.yui-skin-sam .yui-dt-paginator .yui-dt-last,.yui-skin-sam .yui-dt-paginator .yui-dt-selected{padding:2px 6px;}.yui-skin-sam .yui-dt-paginator a.yui-dt-first,.yui-skin-sam .yui-dt-paginator a.yui-dt-last{text-decoration:none;}.!
 yui-skin-sam .yui-dt-paginator .yui-dt-previous,.yui-skin-sam .yui-dt-paginator .yui-dt-next{display:none;}.yui-skin-sam a.yui-dt-page{border:1px solid #CBCBCB;padding:2px 6px;text-decoration:none;}
+.yui-dt{border-bottom:1px solid transparent;}.yui-dt-noop{border-bottom:none;}.yui-dt-hd{display:none;}.yui-dt-scrollable .yui-dt-hd{display:block;}.yui-dt-scrollable .yui-dt-bd thead tr,.yui-dt-scrollable .yui-dt-bd thead th{position:absolute;left:-1500px;}.yui-dt-scrollable tbody{-moz-outline:none;}.yui-dt-draggable{cursor:move;}.yui-dt-coltarget{position:absolute;z-index:999;}.yui-dt-hd{zoom:1;}th.yui-dt-resizeable .yui-dt-liner{position:relative;}.yui-dt-resizer{position:absolute;right:0;bottom:0;height:100%;cursor:e-resize;cursor:col-resize;}.yui-dt-resizerproxy{visibility:hidden;position:absolute;z-index:9000;}.yui-skin-sam th.yui-dt-hidden .yui-dt-liner,.yui-skin-sam td.yui-dt-hidden .yui-dt-liner{margin:0;padding:0;overflow:hidden;white-space:nowrap;}.yui-dt-scrollable .yui-dt-bd{overflow:auto;}.yui-dt-scrollable .yui-dt-hd{overflow:hidden;position:relative;}.yui-dt-editor{position:absolute;z-index:9000;}.yui-skin-sam .yui-dt table{margin:0;padding:0;font-family:ari!
 al;font-size:inherit;border-collapse:collapse;border-spacing:0;}.yui-skin-sam .yui-dt thead{border-spacing:0;}.yui-skin-sam .yui-dt caption{padding-bottom:1em;text-align:left;}.yui-skin-sam .yui-dt-hd table{border-left:1px solid #7F7F7F;border-top:1px solid #7F7F7F;border-right:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-bd table{border:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-scrollable .yui-dt-hd table{border:0px;}.yui-skin-sam .yui-dt-scrollable .yui-dt-bd table{border:0px;}.yui-skin-sam .yui-dt-scrollable .yui-dt-hd{border-left:1px solid #7F7F7F;border-top:1px solid #7F7F7F;border-right:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-scrollable .yui-dt-bd{border-left:1px solid #7F7F7F;border-bottom:1px solid #7F7F7F;border-right:1px solid #7F7F7F;}.yui-skin-sam .yui-dt th{background:#D8D8DA url(sprite.png) repeat-x 0 0;}.yui-skin-sam .yui-dt th,.yui-skin-sam .yui-dt th a{font-weight:normal;text-decoration:none;color:#000;vertical-align:bottom;}.yui-skin-sam .yui-dt th{margin:0;pa!
 dding:0;border:none;border-right:1px solid #CBCBCB;}.yui-skin-!
 sam .yui
-dt-liner{margin:0;padding:0;padding:4px 10px 4px 10px;}.yui-skin-sam .yui-dt-coltarget{width:5px;background-color:red;}.yui-skin-sam .yui-dt td{margin:0;padding:0;border:none;border-right:1px solid #CBCBCB;text-align:left;}.yui-skin-sam .yui-dt-list td{border-right:none;}.yui-skin-sam .yui-dt-resizer{width:6px;}.yui-skin-sam .yui-dt-loading{background-color:#FFF;}.yui-skin-sam .yui-dt-empty{background-color:#FFF;}.yui-skin-sam .yui-dt-error{background-color:#FFF;}.yui-skin-sam thead .yui-dt-sortable{cursor:pointer;}.yui-skin-sam th.yui-dt-asc,.yui-skin-sam th.yui-dt-desc{background:url(sprite.png) repeat-x 0 -100px;}.yui-skin-sam th.yui-dt-sortable .yui-dt-label{margin-right:10px;}.yui-skin-sam th.yui-dt-asc .yui-dt-liner{background:url(dt-arrow-up.png) no-repeat right;}.yui-skin-sam th.yui-dt-desc .yui-dt-liner{background:url(dt-arrow-dn.png) no-repeat right;}.yui-dt-editable{cursor:pointer;}.yui-dt-editor{text-align:left;background-color:#F2F2F2;border:1px solid #808080;p!
 adding:6px;}.yui-dt-editor label{padding-left:4px;padding-right:6px;}.yui-dt-editor .yui-dt-button{padding-top:6px;text-align:right;}.yui-dt-editor .yui-dt-button button{background:url(sprite.png) repeat-x 0 0;border:1px solid #999;width:4em;height:1.8em;margin-left:6px;}.yui-dt-editor .yui-dt-button button.yui-dt-default{background:url(sprite.png) repeat-x 0 -1400px;background-color:#5584E0;border:1px solid #304369;color:#FFF}.yui-dt-editor .yui-dt-button button:hover{background:url(sprite.png) repeat-x 0 -1300px;color:#000;}.yui-dt-editor .yui-dt-button button:active{background:url(sprite.png) repeat-x 0 -1700px;color:#000;}.yui-skin-sam tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam tr.yui-dt-odd{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam tr.yui-dt-even td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam tr.yui-dt-odd td.yui-dt-desc{background-color:#DBEAFF;}.yui-skin-sam .yui-dt-li!
 st tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam .yui-dt!
 -list tr
.yui-dt-odd{background-color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam th.yui-dt-highlighted,.yui-skin-sam th.yui-dt-highlighted a{background-color:#B2D2FF;}.yui-skin-sam tr.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam .yui-dt-list th.yui-dt-highlighted,.yui-skin-sam .yui-dt-list th.yui-dt-highlighted a{background-color:#B2D2FF;}.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-de!
 sc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam th.yui-dt-selected,.yui-skin-sam th.yui-dt-selected a{background-color:#446CD7;}.yui-skin-sam tr.yui-dt-selected td,.yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam tr.yui-dt-selected td.yui-dt-desc{background-color:#426FD9;color:#FFF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam tr.yui-dt-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}.yui-skin-sam .yui-dt-list th.yui-dt-selected,.yui-skin-sam .yui-dt-list th.yui-dt-selected a{background-color:#446CD7;}.yui-skin-sam .yui-dt-list tr.yui-dt-selected td,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc{background-color:#426FD9;color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam .yui-dt-list tr.yui-d!
 t-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}!
 .yui-ski
n-sam .yui-pg-container,.yui-skin-sam .yui-dt-paginator{display:block;margin:6px 0;white-space:nowrap;}.yui-skin-sam .yui-pg-first,.yui-skin-sam .yui-pg-last,.yui-skin-sam .yui-pg-current-page,.yui-skin-sam .yui-dt-first,.yui-skin-sam .yui-dt-paginator .yui-dt-last,.yui-skin-sam .yui-dt-paginator .yui-dt-selected{padding:2px 6px;}.yui-skin-sam a.yui-pg-first,.yui-skin-sam a.yui-pg-previous,.yui-skin-sam a.yui-pg-next,.yui-skin-sam a.yui-pg-last,.yui-skin-sam a.yui-pg-page,.yui-skin-sam .yui-dt-paginator a.yui-dt-first,.yui-skin-sam .yui-dt-paginator a.yui-dt-last{text-decoration:none;}.yui-skin-sam .yui-dt-paginator .yui-dt-previous,.yui-skin-sam .yui-dt-paginator .yui-dt-next{display:none;}.yui-skin-sam a.yui-pg-page,.yui-skin-sam a.yui-dt-page{border:1px solid #CBCBCB;padding:2px 6px;text-decoration:none;background-color:#fff}.yui-skin-sam .yui-pg-current-page,.yui-skin-sam .yui-dt-selected{border:1px solid #fff;background-color:#fff;}.yui-skin-sam .yui-pg-pages{margin-lef!
 t:1ex;margin-right:1ex;}.yui-skin-sam .yui-pg-page{margin-right:1px;margin-left:1px;}.yui-skin-sam .yui-pg-first,.yui-skin-sam .yui-pg-previous{margin-right:3px;}.yui-skin-sam .yui-pg-next,.yui-skin-sam .yui-pg-last{margin-left:3px;}.yui-skin-sam .yui-pg-current,.yui-skin-sam .yui-pg-rpp-options{margin-right:1em;margin-left:1em;}

Added: trunk/root/static/yui/assets/skins/sam/desc.gif
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/assets/skins/sam/desc.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: trunk/root/static/yui/assets/skins/sam/dt-arrow-dn.png
===================================================================
(Binary files differ)

Modified: trunk/root/static/yui/assets/skins/sam/dt-arrow-up.png
===================================================================
(Binary files differ)

Modified: trunk/root/static/yui/assets/skins/sam/editor.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/editor.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/editor.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-.yui-busy{cursor:wait !important;}.yui-toolbar-container .yui-toolbar-subcont{padding:.25em 0;zoom:1;}.yui-toolbar-container-collapsed .yui-toolbar-subcont{display:none;}.yui-toolbar-container .yui-toolbar-subcont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container span.yui-toolbar-draghandle{cursor:move;border-left:1px solid #999;border-right:1px solid #999;overflow:hidden;text-indent:77777px;width:2px;height:20px;display:block;clear:none;float:left;margin:0 0 0 .2em;}.yui-toolbar-container .yui-toolbar-titlebar.draggable{cursor:move;}.yui-toolbar-container .yui-toolbar-titlebar{position:relative;}.yui-toolbar-container .yui-toolbar-titlebar h2{font-weight:bold;letter-spacing:0;border:none;color:#000;margin:0;padding:.2em;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-draghandle{height:40px;}.yui-toolbar-container .yui-toolbar-group{float:left;zoom:1;}.yui-toolbar-container .yui-toolbar-group:after{display:block;clear!
 :both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container .yui-toolbar-group h3{font-size:75%;padding:0 0 0 .25em;margin:0;}.yui-toolbar-container span.yui-toolbar-separator{width:2px;height:18px;margin:.2em 0 .2em .1em;display:block;clear:none;float:left;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-separator{height:35px;}.yui-toolbar-container.yui-toolbar-grouped .yui-toolbar-group span.yui-toolbar-separator{height:18px;}.yui-toolbar-container ul li{margin:0;padding:0;list-style-type:none;}.yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-toolbar-container .yui-push-button,.yui-toolbar-container .yui-color-button,.yui-toolbar-container .yui-menu-button{position:relative;cursor:pointer;}.yui-toolbar-container .yui-button .first-child,.yui-toolbar-container .yui-button .first-child a{height:100%;width:100%;overflow:hidden;}.yui-toolbar-container .yui-button-disabled{cursor:default;}.yui-toolbar-container .yui-button-disabled .!
 yui-toolbar-icon{opacity:.5;filter:alpha(opacity=50);}.yui-too!
 lbar-con
tainer .yui-button-disabled .up,.yui-toolbar-container .yui-button-disabled .down{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button a{overflow:hidden;}.yui-toolbar-container .yui-toolbar-select .first-child a{cursor:pointer;}.yui-toolbar-fontname-arial{font-family:Arial;}.yui-toolbar-fontname-arial-black{font-family:Arial Black;}.yui-toolbar-fontname-comic-sans-ms{font-family:Comic Sans MS;}.yui-toolbar-fontname-courier-new{font-family:Courier New;}.yui-toolbar-fontname-times-new-roman{font-family:Times New Roman;}.yui-toolbar-fontname-verdana{font-family:Verdana;}.yui-toolbar-fontname-impact{font-family:Impact;}.yui-toolbar-fontname-lucida-console{font-family:Lucida Console;}.yui-toolbar-fontname-tahoma{font-family:Tahoma;}.yui-toolbar-fontname-trebuchet-ms{font-family:Trebuchet MS;}.yui-toolbar-container .yui-toolbar-spinbutton{position:relative;}.yui-toolbar-container .yui-toolbar-spinbutton .first-child a{z-index:0;opacity:1;}.yui-toolbar-container !
 .yui-toolbar-spinbutton a.up,.yui-toolbar-container .yui-toolbar-spinbutton a.down{position:absolute;display:block right:0;cursor:pointer;z-index:1;padding:0;margin:0;}.yui-toolbar-container .yui-overlay{position:absolute;}.yui-toolbar-container .yui-overlay ul li{margin:0;list-style-type:none;}.yui-toolbar-container{z-index:1;}.yui-editor-container .yui-editor-editable-container{position:relative;z-index:0;width:100%;}.yui-editor-container .yui-editor-masked{background-color:#CCC;}.yui-editor-container iframe{border:0px;padding:0;margin:0;zoom:1;display:block;}.yui-editor-container .yui-editor-editable{padding:0;margin:0;}.yui-editor-container .dompath{font-size:85%;}.yui-editor-panel .hd{text-align:left;position:relative;}.yui-editor-panel .hd h3{font-weight:bold;padding:0.25em 0pt 0.25em 0.25em;margin:0;}.yui-editor-panel .bd{width:100%;zoom:1;position:relative;}.yui-editor-panel .bd div.yui-editor-body-cont{padding:.25em .1em;zoom:1;}.yui-editor-panel .bd div.yui-editor!
 -body-cont:after{display:block;clear:both;visibility:hidden;co!
 ntent:'.
';height:0;}.yui-editor-panel .ft{text-align:right;width:99%;float:left;clear:both;}.yui-editor-panel .ft span.tip{display:block;position:relative;padding:.5em .5em .5em 23px;text-align:left;zoom:1;}.yui-editor-panel label{clear:both;float:left;padding:0;width:100%;text-align:left;zoom:1;}.yui-editor-panel .gecko label{overflow:auto;}.yui-editor-panel label strong{float:left;width:6em;}.yui-editor-panel .removeLink{width:80%;text-align:right;}.yui-editor-panel label input{margin-left:.25em;float:left;}.yui-editor-panel .yui-toolbar-group-padding{}.yui-editor-panel .yui-toolbar-group-border{}.yui-editor-panel .yui-toolbar-group-textflow{}.yui-editor-panel .height-width{float:left;}.yui-editor-panel .height-width h3{}.yui-editor-panel .height-width span{font-style:italic;display:block;float:left;overflow:auto;}.yui-editor-panel .height-width span.info{font-size:70%;}.yui-editor-panel .yui-toolbar-bordersize,.yui-editor-panel .yui-toolbar-bordertype{font-size:75%;}.yui-editor-p!
 anel .yui-toolbar-container span.yui-toolbar-separator{border:none;}.yui-editor-panel .yui-toolbar-bordersize span a span,.yui-editor-panel .yui-toolbar-bordertype span a span{display:block;height:8px;left:4px;position:absolute;top:3px;*top:-5px;width:24px;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-solid{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dotted{border-bottom:1px dotted black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dashed{border-bottom:1px dashed black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-0{*top:0px;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-1{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-2{border-bottom:2px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersiz!
 e-3{top:2px;*top:-5px;border-bottom:3px solid black;}.yui-edit!
 or-panel
 .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-4{top:1px;*top:-5px;border-bottom:4px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-5{top:1px;*top:-5px;border-bottom:5px solid black;}.yui-toolbar-container .yui-toolbar-bordersize-menu,.yui-toolbar-container .yui-toolbar-bordertype-menu{width:95px !important;}.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel,.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel:hover{margin:0px 3px 7px 17px;}.yui-toolbar-bordersize-menu .yuimenuitemlabel .checkedindicator,.yui-toolbar-bordertype-menu .yuimenuitemlabel .checkedindicator{position:absolute;left:-12px;*top:14px;*left:0px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-1 a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-2 a{border-bottom:2px solid black;height:14px;}.yui-toolbar-borders!
 ize-menu li.yui-toolbar-bordersize-3 a{border-bottom:3px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-4 a{border-bottom:4px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-5 a{border-bottom:5px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-solid a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dashed a{border-bottom:1px dashed black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dotted a{border-bottom:1px dotted black;height:14px;}h2.yui-editor-skipheader,h3.yui-editor-skipheader{height:0;margin:0;padding:0;border:none;width:0;overflow:hidden;position:absolute;}.yui-toolbar-colors{width:133px;zoom:1;display:none;z-index:100;overflow:hidden;}.yui-toolbar-colors:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors a{height:9px;width:9px;float:left;display:block;overflo!
 w:hidden;text-indent:999px;margin:0;cursor:pointer;border:1px !
 solid #F
6F7EE;}.yui-toolbar-colors a:hover{border:1px solid black;}.yui-color-button-menu{overflow:visible;background-color:transparent;}.yui-toolbar-colors span{position:relative;display:block;padding:3px;overflow:hidden;float:left;width:100%;zoom:1;}.yui-toolbar-colors span:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors span em{height:35px;width:30px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0.75px;border:1px solid black;}.yui-toolbar-colors span strong{font-weight:normal;padding-left:3px;display:block;font-size:85%;float:left;width:65%;}.yui-skin-sam .yui-editor-container{border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container{zoom:1;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar{background:url(sprite.png) repeat-x 0 -200px;position:relative;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar h2{color:#000000;font-weight:bold;margin:0;padding:0.3em 1em;font-size:100%;text-align:left;}.!
 yui-skin-sam .yui-toolbar-container .yui-toolbar-group h3{color:#808080;font-size:75%;margin:1em 0 0;padding-bottom:0;padding-left:0.25em;text-align:left;}.yui-toolbar-container span.yui-toolbar-separator{border:none;text-indent:33px;overflow:hidden;margin:.25em;}.yui-skin-sam .yui-toolbar-container{background-color:#F2F2F2;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subcont{padding:0 1em 0.35em;border-bottom:1px solid #808080;}.yui-skin-sam .yui-toolbar-container-collapsed .yui-toolbar-titlebar{border-bottom:1px solid #808080;}.yui-skin-sam .yui-editor-container .visible .yui-menu-shadow,.yui-skin-sam .yui-editor-panel .visible .yui-menu-shadow{display:none;}.yui-skin-sam .yui-editor-container ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-container ul li{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-toolbar-group ul li.yui-toolbar-groupitem{float:left;}.yui-skin-sam .yui-editor-container .dompath{background-color:#F2F2F2;border-!
 top:1px solid #808080;color:#999;text-align:left;padding:0.25e!
 m;}.yui-
skin-sam .yui-toolbar-container .collapse{background:url(sprite.png) no-repeat 0 -400px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar span.collapse{cursor:pointer;position:absolute;top:4px;right:2px;display:block;overflow:hidden;height:15px;width:15px;text-indent:9999px;}.yui-skin-sam .yui-toolbar-container .yui-push-button,.yui-skin-sam .yui-toolbar-container .yui-color-button,.yui-skin-sam .yui-toolbar-container .yui-menu-button{background:url(sprite.png) repeat-x 0 0;position:relative;display:block;height:22px;width:30px;margin:0;border-color:#808080;border-style:solid;border-width:1px 0;}.yui-skin-sam .yui-toolbar-container .yui-push-button a,.yui-skin-sam .yui-toolbar-container .yui-color-button a,.yui-skin-sam .yui-toolbar-container .yui-menu-button a{padding-left:35px;height:20px;text-decoration:none;font-size:93%;line-height:2;display:block;color:#000000;overflow:hidden;}.yui-skin-sam .yui-toolbar-container .yui-push-button .first-child,.yui-skin-sam .y!
 ui-toolbar-container .yui-color-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button .first-child{border-color:#808080;border-style:solid;border-width:0 1px;margin:0 -1px;display:block;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-button .first-child{*left:0px;}.yui-skin-sam .yui-toolba!
 r-container .yui-toolbar-fontname{width:135px;}.yui-skin-sam .!
 yui-tool
bar-container .yui-toolbar-heading{width:92px;}.yui-skin-sam .yui-toolbar-container .yui-button-hover{background:url(sprite.png) repeat-x 0 -1300px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-button-selected{background:url(sprite.png) repeat-x 0 -1700px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels .yui-toolbar-group{margin-top:.75em;}.yui-skin-sam .yui-toolbar-container .yui-push-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-color-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-menu-button span.yui-toolbar-icon{display:block;position:absolute;top:2px;height:18px;width:18px;overflow:hidden;background:url(editor-sprite.gif) no-repeat 30px 30px;}.yui-skin-sam .yui-toolbar-container .yui-button-selected span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-button-hover span.yui-tool!
 bar-icon{background-image:url(editor-sprite-active.gif);}.yui-skin-sam .yui-toolbar-container .visible .yuimenuitemlabel{cursor:pointer;color:#000;*position:relative;}.yui-skin-sam .yui-toolbar-container .yui-button-menu{background-color:#fff;}.yui-skin-sam div.yuimenu li.selected{background-color:#B3D4FF;}.yui-skin-sam div.yuimenu li.selected a.selected{color:#000;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bold span.yui-toolbar-icon{background-position:0 0;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-italic span.yui-toolbar-icon{background-position:0 -36px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-underline span.yui-toolbar-icon{background-position:0 -72px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subscript span.yui-toolbar-icon{background-position:0 -180px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-superscript span.yui-toolbar-icon{background-position:0 -144px;left:5px;}.yui-skin-sam .yui-toolbar-!
 container .yui-toolbar-forecolor span.yui-toolbar-icon{backgro!
 und-posi
tion:0 -216px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-backcolor span.yui-toolbar-icon{background-position:0 -288px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyleft span.yui-toolbar-icon{background-position:0 -324px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifycenter span.yui-toolbar-icon{background-position:0 -360px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyright span.yui-toolbar-icon{background-position:0 -396px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyfull span.yui-toolbar-icon{background-position:0 -432px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-indent span.yui-toolbar-icon{background-position:0 -720px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-outdent span.yui-toolbar-icon{background-position:0 -684px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-createlink span.yui-toolbar-icon{background-position:0 -792px;!
 left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertimage span.yui-toolbar-icon{background-position:1px -756px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-left span.yui-toolbar-icon{background-position:0 -972px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-right span.yui-toolbar-icon{background-position:0 -936px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-inline span.yui-toolbar-icon{background-position:0 -900px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-block span.yui-toolbar-icon{background-position:0 -864px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bordercolor span.yui-toolbar-icon{background-position:0 -252px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-removeformat span.yui-toolbar-icon{background-position:0 -1080px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-hiddenelements span.yui-toolbar-icon{background-position:0 -1044px;left:5px;}.yui-skin-!
 sam .yui-toolbar-container .yui-toolbar-insertunorderedlist sp!
 an.yui-t
oolbar-icon{background-position:0 -468px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertorderedlist span.yui-toolbar-icon{background-position:0 -504px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child{width:35px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child a{padding-left:2px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton span.yui-toolbar-icon{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{right:2px;background:url(editor-sprite.gif) no-repeat 0 -1222px;overflow:hidden;height:6px;width:7px;min-height:0;padding:0;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up{top:2px;background-position:0 -1222px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{bottom:2px;background-p!
 osition:0 -1187px;}.yui-skin-sam .yui-toolbar-container select{height:22px;border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select .first-child a{padding-left:5px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select span.yui-toolbar-icon{background:url( editor-sprite.gif ) no-repeat 0 -1144px;overflow:hidden;right:-2px;top:0px;height:20px;}.yui-skin-sam .yui-editor-panel .yui-color-button-menu .bd{background-color:transparent;border:none;width:135px;}.yui-skin-sam .yui-color-button-menu .yui-toolbar-colors{border:1px solid #808080;}.yui-skin-sam .yui-editor-panel{padding:0;margin:0;border:none;background-color:transparent;overflow:visible;}.yui-skin-sam .yui-editor-panel .hd{margin:10px 0 0;padding:0;border:none;}.yui-skin-sam .yui-editor-panel .hd h3{color:#000;border:1px solid #808080;background:url(sprite.png) repeat-x 0 -200px;width:99%;position:relative;margin:0;padding:3px 0 0 0;font-size:93%;text-indent:5px;height:20px;!
 }.yui-skin-sam .yui-editor-panel .bd{background-color:#F2F2F2;!
 border-l
eft:1px solid #808080;border-right:1px solid #808080;width:99%;margin:0;padding:0;overflow:visible;}.yui-skin-sam .yui-editor-panel ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-panel ul li{margin:0;padding:0;}.yui-skin-sam .yui-editor-panel .yuimenu{}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .yui-toolbar-subcont{padding:0;border:none;margin-top:0.35em;}.yui-skin-sam .yui-editor-panel .yui-toolbar-bordersize,.yui-skin-sam .yui-editor-panel .yui-toolbar-bordertype{width:50px;}.yui-skin-sam .yui-editor-panel label{display:block;float:none;padding:4px 0;margin-bottom:7px;}.yui-skin-sam .yui-editor-panel label strong{font-weight:normal;font-size:93%;text-align:right;padding-top:2px;}.yui-skin-sam .yui-editor-panel label input{width:75%;}.yui-skin-sam .yui-editor-panel #createlink_target,.yui-skin-sam .yui-editor-panel #insertimage_target{width:auto;margin-right:5px;}.yui-skin-sam .yui-editor-panel .removeLink{width:98%;}.yui-skin-sam .yui-edi!
 tor-panel label input.warning{background-color:#FFEE69;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group h3{color:#000;float:left;font-weight:normal;font-size:93%;margin:5px 0 0 0;padding:0 3px 0 0;text-align:right;}.yui-skin-sam .yui-editor-panel .height-width h3{margin:3px 0 0 10px;}.yui-skin-sam .yui-editor-panel .height-width{margin:3px 0 0 35px;*margin-left:14px;width:42%;*width:44%;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-border{width:190px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-border{width:210px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding{width:203px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-padding{width:172px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding h3{margin-left:25px;*margin-left:12px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-textflow{width:182px;}.yui-skin-sam .yui-editor-panel .hd{background:none;}.yui-skin-sam .yui-editor-panel .ft{background-color:#F2F2F2;b!
 order:1px solid #808080;border-top:none;padding:0;margin:0 0 2!
 px 0;}.y
ui-skin-sam .yui-editor-panel .hd span.close{background:url(sprite.png) no-repeat 0 -300px;cursor:pointer;display:block;height:16px;overflow:hidden;position:absolute;right:5px;text-indent:500px;top:2px;width:26px;}.yui-skin-sam .yui-editor-panel .ft span.tip{background-color:#EDF5FF;border-top:1px solid #808080;font-size:85%;}.yui-skin-sam .yui-editor-panel .ft span.tip strong{display:block;float:left;margin:0 2px 8px 0;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon{background:url( editor-sprite.gif ) no-repeat 0 -1260px;display:block;height:20px;left:2px;position:absolute;top:8px;width:20px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-info{background-position:2px -1260px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-warn{background-position:2px -1296px;}.yui-skin-sam .yui-editor-panel .hd span.knob{position:absolute;height:10px;width:28px;top:-10px;left:25px;text-indent:9999px;overflow:hidden;background:url( editor-knob.gif ) no-repeat 0 0;}.yu!
 i-skin-sam .yui-editor-panel .yui-toolbar-container{float:left;width:100%;background-image:none;border:none;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .bd{background-color:#ffffff;}.yui-editor-blankimage{background-image:url( blankimage.png );}
+.yui-busy{cursor:wait !important;}.yui-toolbar-container fieldset{padding:0;margin:0;border:0;}.yui-toolbar-container legend{display:none;}.yui-toolbar-container .yui-toolbar-subcont{padding:.25em 0;zoom:1;}.yui-toolbar-container-collapsed .yui-toolbar-subcont{display:none;}.yui-toolbar-container .yui-toolbar-subcont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container span.yui-toolbar-draghandle{cursor:move;border-left:1px solid #999;border-right:1px solid #999;overflow:hidden;text-indent:77777px;width:2px;height:20px;display:block;clear:none;float:left;margin:0 0 0 .2em;}.yui-toolbar-container .yui-toolbar-titlebar.draggable{cursor:move;}.yui-toolbar-container .yui-toolbar-titlebar{position:relative;}.yui-toolbar-container .yui-toolbar-titlebar h2{font-weight:bold;letter-spacing:0;border:none;color:#000;margin:0;padding:.2em;}.yui-toolbar-container .yui-toolbar-titlebar h2 a{text-decoration:none;color:#000;cursor:default;}.yui-tool!
 bar-container.yui-toolbar-grouped span.yui-toolbar-draghandle{height:40px;}.yui-toolbar-container .yui-toolbar-group{float:left;zoom:1;}.yui-toolbar-container .yui-toolbar-group:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container .yui-toolbar-group h3{font-size:75%;padding:0 0 0 .25em;margin:0;}.yui-toolbar-container span.yui-toolbar-separator{width:2px;height:18px;margin:.2em 0 .2em .1em;display:block;clear:none;float:left;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-separator{height:35px;}.yui-toolbar-container.yui-toolbar-grouped .yui-toolbar-group span.yui-toolbar-separator{height:18px;}.yui-toolbar-container ul li{margin:0;padding:0;list-style-type:none;}.yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-toolbar-container .yui-push-button,.yui-toolbar-container .yui-color-button,.yui-toolbar-container .yui-menu-button{position:relative;cursor:pointer;}.yui-toolbar-container .yui-button .firs!
 t-child,.yui-toolbar-container .yui-button .first-child a{heig!
 ht:100%;
width:100%;overflow:hidden;}.yui-toolbar-container .yui-button-disabled{cursor:default;}.yui-toolbar-container .yui-button-disabled .yui-toolbar-icon{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button-disabled .up,.yui-toolbar-container .yui-button-disabled .down{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button a{overflow:hidden;}.yui-toolbar-container .yui-toolbar-select .first-child a{cursor:pointer;}.yui-toolbar-fontname-arial{font-family:Arial;}.yui-toolbar-fontname-arial-black{font-family:Arial Black;}.yui-toolbar-fontname-comic-sans-ms{font-family:Comic Sans MS;}.yui-toolbar-fontname-courier-new{font-family:Courier New;}.yui-toolbar-fontname-times-new-roman{font-family:Times New Roman;}.yui-toolbar-fontname-verdana{font-family:Verdana;}.yui-toolbar-fontname-impact{font-family:Impact;}.yui-toolbar-fontname-lucida-console{font-family:Lucida Console;}.yui-toolbar-fontname-tahoma{font-family:Tahoma;}.yui-toolbar-fontname-trebuche!
 t-ms{font-family:Trebuchet MS;}.yui-toolbar-container .yui-toolbar-spinbutton{position:relative;}.yui-toolbar-container .yui-toolbar-spinbutton .first-child a{z-index:0;opacity:1;}.yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-toolbar-container .yui-toolbar-spinbutton a.down{position:absolute;display:block right:0;cursor:pointer;z-index:1;padding:0;margin:0;}.yui-toolbar-container .yui-overlay{position:absolute;}.yui-toolbar-container .yui-overlay ul li{margin:0;list-style-type:none;}.yui-toolbar-container{z-index:1;}.yui-editor-container .yui-editor-editable-container{position:relative;z-index:0;width:100%;}.yui-editor-container .yui-editor-masked{background-color:#CCC;}.yui-editor-container iframe{border:0px;padding:0;margin:0;zoom:1;display:block;}.yui-editor-container .yui-editor-editable{padding:0;margin:0;}.yui-editor-container .dompath{font-size:85%;}.yui-editor-panel .hd{text-align:left;position:relative;}.yui-editor-panel .hd h3{font-weight:bold;padding:0!
 .25em 0pt 0.25em 0.25em;margin:0;}.yui-editor-panel .bd{width:!
 100%;zoo
m:1;position:relative;}.yui-editor-panel .bd div.yui-editor-body-cont{padding:.25em .1em;zoom:1;}.yui-editor-panel .bd div.yui-editor-body-cont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-editor-panel .ft{text-align:right;width:99%;float:left;clear:both;}.yui-editor-panel .ft span.tip{display:block;position:relative;padding:.5em .5em .5em 23px;text-align:left;zoom:1;}.yui-editor-panel label{clear:both;float:left;padding:0;width:100%;text-align:left;zoom:1;}.yui-editor-panel .gecko label{overflow:auto;}.yui-editor-panel label strong{float:left;width:6em;}.yui-editor-panel .removeLink{width:80%;text-align:right;}.yui-editor-panel label input{margin-left:.25em;float:left;}.yui-editor-panel .yui-toolbar-group-padding{}.yui-editor-panel .yui-toolbar-group-border{}.yui-editor-panel .yui-toolbar-group-textflow{}.yui-editor-panel .height-width{float:left;}.yui-editor-panel .height-width h3{}.yui-editor-panel .height-width span{font-style:italic;displa!
 y:block;float:left;overflow:auto;}.yui-editor-panel .height-width span.info{font-size:70%;}.yui-editor-panel .yui-toolbar-bordersize,.yui-editor-panel .yui-toolbar-bordertype{font-size:75%;}.yui-editor-panel .yui-toolbar-container span.yui-toolbar-separator{border:none;}.yui-editor-panel .yui-toolbar-bordersize span a span,.yui-editor-panel .yui-toolbar-bordertype span a span{display:block;height:8px;left:4px;position:absolute;top:3px;*top:-5px;width:24px;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-solid{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dotted{border-bottom:1px dotted black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dashed{border-bottom:1px dashed black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-0{*top:0px;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-1{border-bottom!
 :1px solid black;}.yui-editor-panel .yui-toolbar-bordersize sp!
 an a spa
n.yui-toolbar-bordersize-2{border-bottom:2px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-3{top:2px;*top:-5px;border-bottom:3px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-4{top:1px;*top:-5px;border-bottom:4px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-5{top:1px;*top:-5px;border-bottom:5px solid black;}.yui-toolbar-container .yui-toolbar-bordersize-menu,.yui-toolbar-container .yui-toolbar-bordertype-menu{width:95px !important;}.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel,.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel:hover{margin:0px 3px 7px 17px;}.yui-toolbar-bordersize-menu .yuimenuitemlabel .checkedindicator,.yui-toolbar-bordertype-menu .yuimenuitemlabel .checkedindicator{position:absolute;left:-12px;*top:14px;*left:0px;}.yui-toolbar-bordersi!
 ze-menu li.yui-toolbar-bordersize-1 a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-2 a{border-bottom:2px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-3 a{border-bottom:3px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-4 a{border-bottom:4px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-5 a{border-bottom:5px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-solid a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dashed a{border-bottom:1px dashed black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dotted a{border-bottom:1px dotted black;height:14px;}h2.yui-editor-skipheader,h3.yui-editor-skipheader{height:0;margin:0;padding:0;border:none;width:0;overflow:hidden;position:absolute;}.yui-toolbar-colors{width:133px;zoom:1;displ!
 ay:none;z-index:100;overflow:hidden;}.yui-toolbar-colors:after!
 {display
:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors a{height:9px;width:9px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0;cursor:pointer;border:1px solid #F6F7EE;}.yui-toolbar-colors a:hover{border:1px solid black;}.yui-color-button-menu{overflow:visible;background-color:transparent;}.yui-toolbar-colors span{position:relative;display:block;padding:3px;overflow:hidden;float:left;width:100%;zoom:1;}.yui-toolbar-colors span:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors span em{height:35px;width:30px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0.75px;border:1px solid black;}.yui-toolbar-colors span strong{font-weight:normal;padding-left:3px;display:block;font-size:85%;float:left;width:65%;}.yui-skin-sam .yui-editor-container{border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container{zoom:1;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar{background:url!
 (sprite.png) repeat-x 0 -200px;position:relative;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar h2{color:#000000;font-weight:bold;margin:0;padding:0.3em 1em;font-size:100%;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-group h3{color:#808080;font-size:75%;margin:1em 0 0;padding-bottom:0;padding-left:0.25em;text-align:left;}.yui-toolbar-container span.yui-toolbar-separator{border:none;text-indent:33px;overflow:hidden;margin:.25em;}.yui-skin-sam .yui-toolbar-container{background-color:#F2F2F2;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subcont{padding:0 1em 0.35em;border-bottom:1px solid #808080;}.yui-skin-sam .yui-toolbar-container-collapsed .yui-toolbar-titlebar{border-bottom:1px solid #808080;}.yui-skin-sam .yui-editor-container .visible .yui-menu-shadow,.yui-skin-sam .yui-editor-panel .visible .yui-menu-shadow{display:none;}.yui-skin-sam .yui-editor-container ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-cont!
 ainer ul li{list-style-type:none;margin:0;padding:0;}.yui-skin!
 -sam .yu
i-toolbar-group ul li.yui-toolbar-groupitem{float:left;}.yui-skin-sam .yui-editor-container .dompath{background-color:#F2F2F2;border-top:1px solid #808080;color:#999;text-align:left;padding:0.25em;}.yui-skin-sam .yui-toolbar-container .collapse{background:url(sprite.png) no-repeat 0 -400px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar span.collapse{cursor:pointer;position:absolute;top:4px;right:2px;display:block;overflow:hidden;height:15px;width:15px;text-indent:9999px;}.yui-skin-sam .yui-toolbar-container .yui-push-button,.yui-skin-sam .yui-toolbar-container .yui-color-button,.yui-skin-sam .yui-toolbar-container .yui-menu-button{background:url(sprite.png) repeat-x 0 0;position:relative;display:block;height:22px;width:30px;margin:0;border-color:#808080;border-style:solid;border-width:1px 0;}.yui-skin-sam .yui-toolbar-container .yui-push-button a,.yui-skin-sam .yui-toolbar-container .yui-color-button a,.yui-skin-sam .yui-toolbar-container .yui-menu-button a{padd!
 ing-left:35px;height:20px;text-decoration:none;font-size:93%;line-height:2;display:block;color:#000000;overflow:hidden;}.yui-skin-sam .yui-toolbar-container .yui-push-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button .first-child{border-color:#808080;border-style:solid;border-width:0 1px;margin:0 -1px;display:block;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled,.yui-skin-sam .yui-toolbar-container .yui!
 -color-button-disabled,.yui-skin-sam .yui-toolbar-container .y!
 ui-menu-
button-disabled{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-button .first-child{*left:0px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-fontname{width:135px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-heading{width:92px;}.yui-skin-sam .yui-toolbar-container .yui-button-hover{background:url(sprite.png) repeat-x 0 -1300px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-button-selected{background:url(sprite.png) repeat-x 0 -1700px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels .yui-toolbar-group{margin-top:.75em;}.yui-skin-sam .yui-toolbar-container .yui-push-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-color-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-menu-button span.yui-toolbar-icon{display:block;position:absolute;top:2px;height:18px;width:18px;overflow:hidden;!
 background:url(editor-sprite.gif) no-repeat 30px 30px;}.yui-skin-sam .yui-toolbar-container .yui-button-selected span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-button-hover span.yui-toolbar-icon{background-image:url(editor-sprite-active.gif);}.yui-skin-sam .yui-toolbar-container .visible .yuimenuitemlabel{cursor:pointer;color:#000;*position:relative;}.yui-skin-sam .yui-toolbar-container .yui-button-menu{background-color:#fff;}.yui-skin-sam div.yuimenu li.selected{background-color:#B3D4FF;}.yui-skin-sam div.yuimenu li.selected a.selected{color:#000;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bold span.yui-toolbar-icon{background-position:0 0;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-italic span.yui-toolbar-icon{background-position:0 -36px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-underline span.yui-toolbar-icon{background-position:0 -72px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subscript span.yui!
 -toolbar-icon{background-position:0 -180px;left:5px;}.yui-skin!
 -sam .yu
i-toolbar-container .yui-toolbar-superscript span.yui-toolbar-icon{background-position:0 -144px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-forecolor span.yui-toolbar-icon{background-position:0 -216px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-backcolor span.yui-toolbar-icon{background-position:0 -288px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyleft span.yui-toolbar-icon{background-position:0 -324px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifycenter span.yui-toolbar-icon{background-position:0 -360px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyright span.yui-toolbar-icon{background-position:0 -396px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyfull span.yui-toolbar-icon{background-position:0 -432px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-indent span.yui-toolbar-icon{background-position:0 -720px;left:5px;}.yui-skin-sam .yui-toolbar-c!
 ontainer .yui-toolbar-outdent span.yui-toolbar-icon{background-position:0 -684px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-createlink span.yui-toolbar-icon{background-position:0 -792px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertimage span.yui-toolbar-icon{background-position:1px -756px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-left span.yui-toolbar-icon{background-position:0 -972px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-right span.yui-toolbar-icon{background-position:0 -936px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-inline span.yui-toolbar-icon{background-position:0 -900px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-block span.yui-toolbar-icon{background-position:0 -864px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bordercolor span.yui-toolbar-icon{background-position:0 -252px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-removefor!
 mat span.yui-toolbar-icon{background-position:0 -1080px;left:5!
 px;}.yui
-skin-sam .yui-toolbar-container .yui-toolbar-hiddenelements span.yui-toolbar-icon{background-position:0 -1044px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertunorderedlist span.yui-toolbar-icon{background-position:0 -468px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertorderedlist span.yui-toolbar-icon{background-position:0 -504px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child{width:35px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child a{padding-left:2px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton span.yui-toolbar-icon{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{right:2px;background:url(editor-sprite.gif) no-repeat 0 -1222px;overflow:hidden;height:6px;width:7px;min-height:0;padd!
 ing:0;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up{top:2px;background-position:0 -1222px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{bottom:2px;background-position:0 -1187px;}.yui-skin-sam .yui-toolbar-container select{height:22px;border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select .first-child a{padding-left:5px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select span.yui-toolbar-icon{background:url( editor-sprite.gif ) no-repeat 0 -1144px;overflow:hidden;right:-2px;top:0px;height:20px;}.yui-skin-sam .yui-editor-panel .yui-color-button-menu .bd{background-color:transparent;border:none;width:135px;}.yui-skin-sam .yui-color-button-menu .yui-toolbar-colors{border:1px solid #808080;}.yui-skin-sam .yui-editor-panel{padding:0;margin:0;border:none;background-color:transparent;overflow:visible;}.yui-skin-sam .yui-editor-panel .hd{margin:10px 0 0;padding:0;border:none;}.yui-skin-sam !
 .yui-editor-panel .hd h3{color:#000;border:1px solid #808080;b!
 ackgroun
d:url(sprite.png) repeat-x 0 -200px;width:99%;position:relative;margin:0;padding:3px 0 0 0;font-size:93%;text-indent:5px;height:20px;}.yui-skin-sam .yui-editor-panel .bd{background-color:#F2F2F2;border-left:1px solid #808080;border-right:1px solid #808080;width:99%;margin:0;padding:0;overflow:visible;}.yui-skin-sam .yui-editor-panel ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-panel ul li{margin:0;padding:0;}.yui-skin-sam .yui-editor-panel .yuimenu{}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .yui-toolbar-subcont{padding:0;border:none;margin-top:0.35em;}.yui-skin-sam .yui-editor-panel .yui-toolbar-bordersize,.yui-skin-sam .yui-editor-panel .yui-toolbar-bordertype{width:50px;}.yui-skin-sam .yui-editor-panel label{display:block;float:none;padding:4px 0;margin-bottom:7px;}.yui-skin-sam .yui-editor-panel label strong{font-weight:normal;font-size:93%;text-align:right;padding-top:2px;}.yui-skin-sam .yui-editor-panel label input{width:75%;}.yui-s!
 kin-sam .yui-editor-panel #createlink_target,.yui-skin-sam .yui-editor-panel #insertimage_target{width:auto;margin-right:5px;}.yui-skin-sam .yui-editor-panel .removeLink{width:98%;}.yui-skin-sam .yui-editor-panel label input.warning{background-color:#FFEE69;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group h3{color:#000;float:left;font-weight:normal;font-size:93%;margin:5px 0 0 0;padding:0 3px 0 0;text-align:right;}.yui-skin-sam .yui-editor-panel .height-width h3{margin:3px 0 0 10px;}.yui-skin-sam .yui-editor-panel .height-width{margin:3px 0 0 35px;*margin-left:14px;width:42%;*width:44%;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-border{width:190px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-border{width:210px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding{width:203px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-padding{width:172px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding h3{margin-left:25px;*mar!
 gin-left:12px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-gr!
 oup-text
flow{width:182px;}.yui-skin-sam .yui-editor-panel .hd{background:none;}.yui-skin-sam .yui-editor-panel .ft{background-color:#F2F2F2;border:1px solid #808080;border-top:none;padding:0;margin:0 0 2px 0;}.yui-skin-sam .yui-editor-panel .hd span.close{background:url(sprite.png) no-repeat 0 -300px;cursor:pointer;display:block;height:16px;overflow:hidden;position:absolute;right:5px;text-indent:500px;top:2px;width:26px;}.yui-skin-sam .yui-editor-panel .ft span.tip{background-color:#EDF5FF;border-top:1px solid #808080;font-size:85%;}.yui-skin-sam .yui-editor-panel .ft span.tip strong{display:block;float:left;margin:0 2px 8px 0;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon{background:url( editor-sprite.gif ) no-repeat 0 -1260px;display:block;height:20px;left:2px;position:absolute;top:8px;width:20px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-info{background-position:2px -1260px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-warn{background-position:2px !
 -1296px;}.yui-skin-sam .yui-editor-panel .hd span.knob{position:absolute;height:10px;width:28px;top:-10px;left:25px;text-indent:9999px;overflow:hidden;background:url( editor-knob.gif ) no-repeat 0 0;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container{float:left;width:100%;background-image:none;border:none;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .bd{background-color:#ffffff;}.yui-editor-blankimage{background-image:url( blankimage.png );}

Added: trunk/root/static/yui/assets/skins/sam/header_background.png
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/assets/skins/sam/header_background.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/root/static/yui/assets/skins/sam/imagecropper.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/imagecropper.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/imagecropper.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+.yui-crop{position:relative;}.yui-crop .yui-crop-mask{position:absolute;top:0;left:0;height:100%;width:100%;}.yui-crop .yui-resize{position:absolute;top:10px;left:10px;}.yui-crop .yui-crop-resize-mask{position:absolute;top:0;left:0;height:100%;width:100%;background-position:-10px -10px;overflow:hidden;}.yui-skin-sam .yui-crop .yui-crop-mask{background-color:#000;opacity:.5;filter:alpha(opacity=50);}.yui-skin-sam .yui-crop .yui-resize{border:1px dashed #fff;}

Added: trunk/root/static/yui/assets/skins/sam/layout.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/layout.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/layout.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+.yui-layout-loading{visibility:hidden;}body.yui-layout{overflow:hidden;position:relative;padding:0;margin:0;}.yui-layout-doc{position:relative;}.yui-layout-unit{height:50px;width:50px;padding:0;margin:0;float:none;z-index:0;overflow:hidden;}.yui-layout-unit-top{position:absolute;top:0;left:0;width:100%;}.yui-layout-unit-left{position:absolute;top:0;left:0;}.yui-layout-unit-right{position:absolute;top:0;right:0;}.yui-layout-unit-bottom{position:absolute;bottom:0;left:0;width:100%;}.yui-layout-unit-center{position:absolute;top:0;left:0;width:100%;}.yui-layout div.yui-layout-hd{position:absolute;top:0;left:0;zoom:1;width:100%;overflow:hidden;}.yui-layout div.yui-layout-bd{position:absolute;top:0;left:0;zoom:1;width:100%;overflow:hidden;}.yui-layout .yui-layout-scroll div.yui-layout-bd{overflow:auto;}.yui-layout div.yui-layout-ft{position:absolute;bottom:0;left:0;width:100%;zoom:1;overflow:hidden;}.yui-layout .yui-layout-unit div.yui-layout-hd h2{text-align:left;}.yui-layout .y!
 ui-layout-unit div.yui-layout-hd .collapse{cursor:pointer;height:13px;position:absolute;right:2px;top:2px;width:17px;font-size:0;}.yui-layout .yui-layout-unit div.yui-layout-hd .close{cursor:pointer;height:13px;position:absolute;right:2px;top:2px;width:17px;font-size:0;}.yui-layout .yui-layout-unit div.yui-layout-hd .collapse-close{right:25px;}.yui-layout .yui-layout-clip{position:absolute;height:20px;background-color:#c0c0c0;display:none;}.yui-layout .yui-layout-clip .collapse{cursor:pointer;height:13px;position:absolute;right:2px;top:2px;width:17px;font-size:0px;}.yui-layout .yui-layout-wrap{height:100%;width:100%;position:absolute;left:0;}.yui-layout .yui-layout-unit .yui-content{overflow:hidden;}.yui-layout .yui-layout-unit .yui-layout-scroll{overflow:auto;}.yui-skin-sam .yui-layout .yui-resize-proxy{border:none;font-size:0;margin:0;padding:0;}.yui-skin-sam .yui-layout .yui-resize-resizing .yui-resize-handle{opacity:0;filter:alpha(opacity=0);}.yui-skin-sam .yui-layout .!
 yui-resize-proxy div{position:absolute;border:1px solid #80808!
 0;backgr
ound-color:#EDF5FF;}.yui-skin-sam .yui-layout .yui-resize .yui-resize-handle-active{background-color:#EDF5FF;}.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-l{width:5px;height:100%;top:0;left:0;}.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-r{width:5px;top:0;right:0;height:100%;}.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-b{width:100%;bottom:0;left:0;height:5px;}.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-t{width:100%;top:0;left:0;height:5px;}.yui-skin-sam .yui-layout .yui-layout-unit-left div.yui-layout-hd .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -160px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip-left .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -140px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit-right div.yui-layout-hd .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -200px;b!
 order:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip-right .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -120px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit-top div.yui-layout-hd .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -220px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip-top .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -240px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit-bottom div.yui-layout-hd .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -260px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip-bottom .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -180px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-hd .close{background:transparent url(layout_sprite.png) no-repeat -20px -100px;border:1px solid #8080!
 80;}.yui-skin-sam .yui-layout .yui-layout-hd{background:url(sp!
 rite.png
) repeat-x 0 -1400px;border:1px solid #808080;}.yui-skin-sam .yui-layout{background-color:#EDF5FF;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-hd h2{font-weight:bold;color:#fff;padding:3px;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd{border:1px solid #808080;border-bottom:none;border-top:none;*border-bottom-width:0;*border-top-width:0;background-color:#f2f2f2;text-align:left;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd-noft{border-bottom:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd-nohd{border-top:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip{position:absolute;height:20px;background-color:#EDF5FF;display:none;border:1px solid #808080;}.yui-skin-sam .yui-layout div.yui-layout-ft{border:1px solid #808080;border-top:none;*border-top-width:0;background-color:#f2f2f2;}.yui-skin-sam .yui-layout-unit .yui-resize-handle{background-color:transparent;}.yui-skin-sam .yui-layout-unit .yui-!
 resize-handle-r{right:0;top:0;background-image:none;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-l{left:0;top:0;background-image:none;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-b{right:0;bottom:0;background-image:none;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-t{right:0;top:0;background-image:none;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-r .yui-layout-resize-knob,.yui-skin-sam .yui-layout-unit .yui-resize-handle-l .yui-layout-resize-knob{position:absolute;height:16px;width:6px;top:45%;left:0px;background:transparent url(layout_sprite.png) no-repeat 0 -5px;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-t .yui-layout-resize-knob,.yui-skin-sam .yui-layout-unit .yui-resize-handle-b .yui-layout-resize-knob{position:absolute;height:6px;width:16px;left:45%;background:transparent url(layout_sprite.png) no-repeat -20px 0;}

Added: trunk/root/static/yui/assets/skins/sam/layout_sprite.png
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/assets/skins/sam/layout_sprite.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: trunk/root/static/yui/assets/skins/sam/logger.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/logger.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/logger.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-skin-sam .yui-log{padding:1em;width:31em;background-color:#AAA;color:#000;border:1px solid black;font-family:monospace;font-size:77%;text-align:left;z-index:9000;}.yui-skin-sam .yui-log-container{position:absolute;top:1em;right:1em;}.yui-skin-sam .yui-log input{margin:0;padding:0;font-family:arial;font-size:100%;font-weight:normal;}.yui-skin-sam .yui-log .yui-log-btns{position:relative;float:right;bottom:.25em;}.yui-skin-sam .yui-log .yui-log-hd{margin-top:1em;padding:.5em;background-color:#575757;}.yui-skin-sam .yui-log .yui-log-hd h4{margin:0;padding:0;font-size:108%;font-weight:bold;color:#FFF;}.yui-skin-sam .yui-log .yui-log-bd{width:100%;height:20em;background-color:#FFF;border:1px solid gray;overflow:auto;}.yui-skin-sam .yui-log p{margin:1px;padding:.1em;}.yui-skin-sam .yui-log pre{margin:0;padding:0;}.yui-skin-sam .yui-log pre.yui-log-verbose{white-space:pre-wrap;white-space:-moz-pre-wrap !important;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-w!
 ord;}.yui-skin-sam .yui-log .yui-log-ft{margin-top:.5em;}.yui-skin-sam .yui-log .yui-log-ft .yui-log-categoryfilters{}.yui-skin-sam .yui-log .yui-log-ft .yui-log-sourcefilters{width:100%;border-top:1px solid #575757;margin-top:.75em;padding-top:.75em;}.yui-skin-sam .yui-log .yui-log-filtergrp{margin-right:.5em;}.yui-skin-sam .yui-log .info{background-color:#A7CC25;}.yui-skin-sam .yui-log .warn{background-color:#F58516;}.yui-skin-sam .yui-log .error{background-color:#E32F0B;}.yui-skin-sam .yui-log .time{background-color:#A6C9D7;}.yui-skin-sam .yui-log .window{background-color:#F2E886;}

Modified: trunk/root/static/yui/assets/skins/sam/menu.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/menu.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/menu.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-.yuimenubar{visibility:visible;position:static;}.yuimenu .yuimenu,.yuimenubar .yuimenu{visibility:hidden;position:absolute;top:-10000px;left:-10000px;}.yuimenubar li,.yuimenu li{list-style-type:none;}.yuimenubar ul,.yuimenu ul,.yuimenubar li,.yuimenu li,.yuimenu h6,.yuimenubar h6{margin:0;padding:0;}.yuimenuitemlabel,.yuimenubaritemlabel{text-align:left;white-space:nowrap;}.yuimenubar ul{*zoom:1;}.yuimenubar .yuimenu ul{*zoom:normal;}.yuimenubar>.bd>ul:after{content:".";display:block;clear:both;visibility:hidden;height:0;line-height:0;}.yuimenubaritem{float:left;}.yuimenubaritemlabel,.yuimenuitemlabel{display:block;}.yuimenuitemlabel .helptext{font-style:normal;display:block;margin:-1em 0 0 10em;}.yui-menu-shadow{position:absolute;visibility:hidden;z-index:-1;}.yui-skin-sam .yui-menu-shadow-visible{top:2px;right:-3px;left:-3px;bottom:-3px;visibility:visible;}.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.yuimenu.show-scrollbars,.yuimenubar.show-s!
 crollbars{overflow:visible;}.yuimenu.hide-scrollbars .yui-menu-shadow,.yuimenubar.hide-scrollbars .yui-menu-shadow{overflow:hidden;}.yuimenu.show-scrollbars .yui-menu-shadow,.yuimenubar.show-scrollbars .yui-menu-shadow{overflow:auto;}.yui-skin-sam .yuimenubar{font-size:93%;line-height:2;*line-height:1.9;border:solid 1px #808080;background:url(sprite.png) repeat-x 0 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritem{border-right:solid 1px #ccc;}.yui-skin-sam .yuimenubaritemlabel{padding:0 10px;color:#000;text-decoration:none;cursor:default;border-style:solid;border-color:#808080;border-width:1px 0;*position:relative;margin:-1px 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel{padding-right:20px;*display:inline-block;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu{background:url(menubaritem_submenuindicator.png) right center no-repeat;}.yui-skin-sam .yuimenubaritem-selected{background:url(sprite.png) repeat-x 0 -1700px;}.yui-skin-sam .yuimenubaritemlabel-select!
 ed{border-color:#7D98B8;}.yui-skin-sam .yuimenubarnav .yuimenu!
 bariteml
abel-selected{border-left-width:1px;margin-left:-1px;*left:-1px;}.yui-skin-sam .yuimenubaritemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu-disabled{background-image:url(menubaritem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenu{font-size:93%;line-height:1.5;*line-height:1.45;}.yui-skin-sam .yuimenubar .yuimenu,.yui-skin-sam .yuimenu .yuimenu{font-size:100%;}.yui-skin-sam .yuimenu .bd{border:solid 1px #808080;background-color:#fff;}.yui-skin-sam .yuimenu ul{padding:3px 0;border-width:1px 0 0 0;border-color:#ccc;border-style:solid;}.yui-skin-sam .yuimenu ul.first-of-type{border-width:0;}.yui-skin-sam .yuimenu h6{font-weight:bold;border-style:solid;border-color:#ccc;border-width:1px 0 0 0;color:#a4a4a4;padding:3px 10px 0 10px;}.yui-skin-sam .yuimenu ul.hastitle,.yui-skin-sam .yuimenu h6.first-of-type{border-width:0;}.yui-skin-sam .yuimenu .yui-menu-body-scrolled{border-color:#ccc #808080;overflow:hidden;}.yui-!
 skin-sam .yuimenu .topscrollbar,.yui-skin-sam .yuimenu .bottomscrollbar{height:16px;border:solid 1px #808080;background:#fff url(sprite.png) no-repeat 0 0;}.yui-skin-sam .yuimenu .topscrollbar{border-bottom-width:0;background-position:center -950px;}.yui-skin-sam .yuimenu .topscrollbar_disabled{background-position:center -975px;}.yui-skin-sam .yuimenu .bottomscrollbar{border-top-width:0;background-position:center -850px;}.yui-skin-sam .yuimenu .bottomscrollbar_disabled{background-position:center -875px;}.yui-skin-sam .yuimenuitem{_border-bottom:solid 1px #fff;}.yui-skin-sam .yuimenuitemlabel{padding:0 20px;color:#000;text-decoration:none;cursor:default;}.yui-skin-sam .yuimenuitemlabel .helptext{margin-top:-1.5em;*margin-top:-1.45em;}.yui-skin-sam .yuimenuitem-hassubmenu{background-image:url(menuitem_submenuindicator.png);background-position:right center;background-repeat:no-repeat;}.yui-skin-sam .yuimenuitem-checked{background-image:url(menuitem_checkbox.png);background-pos!
 ition:left center;background-repeat:no-repeat;}.yui-skin-sam .!
 yui-menu
-shadow-visible{background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yuimenuitem-selected{background-color:#B3D4FF;}.yui-skin-sam .yuimenuitemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenuitem-hassubmenu-disabled{background-image:url(menuitem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenuitem-checked-disabled{background-image:url(menuitem_checkbox_disabled.png);}
+.yuimenubar{visibility:visible;position:static;}.yuimenu .yuimenu,.yuimenubar .yuimenu{visibility:hidden;position:absolute;top:-10000px;left:-10000px;}.yuimenubar li,.yuimenu li{list-style-type:none;}.yuimenubar ul,.yuimenu ul,.yuimenubar li,.yuimenu li,.yuimenu h6,.yuimenubar h6{margin:0;padding:0;}.yuimenuitemlabel,.yuimenubaritemlabel{text-align:left;white-space:nowrap;}.yuimenubar ul{*zoom:1;}.yuimenubar .yuimenu ul{*zoom:normal;}.yuimenubar>.bd>ul:after{content:".";display:block;clear:both;visibility:hidden;height:0;line-height:0;}.yuimenubaritem{float:left;}.yuimenubaritemlabel,.yuimenuitemlabel{display:block;}.yuimenuitemlabel .helptext{font-style:normal;display:block;margin:-1em 0 0 10em;}.yui-menu-shadow{position:absolute;visibility:hidden;z-index:-1;}.yui-menu-shadow-visible{top:2px;right:-3px;left:-3px;bottom:-3px;visibility:visible;}.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.yuimenu.show-scrollbars,.yuimenubar.show-scrollbars{over!
 flow:visible;}.yuimenu.hide-scrollbars .yui-menu-shadow,.yuimenubar.hide-scrollbars .yui-menu-shadow{overflow:hidden;}.yuimenu.show-scrollbars .yui-menu-shadow,.yuimenubar.show-scrollbars .yui-menu-shadow{overflow:auto;}.yui-skin-sam .yuimenubar{font-size:93%;line-height:2;*line-height:1.9;border:solid 1px #808080;background:url(sprite.png) repeat-x 0 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritem{border-right:solid 1px #ccc;}.yui-skin-sam .yuimenubaritemlabel{padding:0 10px;color:#000;text-decoration:none;cursor:default;border-style:solid;border-color:#808080;border-width:1px 0;*position:relative;margin:-1px 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel{padding-right:20px;*display:inline-block;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu{background:url(menubaritem_submenuindicator.png) right center no-repeat;}.yui-skin-sam .yuimenubaritem-selected{background:url(sprite.png) repeat-x 0 -1700px;}.yui-skin-sam .yuimenubaritemlabel-selected{border-colo!
 r:#7D98B8;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-s!
 elected{
border-left-width:1px;margin-left:-1px;*left:-1px;}.yui-skin-sam .yuimenubaritemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu-disabled{background-image:url(menubaritem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenu{font-size:93%;line-height:1.5;*line-height:1.45;}.yui-skin-sam .yuimenubar .yuimenu,.yui-skin-sam .yuimenu .yuimenu{font-size:100%;}.yui-skin-sam .yuimenu .bd{border:solid 1px #808080;background-color:#fff;}.yui-skin-sam .yuimenu ul{padding:3px 0;border-width:1px 0 0 0;border-color:#ccc;border-style:solid;}.yui-skin-sam .yuimenu ul.first-of-type{border-width:0;}.yui-skin-sam .yuimenu h6{font-weight:bold;border-style:solid;border-color:#ccc;border-width:1px 0 0 0;color:#a4a4a4;padding:3px 10px 0 10px;}.yui-skin-sam .yuimenu ul.hastitle,.yui-skin-sam .yuimenu h6.first-of-type{border-width:0;}.yui-skin-sam .yuimenu .yui-menu-body-scrolled{border-color:#ccc #808080;overflow:hidden;}.yui-skin-sam .yuim!
 enu .topscrollbar,.yui-skin-sam .yuimenu .bottomscrollbar{height:16px;border:solid 1px #808080;background:#fff url(sprite.png) no-repeat 0 0;}.yui-skin-sam .yuimenu .topscrollbar{border-bottom-width:0;background-position:center -950px;}.yui-skin-sam .yuimenu .topscrollbar_disabled{background-position:center -975px;}.yui-skin-sam .yuimenu .bottomscrollbar{border-top-width:0;background-position:center -850px;}.yui-skin-sam .yuimenu .bottomscrollbar_disabled{background-position:center -875px;}.yui-skin-sam .yuimenuitem{_border-bottom:solid 1px #fff;}.yui-skin-sam .yuimenuitemlabel{padding:0 20px;color:#000;text-decoration:none;cursor:default;}.yui-skin-sam .yuimenuitemlabel .helptext{margin-top:-1.5em;*margin-top:-1.45em;}.yui-skin-sam .yuimenuitem-hassubmenu{background-image:url(menuitem_submenuindicator.png);background-position:right center;background-repeat:no-repeat;}.yui-skin-sam .yuimenuitem-checked{background-image:url(menuitem_checkbox.png);background-position:left cen!
 ter;background-repeat:no-repeat;}.yui-skin-sam .yui-menu-shado!
 w-visibl
e{background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yuimenuitem-selected{background-color:#B3D4FF;}.yui-skin-sam .yuimenuitemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenuitem-hassubmenu-disabled{background-image:url(menuitem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenuitem-checked-disabled{background-image:url(menuitem_checkbox_disabled.png);}

Added: trunk/root/static/yui/assets/skins/sam/profilerviewer.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/profilerviewer.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/profilerviewer.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+.yui-skin-sam .yui-pv{background-color:#4a4a4a;font:arial;position:relative;width:99%;z-index:1000;margin-bottom:1em;overflow:hidden;}.yui-skin-sam .yui-pv .hd{background:url(header_background.png) repeat-x;min-height:30px;overflow:hidden;zoom:1;padding:2px 0;}.yui-skin-sam .yui-pv .hd h4{padding:8px 10px;margin:0;font:bold 14px arial;color:#fff;}.yui-skin-sam .yui-pv .hd a{background:#3f6bc3;font:bold 11px arial;color:#fff;padding:4px;margin:3px 10px 0 0;border:1px solid #3f567d;cursor:pointer;display:block;float:right;}.yui-skin-sam .yui-pv .hd span{display:none;}.yui-skin-sam .yui-pv .hd span.yui-pv-busy{height:18px;width:18px;background:url(wait.gif) no-repeat;overflow:hidden;display:block;float:right;margin:4px 10px 0 0;}.yui-skin-sam .yui-pv .hd:after,.yui-pv .bd:after,.yui-skin-sam .yui-pv-chartlegend dl:after{content:'.';visibility:hidden;clear:left;height:0;display:block;}.yui-skin-sam .yui-pv .bd{position:relative;zoom:1;overflow-x:auto;overflow-y:hidden;}.yui-ski!
 n-sam .yui-pv .yui-pv-table{padding:0 10px;margin:5px 0 10px 0;}.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-bd td{color:#eeee5c;font:12px arial;}.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-odd{background:#929292;}.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-even{background:#58637a;}.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-even td.yui-dt-desc{background:#384970;}.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-odd td.yui-dt-desc{background:#6F6E6E;}.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-hd th{background-image:none;background:#2E2D2D;}.yui-skin-sam .yui-pv th.yui-dt-asc .yui-dt-liner{background:transparent url(asc.gif) no-repeat scroll right center;}.yui-skin-sam .yui-pv th.yui-dt-desc .yui-dt-liner{background:transparent url(desc.gif) no-repeat scroll right center;}.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-hd th a{color:#fff;font:bold 1!
 2px arial;}.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-hd th.y!
 ui-dt-as
c,.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-hd th.yui-dt-desc{background:#333;}.yui-skin-sam .yui-pv-chartcontainer{padding:0 10px;}.yui-skin-sam .yui-pv-chart{height:250px;clear:right;margin:5px 0 0 0;color:#fff;}.yui-skin-sam .yui-pv-chartlegend div{float:right;margin:0 0 0 10px;_width:250px;}.yui-skin-sam .yui-pv-chartlegend dl{border:1px solid #999;padding:.2em 0 .2em .5em;zoom:1;margin:5px 0;}.yui-skin-sam .yui-pv-chartlegend dt{float:left;display:block;height:.7em;width:.7em;padding:0;}.yui-skin-sam .yui-pv-chartlegend dd{float:left;display:block;color:#fff;margin:0 1em 0 .5em;padding:0;font:11px arial;}.yui-skin-sam .yui-pv-minimized{height:35px;}.yui-skin-sam .yui-pv-minimized .bd{top:-3000px;}.yui-skin-sam .yui-pv-minimized .hd a.yui-pv-refresh{display:none;}

Added: trunk/root/static/yui/assets/skins/sam/resize.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/resize.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/resize.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+.yui-resize{position:relative;zoom:1;z-index:0;}.yui-resize-wrap{zoom:1;}.yui-draggable{cursor:move;}.yui-resize .yui-resize-handle{position:absolute;z-index:1;font-size:0;margin:0;padding:0;zoom:1;height:1px;width:1px;}.yui-resize .yui-resize-handle-br{height:5px;width:5px;bottom:0;right:0;cursor:se-resize;z-index:2;zoom:1;}.yui-resize .yui-resize-handle-bl{height:5px;width:5px;bottom:0;left:0;cursor:sw-resize;z-index:2;zoom:1;}.yui-resize .yui-resize-handle-tl{height:5px;width:5px;top:0;left:0;cursor:nw-resize;z-index:2;zoom:1;}.yui-resize .yui-resize-handle-tr{height:5px;width:5px;top:0;right:0;cursor:ne-resize;z-index:2;zoom:1;}.yui-resize .yui-resize-handle-r{width:5px;height:100%;top:0;right:0;cursor:e-resize;zoom:1;}.yui-resize .yui-resize-handle-l{height:100%;width:5px;top:0;left:0;cursor:w-resize;zoom:1;}.yui-resize .yui-resize-handle-b{width:100%;height:5px;bottom:0;right:0;cursor:s-resize;zoom:1;}.yui-resize .yui-resize-handle-t{width:100%;height:5px;top:0;right:!
 0;cursor:n-resize;zoom:1;}.yui-resize-proxy{position:absolute;border:1px dashed #000;visibility:hidden;z-index:1000;}.yui-resize-hover .yui-resize-handle,.yui-resize-hidden .yui-resize-handle{opacity:0;filter:alpha(opacity=0);}.yui-resize-ghost{opacity:.5;filter:alpha(opacity=50);}.yui-resize-knob .yui-resize-handle{height:6px;width:6px;}.yui-resize-knob .yui-resize-handle-tr{right:-3px;top:-3px;}.yui-resize-knob .yui-resize-handle-tl{left:-3px;top:-3px;}.yui-resize-knob .yui-resize-handle-bl{left:-3px;bottom:-3px;}.yui-resize-knob .yui-resize-handle-br{right:-3px;bottom:-3px;}.yui-resize-knob .yui-resize-handle-t{left:45%;top:-3px;}.yui-resize-knob .yui-resize-handle-r{right:-3px;top:45%;}.yui-resize-knob .yui-resize-handle-l{left:-3px;top:45%;}.yui-resize-knob .yui-resize-handle-b{left:45%;bottom:-3px;}.yui-resize-status{position:absolute;top:-999px;left:-999px;padding:2px;font-size:80%;display:none;zoom:1;z-index:9999;}.yui-resize-status strong,.yui-resize-status em{font!
 -weight:normal;font-style:normal;padding:1px;zoom:1;}.yui-skin!
 -sam .yu
i-resize .yui-resize-handle{background-color:#F2F2F2;}.yui-skin-sam .yui-resize .yui-resize-handle-active{background-color:#7D98B8;zoom:1;}.yui-skin-sam .yui-resize .yui-resize-handle-l,.yui-skin-sam .yui-resize .yui-resize-handle-r,.yui-skin-sam .yui-resize .yui-resize-handle-l-active,.yui-skin-sam .yui-resize .yui-resize-handle-r-active{height:100%;}.yui-skin-sam .yui-resize-knob .yui-resize-handle{border:1px solid #808080;}.yui-skin-sam .yui-resize-hover .yui-resize-handle-active{opacity:1;filter:alpha(opacity=100);}.yui-skin-sam .yui-resize-proxy{border:1px dashed #426FD9;}.yui-skin-sam .yui-resize-status{border:1px solid #A6982B;border-top:1px solid #D4C237;background-color:#FFEE69}.yui-skin-sam .yui-resize-status strong,.yui-skin-sam .yui-resize-status em{float:left;display:block;clear:both;padding:1px;text-align:center;}.yui-skin-sam .yui-resize .yui-resize-handle-inner-r,.yui-skin-sam .yui-resize .yui-resize-handle-inner-l{background:transparent url( layout_sprite.pn!
 g) no-repeat 0 -5px;height:16px;width:5px;position:absolute;top:45%;}.yui-skin-sam .yui-resize .yui-resize-handle-inner-t,.yui-skin-sam .yui-resize .yui-resize-handle-inner-b{background:transparent url(layout_sprite.png) no-repeat -20px 0;height:5px;width:16px;position:absolute;left:50%;}.yui-skin-sam .yui-resize .yui-resize-handle-br{background-image:url( layout_sprite.png );background-repeat:no-repeat;background-position:-22px -62px;}.yui-skin-sam .yui-resize .yui-resize-handle-tr{background-image:url( layout_sprite.png );background-repeat:no-repeat;background-position:-22px -42px;}.yui-skin-sam .yui-resize .yui-resize-handle-tl{background-image:url( layout_sprite.png );background-repeat:no-repeat;background-position:-22px -82px;}.yui-skin-sam .yui-resize .yui-resize-handle-bl{background-image:url( layout_sprite.png );background-repeat:no-repeat;background-position:-22px -23px;}.yui-skin-sam .yui-resize-knob .yui-resize-handle-t,.yui-skin-sam .yui-resize-knob .yui-resize-!
 handle-r,.yui-skin-sam .yui-resize-knob .yui-resize-handle-b,.!
 yui-skin
-sam .yui-resize-knob .yui-resize-handle-l,.yui-skin-sam .yui-resize-knob .yui-resize-handle-tl,.yui-skin-sam .yui-resize-knob .yui-resize-handle-tr,.yui-skin-sam .yui-resize-knob .yui-resize-handle-bl,.yui-skin-sam .yui-resize-knob .yui-resize-handle-br,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-t,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-r,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-b,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-l,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-tl,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-tr,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-bl,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-br{background-image:none;}.yui-skin-sam .yui-resize-knob .yui-resize-handle-l,.yui-skin-sam .yui-resize-knob .yui-resize-handle-r,.yui-skin-sam .yui-resize-knob .yui-resize-handle-l-active,.yui-skin-sam .yui-resize-knob .yui-resize-handle-r-active{height:6px;width:6px;}

Modified: trunk/root/static/yui/assets/skins/sam/simpleeditor.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/simpleeditor.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/simpleeditor.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-.yui-busy{cursor:wait !important;}.yui-toolbar-container .yui-toolbar-subcont{padding:.25em 0;zoom:1;}.yui-toolbar-container-collapsed .yui-toolbar-subcont{display:none;}.yui-toolbar-container .yui-toolbar-subcont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container span.yui-toolbar-draghandle{cursor:move;border-left:1px solid #999;border-right:1px solid #999;overflow:hidden;text-indent:77777px;width:2px;height:20px;display:block;clear:none;float:left;margin:0 0 0 .2em;}.yui-toolbar-container .yui-toolbar-titlebar.draggable{cursor:move;}.yui-toolbar-container .yui-toolbar-titlebar{position:relative;}.yui-toolbar-container .yui-toolbar-titlebar h2{font-weight:bold;letter-spacing:0;border:none;color:#000;margin:0;padding:.2em;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-draghandle{height:40px;}.yui-toolbar-container .yui-toolbar-group{float:left;zoom:1;}.yui-toolbar-container .yui-toolbar-group:after{display:block;clear!
 :both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container .yui-toolbar-group h3{font-size:75%;padding:0 0 0 .25em;margin:0;}.yui-toolbar-container span.yui-toolbar-separator{width:2px;height:18px;margin:.2em 0 .2em .1em;display:block;clear:none;float:left;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-separator{height:35px;}.yui-toolbar-container.yui-toolbar-grouped .yui-toolbar-group span.yui-toolbar-separator{height:18px;}.yui-toolbar-container ul li{margin:0;padding:0;list-style-type:none;}.yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-toolbar-container .yui-push-button,.yui-toolbar-container .yui-color-button,.yui-toolbar-container .yui-menu-button{position:relative;cursor:pointer;}.yui-toolbar-container .yui-button .first-child,.yui-toolbar-container .yui-button .first-child a{height:100%;width:100%;overflow:hidden;}.yui-toolbar-container .yui-button-disabled{cursor:default;}.yui-toolbar-container .yui-button-disabled .!
 yui-toolbar-icon{opacity:.5;filter:alpha(opacity=50);}.yui-too!
 lbar-con
tainer .yui-button-disabled .up,.yui-toolbar-container .yui-button-disabled .down{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button a{overflow:hidden;}.yui-toolbar-container .yui-toolbar-select .first-child a{cursor:pointer;}.yui-toolbar-fontname-arial{font-family:Arial;}.yui-toolbar-fontname-arial-black{font-family:Arial Black;}.yui-toolbar-fontname-comic-sans-ms{font-family:Comic Sans MS;}.yui-toolbar-fontname-courier-new{font-family:Courier New;}.yui-toolbar-fontname-times-new-roman{font-family:Times New Roman;}.yui-toolbar-fontname-verdana{font-family:Verdana;}.yui-toolbar-fontname-impact{font-family:Impact;}.yui-toolbar-fontname-lucida-console{font-family:Lucida Console;}.yui-toolbar-fontname-tahoma{font-family:Tahoma;}.yui-toolbar-fontname-trebuchet-ms{font-family:Trebuchet MS;}.yui-toolbar-container .yui-toolbar-spinbutton{position:relative;}.yui-toolbar-container .yui-toolbar-spinbutton .first-child a{z-index:0;opacity:1;}.yui-toolbar-container !
 .yui-toolbar-spinbutton a.up,.yui-toolbar-container .yui-toolbar-spinbutton a.down{position:absolute;display:block right:0;cursor:pointer;z-index:1;padding:0;margin:0;}.yui-toolbar-container .yui-overlay{position:absolute;}.yui-toolbar-container .yui-overlay ul li{margin:0;list-style-type:none;}.yui-toolbar-container{z-index:1;}.yui-editor-container .yui-editor-editable-container{position:relative;z-index:0;width:100%;}.yui-editor-container .yui-editor-masked{background-color:#CCC;}.yui-editor-container iframe{border:0px;padding:0;margin:0;zoom:1;display:block;}.yui-editor-container .yui-editor-editable{padding:0;margin:0;}.yui-editor-container .dompath{font-size:85%;}.yui-editor-panel .hd{text-align:left;position:relative;}.yui-editor-panel .hd h3{font-weight:bold;padding:0.25em 0pt 0.25em 0.25em;margin:0;}.yui-editor-panel .bd{width:100%;zoom:1;position:relative;}.yui-editor-panel .bd div.yui-editor-body-cont{padding:.25em .1em;zoom:1;}.yui-editor-panel .bd div.yui-editor!
 -body-cont:after{display:block;clear:both;visibility:hidden;co!
 ntent:'.
';height:0;}.yui-editor-panel .ft{text-align:right;width:99%;float:left;clear:both;}.yui-editor-panel .ft span.tip{display:block;position:relative;padding:.5em .5em .5em 23px;text-align:left;zoom:1;}.yui-editor-panel label{clear:both;float:left;padding:0;width:100%;text-align:left;zoom:1;}.yui-editor-panel .gecko label{overflow:auto;}.yui-editor-panel label strong{float:left;width:6em;}.yui-editor-panel .removeLink{width:80%;text-align:right;}.yui-editor-panel label input{margin-left:.25em;float:left;}.yui-editor-panel .yui-toolbar-group-padding{}.yui-editor-panel .yui-toolbar-group-border{}.yui-editor-panel .yui-toolbar-group-textflow{}.yui-editor-panel .height-width{float:left;}.yui-editor-panel .height-width h3{}.yui-editor-panel .height-width span{font-style:italic;display:block;float:left;overflow:auto;}.yui-editor-panel .height-width span.info{font-size:70%;}.yui-editor-panel .yui-toolbar-bordersize,.yui-editor-panel .yui-toolbar-bordertype{font-size:75%;}.yui-editor-p!
 anel .yui-toolbar-container span.yui-toolbar-separator{border:none;}.yui-editor-panel .yui-toolbar-bordersize span a span,.yui-editor-panel .yui-toolbar-bordertype span a span{display:block;height:8px;left:4px;position:absolute;top:3px;*top:-5px;width:24px;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-solid{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dotted{border-bottom:1px dotted black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dashed{border-bottom:1px dashed black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-0{*top:0px;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-1{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-2{border-bottom:2px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersiz!
 e-3{top:2px;*top:-5px;border-bottom:3px solid black;}.yui-edit!
 or-panel
 .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-4{top:1px;*top:-5px;border-bottom:4px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-5{top:1px;*top:-5px;border-bottom:5px solid black;}.yui-toolbar-container .yui-toolbar-bordersize-menu,.yui-toolbar-container .yui-toolbar-bordertype-menu{width:95px !important;}.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel,.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel:hover{margin:0px 3px 7px 17px;}.yui-toolbar-bordersize-menu .yuimenuitemlabel .checkedindicator,.yui-toolbar-bordertype-menu .yuimenuitemlabel .checkedindicator{position:absolute;left:-12px;*top:14px;*left:0px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-1 a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-2 a{border-bottom:2px solid black;height:14px;}.yui-toolbar-borders!
 ize-menu li.yui-toolbar-bordersize-3 a{border-bottom:3px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-4 a{border-bottom:4px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-5 a{border-bottom:5px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-solid a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dashed a{border-bottom:1px dashed black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dotted a{border-bottom:1px dotted black;height:14px;}h2.yui-editor-skipheader,h3.yui-editor-skipheader{height:0;margin:0;padding:0;border:none;width:0;overflow:hidden;position:absolute;}.yui-toolbar-colors{width:133px;zoom:1;display:none;z-index:100;overflow:hidden;}.yui-toolbar-colors:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors a{height:9px;width:9px;float:left;display:block;overflo!
 w:hidden;text-indent:999px;margin:0;cursor:pointer;border:1px !
 solid #F
6F7EE;}.yui-toolbar-colors a:hover{border:1px solid black;}.yui-color-button-menu{overflow:visible;background-color:transparent;}.yui-toolbar-colors span{position:relative;display:block;padding:3px;overflow:hidden;float:left;width:100%;zoom:1;}.yui-toolbar-colors span:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors span em{height:35px;width:30px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0.75px;border:1px solid black;}.yui-toolbar-colors span strong{font-weight:normal;padding-left:3px;display:block;font-size:85%;float:left;width:65%;}.yui-skin-sam .yui-editor-container{border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container{zoom:1;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar{background:url(sprite.png) repeat-x 0 -200px;position:relative;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar h2{color:#000000;font-weight:bold;margin:0;padding:0.3em 1em;font-size:100%;text-align:left;}.!
 yui-skin-sam .yui-toolbar-container .yui-toolbar-group h3{color:#808080;font-size:75%;margin:1em 0 0;padding-bottom:0;padding-left:0.25em;text-align:left;}.yui-toolbar-container span.yui-toolbar-separator{border:none;text-indent:33px;overflow:hidden;margin:.25em;}.yui-skin-sam .yui-toolbar-container{background-color:#F2F2F2;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subcont{padding:0 1em 0.35em;border-bottom:1px solid #808080;}.yui-skin-sam .yui-toolbar-container-collapsed .yui-toolbar-titlebar{border-bottom:1px solid #808080;}.yui-skin-sam .yui-editor-container .visible .yui-menu-shadow,.yui-skin-sam .yui-editor-panel .visible .yui-menu-shadow{display:none;}.yui-skin-sam .yui-editor-container ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-container ul li{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-toolbar-group ul li.yui-toolbar-groupitem{float:left;}.yui-skin-sam .yui-editor-container .dompath{background-color:#F2F2F2;border-!
 top:1px solid #808080;color:#999;text-align:left;padding:0.25e!
 m;}.yui-
skin-sam .yui-toolbar-container .collapse{background:url(sprite.png) no-repeat 0 -400px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar span.collapse{cursor:pointer;position:absolute;top:4px;right:2px;display:block;overflow:hidden;height:15px;width:15px;text-indent:9999px;}.yui-skin-sam .yui-toolbar-container .yui-push-button,.yui-skin-sam .yui-toolbar-container .yui-color-button,.yui-skin-sam .yui-toolbar-container .yui-menu-button{background:url(sprite.png) repeat-x 0 0;position:relative;display:block;height:22px;width:30px;margin:0;border-color:#808080;border-style:solid;border-width:1px 0;}.yui-skin-sam .yui-toolbar-container .yui-push-button a,.yui-skin-sam .yui-toolbar-container .yui-color-button a,.yui-skin-sam .yui-toolbar-container .yui-menu-button a{padding-left:35px;height:20px;text-decoration:none;font-size:93%;line-height:2;display:block;color:#000000;overflow:hidden;}.yui-skin-sam .yui-toolbar-container .yui-push-button .first-child,.yui-skin-sam .y!
 ui-toolbar-container .yui-color-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button .first-child{border-color:#808080;border-style:solid;border-width:0 1px;margin:0 -1px;display:block;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-button .first-child{*left:0px;}.yui-skin-sam .yui-toolba!
 r-container .yui-toolbar-fontname{width:135px;}.yui-skin-sam .!
 yui-tool
bar-container .yui-toolbar-heading{width:92px;}.yui-skin-sam .yui-toolbar-container .yui-button-hover{background:url(sprite.png) repeat-x 0 -1300px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-button-selected{background:url(sprite.png) repeat-x 0 -1700px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels .yui-toolbar-group{margin-top:.75em;}.yui-skin-sam .yui-toolbar-container .yui-push-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-color-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-menu-button span.yui-toolbar-icon{display:block;position:absolute;top:2px;height:18px;width:18px;overflow:hidden;background:url(editor-sprite.gif) no-repeat 30px 30px;}.yui-skin-sam .yui-toolbar-container .yui-button-selected span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-button-hover span.yui-tool!
 bar-icon{background-image:url(editor-sprite-active.gif);}.yui-skin-sam .yui-toolbar-container .visible .yuimenuitemlabel{cursor:pointer;color:#000;*position:relative;}.yui-skin-sam .yui-toolbar-container .yui-button-menu{background-color:#fff;}.yui-skin-sam div.yuimenu li.selected{background-color:#B3D4FF;}.yui-skin-sam div.yuimenu li.selected a.selected{color:#000;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bold span.yui-toolbar-icon{background-position:0 0;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-italic span.yui-toolbar-icon{background-position:0 -36px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-underline span.yui-toolbar-icon{background-position:0 -72px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subscript span.yui-toolbar-icon{background-position:0 -180px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-superscript span.yui-toolbar-icon{background-position:0 -144px;left:5px;}.yui-skin-sam .yui-toolbar-!
 container .yui-toolbar-forecolor span.yui-toolbar-icon{backgro!
 und-posi
tion:0 -216px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-backcolor span.yui-toolbar-icon{background-position:0 -288px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyleft span.yui-toolbar-icon{background-position:0 -324px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifycenter span.yui-toolbar-icon{background-position:0 -360px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyright span.yui-toolbar-icon{background-position:0 -396px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyfull span.yui-toolbar-icon{background-position:0 -432px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-indent span.yui-toolbar-icon{background-position:0 -720px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-outdent span.yui-toolbar-icon{background-position:0 -684px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-createlink span.yui-toolbar-icon{background-position:0 -792px;!
 left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertimage span.yui-toolbar-icon{background-position:1px -756px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-left span.yui-toolbar-icon{background-position:0 -972px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-right span.yui-toolbar-icon{background-position:0 -936px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-inline span.yui-toolbar-icon{background-position:0 -900px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-block span.yui-toolbar-icon{background-position:0 -864px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bordercolor span.yui-toolbar-icon{background-position:0 -252px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-removeformat span.yui-toolbar-icon{background-position:0 -1080px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-hiddenelements span.yui-toolbar-icon{background-position:0 -1044px;left:5px;}.yui-skin-!
 sam .yui-toolbar-container .yui-toolbar-insertunorderedlist sp!
 an.yui-t
oolbar-icon{background-position:0 -468px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertorderedlist span.yui-toolbar-icon{background-position:0 -504px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child{width:35px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child a{padding-left:2px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton span.yui-toolbar-icon{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{right:2px;background:url(editor-sprite.gif) no-repeat 0 -1222px;overflow:hidden;height:6px;width:7px;min-height:0;padding:0;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up{top:2px;background-position:0 -1222px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{bottom:2px;background-p!
 osition:0 -1187px;}.yui-skin-sam .yui-toolbar-container select{height:22px;border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select .first-child a{padding-left:5px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select span.yui-toolbar-icon{background:url( editor-sprite.gif ) no-repeat 0 -1144px;overflow:hidden;right:-2px;top:0px;height:20px;}.yui-skin-sam .yui-editor-panel .yui-color-button-menu .bd{background-color:transparent;border:none;width:135px;}.yui-skin-sam .yui-color-button-menu .yui-toolbar-colors{border:1px solid #808080;}.yui-skin-sam .yui-editor-panel{padding:0;margin:0;border:none;background-color:transparent;overflow:visible;}.yui-skin-sam .yui-editor-panel .hd{margin:10px 0 0;padding:0;border:none;}.yui-skin-sam .yui-editor-panel .hd h3{color:#000;border:1px solid #808080;background:url(sprite.png) repeat-x 0 -200px;width:99%;position:relative;margin:0;padding:3px 0 0 0;font-size:93%;text-indent:5px;height:20px;!
 }.yui-skin-sam .yui-editor-panel .bd{background-color:#F2F2F2;!
 border-l
eft:1px solid #808080;border-right:1px solid #808080;width:99%;margin:0;padding:0;overflow:visible;}.yui-skin-sam .yui-editor-panel ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-panel ul li{margin:0;padding:0;}.yui-skin-sam .yui-editor-panel .yuimenu{}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .yui-toolbar-subcont{padding:0;border:none;margin-top:0.35em;}.yui-skin-sam .yui-editor-panel .yui-toolbar-bordersize,.yui-skin-sam .yui-editor-panel .yui-toolbar-bordertype{width:50px;}.yui-skin-sam .yui-editor-panel label{display:block;float:none;padding:4px 0;margin-bottom:7px;}.yui-skin-sam .yui-editor-panel label strong{font-weight:normal;font-size:93%;text-align:right;padding-top:2px;}.yui-skin-sam .yui-editor-panel label input{width:75%;}.yui-skin-sam .yui-editor-panel #createlink_target,.yui-skin-sam .yui-editor-panel #insertimage_target{width:auto;margin-right:5px;}.yui-skin-sam .yui-editor-panel .removeLink{width:98%;}.yui-skin-sam .yui-edi!
 tor-panel label input.warning{background-color:#FFEE69;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group h3{color:#000;float:left;font-weight:normal;font-size:93%;margin:5px 0 0 0;padding:0 3px 0 0;text-align:right;}.yui-skin-sam .yui-editor-panel .height-width h3{margin:3px 0 0 10px;}.yui-skin-sam .yui-editor-panel .height-width{margin:3px 0 0 35px;*margin-left:14px;width:42%;*width:44%;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-border{width:190px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-border{width:210px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding{width:203px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-padding{width:172px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding h3{margin-left:25px;*margin-left:12px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-textflow{width:182px;}.yui-skin-sam .yui-editor-panel .hd{background:none;}.yui-skin-sam .yui-editor-panel .ft{background-color:#F2F2F2;b!
 order:1px solid #808080;border-top:none;padding:0;margin:0 0 2!
 px 0;}.y
ui-skin-sam .yui-editor-panel .hd span.close{background:url(sprite.png) no-repeat 0 -300px;cursor:pointer;display:block;height:16px;overflow:hidden;position:absolute;right:5px;text-indent:500px;top:2px;width:26px;}.yui-skin-sam .yui-editor-panel .ft span.tip{background-color:#EDF5FF;border-top:1px solid #808080;font-size:85%;}.yui-skin-sam .yui-editor-panel .ft span.tip strong{display:block;float:left;margin:0 2px 8px 0;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon{background:url( editor-sprite.gif ) no-repeat 0 -1260px;display:block;height:20px;left:2px;position:absolute;top:8px;width:20px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-info{background-position:2px -1260px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-warn{background-position:2px -1296px;}.yui-skin-sam .yui-editor-panel .hd span.knob{position:absolute;height:10px;width:28px;top:-10px;left:25px;text-indent:9999px;overflow:hidden;background:url( editor-knob.gif ) no-repeat 0 0;}.yu!
 i-skin-sam .yui-editor-panel .yui-toolbar-container{float:left;width:100%;background-image:none;border:none;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .bd{background-color:#ffffff;}.yui-editor-blankimage{background-image:url( blankimage.png );}
+.yui-busy{cursor:wait !important;}.yui-toolbar-container fieldset{padding:0;margin:0;border:0;}.yui-toolbar-container legend{display:none;}.yui-toolbar-container .yui-toolbar-subcont{padding:.25em 0;zoom:1;}.yui-toolbar-container-collapsed .yui-toolbar-subcont{display:none;}.yui-toolbar-container .yui-toolbar-subcont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container span.yui-toolbar-draghandle{cursor:move;border-left:1px solid #999;border-right:1px solid #999;overflow:hidden;text-indent:77777px;width:2px;height:20px;display:block;clear:none;float:left;margin:0 0 0 .2em;}.yui-toolbar-container .yui-toolbar-titlebar.draggable{cursor:move;}.yui-toolbar-container .yui-toolbar-titlebar{position:relative;}.yui-toolbar-container .yui-toolbar-titlebar h2{font-weight:bold;letter-spacing:0;border:none;color:#000;margin:0;padding:.2em;}.yui-toolbar-container .yui-toolbar-titlebar h2 a{text-decoration:none;color:#000;cursor:default;}.yui-tool!
 bar-container.yui-toolbar-grouped span.yui-toolbar-draghandle{height:40px;}.yui-toolbar-container .yui-toolbar-group{float:left;zoom:1;}.yui-toolbar-container .yui-toolbar-group:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container .yui-toolbar-group h3{font-size:75%;padding:0 0 0 .25em;margin:0;}.yui-toolbar-container span.yui-toolbar-separator{width:2px;height:18px;margin:.2em 0 .2em .1em;display:block;clear:none;float:left;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-separator{height:35px;}.yui-toolbar-container.yui-toolbar-grouped .yui-toolbar-group span.yui-toolbar-separator{height:18px;}.yui-toolbar-container ul li{margin:0;padding:0;list-style-type:none;}.yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-toolbar-container .yui-push-button,.yui-toolbar-container .yui-color-button,.yui-toolbar-container .yui-menu-button{position:relative;cursor:pointer;}.yui-toolbar-container .yui-button .firs!
 t-child,.yui-toolbar-container .yui-button .first-child a{heig!
 ht:100%;
width:100%;overflow:hidden;}.yui-toolbar-container .yui-button-disabled{cursor:default;}.yui-toolbar-container .yui-button-disabled .yui-toolbar-icon{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button-disabled .up,.yui-toolbar-container .yui-button-disabled .down{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button a{overflow:hidden;}.yui-toolbar-container .yui-toolbar-select .first-child a{cursor:pointer;}.yui-toolbar-fontname-arial{font-family:Arial;}.yui-toolbar-fontname-arial-black{font-family:Arial Black;}.yui-toolbar-fontname-comic-sans-ms{font-family:Comic Sans MS;}.yui-toolbar-fontname-courier-new{font-family:Courier New;}.yui-toolbar-fontname-times-new-roman{font-family:Times New Roman;}.yui-toolbar-fontname-verdana{font-family:Verdana;}.yui-toolbar-fontname-impact{font-family:Impact;}.yui-toolbar-fontname-lucida-console{font-family:Lucida Console;}.yui-toolbar-fontname-tahoma{font-family:Tahoma;}.yui-toolbar-fontname-trebuche!
 t-ms{font-family:Trebuchet MS;}.yui-toolbar-container .yui-toolbar-spinbutton{position:relative;}.yui-toolbar-container .yui-toolbar-spinbutton .first-child a{z-index:0;opacity:1;}.yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-toolbar-container .yui-toolbar-spinbutton a.down{position:absolute;display:block right:0;cursor:pointer;z-index:1;padding:0;margin:0;}.yui-toolbar-container .yui-overlay{position:absolute;}.yui-toolbar-container .yui-overlay ul li{margin:0;list-style-type:none;}.yui-toolbar-container{z-index:1;}.yui-editor-container .yui-editor-editable-container{position:relative;z-index:0;width:100%;}.yui-editor-container .yui-editor-masked{background-color:#CCC;}.yui-editor-container iframe{border:0px;padding:0;margin:0;zoom:1;display:block;}.yui-editor-container .yui-editor-editable{padding:0;margin:0;}.yui-editor-container .dompath{font-size:85%;}.yui-editor-panel .hd{text-align:left;position:relative;}.yui-editor-panel .hd h3{font-weight:bold;padding:0!
 .25em 0pt 0.25em 0.25em;margin:0;}.yui-editor-panel .bd{width:!
 100%;zoo
m:1;position:relative;}.yui-editor-panel .bd div.yui-editor-body-cont{padding:.25em .1em;zoom:1;}.yui-editor-panel .bd div.yui-editor-body-cont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-editor-panel .ft{text-align:right;width:99%;float:left;clear:both;}.yui-editor-panel .ft span.tip{display:block;position:relative;padding:.5em .5em .5em 23px;text-align:left;zoom:1;}.yui-editor-panel label{clear:both;float:left;padding:0;width:100%;text-align:left;zoom:1;}.yui-editor-panel .gecko label{overflow:auto;}.yui-editor-panel label strong{float:left;width:6em;}.yui-editor-panel .removeLink{width:80%;text-align:right;}.yui-editor-panel label input{margin-left:.25em;float:left;}.yui-editor-panel .yui-toolbar-group-padding{}.yui-editor-panel .yui-toolbar-group-border{}.yui-editor-panel .yui-toolbar-group-textflow{}.yui-editor-panel .height-width{float:left;}.yui-editor-panel .height-width h3{}.yui-editor-panel .height-width span{font-style:italic;displa!
 y:block;float:left;overflow:auto;}.yui-editor-panel .height-width span.info{font-size:70%;}.yui-editor-panel .yui-toolbar-bordersize,.yui-editor-panel .yui-toolbar-bordertype{font-size:75%;}.yui-editor-panel .yui-toolbar-container span.yui-toolbar-separator{border:none;}.yui-editor-panel .yui-toolbar-bordersize span a span,.yui-editor-panel .yui-toolbar-bordertype span a span{display:block;height:8px;left:4px;position:absolute;top:3px;*top:-5px;width:24px;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-solid{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dotted{border-bottom:1px dotted black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dashed{border-bottom:1px dashed black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-0{*top:0px;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-1{border-bottom!
 :1px solid black;}.yui-editor-panel .yui-toolbar-bordersize sp!
 an a spa
n.yui-toolbar-bordersize-2{border-bottom:2px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-3{top:2px;*top:-5px;border-bottom:3px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-4{top:1px;*top:-5px;border-bottom:4px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-5{top:1px;*top:-5px;border-bottom:5px solid black;}.yui-toolbar-container .yui-toolbar-bordersize-menu,.yui-toolbar-container .yui-toolbar-bordertype-menu{width:95px !important;}.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel,.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel:hover{margin:0px 3px 7px 17px;}.yui-toolbar-bordersize-menu .yuimenuitemlabel .checkedindicator,.yui-toolbar-bordertype-menu .yuimenuitemlabel .checkedindicator{position:absolute;left:-12px;*top:14px;*left:0px;}.yui-toolbar-bordersi!
 ze-menu li.yui-toolbar-bordersize-1 a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-2 a{border-bottom:2px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-3 a{border-bottom:3px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-4 a{border-bottom:4px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-5 a{border-bottom:5px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-solid a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dashed a{border-bottom:1px dashed black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dotted a{border-bottom:1px dotted black;height:14px;}h2.yui-editor-skipheader,h3.yui-editor-skipheader{height:0;margin:0;padding:0;border:none;width:0;overflow:hidden;position:absolute;}.yui-toolbar-colors{width:133px;zoom:1;displ!
 ay:none;z-index:100;overflow:hidden;}.yui-toolbar-colors:after!
 {display
:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors a{height:9px;width:9px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0;cursor:pointer;border:1px solid #F6F7EE;}.yui-toolbar-colors a:hover{border:1px solid black;}.yui-color-button-menu{overflow:visible;background-color:transparent;}.yui-toolbar-colors span{position:relative;display:block;padding:3px;overflow:hidden;float:left;width:100%;zoom:1;}.yui-toolbar-colors span:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors span em{height:35px;width:30px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0.75px;border:1px solid black;}.yui-toolbar-colors span strong{font-weight:normal;padding-left:3px;display:block;font-size:85%;float:left;width:65%;}.yui-skin-sam .yui-editor-container{border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container{zoom:1;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar{background:url!
 (sprite.png) repeat-x 0 -200px;position:relative;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar h2{color:#000000;font-weight:bold;margin:0;padding:0.3em 1em;font-size:100%;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-group h3{color:#808080;font-size:75%;margin:1em 0 0;padding-bottom:0;padding-left:0.25em;text-align:left;}.yui-toolbar-container span.yui-toolbar-separator{border:none;text-indent:33px;overflow:hidden;margin:.25em;}.yui-skin-sam .yui-toolbar-container{background-color:#F2F2F2;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subcont{padding:0 1em 0.35em;border-bottom:1px solid #808080;}.yui-skin-sam .yui-toolbar-container-collapsed .yui-toolbar-titlebar{border-bottom:1px solid #808080;}.yui-skin-sam .yui-editor-container .visible .yui-menu-shadow,.yui-skin-sam .yui-editor-panel .visible .yui-menu-shadow{display:none;}.yui-skin-sam .yui-editor-container ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-cont!
 ainer ul li{list-style-type:none;margin:0;padding:0;}.yui-skin!
 -sam .yu
i-toolbar-group ul li.yui-toolbar-groupitem{float:left;}.yui-skin-sam .yui-editor-container .dompath{background-color:#F2F2F2;border-top:1px solid #808080;color:#999;text-align:left;padding:0.25em;}.yui-skin-sam .yui-toolbar-container .collapse{background:url(sprite.png) no-repeat 0 -400px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar span.collapse{cursor:pointer;position:absolute;top:4px;right:2px;display:block;overflow:hidden;height:15px;width:15px;text-indent:9999px;}.yui-skin-sam .yui-toolbar-container .yui-push-button,.yui-skin-sam .yui-toolbar-container .yui-color-button,.yui-skin-sam .yui-toolbar-container .yui-menu-button{background:url(sprite.png) repeat-x 0 0;position:relative;display:block;height:22px;width:30px;margin:0;border-color:#808080;border-style:solid;border-width:1px 0;}.yui-skin-sam .yui-toolbar-container .yui-push-button a,.yui-skin-sam .yui-toolbar-container .yui-color-button a,.yui-skin-sam .yui-toolbar-container .yui-menu-button a{padd!
 ing-left:35px;height:20px;text-decoration:none;font-size:93%;line-height:2;display:block;color:#000000;overflow:hidden;}.yui-skin-sam .yui-toolbar-container .yui-push-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button .first-child{border-color:#808080;border-style:solid;border-width:0 1px;margin:0 -1px;display:block;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled,.yui-skin-sam .yui-toolbar-container .yui!
 -color-button-disabled,.yui-skin-sam .yui-toolbar-container .y!
 ui-menu-
button-disabled{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-button .first-child{*left:0px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-fontname{width:135px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-heading{width:92px;}.yui-skin-sam .yui-toolbar-container .yui-button-hover{background:url(sprite.png) repeat-x 0 -1300px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-button-selected{background:url(sprite.png) repeat-x 0 -1700px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels .yui-toolbar-group{margin-top:.75em;}.yui-skin-sam .yui-toolbar-container .yui-push-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-color-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-menu-button span.yui-toolbar-icon{display:block;position:absolute;top:2px;height:18px;width:18px;overflow:hidden;!
 background:url(editor-sprite.gif) no-repeat 30px 30px;}.yui-skin-sam .yui-toolbar-container .yui-button-selected span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-button-hover span.yui-toolbar-icon{background-image:url(editor-sprite-active.gif);}.yui-skin-sam .yui-toolbar-container .visible .yuimenuitemlabel{cursor:pointer;color:#000;*position:relative;}.yui-skin-sam .yui-toolbar-container .yui-button-menu{background-color:#fff;}.yui-skin-sam div.yuimenu li.selected{background-color:#B3D4FF;}.yui-skin-sam div.yuimenu li.selected a.selected{color:#000;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bold span.yui-toolbar-icon{background-position:0 0;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-italic span.yui-toolbar-icon{background-position:0 -36px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-underline span.yui-toolbar-icon{background-position:0 -72px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subscript span.yui!
 -toolbar-icon{background-position:0 -180px;left:5px;}.yui-skin!
 -sam .yu
i-toolbar-container .yui-toolbar-superscript span.yui-toolbar-icon{background-position:0 -144px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-forecolor span.yui-toolbar-icon{background-position:0 -216px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-backcolor span.yui-toolbar-icon{background-position:0 -288px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyleft span.yui-toolbar-icon{background-position:0 -324px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifycenter span.yui-toolbar-icon{background-position:0 -360px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyright span.yui-toolbar-icon{background-position:0 -396px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyfull span.yui-toolbar-icon{background-position:0 -432px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-indent span.yui-toolbar-icon{background-position:0 -720px;left:5px;}.yui-skin-sam .yui-toolbar-c!
 ontainer .yui-toolbar-outdent span.yui-toolbar-icon{background-position:0 -684px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-createlink span.yui-toolbar-icon{background-position:0 -792px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertimage span.yui-toolbar-icon{background-position:1px -756px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-left span.yui-toolbar-icon{background-position:0 -972px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-right span.yui-toolbar-icon{background-position:0 -936px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-inline span.yui-toolbar-icon{background-position:0 -900px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-block span.yui-toolbar-icon{background-position:0 -864px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bordercolor span.yui-toolbar-icon{background-position:0 -252px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-removefor!
 mat span.yui-toolbar-icon{background-position:0 -1080px;left:5!
 px;}.yui
-skin-sam .yui-toolbar-container .yui-toolbar-hiddenelements span.yui-toolbar-icon{background-position:0 -1044px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertunorderedlist span.yui-toolbar-icon{background-position:0 -468px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertorderedlist span.yui-toolbar-icon{background-position:0 -504px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child{width:35px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child a{padding-left:2px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton span.yui-toolbar-icon{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{right:2px;background:url(editor-sprite.gif) no-repeat 0 -1222px;overflow:hidden;height:6px;width:7px;min-height:0;padd!
 ing:0;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up{top:2px;background-position:0 -1222px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{bottom:2px;background-position:0 -1187px;}.yui-skin-sam .yui-toolbar-container select{height:22px;border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select .first-child a{padding-left:5px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select span.yui-toolbar-icon{background:url( editor-sprite.gif ) no-repeat 0 -1144px;overflow:hidden;right:-2px;top:0px;height:20px;}.yui-skin-sam .yui-editor-panel .yui-color-button-menu .bd{background-color:transparent;border:none;width:135px;}.yui-skin-sam .yui-color-button-menu .yui-toolbar-colors{border:1px solid #808080;}.yui-skin-sam .yui-editor-panel{padding:0;margin:0;border:none;background-color:transparent;overflow:visible;}.yui-skin-sam .yui-editor-panel .hd{margin:10px 0 0;padding:0;border:none;}.yui-skin-sam !
 .yui-editor-panel .hd h3{color:#000;border:1px solid #808080;b!
 ackgroun
d:url(sprite.png) repeat-x 0 -200px;width:99%;position:relative;margin:0;padding:3px 0 0 0;font-size:93%;text-indent:5px;height:20px;}.yui-skin-sam .yui-editor-panel .bd{background-color:#F2F2F2;border-left:1px solid #808080;border-right:1px solid #808080;width:99%;margin:0;padding:0;overflow:visible;}.yui-skin-sam .yui-editor-panel ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-panel ul li{margin:0;padding:0;}.yui-skin-sam .yui-editor-panel .yuimenu{}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .yui-toolbar-subcont{padding:0;border:none;margin-top:0.35em;}.yui-skin-sam .yui-editor-panel .yui-toolbar-bordersize,.yui-skin-sam .yui-editor-panel .yui-toolbar-bordertype{width:50px;}.yui-skin-sam .yui-editor-panel label{display:block;float:none;padding:4px 0;margin-bottom:7px;}.yui-skin-sam .yui-editor-panel label strong{font-weight:normal;font-size:93%;text-align:right;padding-top:2px;}.yui-skin-sam .yui-editor-panel label input{width:75%;}.yui-s!
 kin-sam .yui-editor-panel #createlink_target,.yui-skin-sam .yui-editor-panel #insertimage_target{width:auto;margin-right:5px;}.yui-skin-sam .yui-editor-panel .removeLink{width:98%;}.yui-skin-sam .yui-editor-panel label input.warning{background-color:#FFEE69;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group h3{color:#000;float:left;font-weight:normal;font-size:93%;margin:5px 0 0 0;padding:0 3px 0 0;text-align:right;}.yui-skin-sam .yui-editor-panel .height-width h3{margin:3px 0 0 10px;}.yui-skin-sam .yui-editor-panel .height-width{margin:3px 0 0 35px;*margin-left:14px;width:42%;*width:44%;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-border{width:190px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-border{width:210px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding{width:203px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-padding{width:172px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding h3{margin-left:25px;*mar!
 gin-left:12px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-gr!
 oup-text
flow{width:182px;}.yui-skin-sam .yui-editor-panel .hd{background:none;}.yui-skin-sam .yui-editor-panel .ft{background-color:#F2F2F2;border:1px solid #808080;border-top:none;padding:0;margin:0 0 2px 0;}.yui-skin-sam .yui-editor-panel .hd span.close{background:url(sprite.png) no-repeat 0 -300px;cursor:pointer;display:block;height:16px;overflow:hidden;position:absolute;right:5px;text-indent:500px;top:2px;width:26px;}.yui-skin-sam .yui-editor-panel .ft span.tip{background-color:#EDF5FF;border-top:1px solid #808080;font-size:85%;}.yui-skin-sam .yui-editor-panel .ft span.tip strong{display:block;float:left;margin:0 2px 8px 0;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon{background:url( editor-sprite.gif ) no-repeat 0 -1260px;display:block;height:20px;left:2px;position:absolute;top:8px;width:20px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-info{background-position:2px -1260px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-warn{background-position:2px !
 -1296px;}.yui-skin-sam .yui-editor-panel .hd span.knob{position:absolute;height:10px;width:28px;top:-10px;left:25px;text-indent:9999px;overflow:hidden;background:url( editor-knob.gif ) no-repeat 0 0;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container{float:left;width:100%;background-image:none;border:none;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .bd{background-color:#ffffff;}.yui-editor-blankimage{background-image:url( blankimage.png );}

Modified: trunk/root/static/yui/assets/skins/sam/skin.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,19 +1,23 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-skin-sam .yui-ac{position:relative;font-family:arial;font-size:100%;}.yui-skin-sam .yui-ac-input{position:absolute;width:100%;}.yui-skin-sam .yui-ac-container{position:absolute;top:1.6em;width:100%;}.yui-skin-sam .yui-ac-content{position:absolute;width:100%;border:1px solid #808080;background:#fff;overflow:hidden;z-index:9050;}.yui-skin-sam .yui-ac-shadow{position:absolute;margin:.3em;width:100%;background:#000;-moz-opacity:0.10;opacity:.10;filter:alpha(opacity=10);z-index:9049;}.yui-skin-sam .yui-ac-content ul{margin:0;padding:0;width:100%;}.yui-skin-sam .yui-ac-content li{margin:0;padding:2px 5px;cursor:default;white-space:nowrap;}.yui-skin-sam .yui-ac-content li.yui-ac-prehighlight{background:#B3D4FF;}.yui-skin-sam .yui-ac-content li.yui-ac-highlight{background:#426FD9;color:#FFF;}
 .yui-button{display:-moz-inline-box;display:inline-block;vertical-align:text-bottom;}.yui-button .first-child{display:block;*display:inline-block;}.yui-button button,.yui-button a{display:block;*display:inline-block;border:none;margin:0;}.yui-button button{background-color:transparent;*overflow:visible;cursor:pointer;}.yui-button a{text-decoration:none;}.yui-skin-sam .yui-button{border-width:1px 0;border-style:solid;border-color:#808080;background:url(sprite.png) repeat-x 0 0;margin:auto .25em;}.yui-skin-sam .yui-button .first-child{border-width:0 1px;border-style:solid;border-color:#808080;margin:0 -1px;*position:relative;*left:-1px;}.yui-skin-sam .yui-button button,.yui-skin-sam .yui-button a{padding:0 10px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-button a{*line-height:2;}.yui-skin-sam .yui-split-button button,.yui-skin-sam .yui-menu-button button{padding-right:20px;background-position:right center;backgro!
 und-repeat:no-repeat;}.yui-skin-sam .yui-menu-button button{background-image:url(menu-button-arrow.png);}.yui-skin-sam .yui-split-button button{background-image:url(split-button-arrow.png);}.yui-skin-sam .yui-button-focus{border-color:#7D98B8;background-position:0 -1300px;}.yui-skin-sam .yui-button-focus .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-button-focus button,.yui-skin-sam .yui-button-focus a{color:#000;}.yui-skin-sam .yui-split-button-focus button{background-image:url(split-button-arrow-focus.png);}.yui-skin-sam .yui-button-hover{border-color:#7D98B8;background-position:0 -1300px;}.yui-skin-sam .yui-button-hover .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-button-hover button,.yui-skin-sam .yui-button-hover a{color:#000;}.yui-skin-sam .yui-split-button-hover button{background-image:url(split-button-arrow-hover.png);}.yui-skin-sam .yui-button-active{border-color:#7D98B8;background-position:0 -1700px;}.yui-skin-sam .yui-button-active .first-child{b!
 order-color:#7D98B8;}.yui-skin-sam .yui-button-active button,.!
 yui-skin
-sam .yui-button-active a{color:#000;}.yui-skin-sam .yui-split-button-activeoption{border-color:#808080;background-position:0 0;}.yui-skin-sam .yui-split-button-activeoption .first-child{border-color:#808080;}.yui-skin-sam .yui-split-button-activeoption button{background-image:url(split-button-arrow-active.png);}.yui-skin-sam .yui-radio-button-checked,.yui-skin-sam .yui-checkbox-button-checked{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-radio-button-checked .first-child,.yui-skin-sam .yui-checkbox-button-checked .first-child{border-color:#304369;}.yui-skin-sam .yui-radio-button-checked button,.yui-skin-sam .yui-checkbox-button-checked button{color:#fff;}.yui-skin-sam .yui-button-disabled{border-color:#ccc;background-position:0 -1500px;}.yui-skin-sam .yui-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-button-disabled button,.yui-skin-sam .yui-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-menu-button-disabled !
 button{background-image:url(menu-button-arrow-disabled.png);}.yui-skin-sam .yui-split-button-disabled button{background-image:url(split-button-arrow-disabled.png);}
-.yui-calcontainer{position:relative;float:left;_overflow:hidden;}.yui-calcontainer iframe{position:absolute;border:none;margin:0;padding:0;z-index:0;width:100%;height:100%;left:0px;top:0px;}.yui-calcontainer iframe.fixedsize{width:50em;height:50em;top:-1px;left:-1px;}.yui-calcontainer.multi .groupcal{z-index:1;float:left;position:relative;}.yui-calcontainer .title{position:relative;z-index:1;}.yui-calcontainer .close-icon{position:absolute;z-index:1;}.yui-calendar{position:relative;}.yui-calendar .calnavleft{position:absolute;z-index:1;}.yui-calendar .calnavright{position:absolute;z-index:1;}.yui-calendar .calheader{position:relative;width:100%;text-align:center;}.yui-calcontainer .yui-cal-nav-mask{position:absolute;z-index:2;margin:0;padding:0;width:100%;height:100%;_width:0;_height:0;left:0;top:0;display:none;}.yui-calcontainer .yui-cal-nav{position:absolute;z-index:3;top:0;display:none;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{display:-moz-inline-box;display:inlin!
 e-block;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{display:block;*display:inline-block;*overflow:visible;border:none;background-color:transparent;cursor:pointer;}.yui-calendar .calbody a:hover{background:inherit;}p#clear{clear:left;padding-top:10px;}.yui-skin-sam .yui-calcontainer{background-color:#f2f2f2;border:1px solid #808080;padding:10px;}.yui-skin-sam .yui-calcontainer.multi{padding:0 5px 0 5px;}.yui-skin-sam .yui-calcontainer.multi .groupcal{background-color:transparent;border:none;padding:10px 5px 10px 5px;margin:0;}.yui-skin-sam .yui-calcontainer .title{background:url(sprite.png) repeat-x 0 0;border-bottom:1px solid #cccccc;font:100% sans-serif;color:#000;font-weight:bold;height:auto;padding:.4em;margin:0 -10px 10px -10px;top:0;left:0;text-align:left;}.yui-skin-sam .yui-calcontainer.multi .title{margin:0 -5px 0 -5px;}.yui-skin-sam .yui-calcontainer.withtitle{padding-top:0;}.yui-skin-sam .yui-calcontainer .calclose{background:url(sprite.png) no-repeat 0!
  -300px;width:25px;height:15px;top:.4em;right:.4em;cursor:poin!
 ter;}.yu
i-skin-sam .yui-calendar{border-spacing:0;border-collapse:collapse;font:100% sans-serif;text-align:center;}.yui-skin-sam .yui-calendar .calhead{background:transparent;border:none;vertical-align:middle;}.yui-skin-sam .yui-calendar .calheader{background:transparent;font-weight:bold;padding:0 0 .6em 0;text-align:center;}.yui-skin-sam .yui-calendar .calheader img{border:none;}.yui-skin-sam .yui-calendar .calnavleft{background:url(sprite.png) no-repeat 0 -450px;width:25px;height:15px;top:0;bottom:0;left:-10px;margin-left:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calnavright{background:url(sprite.png) no-repeat 0 -500px;width:25px;height:15px;top:0;bottom:0;right:-10px;margin-right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calweekdayrow{height:2em;}.yui-skin-sam .yui-calendar .calweekdaycell{color:#000;font-weight:bold;text-align:center;width:2em;}.yui-skin-sam .yui-calendar .calfoot{background-color:#f2f2f2;}.yui-skin-sam .yui-calendar .calrowhead,.yui-skin-sam .y!
 ui-calendar .calrowfoot{color:#a6a6a6;font-size:85%;font-style:normal;font-weight:normal;}.yui-skin-sam .yui-calendar .calrowhead{text-align:right;padding-right:2px;}.yui-skin-sam .yui-calendar .calrowfoot{text-align:left;padding-left:2px;}.yui-skin-sam .yui-calendar td.calcell{border:1px solid #cccccc;background:#fff;padding:1px;height:1.6em;line-height:1.6em;text-align:center;white-space:nowrap;}.yui-skin-sam .yui-calendar td.calcell a{color:#0066cc;display:block;height:100%;text-decoration:none;}.yui-skin-sam .yui-calendar td.calcell.today{background-color:#000;}.yui-skin-sam .yui-calendar td.calcell.today a{background-color:#fff;}.yui-skin-sam .yui-calendar td.calcell.oom{background-color:#cccccc;color:#a6a6a6;cursor:default;}.yui-skin-sam .yui-calendar td.calcell.selected{background-color:#fff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.selected a{background-color:#b3d4ff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.calcellhover{background-color:#426fd9;co!
 lor:#fff;cursor:pointer;}.yui-skin-sam .yui-calendar td.calcel!
 l.calcel
lhover a{background-color:#426fd9;color:#fff;}.yui-skin-sam .yui-calendar td.calcell.previous{color:#e0e0e0;}.yui-skin-sam .yui-calendar td.calcell.restricted{text-decoration:line-through;}.yui-skin-sam .yui-calendar td.calcell.highlight1{background-color:#ccff99;}.yui-skin-sam .yui-calendar td.calcell.highlight2{background-color:#99ccff;}.yui-skin-sam .yui-calendar td.calcell.highlight3{background-color:#ffcccc;}.yui-skin-sam .yui-calendar td.calcell.highlight4{background-color:#ccff99;}.yui-skin-sam .yui-calendar a.calnav{border:1px solid #f2f2f2;padding:0 4px;text-decoration:none;color:#000;zoom:1;}.yui-skin-sam .yui-calendar a.calnav:hover{background:url(sprite.png) repeat-x 0 0;border-color:#A0A0A0;cursor:pointer;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mask{background-color:#000;opacity:0.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-calcontainer .yui-cal-nav{font-family:arial,helvetica,clean,sans-serif;font-size:93%;border:1px solid #808080;left:50%;margin-lef!
 t:-7em;width:14em;padding:0;top:2.5em;background-color:#f2f2f2;}.yui-skin-sam .yui-calcontainer.withtitle .yui-cal-nav{top:4.5em;}.yui-skin-sam .yui-calcontainer.multi .yui-cal-nav{width:16em;margin-left:-8em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y,.yui-skin-sam .yui-calcontainer .yui-cal-nav-m,.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{padding:5px 10px 5px 10px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{text-align:center;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-e{margin-top:5px;padding:5px;background-color:#EDF5FF;border-top:1px solid black;display:none;}.yui-skin-sam .yui-calcontainer .yui-cal-nav label{display:block;font-weight:bold;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mc{width:100%;_width:auto;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y input.yui-invalid{background-color:#FFEE69;border:1px solid #000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-yc{width:4em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{border:1px soli!
 d #808080;background:url(sprite.png) repeat-x 0 0;background-c!
 olor:#cc
c;margin:auto .15em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{padding:0 8px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default{border:1px solid #304369;background-color:#426fd9;background:url(sprite.png) repeat-x 0 -1400px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default button{color:#fff;}
+.yui-calcontainer{position:relative;float:left;_overflow:hidden;}.yui-calcontainer iframe{position:absolute;border:none;margin:0;padding:0;z-index:0;width:100%;height:100%;left:0px;top:0px;}.yui-calcontainer iframe.fixedsize{width:50em;height:50em;top:-1px;left:-1px;}.yui-calcontainer.multi .groupcal{z-index:1;float:left;position:relative;}.yui-calcontainer .title{position:relative;z-index:1;}.yui-calcontainer .close-icon{position:absolute;z-index:1;}.yui-calendar{position:relative;}.yui-calendar .calnavleft{position:absolute;z-index:1;}.yui-calendar .calnavright{position:absolute;z-index:1;}.yui-calendar .calheader{position:relative;width:100%;text-align:center;}.yui-calcontainer .yui-cal-nav-mask{position:absolute;z-index:2;margin:0;padding:0;width:100%;height:100%;_width:0;_height:0;left:0;top:0;display:none;}.yui-calcontainer .yui-cal-nav{position:absolute;z-index:3;top:0;display:none;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{display:-moz-inline-box;display:inlin!
 e-block;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{display:block;*display:inline-block;*overflow:visible;border:none;background-color:transparent;cursor:pointer;}.yui-calendar .calbody a:hover{background:inherit;}p#clear{clear:left;padding-top:10px;}.yui-skin-sam .yui-calcontainer{background-color:#f2f2f2;border:1px solid #808080;padding:10px;}.yui-skin-sam .yui-calcontainer.multi{padding:0 5px 0 5px;}.yui-skin-sam .yui-calcontainer.multi .groupcal{background-color:transparent;border:none;padding:10px 5px 10px 5px;margin:0;}.yui-skin-sam .yui-calcontainer .title{background:url(sprite.png) repeat-x 0 0;border-bottom:1px solid #cccccc;font:100% sans-serif;color:#000;font-weight:bold;height:auto;padding:.4em;margin:0 -10px 10px -10px;top:0;left:0;text-align:left;}.yui-skin-sam .yui-calcontainer.multi .title{margin:0 -5px 0 -5px;}.yui-skin-sam .yui-calcontainer.withtitle{padding-top:0;}.yui-skin-sam .yui-calcontainer .calclose{background:url(sprite.png) no-repeat 0!
  -300px;width:25px;height:15px;top:.4em;right:.4em;cursor:poin!
 ter;}.yu
i-skin-sam .yui-calendar{border-spacing:0;border-collapse:collapse;font:100% sans-serif;text-align:center;margin:0;}.yui-skin-sam .yui-calendar .calhead{background:transparent;border:none;vertical-align:middle;padding:0;}.yui-skin-sam .yui-calendar .calheader{background:transparent;font-weight:bold;padding:0 0 .6em 0;text-align:center;}.yui-skin-sam .yui-calendar .calheader img{border:none;}.yui-skin-sam .yui-calendar .calnavleft{background:url(sprite.png) no-repeat 0 -450px;width:25px;height:15px;top:0;bottom:0;left:-10px;margin-left:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calnavright{background:url(sprite.png) no-repeat 0 -500px;width:25px;height:15px;top:0;bottom:0;right:-10px;margin-right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calweekdayrow{height:2em;}.yui-skin-sam .yui-calendar .calweekdayrow th{padding:0;border:none;}.yui-skin-sam .yui-calendar .calweekdaycell{color:#000;font-weight:bold;text-align:center;width:2em;}.yui-skin-sam .yui-calendar .ca!
 lfoot{background-color:#f2f2f2;}.yui-skin-sam .yui-calendar .calrowhead,.yui-skin-sam .yui-calendar .calrowfoot{color:#a6a6a6;font-size:85%;font-style:normal;font-weight:normal;border:none;}.yui-skin-sam .yui-calendar .calrowhead{text-align:right;padding:0 2px 0 0;}.yui-skin-sam .yui-calendar .calrowfoot{text-align:left;padding:0 0 0 2px;}.yui-skin-sam .yui-calendar td.calcell{border:1px solid #cccccc;background:#fff;padding:1px;height:1.6em;line-height:1.6em;text-align:center;white-space:nowrap;}.yui-skin-sam .yui-calendar td.calcell a{color:#0066cc;display:block;height:100%;text-decoration:none;}.yui-skin-sam .yui-calendar td.calcell.today{background-color:#000;}.yui-skin-sam .yui-calendar td.calcell.today a{background-color:#fff;}.yui-skin-sam .yui-calendar td.calcell.oom{background-color:#cccccc;color:#a6a6a6;cursor:default;}.yui-skin-sam .yui-calendar td.calcell.selected{background-color:#fff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.selected a{background-colo!
 r:#b3d4ff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.c!
 alcellho
ver{background-color:#426fd9;color:#fff;cursor:pointer;}.yui-skin-sam .yui-calendar td.calcell.calcellhover a{background-color:#426fd9;color:#fff;}.yui-skin-sam .yui-calendar td.calcell.previous{color:#e0e0e0;}.yui-skin-sam .yui-calendar td.calcell.restricted{text-decoration:line-through;}.yui-skin-sam .yui-calendar td.calcell.highlight1{background-color:#ccff99;}.yui-skin-sam .yui-calendar td.calcell.highlight2{background-color:#99ccff;}.yui-skin-sam .yui-calendar td.calcell.highlight3{background-color:#ffcccc;}.yui-skin-sam .yui-calendar td.calcell.highlight4{background-color:#ccff99;}.yui-skin-sam .yui-calendar a.calnav{border:1px solid #f2f2f2;padding:0 4px;text-decoration:none;color:#000;zoom:1;}.yui-skin-sam .yui-calendar a.calnav:hover{background:url(sprite.png) repeat-x 0 0;border-color:#A0A0A0;cursor:pointer;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mask{background-color:#000;opacity:0.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-calcontainer .yui-cal-nav{fo!
 nt-family:arial,helvetica,clean,sans-serif;font-size:93%;border:1px solid #808080;left:50%;margin-left:-7em;width:14em;padding:0;top:2.5em;background-color:#f2f2f2;}.yui-skin-sam .yui-calcontainer.withtitle .yui-cal-nav{top:4.5em;}.yui-skin-sam .yui-calcontainer.multi .yui-cal-nav{width:16em;margin-left:-8em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y,.yui-skin-sam .yui-calcontainer .yui-cal-nav-m,.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{padding:5px 10px 5px 10px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{text-align:center;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-e{margin-top:5px;padding:5px;background-color:#EDF5FF;border-top:1px solid black;display:none;}.yui-skin-sam .yui-calcontainer .yui-cal-nav label{display:block;font-weight:bold;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mc{width:100%;_width:auto;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y input.yui-invalid{background-color:#FFEE69;border:1px solid #000;}.yui-skin-sam .yui-calcontainer .yu!
 i-cal-nav-yc{width:4em;}.yui-skin-sam .yui-calcontainer .yui-c!
 al-nav .
yui-cal-nav-btn{border:1px solid #808080;background:url(sprite.png) repeat-x 0 0;background-color:#ccc;margin:auto .15em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{padding:0 8px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default{border:1px solid #304369;background-color:#426fd9;background:url(sprite.png) repeat-x 0 -1400px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default button{color:#fff;}
 .yui-picker-panel{background:#e3e3e3;border-color:#888;}.yui-picker-panel .hd{background-color:#ccc;font-size:100%;line-height:100%;border:1px solid #e3e3e3;font-weight:bold;overflow:hidden;padding:6px;color:#000;}.yui-picker-panel .bd{background:#e8e8e8;margin:1px;height:200px;}.yui-picker-panel .ft{background:#e8e8e8;margin:1px;padding:1px;}.yui-picker{position:relative;}.yui-picker-hue-thumb{cursor:default;width:18px;height:18px;top:-8px;left:-2px;z-index:9;position:absolute;}.yui-picker-hue-bg{-moz-outline:none;outline:0px none;position:absolute;left:200px;height:183px;width:14px;background:url(hue_bg.png) no-repeat;top:4px;}.yui-picker-bg{-moz-outline:none;outline:0px none;position:absolute;top:4px;left:4px;height:182px;width:182px;background-color:#F00;background-image:url(picker_mask.png);}*html .yui-picker-bg{background-image:none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../../build/colorpicker/assets/picker_mask.png',sizingMethod='scale');}.yu!
 i-picker-mask{position:absolute;z-index:1;top:0px;left:0px;}.yui-picker-thumb{cursor:default;width:11px;height:11px;z-index:9;position:absolute;top:-4px;left:-4px;}.yui-picker-swatch{position:absolute;left:240px;top:4px;height:60px;width:55px;border:1px solid #888;}.yui-picker-websafe-swatch{position:absolute;left:304px;top:4px;height:24px;width:24px;border:1px solid #888;}.yui-picker-controls{position:absolute;top:72px;left:226px;font:1em monospace;}.yui-picker-controls .hd{background:transparent;border-width:0px !important;}.yui-picker-controls .bd{height:100px;border-width:0px !important;}.yui-picker-controls ul{float:left;padding:0 2px 0 0;margin:0}.yui-picker-controls li{padding:2px;list-style:none;margin:0}.yui-picker-controls input{font-size:0.85em;width:2.4em;}.yui-picker-hex-controls{clear:both;padding:2px;}.yui-picker-hex-controls input{width:4.6em;}.yui-picker-controls a{font:1em arial,helvetica,clean,sans-serif;display:block;*display:inline-block;padding:0;color!
 :#000;}
-.yui-overlay,.yui-panel-container{visibility:hidden;position:absolute;z-index:2;}.yui-panel-container form{margin:0;}.mask{z-index:1;display:none;position:absolute;top:0;left:0;right:0;bottom:0;overflow:auto;}.masked select,.drag select,.hide-select select{_visibility:hidden;}.yui-panel-container select{_visibility:inherit;}.hide-scrollbars,.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.show-scrollbars{overflow:auto;}.yui-panel-container.show-scrollbars,.yui-tt.show-scrollbars{overflow:visible;}.yui-panel-container.show-scrollbars .underlay,.yui-tt.show-scrollbars .yui-tt-shadow{overflow:auto;}.yui-panel-container.shadow .underlay.yui-force-redraw{padding-bottom:1px;}.yui-effect-fade .underlay{display:none;}.yui-tt-shadow{position:absolute;}.yui-skin-sam .mask{background-color:#000;opacity:.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-panel-container{padding:0 1px;*padding:2px 3px;}.yui-skin-sam .yui-panel{position:relative;*zoom:1;left:0;top!
 :0;border-style:solid;border-width:1px 0;border-color:#808080;z-index:1;}.yui-skin-sam .yui-panel .hd,.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{*zoom:1;*position:relative;border-style:solid;border-width:0 1px;border-color:#808080;margin:0 -1px;}.yui-skin-sam .yui-panel .hd{border-bottom:solid 1px #ccc;}.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{background-color:#F2F2F2;}.yui-skin-sam .yui-panel .hd{padding:0 10px;font-size:93%;line-height:2;*line-height:1.9;font-weight:bold;color:#000;background:url(sprite.png) repeat-x 0 -200px;}.yui-skin-sam .yui-panel .bd{padding:10px;}.yui-skin-sam .yui-panel .ft{border-top:solid 1px #808080;padding:5px 10px;font-size:77%;}.yui-skin-sam .yui-panel-container.focused .yui-panel .hd{}.yui-skin-sam .container-close{position:absolute;top:5px;right:6px;width:25px;height:15px;background:url(sprite.png) no-repeat 0 -300px;cursor:pointer;}.yui-skin-sam .yui-panel-container .underlay{right:-1px;left:-1px;}.yui-skin-!
 sam .yui-panel-container.matte{padding:9px 10px;background-col!
 or:#fff;
}.yui-skin-sam .yui-panel-container.shadow{_padding:2px 5px 0 3px;}.yui-skin-sam .yui-panel-container.shadow .underlay{position:absolute;top:2px;right:-3px;bottom:-3px;left:-3px;*top:3px;*left:-1px;*right:-1px;*bottom:-1px;_top:0;_right:0;_bottom:0;_left:0;_margin-top:3px;_margin-left:-1px;background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yui-dialog .ft{border-top:none;padding:0 10px 10px 10px;font-size:100%;}.yui-skin-sam .yui-dialog .ft .button-group{display:block;text-align:right;}.yui-skin-sam .yui-dialog .ft button.default{font-weight:bold;}.yui-skin-sam .yui-dialog .ft span.default{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-dialog .ft span.default .first-child{border-color:#304369;}.yui-skin-sam .yui-dialog .ft span.default button{color:#fff;}.yui-skin-sam .yui-simple-dialog .bd .yui-icon{background:url(sprite.png) no-repeat 0 0;width:16px;height:16px;margin-right:10px;float:left;}.yui-skin-sam .yui-simple-dialog .b!
 d span.blckicon{background-position:0 -1100px;}.yui-skin-sam .yui-simple-dialog .bd span.alrticon{background-position:0 -1050px;}.yui-skin-sam .yui-simple-dialog .bd span.hlpicon{background-position:0 -1150px;}.yui-skin-sam .yui-simple-dialog .bd span.infoicon{background-position:0 -1200px;}.yui-skin-sam .yui-simple-dialog .bd span.warnicon{background-position:0 -1900px;}.yui-skin-sam .yui-simple-dialog .bd span.tipicon{background-position:0 -1250px;}.yui-skin-sam .yui-tt .bd{position:relative;top:0;left:0;z-index:1;color:#000;padding:2px 5px;border-color:#D4C237 #A6982B #A6982B #A6982B;border-width:1px;border-style:solid;background-color:#FFEE69;}.yui-skin-sam .yui-tt.show-scrollbars .bd{overflow:auto;}.yui-skin-sam .yui-tt-shadow{top:2px;right:-3px;left:-3px;bottom:-3px;background-color:#000;}.yui-skin-sam .yui-tt-shadow-visible{opacity:.12;*filter:alpha(opacity=12);}
-table.yui-dt-table{table-layout:fixed;}th .yui-dt-header{position:relative;}th .yui-dt-label{position:relative;}th .yui-dt-resizer{position:absolute;margin-right:-6px;right:0;bottom:0;width:6px;height:100%;cursor:w-resize;cursor:col-resize;}.yui-dt-scrollable{*overflow-y:auto;}.yui-dt-scrollable thead{display:block;}.yui-dt-scrollable thead tr{position:relative;}.yui-dt-scrollbody{display:block;overflow:auto;}.yui-dt-editor{position:absolute;z-index:9000;}.yui-skin-sam .yui-dt-table{margin:0;padding:0;font-family:arial;font-size:inherit;border-collapse:collapse;border:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-table caption{padding-bottom:1em;text-align:left;}.yui-skin-sam .yui-dt-table th{background:url(sprite.png) repeat-x 0 0;}.yui-skin-sam .yui-dt-table th,.yui-skin-sam .yui-dt-table th a{font-weight:normal;text-decoration:none;color:#000;vertical-align:bottom;}.yui-skin-sam .yui-dt-table th,.yui-skin-sam .yui-dt-table td{padding:4px 10px 4px 10px;border-right:1px solid #!
 CBCBCB;}.yui-skin-sam .yui-dt-table td{text-align:left;}.yui-skin-sam .yui-dt-table th.yui-dt-last,.yui-skin-sam .yui-dt-table td.yui-dt-last{border-right:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-list td{border-right:none;}.yui-skin-sam .yui-dt-table thead{border:1px solid #989898;}.yui-skin-sam .yui-dt-table tbody{border-left:1px solid #7F7F7F;border-right:1px solid #7F7F7F;border-bottom:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-loading{background-color:#FFF;}.yui-skin-sam .yui-dt-loading{background-color:#FFF;}.yui-skin-sam .yui-dt-sortable{cursor:pointer;}.yui-skin-sam th.yui-dt-sortable{padding-right:5px;}.yui-skin-sam th.yui-dt-sortable .yui-dt-label{margin-right:15px;}.yui-skin-sam th.yui-dt-asc,.yui-skin-sam th.yui-dt-desc{background:url(sprite.png) repeat-x 0 -100px;}.yui-skin-sam th.yui-dt-asc .yui-dt-header{background:url(dt-arrow-up.png) no-repeat right;}.yui-skin-sam th.yui-dt-desc .yui-dt-header{background:url(dt-arrow-dn.png) no-repeat right;}.yui-dt-editable{c!
 ursor:pointer;}.yui-dt-editor{text-align:left;background-color!
 :#F2F2F2
;border:1px solid #808080;padding:6px;}.yui-dt-editor label{padding-left:4px;padding-right:6px;}.yui-dt-editor .yui-dt-button{padding-top:6px;text-align:right;}.yui-dt-editor .yui-dt-button button{background:url(sprite.png) repeat-x 0 0;border:1px solid #999;width:4em;height:1.8em;margin-left:6px;}.yui-dt-editor .yui-dt-button button.yui-dt-default{background:url(sprite.png) repeat-x 0 -1400px;background-color:#5584E0;border:1px solid #304369;color:#FFF}.yui-dt-editor .yui-dt-button button:hover{background:url(sprite.png) repeat-x 0 -1300px;color:#000;}.yui-dt-editor .yui-dt-button button:active{background:url(sprite.png) repeat-x 0 -1700px;color:#000;}.yui-skin-sam tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam tr.yui-dt-odd{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam tr.yui-dt-even td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam tr.yui-dt-odd td.yui-dt-desc{background-color:#DBEAFF!
 ;}.yui-skin-sam .yui-dt-list tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-odd{background-color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted!
 {cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam tr.yui!
 -dt-sele
cted td,.yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam tr.yui-dt-selected td.yui-dt-desc{background-color:#426FD9;color:#FFF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam tr.yui-dt-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-selected td,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc{background-color:#426FD9;color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}.yui-skin-sam .yui-dt-paginator{display:block;margin:6px 0;white-space:nowrap;}.yui-skin-sam .yui-dt-paginator .yui-dt-first,.yui-skin-sam .yui-dt-paginator .yui-dt-last,.yui-skin-sam .yui-dt-paginator .yui-dt-selected{padding:2px 6px;}.yui-skin-sam .yui-dt-paginator a.yui-dt-first,.yui-skin-sam .yui-dt-paginator a.yui-dt-last{text-decoration:none;}.!
 yui-skin-sam .yui-dt-paginator .yui-dt-previous,.yui-skin-sam .yui-dt-paginator .yui-dt-next{display:none;}.yui-skin-sam a.yui-dt-page{border:1px solid #CBCBCB;padding:2px 6px;text-decoration:none;}
-.yui-busy{cursor:wait !important;}.yui-toolbar-container .yui-toolbar-subcont{padding:.25em 0;zoom:1;}.yui-toolbar-container-collapsed .yui-toolbar-subcont{display:none;}.yui-toolbar-container .yui-toolbar-subcont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container span.yui-toolbar-draghandle{cursor:move;border-left:1px solid #999;border-right:1px solid #999;overflow:hidden;text-indent:77777px;width:2px;height:20px;display:block;clear:none;float:left;margin:0 0 0 .2em;}.yui-toolbar-container .yui-toolbar-titlebar.draggable{cursor:move;}.yui-toolbar-container .yui-toolbar-titlebar{position:relative;}.yui-toolbar-container .yui-toolbar-titlebar h2{font-weight:bold;letter-spacing:0;border:none;color:#000;margin:0;padding:.2em;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-draghandle{height:40px;}.yui-toolbar-container .yui-toolbar-group{float:left;zoom:1;}.yui-toolbar-container .yui-toolbar-group:after{display:block;clear!
 :both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container .yui-toolbar-group h3{font-size:75%;padding:0 0 0 .25em;margin:0;}.yui-toolbar-container span.yui-toolbar-separator{width:2px;height:18px;margin:.2em 0 .2em .1em;display:block;clear:none;float:left;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-separator{height:35px;}.yui-toolbar-container.yui-toolbar-grouped .yui-toolbar-group span.yui-toolbar-separator{height:18px;}.yui-toolbar-container ul li{margin:0;padding:0;list-style-type:none;}.yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-toolbar-container .yui-push-button,.yui-toolbar-container .yui-color-button,.yui-toolbar-container .yui-menu-button{position:relative;cursor:pointer;}.yui-toolbar-container .yui-button .first-child,.yui-toolbar-container .yui-button .first-child a{height:100%;width:100%;overflow:hidden;}.yui-toolbar-container .yui-button-disabled{cursor:default;}.yui-toolbar-container .yui-button-disabled .!
 yui-toolbar-icon{opacity:.5;filter:alpha(opacity=50);}.yui-too!
 lbar-con
tainer .yui-button-disabled .up,.yui-toolbar-container .yui-button-disabled .down{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button a{overflow:hidden;}.yui-toolbar-container .yui-toolbar-select .first-child a{cursor:pointer;}.yui-toolbar-fontname-arial{font-family:Arial;}.yui-toolbar-fontname-arial-black{font-family:Arial Black;}.yui-toolbar-fontname-comic-sans-ms{font-family:Comic Sans MS;}.yui-toolbar-fontname-courier-new{font-family:Courier New;}.yui-toolbar-fontname-times-new-roman{font-family:Times New Roman;}.yui-toolbar-fontname-verdana{font-family:Verdana;}.yui-toolbar-fontname-impact{font-family:Impact;}.yui-toolbar-fontname-lucida-console{font-family:Lucida Console;}.yui-toolbar-fontname-tahoma{font-family:Tahoma;}.yui-toolbar-fontname-trebuchet-ms{font-family:Trebuchet MS;}.yui-toolbar-container .yui-toolbar-spinbutton{position:relative;}.yui-toolbar-container .yui-toolbar-spinbutton .first-child a{z-index:0;opacity:1;}.yui-toolbar-container !
 .yui-toolbar-spinbutton a.up,.yui-toolbar-container .yui-toolbar-spinbutton a.down{position:absolute;display:block right:0;cursor:pointer;z-index:1;padding:0;margin:0;}.yui-toolbar-container .yui-overlay{position:absolute;}.yui-toolbar-container .yui-overlay ul li{margin:0;list-style-type:none;}.yui-toolbar-container{z-index:1;}.yui-editor-container .yui-editor-editable-container{position:relative;z-index:0;width:100%;}.yui-editor-container .yui-editor-masked{background-color:#CCC;}.yui-editor-container iframe{border:0px;padding:0;margin:0;zoom:1;display:block;}.yui-editor-container .yui-editor-editable{padding:0;margin:0;}.yui-editor-container .dompath{font-size:85%;}.yui-editor-panel .hd{text-align:left;position:relative;}.yui-editor-panel .hd h3{font-weight:bold;padding:0.25em 0pt 0.25em 0.25em;margin:0;}.yui-editor-panel .bd{width:100%;zoom:1;position:relative;}.yui-editor-panel .bd div.yui-editor-body-cont{padding:.25em .1em;zoom:1;}.yui-editor-panel .bd div.yui-editor!
 -body-cont:after{display:block;clear:both;visibility:hidden;co!
 ntent:'.
';height:0;}.yui-editor-panel .ft{text-align:right;width:99%;float:left;clear:both;}.yui-editor-panel .ft span.tip{display:block;position:relative;padding:.5em .5em .5em 23px;text-align:left;zoom:1;}.yui-editor-panel label{clear:both;float:left;padding:0;width:100%;text-align:left;zoom:1;}.yui-editor-panel .gecko label{overflow:auto;}.yui-editor-panel label strong{float:left;width:6em;}.yui-editor-panel .removeLink{width:80%;text-align:right;}.yui-editor-panel label input{margin-left:.25em;float:left;}.yui-editor-panel .yui-toolbar-group-padding{}.yui-editor-panel .yui-toolbar-group-border{}.yui-editor-panel .yui-toolbar-group-textflow{}.yui-editor-panel .height-width{float:left;}.yui-editor-panel .height-width h3{}.yui-editor-panel .height-width span{font-style:italic;display:block;float:left;overflow:auto;}.yui-editor-panel .height-width span.info{font-size:70%;}.yui-editor-panel .yui-toolbar-bordersize,.yui-editor-panel .yui-toolbar-bordertype{font-size:75%;}.yui-editor-p!
 anel .yui-toolbar-container span.yui-toolbar-separator{border:none;}.yui-editor-panel .yui-toolbar-bordersize span a span,.yui-editor-panel .yui-toolbar-bordertype span a span{display:block;height:8px;left:4px;position:absolute;top:3px;*top:-5px;width:24px;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-solid{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dotted{border-bottom:1px dotted black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dashed{border-bottom:1px dashed black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-0{*top:0px;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-1{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-2{border-bottom:2px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersiz!
 e-3{top:2px;*top:-5px;border-bottom:3px solid black;}.yui-edit!
 or-panel
 .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-4{top:1px;*top:-5px;border-bottom:4px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-5{top:1px;*top:-5px;border-bottom:5px solid black;}.yui-toolbar-container .yui-toolbar-bordersize-menu,.yui-toolbar-container .yui-toolbar-bordertype-menu{width:95px !important;}.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel,.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel:hover{margin:0px 3px 7px 17px;}.yui-toolbar-bordersize-menu .yuimenuitemlabel .checkedindicator,.yui-toolbar-bordertype-menu .yuimenuitemlabel .checkedindicator{position:absolute;left:-12px;*top:14px;*left:0px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-1 a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-2 a{border-bottom:2px solid black;height:14px;}.yui-toolbar-borders!
 ize-menu li.yui-toolbar-bordersize-3 a{border-bottom:3px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-4 a{border-bottom:4px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-5 a{border-bottom:5px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-solid a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dashed a{border-bottom:1px dashed black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dotted a{border-bottom:1px dotted black;height:14px;}h2.yui-editor-skipheader,h3.yui-editor-skipheader{height:0;margin:0;padding:0;border:none;width:0;overflow:hidden;position:absolute;}.yui-toolbar-colors{width:133px;zoom:1;display:none;z-index:100;overflow:hidden;}.yui-toolbar-colors:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors a{height:9px;width:9px;float:left;display:block;overflo!
 w:hidden;text-indent:999px;margin:0;cursor:pointer;border:1px !
 solid #F
6F7EE;}.yui-toolbar-colors a:hover{border:1px solid black;}.yui-color-button-menu{overflow:visible;background-color:transparent;}.yui-toolbar-colors span{position:relative;display:block;padding:3px;overflow:hidden;float:left;width:100%;zoom:1;}.yui-toolbar-colors span:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors span em{height:35px;width:30px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0.75px;border:1px solid black;}.yui-toolbar-colors span strong{font-weight:normal;padding-left:3px;display:block;font-size:85%;float:left;width:65%;}.yui-skin-sam .yui-editor-container{border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container{zoom:1;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar{background:url(sprite.png) repeat-x 0 -200px;position:relative;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar h2{color:#000000;font-weight:bold;margin:0;padding:0.3em 1em;font-size:100%;text-align:left;}.!
 yui-skin-sam .yui-toolbar-container .yui-toolbar-group h3{color:#808080;font-size:75%;margin:1em 0 0;padding-bottom:0;padding-left:0.25em;text-align:left;}.yui-toolbar-container span.yui-toolbar-separator{border:none;text-indent:33px;overflow:hidden;margin:.25em;}.yui-skin-sam .yui-toolbar-container{background-color:#F2F2F2;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subcont{padding:0 1em 0.35em;border-bottom:1px solid #808080;}.yui-skin-sam .yui-toolbar-container-collapsed .yui-toolbar-titlebar{border-bottom:1px solid #808080;}.yui-skin-sam .yui-editor-container .visible .yui-menu-shadow,.yui-skin-sam .yui-editor-panel .visible .yui-menu-shadow{display:none;}.yui-skin-sam .yui-editor-container ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-container ul li{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-toolbar-group ul li.yui-toolbar-groupitem{float:left;}.yui-skin-sam .yui-editor-container .dompath{background-color:#F2F2F2;border-!
 top:1px solid #808080;color:#999;text-align:left;padding:0.25e!
 m;}.yui-
skin-sam .yui-toolbar-container .collapse{background:url(sprite.png) no-repeat 0 -400px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar span.collapse{cursor:pointer;position:absolute;top:4px;right:2px;display:block;overflow:hidden;height:15px;width:15px;text-indent:9999px;}.yui-skin-sam .yui-toolbar-container .yui-push-button,.yui-skin-sam .yui-toolbar-container .yui-color-button,.yui-skin-sam .yui-toolbar-container .yui-menu-button{background:url(sprite.png) repeat-x 0 0;position:relative;display:block;height:22px;width:30px;margin:0;border-color:#808080;border-style:solid;border-width:1px 0;}.yui-skin-sam .yui-toolbar-container .yui-push-button a,.yui-skin-sam .yui-toolbar-container .yui-color-button a,.yui-skin-sam .yui-toolbar-container .yui-menu-button a{padding-left:35px;height:20px;text-decoration:none;font-size:93%;line-height:2;display:block;color:#000000;overflow:hidden;}.yui-skin-sam .yui-toolbar-container .yui-push-button .first-child,.yui-skin-sam .y!
 ui-toolbar-container .yui-color-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button .first-child{border-color:#808080;border-style:solid;border-width:0 1px;margin:0 -1px;display:block;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-button .first-child{*left:0px;}.yui-skin-sam .yui-toolba!
 r-container .yui-toolbar-fontname{width:135px;}.yui-skin-sam .!
 yui-tool
bar-container .yui-toolbar-heading{width:92px;}.yui-skin-sam .yui-toolbar-container .yui-button-hover{background:url(sprite.png) repeat-x 0 -1300px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-button-selected{background:url(sprite.png) repeat-x 0 -1700px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels .yui-toolbar-group{margin-top:.75em;}.yui-skin-sam .yui-toolbar-container .yui-push-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-color-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-menu-button span.yui-toolbar-icon{display:block;position:absolute;top:2px;height:18px;width:18px;overflow:hidden;background:url(editor-sprite.gif) no-repeat 30px 30px;}.yui-skin-sam .yui-toolbar-container .yui-button-selected span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-button-hover span.yui-tool!
 bar-icon{background-image:url(editor-sprite-active.gif);}.yui-skin-sam .yui-toolbar-container .visible .yuimenuitemlabel{cursor:pointer;color:#000;*position:relative;}.yui-skin-sam .yui-toolbar-container .yui-button-menu{background-color:#fff;}.yui-skin-sam div.yuimenu li.selected{background-color:#B3D4FF;}.yui-skin-sam div.yuimenu li.selected a.selected{color:#000;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bold span.yui-toolbar-icon{background-position:0 0;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-italic span.yui-toolbar-icon{background-position:0 -36px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-underline span.yui-toolbar-icon{background-position:0 -72px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subscript span.yui-toolbar-icon{background-position:0 -180px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-superscript span.yui-toolbar-icon{background-position:0 -144px;left:5px;}.yui-skin-sam .yui-toolbar-!
 container .yui-toolbar-forecolor span.yui-toolbar-icon{backgro!
 und-posi
tion:0 -216px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-backcolor span.yui-toolbar-icon{background-position:0 -288px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyleft span.yui-toolbar-icon{background-position:0 -324px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifycenter span.yui-toolbar-icon{background-position:0 -360px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyright span.yui-toolbar-icon{background-position:0 -396px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyfull span.yui-toolbar-icon{background-position:0 -432px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-indent span.yui-toolbar-icon{background-position:0 -720px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-outdent span.yui-toolbar-icon{background-position:0 -684px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-createlink span.yui-toolbar-icon{background-position:0 -792px;!
 left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertimage span.yui-toolbar-icon{background-position:1px -756px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-left span.yui-toolbar-icon{background-position:0 -972px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-right span.yui-toolbar-icon{background-position:0 -936px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-inline span.yui-toolbar-icon{background-position:0 -900px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-block span.yui-toolbar-icon{background-position:0 -864px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bordercolor span.yui-toolbar-icon{background-position:0 -252px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-removeformat span.yui-toolbar-icon{background-position:0 -1080px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-hiddenelements span.yui-toolbar-icon{background-position:0 -1044px;left:5px;}.yui-skin-!
 sam .yui-toolbar-container .yui-toolbar-insertunorderedlist sp!
 an.yui-t
oolbar-icon{background-position:0 -468px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertorderedlist span.yui-toolbar-icon{background-position:0 -504px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child{width:35px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child a{padding-left:2px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton span.yui-toolbar-icon{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{right:2px;background:url(editor-sprite.gif) no-repeat 0 -1222px;overflow:hidden;height:6px;width:7px;min-height:0;padding:0;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up{top:2px;background-position:0 -1222px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{bottom:2px;background-p!
 osition:0 -1187px;}.yui-skin-sam .yui-toolbar-container select{height:22px;border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select .first-child a{padding-left:5px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select span.yui-toolbar-icon{background:url( editor-sprite.gif ) no-repeat 0 -1144px;overflow:hidden;right:-2px;top:0px;height:20px;}.yui-skin-sam .yui-editor-panel .yui-color-button-menu .bd{background-color:transparent;border:none;width:135px;}.yui-skin-sam .yui-color-button-menu .yui-toolbar-colors{border:1px solid #808080;}.yui-skin-sam .yui-editor-panel{padding:0;margin:0;border:none;background-color:transparent;overflow:visible;}.yui-skin-sam .yui-editor-panel .hd{margin:10px 0 0;padding:0;border:none;}.yui-skin-sam .yui-editor-panel .hd h3{color:#000;border:1px solid #808080;background:url(sprite.png) repeat-x 0 -200px;width:99%;position:relative;margin:0;padding:3px 0 0 0;font-size:93%;text-indent:5px;height:20px;!
 }.yui-skin-sam .yui-editor-panel .bd{background-color:#F2F2F2;!
 border-l
eft:1px solid #808080;border-right:1px solid #808080;width:99%;margin:0;padding:0;overflow:visible;}.yui-skin-sam .yui-editor-panel ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-panel ul li{margin:0;padding:0;}.yui-skin-sam .yui-editor-panel .yuimenu{}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .yui-toolbar-subcont{padding:0;border:none;margin-top:0.35em;}.yui-skin-sam .yui-editor-panel .yui-toolbar-bordersize,.yui-skin-sam .yui-editor-panel .yui-toolbar-bordertype{width:50px;}.yui-skin-sam .yui-editor-panel label{display:block;float:none;padding:4px 0;margin-bottom:7px;}.yui-skin-sam .yui-editor-panel label strong{font-weight:normal;font-size:93%;text-align:right;padding-top:2px;}.yui-skin-sam .yui-editor-panel label input{width:75%;}.yui-skin-sam .yui-editor-panel #createlink_target,.yui-skin-sam .yui-editor-panel #insertimage_target{width:auto;margin-right:5px;}.yui-skin-sam .yui-editor-panel .removeLink{width:98%;}.yui-skin-sam .yui-edi!
 tor-panel label input.warning{background-color:#FFEE69;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group h3{color:#000;float:left;font-weight:normal;font-size:93%;margin:5px 0 0 0;padding:0 3px 0 0;text-align:right;}.yui-skin-sam .yui-editor-panel .height-width h3{margin:3px 0 0 10px;}.yui-skin-sam .yui-editor-panel .height-width{margin:3px 0 0 35px;*margin-left:14px;width:42%;*width:44%;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-border{width:190px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-border{width:210px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding{width:203px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-padding{width:172px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding h3{margin-left:25px;*margin-left:12px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-textflow{width:182px;}.yui-skin-sam .yui-editor-panel .hd{background:none;}.yui-skin-sam .yui-editor-panel .ft{background-color:#F2F2F2;b!
 order:1px solid #808080;border-top:none;padding:0;margin:0 0 2!
 px 0;}.y
ui-skin-sam .yui-editor-panel .hd span.close{background:url(sprite.png) no-repeat 0 -300px;cursor:pointer;display:block;height:16px;overflow:hidden;position:absolute;right:5px;text-indent:500px;top:2px;width:26px;}.yui-skin-sam .yui-editor-panel .ft span.tip{background-color:#EDF5FF;border-top:1px solid #808080;font-size:85%;}.yui-skin-sam .yui-editor-panel .ft span.tip strong{display:block;float:left;margin:0 2px 8px 0;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon{background:url( editor-sprite.gif ) no-repeat 0 -1260px;display:block;height:20px;left:2px;position:absolute;top:8px;width:20px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-info{background-position:2px -1260px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-warn{background-position:2px -1296px;}.yui-skin-sam .yui-editor-panel .hd span.knob{position:absolute;height:10px;width:28px;top:-10px;left:25px;text-indent:9999px;overflow:hidden;background:url( editor-knob.gif ) no-repeat 0 0;}.yu!
 i-skin-sam .yui-editor-panel .yui-toolbar-container{float:left;width:100%;background-image:none;border:none;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .bd{background-color:#ffffff;}.yui-editor-blankimage{background-image:url( blankimage.png );}
+.yui-overlay,.yui-panel-container{visibility:hidden;position:absolute;z-index:2;}.yui-panel-container form{margin:0;}.mask{z-index:1;display:none;position:absolute;top:0;left:0;right:0;bottom:0;}.mask.block-scrollbars{overflow:auto;}.masked select,.drag select,.hide-select select{_visibility:hidden;}.yui-panel-container select{_visibility:inherit;}.hide-scrollbars,.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.show-scrollbars{overflow:auto;}.yui-panel-container.show-scrollbars,.yui-tt.show-scrollbars{overflow:visible;}.yui-panel-container.show-scrollbars .underlay,.yui-tt.show-scrollbars .yui-tt-shadow{overflow:auto;}.yui-panel-container.shadow .underlay.yui-force-redraw{padding-bottom:1px;}.yui-effect-fade .underlay{display:none;}.yui-tt-shadow{position:absolute;}.yui-skin-sam .mask{background-color:#000;opacity:.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-panel-container{padding:0 1px;*padding:2px 3px;}.yui-skin-sam .yui-panel{position:rel!
 ative;*zoom:1;left:0;top:0;border-style:solid;border-width:1px 0;border-color:#808080;z-index:1;}.yui-skin-sam .yui-panel .hd,.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{*zoom:1;*position:relative;border-style:solid;border-width:0 1px;border-color:#808080;margin:0 -1px;}.yui-skin-sam .yui-panel .hd{border-bottom:solid 1px #ccc;}.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{background-color:#F2F2F2;}.yui-skin-sam .yui-panel .hd{padding:0 10px;font-size:93%;line-height:2;*line-height:1.9;font-weight:bold;color:#000;background:url(sprite.png) repeat-x 0 -200px;}.yui-skin-sam .yui-panel .bd{padding:10px;}.yui-skin-sam .yui-panel .ft{border-top:solid 1px #808080;padding:5px 10px;font-size:77%;}.yui-skin-sam .yui-panel-container.focused .yui-panel .hd{}.yui-skin-sam .container-close{position:absolute;top:5px;right:6px;width:25px;height:15px;background:url(sprite.png) no-repeat 0 -300px;cursor:pointer;}.yui-skin-sam .yui-panel-container .underlay{right:-1!
 px;left:-1px;}.yui-skin-sam .yui-panel-container.matte{padding!
 :9px 10p
x;background-color:#fff;}.yui-skin-sam .yui-panel-container.shadow{_padding:2px 5px 0 3px;}.yui-skin-sam .yui-panel-container.shadow .underlay{position:absolute;top:2px;right:-3px;bottom:-3px;left:-3px;*top:3px;*left:-1px;*right:-1px;*bottom:-1px;_top:0;_right:0;_bottom:0;_left:0;_margin-top:3px;_margin-left:-1px;background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yui-dialog .ft{border-top:none;padding:0 10px 10px 10px;font-size:100%;}.yui-skin-sam .yui-dialog .ft .button-group{display:block;text-align:right;}.yui-skin-sam .yui-dialog .ft button.default{font-weight:bold;}.yui-skin-sam .yui-dialog .ft span.default{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-dialog .ft span.default .first-child{border-color:#304369;}.yui-skin-sam .yui-dialog .ft span.default button{color:#fff;}.yui-skin-sam .yui-simple-dialog .bd .yui-icon{background:url(sprite.png) no-repeat 0 0;width:16px;height:16px;margin-right:10px;float:left;}.yui-skin-s!
 am .yui-simple-dialog .bd span.blckicon{background-position:0 -1100px;}.yui-skin-sam .yui-simple-dialog .bd span.alrticon{background-position:0 -1050px;}.yui-skin-sam .yui-simple-dialog .bd span.hlpicon{background-position:0 -1150px;}.yui-skin-sam .yui-simple-dialog .bd span.infoicon{background-position:0 -1200px;}.yui-skin-sam .yui-simple-dialog .bd span.warnicon{background-position:0 -1900px;}.yui-skin-sam .yui-simple-dialog .bd span.tipicon{background-position:0 -1250px;}.yui-skin-sam .yui-tt .bd{position:relative;top:0;left:0;z-index:1;color:#000;padding:2px 5px;border-color:#D4C237 #A6982B #A6982B #A6982B;border-width:1px;border-style:solid;background-color:#FFEE69;}.yui-skin-sam .yui-tt.show-scrollbars .bd{overflow:auto;}.yui-skin-sam .yui-tt-shadow{top:2px;right:-3px;left:-3px;bottom:-3px;background-color:#000;}.yui-skin-sam .yui-tt-shadow-visible{opacity:.12;*filter:alpha(opacity=12);}
+.yui-dt{border-bottom:1px solid transparent;}.yui-dt-noop{border-bottom:none;}.yui-dt-hd{display:none;}.yui-dt-scrollable .yui-dt-hd{display:block;}.yui-dt-scrollable .yui-dt-bd thead tr,.yui-dt-scrollable .yui-dt-bd thead th{position:absolute;left:-1500px;}.yui-dt-scrollable tbody{-moz-outline:none;}.yui-dt-draggable{cursor:move;}.yui-dt-coltarget{position:absolute;z-index:999;}.yui-dt-hd{zoom:1;}th.yui-dt-resizeable .yui-dt-liner{position:relative;}.yui-dt-resizer{position:absolute;right:0;bottom:0;height:100%;cursor:e-resize;cursor:col-resize;}.yui-dt-resizerproxy{visibility:hidden;position:absolute;z-index:9000;}.yui-skin-sam th.yui-dt-hidden .yui-dt-liner,.yui-skin-sam td.yui-dt-hidden .yui-dt-liner{margin:0;padding:0;overflow:hidden;white-space:nowrap;}.yui-dt-scrollable .yui-dt-bd{overflow:auto;}.yui-dt-scrollable .yui-dt-hd{overflow:hidden;position:relative;}.yui-dt-editor{position:absolute;z-index:9000;}.yui-skin-sam .yui-dt table{margin:0;padding:0;font-family:ari!
 al;font-size:inherit;border-collapse:collapse;border-spacing:0;}.yui-skin-sam .yui-dt thead{border-spacing:0;}.yui-skin-sam .yui-dt caption{padding-bottom:1em;text-align:left;}.yui-skin-sam .yui-dt-hd table{border-left:1px solid #7F7F7F;border-top:1px solid #7F7F7F;border-right:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-bd table{border:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-scrollable .yui-dt-hd table{border:0px;}.yui-skin-sam .yui-dt-scrollable .yui-dt-bd table{border:0px;}.yui-skin-sam .yui-dt-scrollable .yui-dt-hd{border-left:1px solid #7F7F7F;border-top:1px solid #7F7F7F;border-right:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-scrollable .yui-dt-bd{border-left:1px solid #7F7F7F;border-bottom:1px solid #7F7F7F;border-right:1px solid #7F7F7F;}.yui-skin-sam .yui-dt th{background:#D8D8DA url(sprite.png) repeat-x 0 0;}.yui-skin-sam .yui-dt th,.yui-skin-sam .yui-dt th a{font-weight:normal;text-decoration:none;color:#000;vertical-align:bottom;}.yui-skin-sam .yui-dt th{margin:0;pa!
 dding:0;border:none;border-right:1px solid #CBCBCB;}.yui-skin-!
 sam .yui
-dt-liner{margin:0;padding:0;padding:4px 10px 4px 10px;}.yui-skin-sam .yui-dt-coltarget{width:5px;background-color:red;}.yui-skin-sam .yui-dt td{margin:0;padding:0;border:none;border-right:1px solid #CBCBCB;text-align:left;}.yui-skin-sam .yui-dt-list td{border-right:none;}.yui-skin-sam .yui-dt-resizer{width:6px;}.yui-skin-sam .yui-dt-loading{background-color:#FFF;}.yui-skin-sam .yui-dt-empty{background-color:#FFF;}.yui-skin-sam .yui-dt-error{background-color:#FFF;}.yui-skin-sam thead .yui-dt-sortable{cursor:pointer;}.yui-skin-sam th.yui-dt-asc,.yui-skin-sam th.yui-dt-desc{background:url(sprite.png) repeat-x 0 -100px;}.yui-skin-sam th.yui-dt-sortable .yui-dt-label{margin-right:10px;}.yui-skin-sam th.yui-dt-asc .yui-dt-liner{background:url(dt-arrow-up.png) no-repeat right;}.yui-skin-sam th.yui-dt-desc .yui-dt-liner{background:url(dt-arrow-dn.png) no-repeat right;}.yui-dt-editable{cursor:pointer;}.yui-dt-editor{text-align:left;background-color:#F2F2F2;border:1px solid #808080;p!
 adding:6px;}.yui-dt-editor label{padding-left:4px;padding-right:6px;}.yui-dt-editor .yui-dt-button{padding-top:6px;text-align:right;}.yui-dt-editor .yui-dt-button button{background:url(sprite.png) repeat-x 0 0;border:1px solid #999;width:4em;height:1.8em;margin-left:6px;}.yui-dt-editor .yui-dt-button button.yui-dt-default{background:url(sprite.png) repeat-x 0 -1400px;background-color:#5584E0;border:1px solid #304369;color:#FFF}.yui-dt-editor .yui-dt-button button:hover{background:url(sprite.png) repeat-x 0 -1300px;color:#000;}.yui-dt-editor .yui-dt-button button:active{background:url(sprite.png) repeat-x 0 -1700px;color:#000;}.yui-skin-sam tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam tr.yui-dt-odd{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam tr.yui-dt-even td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam tr.yui-dt-odd td.yui-dt-desc{background-color:#DBEAFF;}.yui-skin-sam .yui-dt-li!
 st tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam .yui-dt!
 -list tr
.yui-dt-odd{background-color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam th.yui-dt-highlighted,.yui-skin-sam th.yui-dt-highlighted a{background-color:#B2D2FF;}.yui-skin-sam tr.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam .yui-dt-list th.yui-dt-highlighted,.yui-skin-sam .yui-dt-list th.yui-dt-highlighted a{background-color:#B2D2FF;}.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-de!
 sc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam th.yui-dt-selected,.yui-skin-sam th.yui-dt-selected a{background-color:#446CD7;}.yui-skin-sam tr.yui-dt-selected td,.yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam tr.yui-dt-selected td.yui-dt-desc{background-color:#426FD9;color:#FFF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam tr.yui-dt-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}.yui-skin-sam .yui-dt-list th.yui-dt-selected,.yui-skin-sam .yui-dt-list th.yui-dt-selected a{background-color:#446CD7;}.yui-skin-sam .yui-dt-list tr.yui-dt-selected td,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc{background-color:#426FD9;color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam .yui-dt-list tr.yui-d!
 t-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}!
 .yui-ski
n-sam .yui-pg-container,.yui-skin-sam .yui-dt-paginator{display:block;margin:6px 0;white-space:nowrap;}.yui-skin-sam .yui-pg-first,.yui-skin-sam .yui-pg-last,.yui-skin-sam .yui-pg-current-page,.yui-skin-sam .yui-dt-first,.yui-skin-sam .yui-dt-paginator .yui-dt-last,.yui-skin-sam .yui-dt-paginator .yui-dt-selected{padding:2px 6px;}.yui-skin-sam a.yui-pg-first,.yui-skin-sam a.yui-pg-previous,.yui-skin-sam a.yui-pg-next,.yui-skin-sam a.yui-pg-last,.yui-skin-sam a.yui-pg-page,.yui-skin-sam .yui-dt-paginator a.yui-dt-first,.yui-skin-sam .yui-dt-paginator a.yui-dt-last{text-decoration:none;}.yui-skin-sam .yui-dt-paginator .yui-dt-previous,.yui-skin-sam .yui-dt-paginator .yui-dt-next{display:none;}.yui-skin-sam a.yui-pg-page,.yui-skin-sam a.yui-dt-page{border:1px solid #CBCBCB;padding:2px 6px;text-decoration:none;background-color:#fff}.yui-skin-sam .yui-pg-current-page,.yui-skin-sam .yui-dt-selected{border:1px solid #fff;background-color:#fff;}.yui-skin-sam .yui-pg-pages{margin-lef!
 t:1ex;margin-right:1ex;}.yui-skin-sam .yui-pg-page{margin-right:1px;margin-left:1px;}.yui-skin-sam .yui-pg-first,.yui-skin-sam .yui-pg-previous{margin-right:3px;}.yui-skin-sam .yui-pg-next,.yui-skin-sam .yui-pg-last{margin-left:3px;}.yui-skin-sam .yui-pg-current,.yui-skin-sam .yui-pg-rpp-options{margin-right:1em;margin-left:1em;}
+.yui-busy{cursor:wait !important;}.yui-toolbar-container fieldset{padding:0;margin:0;border:0;}.yui-toolbar-container legend{display:none;}.yui-toolbar-container .yui-toolbar-subcont{padding:.25em 0;zoom:1;}.yui-toolbar-container-collapsed .yui-toolbar-subcont{display:none;}.yui-toolbar-container .yui-toolbar-subcont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container span.yui-toolbar-draghandle{cursor:move;border-left:1px solid #999;border-right:1px solid #999;overflow:hidden;text-indent:77777px;width:2px;height:20px;display:block;clear:none;float:left;margin:0 0 0 .2em;}.yui-toolbar-container .yui-toolbar-titlebar.draggable{cursor:move;}.yui-toolbar-container .yui-toolbar-titlebar{position:relative;}.yui-toolbar-container .yui-toolbar-titlebar h2{font-weight:bold;letter-spacing:0;border:none;color:#000;margin:0;padding:.2em;}.yui-toolbar-container .yui-toolbar-titlebar h2 a{text-decoration:none;color:#000;cursor:default;}.yui-tool!
 bar-container.yui-toolbar-grouped span.yui-toolbar-draghandle{height:40px;}.yui-toolbar-container .yui-toolbar-group{float:left;zoom:1;}.yui-toolbar-container .yui-toolbar-group:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container .yui-toolbar-group h3{font-size:75%;padding:0 0 0 .25em;margin:0;}.yui-toolbar-container span.yui-toolbar-separator{width:2px;height:18px;margin:.2em 0 .2em .1em;display:block;clear:none;float:left;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-separator{height:35px;}.yui-toolbar-container.yui-toolbar-grouped .yui-toolbar-group span.yui-toolbar-separator{height:18px;}.yui-toolbar-container ul li{margin:0;padding:0;list-style-type:none;}.yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-toolbar-container .yui-push-button,.yui-toolbar-container .yui-color-button,.yui-toolbar-container .yui-menu-button{position:relative;cursor:pointer;}.yui-toolbar-container .yui-button .firs!
 t-child,.yui-toolbar-container .yui-button .first-child a{heig!
 ht:100%;
width:100%;overflow:hidden;}.yui-toolbar-container .yui-button-disabled{cursor:default;}.yui-toolbar-container .yui-button-disabled .yui-toolbar-icon{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button-disabled .up,.yui-toolbar-container .yui-button-disabled .down{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button a{overflow:hidden;}.yui-toolbar-container .yui-toolbar-select .first-child a{cursor:pointer;}.yui-toolbar-fontname-arial{font-family:Arial;}.yui-toolbar-fontname-arial-black{font-family:Arial Black;}.yui-toolbar-fontname-comic-sans-ms{font-family:Comic Sans MS;}.yui-toolbar-fontname-courier-new{font-family:Courier New;}.yui-toolbar-fontname-times-new-roman{font-family:Times New Roman;}.yui-toolbar-fontname-verdana{font-family:Verdana;}.yui-toolbar-fontname-impact{font-family:Impact;}.yui-toolbar-fontname-lucida-console{font-family:Lucida Console;}.yui-toolbar-fontname-tahoma{font-family:Tahoma;}.yui-toolbar-fontname-trebuche!
 t-ms{font-family:Trebuchet MS;}.yui-toolbar-container .yui-toolbar-spinbutton{position:relative;}.yui-toolbar-container .yui-toolbar-spinbutton .first-child a{z-index:0;opacity:1;}.yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-toolbar-container .yui-toolbar-spinbutton a.down{position:absolute;display:block right:0;cursor:pointer;z-index:1;padding:0;margin:0;}.yui-toolbar-container .yui-overlay{position:absolute;}.yui-toolbar-container .yui-overlay ul li{margin:0;list-style-type:none;}.yui-toolbar-container{z-index:1;}.yui-editor-container .yui-editor-editable-container{position:relative;z-index:0;width:100%;}.yui-editor-container .yui-editor-masked{background-color:#CCC;}.yui-editor-container iframe{border:0px;padding:0;margin:0;zoom:1;display:block;}.yui-editor-container .yui-editor-editable{padding:0;margin:0;}.yui-editor-container .dompath{font-size:85%;}.yui-editor-panel .hd{text-align:left;position:relative;}.yui-editor-panel .hd h3{font-weight:bold;padding:0!
 .25em 0pt 0.25em 0.25em;margin:0;}.yui-editor-panel .bd{width:!
 100%;zoo
m:1;position:relative;}.yui-editor-panel .bd div.yui-editor-body-cont{padding:.25em .1em;zoom:1;}.yui-editor-panel .bd div.yui-editor-body-cont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-editor-panel .ft{text-align:right;width:99%;float:left;clear:both;}.yui-editor-panel .ft span.tip{display:block;position:relative;padding:.5em .5em .5em 23px;text-align:left;zoom:1;}.yui-editor-panel label{clear:both;float:left;padding:0;width:100%;text-align:left;zoom:1;}.yui-editor-panel .gecko label{overflow:auto;}.yui-editor-panel label strong{float:left;width:6em;}.yui-editor-panel .removeLink{width:80%;text-align:right;}.yui-editor-panel label input{margin-left:.25em;float:left;}.yui-editor-panel .yui-toolbar-group-padding{}.yui-editor-panel .yui-toolbar-group-border{}.yui-editor-panel .yui-toolbar-group-textflow{}.yui-editor-panel .height-width{float:left;}.yui-editor-panel .height-width h3{}.yui-editor-panel .height-width span{font-style:italic;displa!
 y:block;float:left;overflow:auto;}.yui-editor-panel .height-width span.info{font-size:70%;}.yui-editor-panel .yui-toolbar-bordersize,.yui-editor-panel .yui-toolbar-bordertype{font-size:75%;}.yui-editor-panel .yui-toolbar-container span.yui-toolbar-separator{border:none;}.yui-editor-panel .yui-toolbar-bordersize span a span,.yui-editor-panel .yui-toolbar-bordertype span a span{display:block;height:8px;left:4px;position:absolute;top:3px;*top:-5px;width:24px;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-solid{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dotted{border-bottom:1px dotted black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dashed{border-bottom:1px dashed black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-0{*top:0px;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-1{border-bottom!
 :1px solid black;}.yui-editor-panel .yui-toolbar-bordersize sp!
 an a spa
n.yui-toolbar-bordersize-2{border-bottom:2px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-3{top:2px;*top:-5px;border-bottom:3px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-4{top:1px;*top:-5px;border-bottom:4px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-5{top:1px;*top:-5px;border-bottom:5px solid black;}.yui-toolbar-container .yui-toolbar-bordersize-menu,.yui-toolbar-container .yui-toolbar-bordertype-menu{width:95px !important;}.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel,.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel:hover{margin:0px 3px 7px 17px;}.yui-toolbar-bordersize-menu .yuimenuitemlabel .checkedindicator,.yui-toolbar-bordertype-menu .yuimenuitemlabel .checkedindicator{position:absolute;left:-12px;*top:14px;*left:0px;}.yui-toolbar-bordersi!
 ze-menu li.yui-toolbar-bordersize-1 a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-2 a{border-bottom:2px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-3 a{border-bottom:3px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-4 a{border-bottom:4px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-5 a{border-bottom:5px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-solid a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dashed a{border-bottom:1px dashed black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dotted a{border-bottom:1px dotted black;height:14px;}h2.yui-editor-skipheader,h3.yui-editor-skipheader{height:0;margin:0;padding:0;border:none;width:0;overflow:hidden;position:absolute;}.yui-toolbar-colors{width:133px;zoom:1;displ!
 ay:none;z-index:100;overflow:hidden;}.yui-toolbar-colors:after!
 {display
:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors a{height:9px;width:9px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0;cursor:pointer;border:1px solid #F6F7EE;}.yui-toolbar-colors a:hover{border:1px solid black;}.yui-color-button-menu{overflow:visible;background-color:transparent;}.yui-toolbar-colors span{position:relative;display:block;padding:3px;overflow:hidden;float:left;width:100%;zoom:1;}.yui-toolbar-colors span:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors span em{height:35px;width:30px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0.75px;border:1px solid black;}.yui-toolbar-colors span strong{font-weight:normal;padding-left:3px;display:block;font-size:85%;float:left;width:65%;}.yui-skin-sam .yui-editor-container{border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container{zoom:1;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar{background:url!
 (sprite.png) repeat-x 0 -200px;position:relative;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar h2{color:#000000;font-weight:bold;margin:0;padding:0.3em 1em;font-size:100%;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-group h3{color:#808080;font-size:75%;margin:1em 0 0;padding-bottom:0;padding-left:0.25em;text-align:left;}.yui-toolbar-container span.yui-toolbar-separator{border:none;text-indent:33px;overflow:hidden;margin:.25em;}.yui-skin-sam .yui-toolbar-container{background-color:#F2F2F2;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subcont{padding:0 1em 0.35em;border-bottom:1px solid #808080;}.yui-skin-sam .yui-toolbar-container-collapsed .yui-toolbar-titlebar{border-bottom:1px solid #808080;}.yui-skin-sam .yui-editor-container .visible .yui-menu-shadow,.yui-skin-sam .yui-editor-panel .visible .yui-menu-shadow{display:none;}.yui-skin-sam .yui-editor-container ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-cont!
 ainer ul li{list-style-type:none;margin:0;padding:0;}.yui-skin!
 -sam .yu
i-toolbar-group ul li.yui-toolbar-groupitem{float:left;}.yui-skin-sam .yui-editor-container .dompath{background-color:#F2F2F2;border-top:1px solid #808080;color:#999;text-align:left;padding:0.25em;}.yui-skin-sam .yui-toolbar-container .collapse{background:url(sprite.png) no-repeat 0 -400px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar span.collapse{cursor:pointer;position:absolute;top:4px;right:2px;display:block;overflow:hidden;height:15px;width:15px;text-indent:9999px;}.yui-skin-sam .yui-toolbar-container .yui-push-button,.yui-skin-sam .yui-toolbar-container .yui-color-button,.yui-skin-sam .yui-toolbar-container .yui-menu-button{background:url(sprite.png) repeat-x 0 0;position:relative;display:block;height:22px;width:30px;margin:0;border-color:#808080;border-style:solid;border-width:1px 0;}.yui-skin-sam .yui-toolbar-container .yui-push-button a,.yui-skin-sam .yui-toolbar-container .yui-color-button a,.yui-skin-sam .yui-toolbar-container .yui-menu-button a{padd!
 ing-left:35px;height:20px;text-decoration:none;font-size:93%;line-height:2;display:block;color:#000000;overflow:hidden;}.yui-skin-sam .yui-toolbar-container .yui-push-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button .first-child{border-color:#808080;border-style:solid;border-width:0 1px;margin:0 -1px;display:block;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled,.yui-skin-sam .yui-toolbar-container .yui!
 -color-button-disabled,.yui-skin-sam .yui-toolbar-container .y!
 ui-menu-
button-disabled{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-button .first-child{*left:0px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-fontname{width:135px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-heading{width:92px;}.yui-skin-sam .yui-toolbar-container .yui-button-hover{background:url(sprite.png) repeat-x 0 -1300px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-button-selected{background:url(sprite.png) repeat-x 0 -1700px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels .yui-toolbar-group{margin-top:.75em;}.yui-skin-sam .yui-toolbar-container .yui-push-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-color-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-menu-button span.yui-toolbar-icon{display:block;position:absolute;top:2px;height:18px;width:18px;overflow:hidden;!
 background:url(editor-sprite.gif) no-repeat 30px 30px;}.yui-skin-sam .yui-toolbar-container .yui-button-selected span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-button-hover span.yui-toolbar-icon{background-image:url(editor-sprite-active.gif);}.yui-skin-sam .yui-toolbar-container .visible .yuimenuitemlabel{cursor:pointer;color:#000;*position:relative;}.yui-skin-sam .yui-toolbar-container .yui-button-menu{background-color:#fff;}.yui-skin-sam div.yuimenu li.selected{background-color:#B3D4FF;}.yui-skin-sam div.yuimenu li.selected a.selected{color:#000;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bold span.yui-toolbar-icon{background-position:0 0;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-italic span.yui-toolbar-icon{background-position:0 -36px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-underline span.yui-toolbar-icon{background-position:0 -72px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subscript span.yui!
 -toolbar-icon{background-position:0 -180px;left:5px;}.yui-skin!
 -sam .yu
i-toolbar-container .yui-toolbar-superscript span.yui-toolbar-icon{background-position:0 -144px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-forecolor span.yui-toolbar-icon{background-position:0 -216px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-backcolor span.yui-toolbar-icon{background-position:0 -288px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyleft span.yui-toolbar-icon{background-position:0 -324px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifycenter span.yui-toolbar-icon{background-position:0 -360px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyright span.yui-toolbar-icon{background-position:0 -396px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyfull span.yui-toolbar-icon{background-position:0 -432px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-indent span.yui-toolbar-icon{background-position:0 -720px;left:5px;}.yui-skin-sam .yui-toolbar-c!
 ontainer .yui-toolbar-outdent span.yui-toolbar-icon{background-position:0 -684px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-createlink span.yui-toolbar-icon{background-position:0 -792px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertimage span.yui-toolbar-icon{background-position:1px -756px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-left span.yui-toolbar-icon{background-position:0 -972px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-right span.yui-toolbar-icon{background-position:0 -936px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-inline span.yui-toolbar-icon{background-position:0 -900px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-block span.yui-toolbar-icon{background-position:0 -864px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bordercolor span.yui-toolbar-icon{background-position:0 -252px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-removefor!
 mat span.yui-toolbar-icon{background-position:0 -1080px;left:5!
 px;}.yui
-skin-sam .yui-toolbar-container .yui-toolbar-hiddenelements span.yui-toolbar-icon{background-position:0 -1044px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertunorderedlist span.yui-toolbar-icon{background-position:0 -468px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertorderedlist span.yui-toolbar-icon{background-position:0 -504px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child{width:35px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child a{padding-left:2px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton span.yui-toolbar-icon{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{right:2px;background:url(editor-sprite.gif) no-repeat 0 -1222px;overflow:hidden;height:6px;width:7px;min-height:0;padd!
 ing:0;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up{top:2px;background-position:0 -1222px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{bottom:2px;background-position:0 -1187px;}.yui-skin-sam .yui-toolbar-container select{height:22px;border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select .first-child a{padding-left:5px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select span.yui-toolbar-icon{background:url( editor-sprite.gif ) no-repeat 0 -1144px;overflow:hidden;right:-2px;top:0px;height:20px;}.yui-skin-sam .yui-editor-panel .yui-color-button-menu .bd{background-color:transparent;border:none;width:135px;}.yui-skin-sam .yui-color-button-menu .yui-toolbar-colors{border:1px solid #808080;}.yui-skin-sam .yui-editor-panel{padding:0;margin:0;border:none;background-color:transparent;overflow:visible;}.yui-skin-sam .yui-editor-panel .hd{margin:10px 0 0;padding:0;border:none;}.yui-skin-sam !
 .yui-editor-panel .hd h3{color:#000;border:1px solid #808080;b!
 ackgroun
d:url(sprite.png) repeat-x 0 -200px;width:99%;position:relative;margin:0;padding:3px 0 0 0;font-size:93%;text-indent:5px;height:20px;}.yui-skin-sam .yui-editor-panel .bd{background-color:#F2F2F2;border-left:1px solid #808080;border-right:1px solid #808080;width:99%;margin:0;padding:0;overflow:visible;}.yui-skin-sam .yui-editor-panel ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-panel ul li{margin:0;padding:0;}.yui-skin-sam .yui-editor-panel .yuimenu{}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .yui-toolbar-subcont{padding:0;border:none;margin-top:0.35em;}.yui-skin-sam .yui-editor-panel .yui-toolbar-bordersize,.yui-skin-sam .yui-editor-panel .yui-toolbar-bordertype{width:50px;}.yui-skin-sam .yui-editor-panel label{display:block;float:none;padding:4px 0;margin-bottom:7px;}.yui-skin-sam .yui-editor-panel label strong{font-weight:normal;font-size:93%;text-align:right;padding-top:2px;}.yui-skin-sam .yui-editor-panel label input{width:75%;}.yui-s!
 kin-sam .yui-editor-panel #createlink_target,.yui-skin-sam .yui-editor-panel #insertimage_target{width:auto;margin-right:5px;}.yui-skin-sam .yui-editor-panel .removeLink{width:98%;}.yui-skin-sam .yui-editor-panel label input.warning{background-color:#FFEE69;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group h3{color:#000;float:left;font-weight:normal;font-size:93%;margin:5px 0 0 0;padding:0 3px 0 0;text-align:right;}.yui-skin-sam .yui-editor-panel .height-width h3{margin:3px 0 0 10px;}.yui-skin-sam .yui-editor-panel .height-width{margin:3px 0 0 35px;*margin-left:14px;width:42%;*width:44%;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-border{width:190px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-border{width:210px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding{width:203px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-padding{width:172px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding h3{margin-left:25px;*mar!
 gin-left:12px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-gr!
 oup-text
flow{width:182px;}.yui-skin-sam .yui-editor-panel .hd{background:none;}.yui-skin-sam .yui-editor-panel .ft{background-color:#F2F2F2;border:1px solid #808080;border-top:none;padding:0;margin:0 0 2px 0;}.yui-skin-sam .yui-editor-panel .hd span.close{background:url(sprite.png) no-repeat 0 -300px;cursor:pointer;display:block;height:16px;overflow:hidden;position:absolute;right:5px;text-indent:500px;top:2px;width:26px;}.yui-skin-sam .yui-editor-panel .ft span.tip{background-color:#EDF5FF;border-top:1px solid #808080;font-size:85%;}.yui-skin-sam .yui-editor-panel .ft span.tip strong{display:block;float:left;margin:0 2px 8px 0;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon{background:url( editor-sprite.gif ) no-repeat 0 -1260px;display:block;height:20px;left:2px;position:absolute;top:8px;width:20px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-info{background-position:2px -1260px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-warn{background-position:2px !
 -1296px;}.yui-skin-sam .yui-editor-panel .hd span.knob{position:absolute;height:10px;width:28px;top:-10px;left:25px;text-indent:9999px;overflow:hidden;background:url( editor-knob.gif ) no-repeat 0 0;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container{float:left;width:100%;background-image:none;border:none;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .bd{background-color:#ffffff;}.yui-editor-blankimage{background-image:url( blankimage.png );}
+.yui-crop{position:relative;}.yui-crop .yui-crop-mask{position:absolute;top:0;left:0;height:100%;width:100%;}.yui-crop .yui-resize{position:absolute;top:10px;left:10px;}.yui-crop .yui-crop-resize-mask{position:absolute;top:0;left:0;height:100%;width:100%;background-position:-10px -10px;overflow:hidden;}.yui-skin-sam .yui-crop .yui-crop-mask{background-color:#000;opacity:.5;filter:alpha(opacity=50);}.yui-skin-sam .yui-crop .yui-resize{border:1px dashed #fff;}
+.yui-layout-loading{visibility:hidden;}body.yui-layout{overflow:hidden;position:relative;padding:0;margin:0;}.yui-layout-doc{position:relative;}.yui-layout-unit{height:50px;width:50px;padding:0;margin:0;float:none;z-index:0;overflow:hidden;}.yui-layout-unit-top{position:absolute;top:0;left:0;width:100%;}.yui-layout-unit-left{position:absolute;top:0;left:0;}.yui-layout-unit-right{position:absolute;top:0;right:0;}.yui-layout-unit-bottom{position:absolute;bottom:0;left:0;width:100%;}.yui-layout-unit-center{position:absolute;top:0;left:0;width:100%;}.yui-layout div.yui-layout-hd{position:absolute;top:0;left:0;zoom:1;width:100%;overflow:hidden;}.yui-layout div.yui-layout-bd{position:absolute;top:0;left:0;zoom:1;width:100%;overflow:hidden;}.yui-layout .yui-layout-scroll div.yui-layout-bd{overflow:auto;}.yui-layout div.yui-layout-ft{position:absolute;bottom:0;left:0;width:100%;zoom:1;overflow:hidden;}.yui-layout .yui-layout-unit div.yui-layout-hd h2{text-align:left;}.yui-layout .y!
 ui-layout-unit div.yui-layout-hd .collapse{cursor:pointer;height:13px;position:absolute;right:2px;top:2px;width:17px;font-size:0;}.yui-layout .yui-layout-unit div.yui-layout-hd .close{cursor:pointer;height:13px;position:absolute;right:2px;top:2px;width:17px;font-size:0;}.yui-layout .yui-layout-unit div.yui-layout-hd .collapse-close{right:25px;}.yui-layout .yui-layout-clip{position:absolute;height:20px;background-color:#c0c0c0;display:none;}.yui-layout .yui-layout-clip .collapse{cursor:pointer;height:13px;position:absolute;right:2px;top:2px;width:17px;font-size:0px;}.yui-layout .yui-layout-wrap{height:100%;width:100%;position:absolute;left:0;}.yui-layout .yui-layout-unit .yui-content{overflow:hidden;}.yui-layout .yui-layout-unit .yui-layout-scroll{overflow:auto;}.yui-skin-sam .yui-layout .yui-resize-proxy{border:none;font-size:0;margin:0;padding:0;}.yui-skin-sam .yui-layout .yui-resize-resizing .yui-resize-handle{opacity:0;filter:alpha(opacity=0);}.yui-skin-sam .yui-layout .!
 yui-resize-proxy div{position:absolute;border:1px solid #80808!
 0;backgr
ound-color:#EDF5FF;}.yui-skin-sam .yui-layout .yui-resize .yui-resize-handle-active{background-color:#EDF5FF;}.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-l{width:5px;height:100%;top:0;left:0;}.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-r{width:5px;top:0;right:0;height:100%;}.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-b{width:100%;bottom:0;left:0;height:5px;}.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-t{width:100%;top:0;left:0;height:5px;}.yui-skin-sam .yui-layout .yui-layout-unit-left div.yui-layout-hd .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -160px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip-left .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -140px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit-right div.yui-layout-hd .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -200px;b!
 order:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip-right .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -120px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit-top div.yui-layout-hd .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -220px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip-top .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -240px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit-bottom div.yui-layout-hd .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -260px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip-bottom .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -180px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-hd .close{background:transparent url(layout_sprite.png) no-repeat -20px -100px;border:1px solid #8080!
 80;}.yui-skin-sam .yui-layout .yui-layout-hd{background:url(sp!
 rite.png
) repeat-x 0 -1400px;border:1px solid #808080;}.yui-skin-sam .yui-layout{background-color:#EDF5FF;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-hd h2{font-weight:bold;color:#fff;padding:3px;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd{border:1px solid #808080;border-bottom:none;border-top:none;*border-bottom-width:0;*border-top-width:0;background-color:#f2f2f2;text-align:left;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd-noft{border-bottom:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd-nohd{border-top:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip{position:absolute;height:20px;background-color:#EDF5FF;display:none;border:1px solid #808080;}.yui-skin-sam .yui-layout div.yui-layout-ft{border:1px solid #808080;border-top:none;*border-top-width:0;background-color:#f2f2f2;}.yui-skin-sam .yui-layout-unit .yui-resize-handle{background-color:transparent;}.yui-skin-sam .yui-layout-unit .yui-!
 resize-handle-r{right:0;top:0;background-image:none;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-l{left:0;top:0;background-image:none;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-b{right:0;bottom:0;background-image:none;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-t{right:0;top:0;background-image:none;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-r .yui-layout-resize-knob,.yui-skin-sam .yui-layout-unit .yui-resize-handle-l .yui-layout-resize-knob{position:absolute;height:16px;width:6px;top:45%;left:0px;background:transparent url(layout_sprite.png) no-repeat 0 -5px;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-t .yui-layout-resize-knob,.yui-skin-sam .yui-layout-unit .yui-resize-handle-b .yui-layout-resize-knob{position:absolute;height:6px;width:16px;left:45%;background:transparent url(layout_sprite.png) no-repeat -20px 0;}
 .yui-skin-sam .yui-log{padding:1em;width:31em;background-color:#AAA;color:#000;border:1px solid black;font-family:monospace;font-size:77%;text-align:left;z-index:9000;}.yui-skin-sam .yui-log-container{position:absolute;top:1em;right:1em;}.yui-skin-sam .yui-log input{margin:0;padding:0;font-family:arial;font-size:100%;font-weight:normal;}.yui-skin-sam .yui-log .yui-log-btns{position:relative;float:right;bottom:.25em;}.yui-skin-sam .yui-log .yui-log-hd{margin-top:1em;padding:.5em;background-color:#575757;}.yui-skin-sam .yui-log .yui-log-hd h4{margin:0;padding:0;font-size:108%;font-weight:bold;color:#FFF;}.yui-skin-sam .yui-log .yui-log-bd{width:100%;height:20em;background-color:#FFF;border:1px solid gray;overflow:auto;}.yui-skin-sam .yui-log p{margin:1px;padding:.1em;}.yui-skin-sam .yui-log pre{margin:0;padding:0;}.yui-skin-sam .yui-log pre.yui-log-verbose{white-space:pre-wrap;white-space:-moz-pre-wrap !important;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-w!
 ord;}.yui-skin-sam .yui-log .yui-log-ft{margin-top:.5em;}.yui-skin-sam .yui-log .yui-log-ft .yui-log-categoryfilters{}.yui-skin-sam .yui-log .yui-log-ft .yui-log-sourcefilters{width:100%;border-top:1px solid #575757;margin-top:.75em;padding-top:.75em;}.yui-skin-sam .yui-log .yui-log-filtergrp{margin-right:.5em;}.yui-skin-sam .yui-log .info{background-color:#A7CC25;}.yui-skin-sam .yui-log .warn{background-color:#F58516;}.yui-skin-sam .yui-log .error{background-color:#E32F0B;}.yui-skin-sam .yui-log .time{background-color:#A6C9D7;}.yui-skin-sam .yui-log .window{background-color:#F2E886;}
-.yuimenubar{visibility:visible;position:static;}.yuimenu .yuimenu,.yuimenubar .yuimenu{visibility:hidden;position:absolute;top:-10000px;left:-10000px;}.yuimenubar li,.yuimenu li{list-style-type:none;}.yuimenubar ul,.yuimenu ul,.yuimenubar li,.yuimenu li,.yuimenu h6,.yuimenubar h6{margin:0;padding:0;}.yuimenuitemlabel,.yuimenubaritemlabel{text-align:left;white-space:nowrap;}.yuimenubar ul{*zoom:1;}.yuimenubar .yuimenu ul{*zoom:normal;}.yuimenubar>.bd>ul:after{content:".";display:block;clear:both;visibility:hidden;height:0;line-height:0;}.yuimenubaritem{float:left;}.yuimenubaritemlabel,.yuimenuitemlabel{display:block;}.yuimenuitemlabel .helptext{font-style:normal;display:block;margin:-1em 0 0 10em;}.yui-menu-shadow{position:absolute;visibility:hidden;z-index:-1;}.yui-skin-sam .yui-menu-shadow-visible{top:2px;right:-3px;left:-3px;bottom:-3px;visibility:visible;}.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.yuimenu.show-scrollbars,.yuimenubar.show-s!
 crollbars{overflow:visible;}.yuimenu.hide-scrollbars .yui-menu-shadow,.yuimenubar.hide-scrollbars .yui-menu-shadow{overflow:hidden;}.yuimenu.show-scrollbars .yui-menu-shadow,.yuimenubar.show-scrollbars .yui-menu-shadow{overflow:auto;}.yui-skin-sam .yuimenubar{font-size:93%;line-height:2;*line-height:1.9;border:solid 1px #808080;background:url(sprite.png) repeat-x 0 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritem{border-right:solid 1px #ccc;}.yui-skin-sam .yuimenubaritemlabel{padding:0 10px;color:#000;text-decoration:none;cursor:default;border-style:solid;border-color:#808080;border-width:1px 0;*position:relative;margin:-1px 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel{padding-right:20px;*display:inline-block;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu{background:url(menubaritem_submenuindicator.png) right center no-repeat;}.yui-skin-sam .yuimenubaritem-selected{background:url(sprite.png) repeat-x 0 -1700px;}.yui-skin-sam .yuimenubaritemlabel-select!
 ed{border-color:#7D98B8;}.yui-skin-sam .yuimenubarnav .yuimenu!
 bariteml
abel-selected{border-left-width:1px;margin-left:-1px;*left:-1px;}.yui-skin-sam .yuimenubaritemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu-disabled{background-image:url(menubaritem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenu{font-size:93%;line-height:1.5;*line-height:1.45;}.yui-skin-sam .yuimenubar .yuimenu,.yui-skin-sam .yuimenu .yuimenu{font-size:100%;}.yui-skin-sam .yuimenu .bd{border:solid 1px #808080;background-color:#fff;}.yui-skin-sam .yuimenu ul{padding:3px 0;border-width:1px 0 0 0;border-color:#ccc;border-style:solid;}.yui-skin-sam .yuimenu ul.first-of-type{border-width:0;}.yui-skin-sam .yuimenu h6{font-weight:bold;border-style:solid;border-color:#ccc;border-width:1px 0 0 0;color:#a4a4a4;padding:3px 10px 0 10px;}.yui-skin-sam .yuimenu ul.hastitle,.yui-skin-sam .yuimenu h6.first-of-type{border-width:0;}.yui-skin-sam .yuimenu .yui-menu-body-scrolled{border-color:#ccc #808080;overflow:hidden;}.yui-!
 skin-sam .yuimenu .topscrollbar,.yui-skin-sam .yuimenu .bottomscrollbar{height:16px;border:solid 1px #808080;background:#fff url(sprite.png) no-repeat 0 0;}.yui-skin-sam .yuimenu .topscrollbar{border-bottom-width:0;background-position:center -950px;}.yui-skin-sam .yuimenu .topscrollbar_disabled{background-position:center -975px;}.yui-skin-sam .yuimenu .bottomscrollbar{border-top-width:0;background-position:center -850px;}.yui-skin-sam .yuimenu .bottomscrollbar_disabled{background-position:center -875px;}.yui-skin-sam .yuimenuitem{_border-bottom:solid 1px #fff;}.yui-skin-sam .yuimenuitemlabel{padding:0 20px;color:#000;text-decoration:none;cursor:default;}.yui-skin-sam .yuimenuitemlabel .helptext{margin-top:-1.5em;*margin-top:-1.45em;}.yui-skin-sam .yuimenuitem-hassubmenu{background-image:url(menuitem_submenuindicator.png);background-position:right center;background-repeat:no-repeat;}.yui-skin-sam .yuimenuitem-checked{background-image:url(menuitem_checkbox.png);background-pos!
 ition:left center;background-repeat:no-repeat;}.yui-skin-sam .!
 yui-menu
-shadow-visible{background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yuimenuitem-selected{background-color:#B3D4FF;}.yui-skin-sam .yuimenuitemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenuitem-hassubmenu-disabled{background-image:url(menuitem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenuitem-checked-disabled{background-image:url(menuitem_checkbox_disabled.png);}
-.yui-busy{cursor:wait !important;}.yui-toolbar-container .yui-toolbar-subcont{padding:.25em 0;zoom:1;}.yui-toolbar-container-collapsed .yui-toolbar-subcont{display:none;}.yui-toolbar-container .yui-toolbar-subcont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container span.yui-toolbar-draghandle{cursor:move;border-left:1px solid #999;border-right:1px solid #999;overflow:hidden;text-indent:77777px;width:2px;height:20px;display:block;clear:none;float:left;margin:0 0 0 .2em;}.yui-toolbar-container .yui-toolbar-titlebar.draggable{cursor:move;}.yui-toolbar-container .yui-toolbar-titlebar{position:relative;}.yui-toolbar-container .yui-toolbar-titlebar h2{font-weight:bold;letter-spacing:0;border:none;color:#000;margin:0;padding:.2em;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-draghandle{height:40px;}.yui-toolbar-container .yui-toolbar-group{float:left;zoom:1;}.yui-toolbar-container .yui-toolbar-group:after{display:block;clear!
 :both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container .yui-toolbar-group h3{font-size:75%;padding:0 0 0 .25em;margin:0;}.yui-toolbar-container span.yui-toolbar-separator{width:2px;height:18px;margin:.2em 0 .2em .1em;display:block;clear:none;float:left;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-separator{height:35px;}.yui-toolbar-container.yui-toolbar-grouped .yui-toolbar-group span.yui-toolbar-separator{height:18px;}.yui-toolbar-container ul li{margin:0;padding:0;list-style-type:none;}.yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-toolbar-container .yui-push-button,.yui-toolbar-container .yui-color-button,.yui-toolbar-container .yui-menu-button{position:relative;cursor:pointer;}.yui-toolbar-container .yui-button .first-child,.yui-toolbar-container .yui-button .first-child a{height:100%;width:100%;overflow:hidden;}.yui-toolbar-container .yui-button-disabled{cursor:default;}.yui-toolbar-container .yui-button-disabled .!
 yui-toolbar-icon{opacity:.5;filter:alpha(opacity=50);}.yui-too!
 lbar-con
tainer .yui-button-disabled .up,.yui-toolbar-container .yui-button-disabled .down{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button a{overflow:hidden;}.yui-toolbar-container .yui-toolbar-select .first-child a{cursor:pointer;}.yui-toolbar-fontname-arial{font-family:Arial;}.yui-toolbar-fontname-arial-black{font-family:Arial Black;}.yui-toolbar-fontname-comic-sans-ms{font-family:Comic Sans MS;}.yui-toolbar-fontname-courier-new{font-family:Courier New;}.yui-toolbar-fontname-times-new-roman{font-family:Times New Roman;}.yui-toolbar-fontname-verdana{font-family:Verdana;}.yui-toolbar-fontname-impact{font-family:Impact;}.yui-toolbar-fontname-lucida-console{font-family:Lucida Console;}.yui-toolbar-fontname-tahoma{font-family:Tahoma;}.yui-toolbar-fontname-trebuchet-ms{font-family:Trebuchet MS;}.yui-toolbar-container .yui-toolbar-spinbutton{position:relative;}.yui-toolbar-container .yui-toolbar-spinbutton .first-child a{z-index:0;opacity:1;}.yui-toolbar-container !
 .yui-toolbar-spinbutton a.up,.yui-toolbar-container .yui-toolbar-spinbutton a.down{position:absolute;display:block right:0;cursor:pointer;z-index:1;padding:0;margin:0;}.yui-toolbar-container .yui-overlay{position:absolute;}.yui-toolbar-container .yui-overlay ul li{margin:0;list-style-type:none;}.yui-toolbar-container{z-index:1;}.yui-editor-container .yui-editor-editable-container{position:relative;z-index:0;width:100%;}.yui-editor-container .yui-editor-masked{background-color:#CCC;}.yui-editor-container iframe{border:0px;padding:0;margin:0;zoom:1;display:block;}.yui-editor-container .yui-editor-editable{padding:0;margin:0;}.yui-editor-container .dompath{font-size:85%;}.yui-editor-panel .hd{text-align:left;position:relative;}.yui-editor-panel .hd h3{font-weight:bold;padding:0.25em 0pt 0.25em 0.25em;margin:0;}.yui-editor-panel .bd{width:100%;zoom:1;position:relative;}.yui-editor-panel .bd div.yui-editor-body-cont{padding:.25em .1em;zoom:1;}.yui-editor-panel .bd div.yui-editor!
 -body-cont:after{display:block;clear:both;visibility:hidden;co!
 ntent:'.
';height:0;}.yui-editor-panel .ft{text-align:right;width:99%;float:left;clear:both;}.yui-editor-panel .ft span.tip{display:block;position:relative;padding:.5em .5em .5em 23px;text-align:left;zoom:1;}.yui-editor-panel label{clear:both;float:left;padding:0;width:100%;text-align:left;zoom:1;}.yui-editor-panel .gecko label{overflow:auto;}.yui-editor-panel label strong{float:left;width:6em;}.yui-editor-panel .removeLink{width:80%;text-align:right;}.yui-editor-panel label input{margin-left:.25em;float:left;}.yui-editor-panel .yui-toolbar-group-padding{}.yui-editor-panel .yui-toolbar-group-border{}.yui-editor-panel .yui-toolbar-group-textflow{}.yui-editor-panel .height-width{float:left;}.yui-editor-panel .height-width h3{}.yui-editor-panel .height-width span{font-style:italic;display:block;float:left;overflow:auto;}.yui-editor-panel .height-width span.info{font-size:70%;}.yui-editor-panel .yui-toolbar-bordersize,.yui-editor-panel .yui-toolbar-bordertype{font-size:75%;}.yui-editor-p!
 anel .yui-toolbar-container span.yui-toolbar-separator{border:none;}.yui-editor-panel .yui-toolbar-bordersize span a span,.yui-editor-panel .yui-toolbar-bordertype span a span{display:block;height:8px;left:4px;position:absolute;top:3px;*top:-5px;width:24px;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-solid{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dotted{border-bottom:1px dotted black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dashed{border-bottom:1px dashed black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-0{*top:0px;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-1{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-2{border-bottom:2px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersiz!
 e-3{top:2px;*top:-5px;border-bottom:3px solid black;}.yui-edit!
 or-panel
 .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-4{top:1px;*top:-5px;border-bottom:4px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-5{top:1px;*top:-5px;border-bottom:5px solid black;}.yui-toolbar-container .yui-toolbar-bordersize-menu,.yui-toolbar-container .yui-toolbar-bordertype-menu{width:95px !important;}.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel,.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel:hover{margin:0px 3px 7px 17px;}.yui-toolbar-bordersize-menu .yuimenuitemlabel .checkedindicator,.yui-toolbar-bordertype-menu .yuimenuitemlabel .checkedindicator{position:absolute;left:-12px;*top:14px;*left:0px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-1 a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-2 a{border-bottom:2px solid black;height:14px;}.yui-toolbar-borders!
 ize-menu li.yui-toolbar-bordersize-3 a{border-bottom:3px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-4 a{border-bottom:4px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-5 a{border-bottom:5px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-solid a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dashed a{border-bottom:1px dashed black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dotted a{border-bottom:1px dotted black;height:14px;}h2.yui-editor-skipheader,h3.yui-editor-skipheader{height:0;margin:0;padding:0;border:none;width:0;overflow:hidden;position:absolute;}.yui-toolbar-colors{width:133px;zoom:1;display:none;z-index:100;overflow:hidden;}.yui-toolbar-colors:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors a{height:9px;width:9px;float:left;display:block;overflo!
 w:hidden;text-indent:999px;margin:0;cursor:pointer;border:1px !
 solid #F
6F7EE;}.yui-toolbar-colors a:hover{border:1px solid black;}.yui-color-button-menu{overflow:visible;background-color:transparent;}.yui-toolbar-colors span{position:relative;display:block;padding:3px;overflow:hidden;float:left;width:100%;zoom:1;}.yui-toolbar-colors span:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors span em{height:35px;width:30px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0.75px;border:1px solid black;}.yui-toolbar-colors span strong{font-weight:normal;padding-left:3px;display:block;font-size:85%;float:left;width:65%;}.yui-skin-sam .yui-editor-container{border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container{zoom:1;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar{background:url(sprite.png) repeat-x 0 -200px;position:relative;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar h2{color:#000000;font-weight:bold;margin:0;padding:0.3em 1em;font-size:100%;text-align:left;}.!
 yui-skin-sam .yui-toolbar-container .yui-toolbar-group h3{color:#808080;font-size:75%;margin:1em 0 0;padding-bottom:0;padding-left:0.25em;text-align:left;}.yui-toolbar-container span.yui-toolbar-separator{border:none;text-indent:33px;overflow:hidden;margin:.25em;}.yui-skin-sam .yui-toolbar-container{background-color:#F2F2F2;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subcont{padding:0 1em 0.35em;border-bottom:1px solid #808080;}.yui-skin-sam .yui-toolbar-container-collapsed .yui-toolbar-titlebar{border-bottom:1px solid #808080;}.yui-skin-sam .yui-editor-container .visible .yui-menu-shadow,.yui-skin-sam .yui-editor-panel .visible .yui-menu-shadow{display:none;}.yui-skin-sam .yui-editor-container ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-container ul li{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-toolbar-group ul li.yui-toolbar-groupitem{float:left;}.yui-skin-sam .yui-editor-container .dompath{background-color:#F2F2F2;border-!
 top:1px solid #808080;color:#999;text-align:left;padding:0.25e!
 m;}.yui-
skin-sam .yui-toolbar-container .collapse{background:url(sprite.png) no-repeat 0 -400px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar span.collapse{cursor:pointer;position:absolute;top:4px;right:2px;display:block;overflow:hidden;height:15px;width:15px;text-indent:9999px;}.yui-skin-sam .yui-toolbar-container .yui-push-button,.yui-skin-sam .yui-toolbar-container .yui-color-button,.yui-skin-sam .yui-toolbar-container .yui-menu-button{background:url(sprite.png) repeat-x 0 0;position:relative;display:block;height:22px;width:30px;margin:0;border-color:#808080;border-style:solid;border-width:1px 0;}.yui-skin-sam .yui-toolbar-container .yui-push-button a,.yui-skin-sam .yui-toolbar-container .yui-color-button a,.yui-skin-sam .yui-toolbar-container .yui-menu-button a{padding-left:35px;height:20px;text-decoration:none;font-size:93%;line-height:2;display:block;color:#000000;overflow:hidden;}.yui-skin-sam .yui-toolbar-container .yui-push-button .first-child,.yui-skin-sam .y!
 ui-toolbar-container .yui-color-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button .first-child{border-color:#808080;border-style:solid;border-width:0 1px;margin:0 -1px;display:block;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-button .first-child{*left:0px;}.yui-skin-sam .yui-toolba!
 r-container .yui-toolbar-fontname{width:135px;}.yui-skin-sam .!
 yui-tool
bar-container .yui-toolbar-heading{width:92px;}.yui-skin-sam .yui-toolbar-container .yui-button-hover{background:url(sprite.png) repeat-x 0 -1300px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-button-selected{background:url(sprite.png) repeat-x 0 -1700px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels .yui-toolbar-group{margin-top:.75em;}.yui-skin-sam .yui-toolbar-container .yui-push-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-color-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-menu-button span.yui-toolbar-icon{display:block;position:absolute;top:2px;height:18px;width:18px;overflow:hidden;background:url(editor-sprite.gif) no-repeat 30px 30px;}.yui-skin-sam .yui-toolbar-container .yui-button-selected span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-button-hover span.yui-tool!
 bar-icon{background-image:url(editor-sprite-active.gif);}.yui-skin-sam .yui-toolbar-container .visible .yuimenuitemlabel{cursor:pointer;color:#000;*position:relative;}.yui-skin-sam .yui-toolbar-container .yui-button-menu{background-color:#fff;}.yui-skin-sam div.yuimenu li.selected{background-color:#B3D4FF;}.yui-skin-sam div.yuimenu li.selected a.selected{color:#000;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bold span.yui-toolbar-icon{background-position:0 0;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-italic span.yui-toolbar-icon{background-position:0 -36px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-underline span.yui-toolbar-icon{background-position:0 -72px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subscript span.yui-toolbar-icon{background-position:0 -180px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-superscript span.yui-toolbar-icon{background-position:0 -144px;left:5px;}.yui-skin-sam .yui-toolbar-!
 container .yui-toolbar-forecolor span.yui-toolbar-icon{backgro!
 und-posi
tion:0 -216px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-backcolor span.yui-toolbar-icon{background-position:0 -288px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyleft span.yui-toolbar-icon{background-position:0 -324px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifycenter span.yui-toolbar-icon{background-position:0 -360px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyright span.yui-toolbar-icon{background-position:0 -396px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyfull span.yui-toolbar-icon{background-position:0 -432px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-indent span.yui-toolbar-icon{background-position:0 -720px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-outdent span.yui-toolbar-icon{background-position:0 -684px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-createlink span.yui-toolbar-icon{background-position:0 -792px;!
 left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertimage span.yui-toolbar-icon{background-position:1px -756px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-left span.yui-toolbar-icon{background-position:0 -972px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-right span.yui-toolbar-icon{background-position:0 -936px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-inline span.yui-toolbar-icon{background-position:0 -900px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-block span.yui-toolbar-icon{background-position:0 -864px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bordercolor span.yui-toolbar-icon{background-position:0 -252px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-removeformat span.yui-toolbar-icon{background-position:0 -1080px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-hiddenelements span.yui-toolbar-icon{background-position:0 -1044px;left:5px;}.yui-skin-!
 sam .yui-toolbar-container .yui-toolbar-insertunorderedlist sp!
 an.yui-t
oolbar-icon{background-position:0 -468px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertorderedlist span.yui-toolbar-icon{background-position:0 -504px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child{width:35px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child a{padding-left:2px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton span.yui-toolbar-icon{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{right:2px;background:url(editor-sprite.gif) no-repeat 0 -1222px;overflow:hidden;height:6px;width:7px;min-height:0;padding:0;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up{top:2px;background-position:0 -1222px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{bottom:2px;background-p!
 osition:0 -1187px;}.yui-skin-sam .yui-toolbar-container select{height:22px;border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select .first-child a{padding-left:5px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select span.yui-toolbar-icon{background:url( editor-sprite.gif ) no-repeat 0 -1144px;overflow:hidden;right:-2px;top:0px;height:20px;}.yui-skin-sam .yui-editor-panel .yui-color-button-menu .bd{background-color:transparent;border:none;width:135px;}.yui-skin-sam .yui-color-button-menu .yui-toolbar-colors{border:1px solid #808080;}.yui-skin-sam .yui-editor-panel{padding:0;margin:0;border:none;background-color:transparent;overflow:visible;}.yui-skin-sam .yui-editor-panel .hd{margin:10px 0 0;padding:0;border:none;}.yui-skin-sam .yui-editor-panel .hd h3{color:#000;border:1px solid #808080;background:url(sprite.png) repeat-x 0 -200px;width:99%;position:relative;margin:0;padding:3px 0 0 0;font-size:93%;text-indent:5px;height:20px;!
 }.yui-skin-sam .yui-editor-panel .bd{background-color:#F2F2F2;!
 border-l
eft:1px solid #808080;border-right:1px solid #808080;width:99%;margin:0;padding:0;overflow:visible;}.yui-skin-sam .yui-editor-panel ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-panel ul li{margin:0;padding:0;}.yui-skin-sam .yui-editor-panel .yuimenu{}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .yui-toolbar-subcont{padding:0;border:none;margin-top:0.35em;}.yui-skin-sam .yui-editor-panel .yui-toolbar-bordersize,.yui-skin-sam .yui-editor-panel .yui-toolbar-bordertype{width:50px;}.yui-skin-sam .yui-editor-panel label{display:block;float:none;padding:4px 0;margin-bottom:7px;}.yui-skin-sam .yui-editor-panel label strong{font-weight:normal;font-size:93%;text-align:right;padding-top:2px;}.yui-skin-sam .yui-editor-panel label input{width:75%;}.yui-skin-sam .yui-editor-panel #createlink_target,.yui-skin-sam .yui-editor-panel #insertimage_target{width:auto;margin-right:5px;}.yui-skin-sam .yui-editor-panel .removeLink{width:98%;}.yui-skin-sam .yui-edi!
 tor-panel label input.warning{background-color:#FFEE69;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group h3{color:#000;float:left;font-weight:normal;font-size:93%;margin:5px 0 0 0;padding:0 3px 0 0;text-align:right;}.yui-skin-sam .yui-editor-panel .height-width h3{margin:3px 0 0 10px;}.yui-skin-sam .yui-editor-panel .height-width{margin:3px 0 0 35px;*margin-left:14px;width:42%;*width:44%;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-border{width:190px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-border{width:210px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding{width:203px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-padding{width:172px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding h3{margin-left:25px;*margin-left:12px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-textflow{width:182px;}.yui-skin-sam .yui-editor-panel .hd{background:none;}.yui-skin-sam .yui-editor-panel .ft{background-color:#F2F2F2;b!
 order:1px solid #808080;border-top:none;padding:0;margin:0 0 2!
 px 0;}.y
ui-skin-sam .yui-editor-panel .hd span.close{background:url(sprite.png) no-repeat 0 -300px;cursor:pointer;display:block;height:16px;overflow:hidden;position:absolute;right:5px;text-indent:500px;top:2px;width:26px;}.yui-skin-sam .yui-editor-panel .ft span.tip{background-color:#EDF5FF;border-top:1px solid #808080;font-size:85%;}.yui-skin-sam .yui-editor-panel .ft span.tip strong{display:block;float:left;margin:0 2px 8px 0;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon{background:url( editor-sprite.gif ) no-repeat 0 -1260px;display:block;height:20px;left:2px;position:absolute;top:8px;width:20px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-info{background-position:2px -1260px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-warn{background-position:2px -1296px;}.yui-skin-sam .yui-editor-panel .hd span.knob{position:absolute;height:10px;width:28px;top:-10px;left:25px;text-indent:9999px;overflow:hidden;background:url( editor-knob.gif ) no-repeat 0 0;}.yu!
 i-skin-sam .yui-editor-panel .yui-toolbar-container{float:left;width:100%;background-image:none;border:none;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .bd{background-color:#ffffff;}.yui-editor-blankimage{background-image:url( blankimage.png );}
+.yuimenubar{visibility:visible;position:static;}.yuimenu .yuimenu,.yuimenubar .yuimenu{visibility:hidden;position:absolute;top:-10000px;left:-10000px;}.yuimenubar li,.yuimenu li{list-style-type:none;}.yuimenubar ul,.yuimenu ul,.yuimenubar li,.yuimenu li,.yuimenu h6,.yuimenubar h6{margin:0;padding:0;}.yuimenuitemlabel,.yuimenubaritemlabel{text-align:left;white-space:nowrap;}.yuimenubar ul{*zoom:1;}.yuimenubar .yuimenu ul{*zoom:normal;}.yuimenubar>.bd>ul:after{content:".";display:block;clear:both;visibility:hidden;height:0;line-height:0;}.yuimenubaritem{float:left;}.yuimenubaritemlabel,.yuimenuitemlabel{display:block;}.yuimenuitemlabel .helptext{font-style:normal;display:block;margin:-1em 0 0 10em;}.yui-menu-shadow{position:absolute;visibility:hidden;z-index:-1;}.yui-menu-shadow-visible{top:2px;right:-3px;left:-3px;bottom:-3px;visibility:visible;}.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.yuimenu.show-scrollbars,.yuimenubar.show-scrollbars{over!
 flow:visible;}.yuimenu.hide-scrollbars .yui-menu-shadow,.yuimenubar.hide-scrollbars .yui-menu-shadow{overflow:hidden;}.yuimenu.show-scrollbars .yui-menu-shadow,.yuimenubar.show-scrollbars .yui-menu-shadow{overflow:auto;}.yui-skin-sam .yuimenubar{font-size:93%;line-height:2;*line-height:1.9;border:solid 1px #808080;background:url(sprite.png) repeat-x 0 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritem{border-right:solid 1px #ccc;}.yui-skin-sam .yuimenubaritemlabel{padding:0 10px;color:#000;text-decoration:none;cursor:default;border-style:solid;border-color:#808080;border-width:1px 0;*position:relative;margin:-1px 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel{padding-right:20px;*display:inline-block;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu{background:url(menubaritem_submenuindicator.png) right center no-repeat;}.yui-skin-sam .yuimenubaritem-selected{background:url(sprite.png) repeat-x 0 -1700px;}.yui-skin-sam .yuimenubaritemlabel-selected{border-colo!
 r:#7D98B8;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-s!
 elected{
border-left-width:1px;margin-left:-1px;*left:-1px;}.yui-skin-sam .yuimenubaritemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu-disabled{background-image:url(menubaritem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenu{font-size:93%;line-height:1.5;*line-height:1.45;}.yui-skin-sam .yuimenubar .yuimenu,.yui-skin-sam .yuimenu .yuimenu{font-size:100%;}.yui-skin-sam .yuimenu .bd{border:solid 1px #808080;background-color:#fff;}.yui-skin-sam .yuimenu ul{padding:3px 0;border-width:1px 0 0 0;border-color:#ccc;border-style:solid;}.yui-skin-sam .yuimenu ul.first-of-type{border-width:0;}.yui-skin-sam .yuimenu h6{font-weight:bold;border-style:solid;border-color:#ccc;border-width:1px 0 0 0;color:#a4a4a4;padding:3px 10px 0 10px;}.yui-skin-sam .yuimenu ul.hastitle,.yui-skin-sam .yuimenu h6.first-of-type{border-width:0;}.yui-skin-sam .yuimenu .yui-menu-body-scrolled{border-color:#ccc #808080;overflow:hidden;}.yui-skin-sam .yuim!
 enu .topscrollbar,.yui-skin-sam .yuimenu .bottomscrollbar{height:16px;border:solid 1px #808080;background:#fff url(sprite.png) no-repeat 0 0;}.yui-skin-sam .yuimenu .topscrollbar{border-bottom-width:0;background-position:center -950px;}.yui-skin-sam .yuimenu .topscrollbar_disabled{background-position:center -975px;}.yui-skin-sam .yuimenu .bottomscrollbar{border-top-width:0;background-position:center -850px;}.yui-skin-sam .yuimenu .bottomscrollbar_disabled{background-position:center -875px;}.yui-skin-sam .yuimenuitem{_border-bottom:solid 1px #fff;}.yui-skin-sam .yuimenuitemlabel{padding:0 20px;color:#000;text-decoration:none;cursor:default;}.yui-skin-sam .yuimenuitemlabel .helptext{margin-top:-1.5em;*margin-top:-1.45em;}.yui-skin-sam .yuimenuitem-hassubmenu{background-image:url(menuitem_submenuindicator.png);background-position:right center;background-repeat:no-repeat;}.yui-skin-sam .yuimenuitem-checked{background-image:url(menuitem_checkbox.png);background-position:left cen!
 ter;background-repeat:no-repeat;}.yui-skin-sam .yui-menu-shado!
 w-visibl
e{background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yuimenuitem-selected{background-color:#B3D4FF;}.yui-skin-sam .yuimenuitemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenuitem-hassubmenu-disabled{background-image:url(menuitem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenuitem-checked-disabled{background-image:url(menuitem_checkbox_disabled.png);}
+.yui-skin-sam .yui-pv{background-color:#4a4a4a;font:arial;position:relative;width:99%;z-index:1000;margin-bottom:1em;overflow:hidden;}.yui-skin-sam .yui-pv .hd{background:url(header_background.png) repeat-x;min-height:30px;overflow:hidden;zoom:1;padding:2px 0;}.yui-skin-sam .yui-pv .hd h4{padding:8px 10px;margin:0;font:bold 14px arial;color:#fff;}.yui-skin-sam .yui-pv .hd a{background:#3f6bc3;font:bold 11px arial;color:#fff;padding:4px;margin:3px 10px 0 0;border:1px solid #3f567d;cursor:pointer;display:block;float:right;}.yui-skin-sam .yui-pv .hd span{display:none;}.yui-skin-sam .yui-pv .hd span.yui-pv-busy{height:18px;width:18px;background:url(wait.gif) no-repeat;overflow:hidden;display:block;float:right;margin:4px 10px 0 0;}.yui-skin-sam .yui-pv .hd:after,.yui-pv .bd:after,.yui-skin-sam .yui-pv-chartlegend dl:after{content:'.';visibility:hidden;clear:left;height:0;display:block;}.yui-skin-sam .yui-pv .bd{position:relative;zoom:1;overflow-x:auto;overflow-y:hidden;}.yui-ski!
 n-sam .yui-pv .yui-pv-table{padding:0 10px;margin:5px 0 10px 0;}.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-bd td{color:#eeee5c;font:12px arial;}.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-odd{background:#929292;}.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-even{background:#58637a;}.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-even td.yui-dt-desc{background:#384970;}.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-odd td.yui-dt-desc{background:#6F6E6E;}.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-hd th{background-image:none;background:#2E2D2D;}.yui-skin-sam .yui-pv th.yui-dt-asc .yui-dt-liner{background:transparent url(asc.gif) no-repeat scroll right center;}.yui-skin-sam .yui-pv th.yui-dt-desc .yui-dt-liner{background:transparent url(desc.gif) no-repeat scroll right center;}.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-hd th a{color:#fff;font:bold 1!
 2px arial;}.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-hd th.y!
 ui-dt-as
c,.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-hd th.yui-dt-desc{background:#333;}.yui-skin-sam .yui-pv-chartcontainer{padding:0 10px;}.yui-skin-sam .yui-pv-chart{height:250px;clear:right;margin:5px 0 0 0;color:#fff;}.yui-skin-sam .yui-pv-chartlegend div{float:right;margin:0 0 0 10px;_width:250px;}.yui-skin-sam .yui-pv-chartlegend dl{border:1px solid #999;padding:.2em 0 .2em .5em;zoom:1;margin:5px 0;}.yui-skin-sam .yui-pv-chartlegend dt{float:left;display:block;height:.7em;width:.7em;padding:0;}.yui-skin-sam .yui-pv-chartlegend dd{float:left;display:block;color:#fff;margin:0 1em 0 .5em;padding:0;font:11px arial;}.yui-skin-sam .yui-pv-minimized{height:35px;}.yui-skin-sam .yui-pv-minimized .bd{top:-3000px;}.yui-skin-sam .yui-pv-minimized .hd a.yui-pv-refresh{display:none;}
+.yui-resize{position:relative;zoom:1;z-index:0;}.yui-resize-wrap{zoom:1;}.yui-draggable{cursor:move;}.yui-resize .yui-resize-handle{position:absolute;z-index:1;font-size:0;margin:0;padding:0;zoom:1;height:1px;width:1px;}.yui-resize .yui-resize-handle-br{height:5px;width:5px;bottom:0;right:0;cursor:se-resize;z-index:2;zoom:1;}.yui-resize .yui-resize-handle-bl{height:5px;width:5px;bottom:0;left:0;cursor:sw-resize;z-index:2;zoom:1;}.yui-resize .yui-resize-handle-tl{height:5px;width:5px;top:0;left:0;cursor:nw-resize;z-index:2;zoom:1;}.yui-resize .yui-resize-handle-tr{height:5px;width:5px;top:0;right:0;cursor:ne-resize;z-index:2;zoom:1;}.yui-resize .yui-resize-handle-r{width:5px;height:100%;top:0;right:0;cursor:e-resize;zoom:1;}.yui-resize .yui-resize-handle-l{height:100%;width:5px;top:0;left:0;cursor:w-resize;zoom:1;}.yui-resize .yui-resize-handle-b{width:100%;height:5px;bottom:0;right:0;cursor:s-resize;zoom:1;}.yui-resize .yui-resize-handle-t{width:100%;height:5px;top:0;right:!
 0;cursor:n-resize;zoom:1;}.yui-resize-proxy{position:absolute;border:1px dashed #000;visibility:hidden;z-index:1000;}.yui-resize-hover .yui-resize-handle,.yui-resize-hidden .yui-resize-handle{opacity:0;filter:alpha(opacity=0);}.yui-resize-ghost{opacity:.5;filter:alpha(opacity=50);}.yui-resize-knob .yui-resize-handle{height:6px;width:6px;}.yui-resize-knob .yui-resize-handle-tr{right:-3px;top:-3px;}.yui-resize-knob .yui-resize-handle-tl{left:-3px;top:-3px;}.yui-resize-knob .yui-resize-handle-bl{left:-3px;bottom:-3px;}.yui-resize-knob .yui-resize-handle-br{right:-3px;bottom:-3px;}.yui-resize-knob .yui-resize-handle-t{left:45%;top:-3px;}.yui-resize-knob .yui-resize-handle-r{right:-3px;top:45%;}.yui-resize-knob .yui-resize-handle-l{left:-3px;top:45%;}.yui-resize-knob .yui-resize-handle-b{left:45%;bottom:-3px;}.yui-resize-status{position:absolute;top:-999px;left:-999px;padding:2px;font-size:80%;display:none;zoom:1;z-index:9999;}.yui-resize-status strong,.yui-resize-status em{font!
 -weight:normal;font-style:normal;padding:1px;zoom:1;}.yui-skin!
 -sam .yu
i-resize .yui-resize-handle{background-color:#F2F2F2;}.yui-skin-sam .yui-resize .yui-resize-handle-active{background-color:#7D98B8;zoom:1;}.yui-skin-sam .yui-resize .yui-resize-handle-l,.yui-skin-sam .yui-resize .yui-resize-handle-r,.yui-skin-sam .yui-resize .yui-resize-handle-l-active,.yui-skin-sam .yui-resize .yui-resize-handle-r-active{height:100%;}.yui-skin-sam .yui-resize-knob .yui-resize-handle{border:1px solid #808080;}.yui-skin-sam .yui-resize-hover .yui-resize-handle-active{opacity:1;filter:alpha(opacity=100);}.yui-skin-sam .yui-resize-proxy{border:1px dashed #426FD9;}.yui-skin-sam .yui-resize-status{border:1px solid #A6982B;border-top:1px solid #D4C237;background-color:#FFEE69}.yui-skin-sam .yui-resize-status strong,.yui-skin-sam .yui-resize-status em{float:left;display:block;clear:both;padding:1px;text-align:center;}.yui-skin-sam .yui-resize .yui-resize-handle-inner-r,.yui-skin-sam .yui-resize .yui-resize-handle-inner-l{background:transparent url( layout_sprite.pn!
 g) no-repeat 0 -5px;height:16px;width:5px;position:absolute;top:45%;}.yui-skin-sam .yui-resize .yui-resize-handle-inner-t,.yui-skin-sam .yui-resize .yui-resize-handle-inner-b{background:transparent url(layout_sprite.png) no-repeat -20px 0;height:5px;width:16px;position:absolute;left:50%;}.yui-skin-sam .yui-resize .yui-resize-handle-br{background-image:url( layout_sprite.png );background-repeat:no-repeat;background-position:-22px -62px;}.yui-skin-sam .yui-resize .yui-resize-handle-tr{background-image:url( layout_sprite.png );background-repeat:no-repeat;background-position:-22px -42px;}.yui-skin-sam .yui-resize .yui-resize-handle-tl{background-image:url( layout_sprite.png );background-repeat:no-repeat;background-position:-22px -82px;}.yui-skin-sam .yui-resize .yui-resize-handle-bl{background-image:url( layout_sprite.png );background-repeat:no-repeat;background-position:-22px -23px;}.yui-skin-sam .yui-resize-knob .yui-resize-handle-t,.yui-skin-sam .yui-resize-knob .yui-resize-!
 handle-r,.yui-skin-sam .yui-resize-knob .yui-resize-handle-b,.!
 yui-skin
-sam .yui-resize-knob .yui-resize-handle-l,.yui-skin-sam .yui-resize-knob .yui-resize-handle-tl,.yui-skin-sam .yui-resize-knob .yui-resize-handle-tr,.yui-skin-sam .yui-resize-knob .yui-resize-handle-bl,.yui-skin-sam .yui-resize-knob .yui-resize-handle-br,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-t,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-r,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-b,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-l,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-tl,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-tr,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-bl,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-br{background-image:none;}.yui-skin-sam .yui-resize-knob .yui-resize-handle-l,.yui-skin-sam .yui-resize-knob .yui-resize-handle-r,.yui-skin-sam .yui-resize-knob .yui-resize-handle-l-active,.yui-skin-sam .yui-resize-knob .yui-resize-handle-r-active{height:6px;width:6px;}
+.yui-busy{cursor:wait !important;}.yui-toolbar-container fieldset{padding:0;margin:0;border:0;}.yui-toolbar-container legend{display:none;}.yui-toolbar-container .yui-toolbar-subcont{padding:.25em 0;zoom:1;}.yui-toolbar-container-collapsed .yui-toolbar-subcont{display:none;}.yui-toolbar-container .yui-toolbar-subcont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container span.yui-toolbar-draghandle{cursor:move;border-left:1px solid #999;border-right:1px solid #999;overflow:hidden;text-indent:77777px;width:2px;height:20px;display:block;clear:none;float:left;margin:0 0 0 .2em;}.yui-toolbar-container .yui-toolbar-titlebar.draggable{cursor:move;}.yui-toolbar-container .yui-toolbar-titlebar{position:relative;}.yui-toolbar-container .yui-toolbar-titlebar h2{font-weight:bold;letter-spacing:0;border:none;color:#000;margin:0;padding:.2em;}.yui-toolbar-container .yui-toolbar-titlebar h2 a{text-decoration:none;color:#000;cursor:default;}.yui-tool!
 bar-container.yui-toolbar-grouped span.yui-toolbar-draghandle{height:40px;}.yui-toolbar-container .yui-toolbar-group{float:left;zoom:1;}.yui-toolbar-container .yui-toolbar-group:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container .yui-toolbar-group h3{font-size:75%;padding:0 0 0 .25em;margin:0;}.yui-toolbar-container span.yui-toolbar-separator{width:2px;height:18px;margin:.2em 0 .2em .1em;display:block;clear:none;float:left;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-separator{height:35px;}.yui-toolbar-container.yui-toolbar-grouped .yui-toolbar-group span.yui-toolbar-separator{height:18px;}.yui-toolbar-container ul li{margin:0;padding:0;list-style-type:none;}.yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-toolbar-container .yui-push-button,.yui-toolbar-container .yui-color-button,.yui-toolbar-container .yui-menu-button{position:relative;cursor:pointer;}.yui-toolbar-container .yui-button .firs!
 t-child,.yui-toolbar-container .yui-button .first-child a{heig!
 ht:100%;
width:100%;overflow:hidden;}.yui-toolbar-container .yui-button-disabled{cursor:default;}.yui-toolbar-container .yui-button-disabled .yui-toolbar-icon{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button-disabled .up,.yui-toolbar-container .yui-button-disabled .down{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button a{overflow:hidden;}.yui-toolbar-container .yui-toolbar-select .first-child a{cursor:pointer;}.yui-toolbar-fontname-arial{font-family:Arial;}.yui-toolbar-fontname-arial-black{font-family:Arial Black;}.yui-toolbar-fontname-comic-sans-ms{font-family:Comic Sans MS;}.yui-toolbar-fontname-courier-new{font-family:Courier New;}.yui-toolbar-fontname-times-new-roman{font-family:Times New Roman;}.yui-toolbar-fontname-verdana{font-family:Verdana;}.yui-toolbar-fontname-impact{font-family:Impact;}.yui-toolbar-fontname-lucida-console{font-family:Lucida Console;}.yui-toolbar-fontname-tahoma{font-family:Tahoma;}.yui-toolbar-fontname-trebuche!
 t-ms{font-family:Trebuchet MS;}.yui-toolbar-container .yui-toolbar-spinbutton{position:relative;}.yui-toolbar-container .yui-toolbar-spinbutton .first-child a{z-index:0;opacity:1;}.yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-toolbar-container .yui-toolbar-spinbutton a.down{position:absolute;display:block right:0;cursor:pointer;z-index:1;padding:0;margin:0;}.yui-toolbar-container .yui-overlay{position:absolute;}.yui-toolbar-container .yui-overlay ul li{margin:0;list-style-type:none;}.yui-toolbar-container{z-index:1;}.yui-editor-container .yui-editor-editable-container{position:relative;z-index:0;width:100%;}.yui-editor-container .yui-editor-masked{background-color:#CCC;}.yui-editor-container iframe{border:0px;padding:0;margin:0;zoom:1;display:block;}.yui-editor-container .yui-editor-editable{padding:0;margin:0;}.yui-editor-container .dompath{font-size:85%;}.yui-editor-panel .hd{text-align:left;position:relative;}.yui-editor-panel .hd h3{font-weight:bold;padding:0!
 .25em 0pt 0.25em 0.25em;margin:0;}.yui-editor-panel .bd{width:!
 100%;zoo
m:1;position:relative;}.yui-editor-panel .bd div.yui-editor-body-cont{padding:.25em .1em;zoom:1;}.yui-editor-panel .bd div.yui-editor-body-cont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-editor-panel .ft{text-align:right;width:99%;float:left;clear:both;}.yui-editor-panel .ft span.tip{display:block;position:relative;padding:.5em .5em .5em 23px;text-align:left;zoom:1;}.yui-editor-panel label{clear:both;float:left;padding:0;width:100%;text-align:left;zoom:1;}.yui-editor-panel .gecko label{overflow:auto;}.yui-editor-panel label strong{float:left;width:6em;}.yui-editor-panel .removeLink{width:80%;text-align:right;}.yui-editor-panel label input{margin-left:.25em;float:left;}.yui-editor-panel .yui-toolbar-group-padding{}.yui-editor-panel .yui-toolbar-group-border{}.yui-editor-panel .yui-toolbar-group-textflow{}.yui-editor-panel .height-width{float:left;}.yui-editor-panel .height-width h3{}.yui-editor-panel .height-width span{font-style:italic;displa!
 y:block;float:left;overflow:auto;}.yui-editor-panel .height-width span.info{font-size:70%;}.yui-editor-panel .yui-toolbar-bordersize,.yui-editor-panel .yui-toolbar-bordertype{font-size:75%;}.yui-editor-panel .yui-toolbar-container span.yui-toolbar-separator{border:none;}.yui-editor-panel .yui-toolbar-bordersize span a span,.yui-editor-panel .yui-toolbar-bordertype span a span{display:block;height:8px;left:4px;position:absolute;top:3px;*top:-5px;width:24px;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-solid{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dotted{border-bottom:1px dotted black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dashed{border-bottom:1px dashed black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-0{*top:0px;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-1{border-bottom!
 :1px solid black;}.yui-editor-panel .yui-toolbar-bordersize sp!
 an a spa
n.yui-toolbar-bordersize-2{border-bottom:2px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-3{top:2px;*top:-5px;border-bottom:3px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-4{top:1px;*top:-5px;border-bottom:4px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-5{top:1px;*top:-5px;border-bottom:5px solid black;}.yui-toolbar-container .yui-toolbar-bordersize-menu,.yui-toolbar-container .yui-toolbar-bordertype-menu{width:95px !important;}.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel,.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel:hover{margin:0px 3px 7px 17px;}.yui-toolbar-bordersize-menu .yuimenuitemlabel .checkedindicator,.yui-toolbar-bordertype-menu .yuimenuitemlabel .checkedindicator{position:absolute;left:-12px;*top:14px;*left:0px;}.yui-toolbar-bordersi!
 ze-menu li.yui-toolbar-bordersize-1 a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-2 a{border-bottom:2px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-3 a{border-bottom:3px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-4 a{border-bottom:4px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-5 a{border-bottom:5px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-solid a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dashed a{border-bottom:1px dashed black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dotted a{border-bottom:1px dotted black;height:14px;}h2.yui-editor-skipheader,h3.yui-editor-skipheader{height:0;margin:0;padding:0;border:none;width:0;overflow:hidden;position:absolute;}.yui-toolbar-colors{width:133px;zoom:1;displ!
 ay:none;z-index:100;overflow:hidden;}.yui-toolbar-colors:after!
 {display
:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors a{height:9px;width:9px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0;cursor:pointer;border:1px solid #F6F7EE;}.yui-toolbar-colors a:hover{border:1px solid black;}.yui-color-button-menu{overflow:visible;background-color:transparent;}.yui-toolbar-colors span{position:relative;display:block;padding:3px;overflow:hidden;float:left;width:100%;zoom:1;}.yui-toolbar-colors span:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors span em{height:35px;width:30px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0.75px;border:1px solid black;}.yui-toolbar-colors span strong{font-weight:normal;padding-left:3px;display:block;font-size:85%;float:left;width:65%;}.yui-skin-sam .yui-editor-container{border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container{zoom:1;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar{background:url!
 (sprite.png) repeat-x 0 -200px;position:relative;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar h2{color:#000000;font-weight:bold;margin:0;padding:0.3em 1em;font-size:100%;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-group h3{color:#808080;font-size:75%;margin:1em 0 0;padding-bottom:0;padding-left:0.25em;text-align:left;}.yui-toolbar-container span.yui-toolbar-separator{border:none;text-indent:33px;overflow:hidden;margin:.25em;}.yui-skin-sam .yui-toolbar-container{background-color:#F2F2F2;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subcont{padding:0 1em 0.35em;border-bottom:1px solid #808080;}.yui-skin-sam .yui-toolbar-container-collapsed .yui-toolbar-titlebar{border-bottom:1px solid #808080;}.yui-skin-sam .yui-editor-container .visible .yui-menu-shadow,.yui-skin-sam .yui-editor-panel .visible .yui-menu-shadow{display:none;}.yui-skin-sam .yui-editor-container ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-cont!
 ainer ul li{list-style-type:none;margin:0;padding:0;}.yui-skin!
 -sam .yu
i-toolbar-group ul li.yui-toolbar-groupitem{float:left;}.yui-skin-sam .yui-editor-container .dompath{background-color:#F2F2F2;border-top:1px solid #808080;color:#999;text-align:left;padding:0.25em;}.yui-skin-sam .yui-toolbar-container .collapse{background:url(sprite.png) no-repeat 0 -400px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar span.collapse{cursor:pointer;position:absolute;top:4px;right:2px;display:block;overflow:hidden;height:15px;width:15px;text-indent:9999px;}.yui-skin-sam .yui-toolbar-container .yui-push-button,.yui-skin-sam .yui-toolbar-container .yui-color-button,.yui-skin-sam .yui-toolbar-container .yui-menu-button{background:url(sprite.png) repeat-x 0 0;position:relative;display:block;height:22px;width:30px;margin:0;border-color:#808080;border-style:solid;border-width:1px 0;}.yui-skin-sam .yui-toolbar-container .yui-push-button a,.yui-skin-sam .yui-toolbar-container .yui-color-button a,.yui-skin-sam .yui-toolbar-container .yui-menu-button a{padd!
 ing-left:35px;height:20px;text-decoration:none;font-size:93%;line-height:2;display:block;color:#000000;overflow:hidden;}.yui-skin-sam .yui-toolbar-container .yui-push-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button .first-child{border-color:#808080;border-style:solid;border-width:0 1px;margin:0 -1px;display:block;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled,.yui-skin-sam .yui-toolbar-container .yui!
 -color-button-disabled,.yui-skin-sam .yui-toolbar-container .y!
 ui-menu-
button-disabled{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-button .first-child{*left:0px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-fontname{width:135px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-heading{width:92px;}.yui-skin-sam .yui-toolbar-container .yui-button-hover{background:url(sprite.png) repeat-x 0 -1300px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-button-selected{background:url(sprite.png) repeat-x 0 -1700px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels .yui-toolbar-group{margin-top:.75em;}.yui-skin-sam .yui-toolbar-container .yui-push-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-color-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-menu-button span.yui-toolbar-icon{display:block;position:absolute;top:2px;height:18px;width:18px;overflow:hidden;!
 background:url(editor-sprite.gif) no-repeat 30px 30px;}.yui-skin-sam .yui-toolbar-container .yui-button-selected span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-button-hover span.yui-toolbar-icon{background-image:url(editor-sprite-active.gif);}.yui-skin-sam .yui-toolbar-container .visible .yuimenuitemlabel{cursor:pointer;color:#000;*position:relative;}.yui-skin-sam .yui-toolbar-container .yui-button-menu{background-color:#fff;}.yui-skin-sam div.yuimenu li.selected{background-color:#B3D4FF;}.yui-skin-sam div.yuimenu li.selected a.selected{color:#000;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bold span.yui-toolbar-icon{background-position:0 0;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-italic span.yui-toolbar-icon{background-position:0 -36px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-underline span.yui-toolbar-icon{background-position:0 -72px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subscript span.yui!
 -toolbar-icon{background-position:0 -180px;left:5px;}.yui-skin!
 -sam .yu
i-toolbar-container .yui-toolbar-superscript span.yui-toolbar-icon{background-position:0 -144px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-forecolor span.yui-toolbar-icon{background-position:0 -216px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-backcolor span.yui-toolbar-icon{background-position:0 -288px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyleft span.yui-toolbar-icon{background-position:0 -324px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifycenter span.yui-toolbar-icon{background-position:0 -360px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyright span.yui-toolbar-icon{background-position:0 -396px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyfull span.yui-toolbar-icon{background-position:0 -432px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-indent span.yui-toolbar-icon{background-position:0 -720px;left:5px;}.yui-skin-sam .yui-toolbar-c!
 ontainer .yui-toolbar-outdent span.yui-toolbar-icon{background-position:0 -684px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-createlink span.yui-toolbar-icon{background-position:0 -792px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertimage span.yui-toolbar-icon{background-position:1px -756px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-left span.yui-toolbar-icon{background-position:0 -972px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-right span.yui-toolbar-icon{background-position:0 -936px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-inline span.yui-toolbar-icon{background-position:0 -900px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-block span.yui-toolbar-icon{background-position:0 -864px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bordercolor span.yui-toolbar-icon{background-position:0 -252px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-removefor!
 mat span.yui-toolbar-icon{background-position:0 -1080px;left:5!
 px;}.yui
-skin-sam .yui-toolbar-container .yui-toolbar-hiddenelements span.yui-toolbar-icon{background-position:0 -1044px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertunorderedlist span.yui-toolbar-icon{background-position:0 -468px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertorderedlist span.yui-toolbar-icon{background-position:0 -504px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child{width:35px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child a{padding-left:2px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton span.yui-toolbar-icon{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{right:2px;background:url(editor-sprite.gif) no-repeat 0 -1222px;overflow:hidden;height:6px;width:7px;min-height:0;padd!
 ing:0;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up{top:2px;background-position:0 -1222px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{bottom:2px;background-position:0 -1187px;}.yui-skin-sam .yui-toolbar-container select{height:22px;border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select .first-child a{padding-left:5px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select span.yui-toolbar-icon{background:url( editor-sprite.gif ) no-repeat 0 -1144px;overflow:hidden;right:-2px;top:0px;height:20px;}.yui-skin-sam .yui-editor-panel .yui-color-button-menu .bd{background-color:transparent;border:none;width:135px;}.yui-skin-sam .yui-color-button-menu .yui-toolbar-colors{border:1px solid #808080;}.yui-skin-sam .yui-editor-panel{padding:0;margin:0;border:none;background-color:transparent;overflow:visible;}.yui-skin-sam .yui-editor-panel .hd{margin:10px 0 0;padding:0;border:none;}.yui-skin-sam !
 .yui-editor-panel .hd h3{color:#000;border:1px solid #808080;b!
 ackgroun
d:url(sprite.png) repeat-x 0 -200px;width:99%;position:relative;margin:0;padding:3px 0 0 0;font-size:93%;text-indent:5px;height:20px;}.yui-skin-sam .yui-editor-panel .bd{background-color:#F2F2F2;border-left:1px solid #808080;border-right:1px solid #808080;width:99%;margin:0;padding:0;overflow:visible;}.yui-skin-sam .yui-editor-panel ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-panel ul li{margin:0;padding:0;}.yui-skin-sam .yui-editor-panel .yuimenu{}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .yui-toolbar-subcont{padding:0;border:none;margin-top:0.35em;}.yui-skin-sam .yui-editor-panel .yui-toolbar-bordersize,.yui-skin-sam .yui-editor-panel .yui-toolbar-bordertype{width:50px;}.yui-skin-sam .yui-editor-panel label{display:block;float:none;padding:4px 0;margin-bottom:7px;}.yui-skin-sam .yui-editor-panel label strong{font-weight:normal;font-size:93%;text-align:right;padding-top:2px;}.yui-skin-sam .yui-editor-panel label input{width:75%;}.yui-s!
 kin-sam .yui-editor-panel #createlink_target,.yui-skin-sam .yui-editor-panel #insertimage_target{width:auto;margin-right:5px;}.yui-skin-sam .yui-editor-panel .removeLink{width:98%;}.yui-skin-sam .yui-editor-panel label input.warning{background-color:#FFEE69;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group h3{color:#000;float:left;font-weight:normal;font-size:93%;margin:5px 0 0 0;padding:0 3px 0 0;text-align:right;}.yui-skin-sam .yui-editor-panel .height-width h3{margin:3px 0 0 10px;}.yui-skin-sam .yui-editor-panel .height-width{margin:3px 0 0 35px;*margin-left:14px;width:42%;*width:44%;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-border{width:190px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-border{width:210px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding{width:203px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-padding{width:172px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding h3{margin-left:25px;*mar!
 gin-left:12px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-gr!
 oup-text
flow{width:182px;}.yui-skin-sam .yui-editor-panel .hd{background:none;}.yui-skin-sam .yui-editor-panel .ft{background-color:#F2F2F2;border:1px solid #808080;border-top:none;padding:0;margin:0 0 2px 0;}.yui-skin-sam .yui-editor-panel .hd span.close{background:url(sprite.png) no-repeat 0 -300px;cursor:pointer;display:block;height:16px;overflow:hidden;position:absolute;right:5px;text-indent:500px;top:2px;width:26px;}.yui-skin-sam .yui-editor-panel .ft span.tip{background-color:#EDF5FF;border-top:1px solid #808080;font-size:85%;}.yui-skin-sam .yui-editor-panel .ft span.tip strong{display:block;float:left;margin:0 2px 8px 0;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon{background:url( editor-sprite.gif ) no-repeat 0 -1260px;display:block;height:20px;left:2px;position:absolute;top:8px;width:20px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-info{background-position:2px -1260px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-warn{background-position:2px !
 -1296px;}.yui-skin-sam .yui-editor-panel .hd span.knob{position:absolute;height:10px;width:28px;top:-10px;left:25px;text-indent:9999px;overflow:hidden;background:url( editor-knob.gif ) no-repeat 0 0;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container{float:left;width:100%;background-image:none;border:none;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .bd{background-color:#ffffff;}.yui-editor-blankimage{background-image:url( blankimage.png );}
 .yui-navset .yui-nav li,.yui-navset .yui-navset-top .yui-nav li,.yui-navset .yui-navset-bottom .yui-nav li{margin:0 0.5em 0 0;}.yui-navset-left .yui-nav li,.yui-navset-right .yui-nav li{margin:0 0 0.5em;}.yui-navset .yui-navset-left .yui-nav,.yui-navset .yui-navset-right .yui-nav,.yui-navset-left .yui-nav,.yui-navset-right .yui-nav{width:6em;}.yui-navset-top .yui-nav,.yui-navset-bottom .yui-nav{width:auto;}.yui-navset .yui-navset-left,.yui-navset-left{padding:0 0 0 6em;}.yui-navset-right{padding:0 6em 0 0;}.yui-navset-top,.yui-navset-bottom{padding:auto;}.yui-nav,.yui-nav li{margin:0;padding:0;list-style:none;}.yui-navset li em{font-style:normal;}.yui-navset{position:relative;zoom:1;}.yui-navset .yui-content{zoom:1;}.yui-navset .yui-nav li,.yui-navset .yui-navset-top .yui-nav li,.yui-navset .yui-navset-bottom .yui-nav li{display:inline-block;display:-moz-inline-stack;*display:inline;vertical-align:bottom;cursor:pointer;zoom:1;}.yui-navset-left .yui-nav li,.yui-navset-right !
 .yui-nav li{display:block;}.yui-navset .yui-nav a{position:relative;}.yui-navset .yui-nav li a,.yui-navset-top .yui-nav li a,.yui-navset-bottom .yui-nav li a{display:block;display:inline-block;vertical-align:bottom;zoom:1;}.yui-navset-left .yui-nav li a,.yui-navset-right .yui-nav li a{display:block;}.yui-navset-bottom .yui-nav li a{vertical-align:text-top;}.yui-navset .yui-nav li a em,.yui-navset-top .yui-nav li a em,.yui-navset-bottom .yui-nav li a em{display:block;}.yui-navset .yui-navset-left .yui-nav,.yui-navset .yui-navset-right .yui-nav,.yui-navset-left .yui-nav,.yui-navset-right .yui-nav{position:absolute;z-index:1;}.yui-navset-top .yui-nav,.yui-navset-bottom .yui-nav{position:static;}.yui-navset .yui-navset-left .yui-nav,.yui-navset-left .yui-nav{left:0;right:auto;}.yui-navset .yui-navset-right .yui-nav,.yui-navset-right .yui-nav{right:0;left:auto;}.yui-skin-sam .yui-navset .yui-nav,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav{border:solid #2647a0;border-width!
 :0 0 5px;Xposition:relative;zoom:1;}.yui-skin-sam .yui-navset !
 .yui-nav
 li,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav li{margin:0 0.16em 0 0;padding:1px 0 0;zoom:1;}.yui-skin-sam .yui-navset .yui-nav .selected,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav .selected{margin:0 0.16em -1px 0;}.yui-skin-sam .yui-navset .yui-nav a,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav a{background:#d8d8d8 url(sprite.png) repeat-x;border:solid #a3a3a3;border-width:0 1px;color:#000;position:relative;text-decoration:none;}.yui-skin-sam .yui-navset .yui-nav a em,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav a em{border:solid #a3a3a3;border-width:1px 0 0;cursor:hand;padding:0.25em .75em;left:0;right:0;bottom:0;top:-1px;position:relative;}.yui-skin-sam .yui-navset .yui-nav .selected a,.yui-skin-sam .yui-navset .yui-nav .selected a:focus,.yui-skin-sam .yui-navset .yui-nav .selected a:hover{background:#2647a0 url(sprite.png) repeat-x left -1400px;color:#fff;}.yui-skin-sam .yui-navset .yui-nav a:hover,.yui-skin-sam .yui-navset .yui-nav a:focus{b!
 ackground:#bfdaff url(sprite.png) repeat-x left -1300px;outline:0;}.yui-skin-sam .yui-navset .yui-nav .selected a em{padding:0.35em 0.75em;}.yui-skin-sam .yui-navset .yui-nav .selected a,.yui-skin-sam .yui-navset .yui-nav .selected a em{border-color:#243356;}.yui-skin-sam .yui-navset .yui-content{background:#edf5ff;}.yui-skin-sam .yui-navset .yui-content,.yui-skin-sam .yui-navset .yui-navset-top .yui-content{border:1px solid #808080;border-top-color:#243356;padding:0.25em 0.5em;}.yui-skin-sam .yui-navset-left .yui-nav,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav,.yui-skin-sam .yui-navset .yui-navset-right .yui-nav,.yui-skin-sam .yui-navset-right .yui-nav{border-width:0 5px 0 0;Xposition:absolute;top:0;bottom:0;}.yui-skin-sam .yui-navset .yui-navset-right .yui-nav,.yui-skin-sam .yui-navset-right .yui-nav{border-width:0 0 0 5px;}.yui-skin-sam .yui-navset-left .yui-nav li,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav li,.yui-skin-sam .yui-navset-right .yui-nav li{!
 margin:0 0 0.16em;padding:0 0 0 1px;}.yui-skin-sam .yui-navset!
 -right .
yui-nav li{padding:0 1px 0 0;}.yui-skin-sam .yui-navset-left .yui-nav .selected,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav .selected{margin:0 -1px 0.16em 0;}.yui-skin-sam .yui-navset-right .yui-nav .selected{margin:0 0 0.16em -1px;}.yui-skin-sam .yui-navset-left .yui-nav a,.yui-skin-sam .yui-navset-right .yui-nav a{border-width:1px 0;}.yui-skin-sam .yui-navset-left .yui-nav a em,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav a em,.yui-skin-sam .yui-navset-right .yui-nav a em{border-width:0 0 0 1px;padding:0.2em .75em;top:auto;left:-1px;}.yui-skin-sam .yui-navset-right .yui-nav a em{border-width:0 1px 0 0;left:auto;right:-1px;}.yui-skin-sam .yui-navset-left .yui-nav a,.yui-skin-sam .yui-navset-left .yui-nav .selected a,.yui-skin-sam .yui-navset-left .yui-nav a:hover,.yui-skin-sam .yui-navset-right .yui-nav a,.yui-skin-sam .yui-navset-right .yui-nav .selected a,.yui-skin-sam .yui-navset-right .yui-nav a:hover,.yui-skin-sam .yui-navset-bottom .yui-nav a,.yui-skin-!
 sam .yui-navset-bottom .yui-nav .selected a,.yui-skin-sam .yui-navset-bottom .yui-nav a:hover{background-image:none;}.yui-skin-sam .yui-navset-left .yui-content{border:1px solid #808080;border-left-color:#243356;}.yui-skin-sam .yui-navset-bottom .yui-nav,.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav{border-width:5px 0 0;}.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav .selected,.yui-skin-sam .yui-navset-bottom .yui-nav .selected{margin:-1px 0.16em 0 0;}.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav li,.yui-skin-sam .yui-navset-bottom .yui-nav li{padding:0 0 1px 0;vertical-align:top;}.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav li a,.yui-skin-sam .yui-navset-bottom .yui-nav li a{}.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav a em,.yui-skin-sam .yui-navset-bottom .yui-nav a em{border-width:0 0 1px;top:auto;bottom:-1px;}.yui-skin-sam .yui-navset-bottom .yui-content,.yui-skin-sam .yui-navset .yui-navset-bottom .yui-content{border:1px solid !
 #808080;border-bottom-color:#243356;}
 .ygtvtn{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -5600px no-repeat;}.ygtvtm{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -4000px no-repeat;}.ygtvtmh{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -4800px no-repeat;}.ygtvtp{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -6400px no-repeat;}.ygtvtph{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -7200px no-repeat;}.ygtvln{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -1600px no-repeat;}.ygtvlm{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 0px no-repeat;}.ygtvlmh{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -800px no-repeat;}.ygtvlp{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -2400px no-repeat;}.ygtvlph{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -3200px !
 no-repeat;}.ygtvloading{width:18px;height:22px;background:url(treeview-loading.gif) 0 0 no-repeat;}.ygtvdepthcell{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -8000px no-repeat;}.ygtvblankdepthcell{width:18px;height:22px;}.ygtvitem{}.ygtvchildren{*zoom:1;}.ygtvlabel,.ygtvlabel:link,.ygtvlabel:visited,.ygtvlabel:hover{margin-left:2px;text-decoration:none;background-color:white;}.ygtvspacer{height:22px;width:12px;}
 

Modified: trunk/root/static/yui/assets/skins/sam/tabview.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/tabview.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/tabview.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-navset .yui-nav li,.yui-navset .yui-navset-top .yui-nav li,.yui-navset .yui-navset-bottom .yui-nav li{margin:0 0.5em 0 0;}.yui-navset-left .yui-nav li,.yui-navset-right .yui-nav li{margin:0 0 0.5em;}.yui-navset .yui-navset-left .yui-nav,.yui-navset .yui-navset-right .yui-nav,.yui-navset-left .yui-nav,.yui-navset-right .yui-nav{width:6em;}.yui-navset-top .yui-nav,.yui-navset-bottom .yui-nav{width:auto;}.yui-navset .yui-navset-left,.yui-navset-left{padding:0 0 0 6em;}.yui-navset-right{padding:0 6em 0 0;}.yui-navset-top,.yui-navset-bottom{padding:auto;}.yui-nav,.yui-nav li{margin:0;padding:0;list-style:none;}.yui-navset li em{font-style:normal;}.yui-navset{position:relative;zoom:1;}.yui-navset .yui-content{zoom:1;}.yui-navset .yui-nav li,.yui-navset .yui-navset-top .yui-nav li,.yui-navset .yui-navset-bottom .yui-nav li{display:inline-block;display:-moz-inline-stack;*display:inline;vertical-align:bottom;cursor:pointer;zoom:1;}.yui-navset-left .yui-nav li,.yui-navset-right !
 .yui-nav li{display:block;}.yui-navset .yui-nav a{position:relative;}.yui-navset .yui-nav li a,.yui-navset-top .yui-nav li a,.yui-navset-bottom .yui-nav li a{display:block;display:inline-block;vertical-align:bottom;zoom:1;}.yui-navset-left .yui-nav li a,.yui-navset-right .yui-nav li a{display:block;}.yui-navset-bottom .yui-nav li a{vertical-align:text-top;}.yui-navset .yui-nav li a em,.yui-navset-top .yui-nav li a em,.yui-navset-bottom .yui-nav li a em{display:block;}.yui-navset .yui-navset-left .yui-nav,.yui-navset .yui-navset-right .yui-nav,.yui-navset-left .yui-nav,.yui-navset-right .yui-nav{position:absolute;z-index:1;}.yui-navset-top .yui-nav,.yui-navset-bottom .yui-nav{position:static;}.yui-navset .yui-navset-left .yui-nav,.yui-navset-left .yui-nav{left:0;right:auto;}.yui-navset .yui-navset-right .yui-nav,.yui-navset-right .yui-nav{right:0;left:auto;}.yui-skin-sam .yui-navset .yui-nav,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav{border:solid #2647a0;border-width!
 :0 0 5px;Xposition:relative;zoom:1;}.yui-skin-sam .yui-navset !
 .yui-nav
 li,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav li{margin:0 0.16em 0 0;padding:1px 0 0;zoom:1;}.yui-skin-sam .yui-navset .yui-nav .selected,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav .selected{margin:0 0.16em -1px 0;}.yui-skin-sam .yui-navset .yui-nav a,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav a{background:#d8d8d8 url(sprite.png) repeat-x;border:solid #a3a3a3;border-width:0 1px;color:#000;position:relative;text-decoration:none;}.yui-skin-sam .yui-navset .yui-nav a em,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav a em{border:solid #a3a3a3;border-width:1px 0 0;cursor:hand;padding:0.25em .75em;left:0;right:0;bottom:0;top:-1px;position:relative;}.yui-skin-sam .yui-navset .yui-nav .selected a,.yui-skin-sam .yui-navset .yui-nav .selected a:focus,.yui-skin-sam .yui-navset .yui-nav .selected a:hover{background:#2647a0 url(sprite.png) repeat-x left -1400px;color:#fff;}.yui-skin-sam .yui-navset .yui-nav a:hover,.yui-skin-sam .yui-navset .yui-nav a:focus{b!
 ackground:#bfdaff url(sprite.png) repeat-x left -1300px;outline:0;}.yui-skin-sam .yui-navset .yui-nav .selected a em{padding:0.35em 0.75em;}.yui-skin-sam .yui-navset .yui-nav .selected a,.yui-skin-sam .yui-navset .yui-nav .selected a em{border-color:#243356;}.yui-skin-sam .yui-navset .yui-content{background:#edf5ff;}.yui-skin-sam .yui-navset .yui-content,.yui-skin-sam .yui-navset .yui-navset-top .yui-content{border:1px solid #808080;border-top-color:#243356;padding:0.25em 0.5em;}.yui-skin-sam .yui-navset-left .yui-nav,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav,.yui-skin-sam .yui-navset .yui-navset-right .yui-nav,.yui-skin-sam .yui-navset-right .yui-nav{border-width:0 5px 0 0;Xposition:absolute;top:0;bottom:0;}.yui-skin-sam .yui-navset .yui-navset-right .yui-nav,.yui-skin-sam .yui-navset-right .yui-nav{border-width:0 0 0 5px;}.yui-skin-sam .yui-navset-left .yui-nav li,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav li,.yui-skin-sam .yui-navset-right .yui-nav li{!
 margin:0 0 0.16em;padding:0 0 0 1px;}.yui-skin-sam .yui-navset!
 -right .
yui-nav li{padding:0 1px 0 0;}.yui-skin-sam .yui-navset-left .yui-nav .selected,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav .selected{margin:0 -1px 0.16em 0;}.yui-skin-sam .yui-navset-right .yui-nav .selected{margin:0 0 0.16em -1px;}.yui-skin-sam .yui-navset-left .yui-nav a,.yui-skin-sam .yui-navset-right .yui-nav a{border-width:1px 0;}.yui-skin-sam .yui-navset-left .yui-nav a em,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav a em,.yui-skin-sam .yui-navset-right .yui-nav a em{border-width:0 0 0 1px;padding:0.2em .75em;top:auto;left:-1px;}.yui-skin-sam .yui-navset-right .yui-nav a em{border-width:0 1px 0 0;left:auto;right:-1px;}.yui-skin-sam .yui-navset-left .yui-nav a,.yui-skin-sam .yui-navset-left .yui-nav .selected a,.yui-skin-sam .yui-navset-left .yui-nav a:hover,.yui-skin-sam .yui-navset-right .yui-nav a,.yui-skin-sam .yui-navset-right .yui-nav .selected a,.yui-skin-sam .yui-navset-right .yui-nav a:hover,.yui-skin-sam .yui-navset-bottom .yui-nav a,.yui-skin-!
 sam .yui-navset-bottom .yui-nav .selected a,.yui-skin-sam .yui-navset-bottom .yui-nav a:hover{background-image:none;}.yui-skin-sam .yui-navset-left .yui-content{border:1px solid #808080;border-left-color:#243356;}.yui-skin-sam .yui-navset-bottom .yui-nav,.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav{border-width:5px 0 0;}.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav .selected,.yui-skin-sam .yui-navset-bottom .yui-nav .selected{margin:-1px 0.16em 0 0;}.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav li,.yui-skin-sam .yui-navset-bottom .yui-nav li{padding:0 0 1px 0;vertical-align:top;}.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav li a,.yui-skin-sam .yui-navset-bottom .yui-nav li a{}.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav a em,.yui-skin-sam .yui-navset-bottom .yui-nav a em{border-width:0 0 1px;top:auto;bottom:-1px;}.yui-skin-sam .yui-navset-bottom .yui-content,.yui-skin-sam .yui-navset .yui-navset-bottom .yui-content{border:1px solid !
 #808080;border-bottom-color:#243356;}

Modified: trunk/root/static/yui/assets/skins/sam/treeview.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/treeview.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/treeview.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .ygtvtn{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -5600px no-repeat;}.ygtvtm{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -4000px no-repeat;}.ygtvtmh{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -4800px no-repeat;}.ygtvtp{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -6400px no-repeat;}.ygtvtph{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -7200px no-repeat;}.ygtvln{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -1600px no-repeat;}.ygtvlm{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 0px no-repeat;}.ygtvlmh{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -800px no-repeat;}.ygtvlp{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -2400px no-repeat;}.ygtvlph{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -3200px !
 no-repeat;}.ygtvloading{width:18px;height:22px;background:url(treeview-loading.gif) 0 0 no-repeat;}.ygtvdepthcell{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -8000px no-repeat;}.ygtvblankdepthcell{width:18px;height:22px;}.ygtvitem{}.ygtvchildren{*zoom:1;}.ygtvlabel,.ygtvlabel:link,.ygtvlabel:visited,.ygtvlabel:hover{margin-left:2px;text-decoration:none;background-color:white;}.ygtvspacer{height:22px;width:12px;}

Added: trunk/root/static/yui/assets/skins/sam/wait.gif
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/assets/skins/sam/wait.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: trunk/root/static/yui/assets/skins/sam/yuitest.css
===================================================================
--- trunk/root/static/yui/assets/skins/sam/yuitest.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/assets/skins/sam/yuitest.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 

Modified: trunk/root/static/yui/autocomplete/README
===================================================================
--- trunk/root/static/yui/autocomplete/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/autocomplete/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +1,11 @@
 AutoComplete Release Notes
 
-*** version 2.4.1 ***
+*** version 2.5.0 ***
 
-* No change
+* Fixed bug where Mac users were not able to input "&" or "(" characters.
 
+
+
 *** version 2.4.0 ***
 
 * Support for YUI JSON Utility.

Modified: trunk/root/static/yui/autocomplete/assets/autocomplete-core.css
===================================================================
--- trunk/root/static/yui/autocomplete/assets/autocomplete-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/autocomplete/assets/autocomplete-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* This file intentionally left blank */

Modified: trunk/root/static/yui/autocomplete/assets/skins/sam/autocomplete-skin.css
===================================================================
--- trunk/root/static/yui/autocomplete/assets/skins/sam/autocomplete-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/autocomplete/assets/skins/sam/autocomplete-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* styles for entire widget */
 .yui-skin-sam .yui-ac {

Modified: trunk/root/static/yui/autocomplete/assets/skins/sam/autocomplete.css
===================================================================
--- trunk/root/static/yui/autocomplete/assets/skins/sam/autocomplete.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/autocomplete/assets/skins/sam/autocomplete.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-skin-sam .yui-ac{position:relative;font-family:arial;font-size:100%;}.yui-skin-sam .yui-ac-input{position:absolute;width:100%;}.yui-skin-sam .yui-ac-container{position:absolute;top:1.6em;width:100%;}.yui-skin-sam .yui-ac-content{position:absolute;width:100%;border:1px solid #808080;background:#fff;overflow:hidden;z-index:9050;}.yui-skin-sam .yui-ac-shadow{position:absolute;margin:.3em;width:100%;background:#000;-moz-opacity:0.10;opacity:.10;filter:alpha(opacity=10);z-index:9049;}.yui-skin-sam .yui-ac-content ul{margin:0;padding:0;width:100%;}.yui-skin-sam .yui-ac-content li{margin:0;padding:2px 5px;cursor:default;white-space:nowrap;}.yui-skin-sam .yui-ac-content li.yui-ac-prehighlight{background:#B3D4FF;}.yui-skin-sam .yui-ac-content li.yui-ac-highlight{background:#426FD9;color:#FFF;}

Modified: trunk/root/static/yui/autocomplete/autocomplete-debug.js
===================================================================
--- trunk/root/static/yui/autocomplete/autocomplete-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/autocomplete/autocomplete-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
  /**
  * The AutoComplete control provides the front-end logic for text-entry suggestion and
@@ -10,7 +10,7 @@
  *
  * @module autocomplete
  * @requires yahoo, dom, event, datasource
- * @optional animation, connection
+ * @optional animation, connection, get
  * @namespace YAHOO.widget
  * @title AutoComplete Widget
  */
@@ -54,15 +54,15 @@
         if(YAHOO.util.Dom.inDocument(elInput)) {
             if(YAHOO.lang.isString(elInput)) {
                     this._sName = "instance" + YAHOO.widget.AutoComplete._nIndex + " " + elInput;
-                    this._oTextbox = document.getElementById(elInput);
+                    this._elTextbox = document.getElementById(elInput);
             }
             else {
                 this._sName = (elInput.id) ?
                     "instance" + YAHOO.widget.AutoComplete._nIndex + " " + elInput.id:
                     "instance" + YAHOO.widget.AutoComplete._nIndex;
-                this._oTextbox = elInput;
+                this._elTextbox = elInput;
             }
-            YAHOO.util.Dom.addClass(this._oTextbox, "yui-ac-input");
+            YAHOO.util.Dom.addClass(this._elTextbox, "yui-ac-input");
         }
         else {
             YAHOO.log("Could not instantiate AutoComplete due to an invalid input element", "error", this.toString());
@@ -72,17 +72,17 @@
         // Validate container element
         if(YAHOO.util.Dom.inDocument(elContainer)) {
             if(YAHOO.lang.isString(elContainer)) {
-                    this._oContainer = document.getElementById(elContainer);
+                    this._elContainer = document.getElementById(elContainer);
             }
             else {
-                this._oContainer = elContainer;
+                this._elContainer = elContainer;
             }
-            if(this._oContainer.style.display == "none") {
+            if(this._elContainer.style.display == "none") {
                 YAHOO.log("The container may not display properly if display is set to \"none\" in CSS", "warn", this.toString());
             }
             
             // For skinning
-            var elParent = this._oContainer.parentNode;
+            var elParent = this._elContainer.parentNode;
             var elTag = elParent.tagName.toLowerCase();
             if(elTag == "div") {
                 YAHOO.util.Dom.addClass(elParent, "yui-ac");
@@ -113,20 +113,20 @@
 
         // Set up events
         var oSelf = this;
-        var oTextbox = this._oTextbox;
+        var elTextbox = this._elTextbox;
         // Events are actually for the content module within the container
-        var oContent = this._oContainer._oContent;
+        var elContent = this._elContent;
 
         // Dom events
-        YAHOO.util.Event.addListener(oTextbox,"keyup",oSelf._onTextboxKeyUp,oSelf);
-        YAHOO.util.Event.addListener(oTextbox,"keydown",oSelf._onTextboxKeyDown,oSelf);
-        YAHOO.util.Event.addListener(oTextbox,"focus",oSelf._onTextboxFocus,oSelf);
-        YAHOO.util.Event.addListener(oTextbox,"blur",oSelf._onTextboxBlur,oSelf);
-        YAHOO.util.Event.addListener(oContent,"mouseover",oSelf._onContainerMouseover,oSelf);
-        YAHOO.util.Event.addListener(oContent,"mouseout",oSelf._onContainerMouseout,oSelf);
-        YAHOO.util.Event.addListener(oContent,"scroll",oSelf._onContainerScroll,oSelf);
-        YAHOO.util.Event.addListener(oContent,"resize",oSelf._onContainerResize,oSelf);
-        YAHOO.util.Event.addListener(oTextbox,"keypress",oSelf._onTextboxKeyPress,oSelf);
+        YAHOO.util.Event.addListener(elTextbox,"keyup",oSelf._onTextboxKeyUp,oSelf);
+        YAHOO.util.Event.addListener(elTextbox,"keydown",oSelf._onTextboxKeyDown,oSelf);
+        YAHOO.util.Event.addListener(elTextbox,"focus",oSelf._onTextboxFocus,oSelf);
+        YAHOO.util.Event.addListener(elTextbox,"blur",oSelf._onTextboxBlur,oSelf);
+        YAHOO.util.Event.addListener(elContent,"mouseover",oSelf._onContainerMouseover,oSelf);
+        YAHOO.util.Event.addListener(elContent,"mouseout",oSelf._onContainerMouseout,oSelf);
+        YAHOO.util.Event.addListener(elContent,"scroll",oSelf._onContainerScroll,oSelf);
+        YAHOO.util.Event.addListener(elContent,"resize",oSelf._onContainerResize,oSelf);
+        YAHOO.util.Event.addListener(elTextbox,"keypress",oSelf._onTextboxKeyPress,oSelf);
         YAHOO.util.Event.addListener(window,"unload",oSelf._onWindowUnload,oSelf);
 
         // Custom events
@@ -148,7 +148,7 @@
         this.textboxBlurEvent = new YAHOO.util.CustomEvent("textboxBlur", this);
         
         // Finish up
-        oTextbox.setAttribute("autocomplete","off");
+        elTextbox.setAttribute("autocomplete","off");
         YAHOO.widget.AutoComplete._nIndex++;
         YAHOO.log("AutoComplete initialized","info",this.toString());
     }
@@ -406,16 +406,17 @@
  * @param sHeader {String} HTML markup for results container header.
  */
 YAHOO.widget.AutoComplete.prototype.setHeader = function(sHeader) {
-    if(sHeader) {
-        if(this._oContainer._oContent._oHeader) {
-            this._oContainer._oContent._oHeader.innerHTML = sHeader;
-            this._oContainer._oContent._oHeader.style.display = "block";
+    if(this._elHeader) {
+        var elHeader = this._elHeader;
+        if(sHeader) {
+            elHeader.innerHTML = sHeader;
+            elHeader.style.display = "block";
         }
+        else {
+            elHeader.innerHTML = "";
+            elHeader.style.display = "none";
+        }
     }
-    else {
-        this._oContainer._oContent._oHeader.innerHTML = "";
-        this._oContainer._oContent._oHeader.style.display = "none";
-    }
 };
 
 /**
@@ -426,16 +427,17 @@
  * @param sFooter {String} HTML markup for results container footer.
  */
 YAHOO.widget.AutoComplete.prototype.setFooter = function(sFooter) {
-    if(sFooter) {
-        if(this._oContainer._oContent._oFooter) {
-            this._oContainer._oContent._oFooter.innerHTML = sFooter;
-            this._oContainer._oContent._oFooter.style.display = "block";
+    if(this._elFooter) {
+        var elFooter = this._elFooter;
+        if(sFooter) {
+                elFooter.innerHTML = sFooter;
+                elFooter.style.display = "block";
         }
+        else {
+            elFooter.innerHTML = "";
+            elFooter.style.display = "none";
+        }
     }
-    else {
-        this._oContainer._oContent._oFooter.innerHTML = "";
-        this._oContainer._oContent._oFooter.style.display = "none";
-    }
 };
 
 /**
@@ -446,18 +448,19 @@
  * @param sBody {String} HTML markup for results container body.
  */
 YAHOO.widget.AutoComplete.prototype.setBody = function(sBody) {
-    if(sBody) {
-        if(this._oContainer._oContent._oBody) {
-            this._oContainer._oContent._oBody.innerHTML = sBody;
-            this._oContainer._oContent._oBody.style.display = "block";
-            this._oContainer._oContent.style.display = "block";
+    if(this._elBody) {
+        var elBody = this._elBody;
+        if(sBody) {
+                elBody.innerHTML = sBody;
+                elBody.style.display = "block";
+                elBody.style.display = "block";
         }
+        else {
+            elBody.innerHTML = "";
+            elBody.style.display = "none";
+        }
+        this._maxResultsDisplayed = 0;
     }
-    else {
-        this._oContainer._oContent._oBody.innerHTML = "";
-        this._oContainer._oContent.style.display = "none";
-    }
-    this._maxResultsDisplayed = 0;
 };
 
 /**
@@ -486,13 +489,13 @@
  * and DOM elements.
  *
  * @method doBeforeExpandContainer
- * @param oTextbox {HTMLElement} The text input box.
- * @param oContainer {HTMLElement} The container element.
+ * @param elTextbox {HTMLElement} The text input box.
+ * @param elContainer {HTMLElement} The container element.
  * @param sQuery {String} The query string.
  * @param aResults {Object[]}  An array of query results.
  * @return {Boolean} Return true to continue expanding container, false to cancel the expand.
  */
-YAHOO.widget.AutoComplete.prototype.doBeforeExpandContainer = function(oTextbox, oContainer, sQuery, aResults) {
+YAHOO.widget.AutoComplete.prototype.doBeforeExpandContainer = function(elTextbox, elContainer, sQuery, aResults) {
     return true;
 };
 
@@ -527,26 +530,26 @@
  */
 YAHOO.widget.AutoComplete.prototype.destroy = function() {
     var instanceName = this.toString();
-    var elInput = this._oTextbox;
-    var elContainer = this._oContainer;
+    var elInput = this._elTextbox;
+    var elContainer = this._elContainer;
 
     // Unhook custom events
-    this.textboxFocusEvent.unsubscribe();
-    this.textboxKeyEvent.unsubscribe();
-    this.dataRequestEvent.unsubscribe();
-    this.dataReturnEvent.unsubscribe();
-    this.dataErrorEvent.unsubscribe();
-    this.containerExpandEvent.unsubscribe();
-    this.typeAheadEvent.unsubscribe();
-    this.itemMouseOverEvent.unsubscribe();
-    this.itemMouseOutEvent.unsubscribe();
-    this.itemArrowToEvent.unsubscribe();
-    this.itemArrowFromEvent.unsubscribe();
-    this.itemSelectEvent.unsubscribe();
-    this.unmatchedItemSelectEvent.unsubscribe();
-    this.selectionEnforceEvent.unsubscribe();
-    this.containerCollapseEvent.unsubscribe();
-    this.textboxBlurEvent.unsubscribe();
+    this.textboxFocusEvent.unsubscribeAll();
+    this.textboxKeyEvent.unsubscribeAll();
+    this.dataRequestEvent.unsubscribeAll();
+    this.dataReturnEvent.unsubscribeAll();
+    this.dataErrorEvent.unsubscribeAll();
+    this.containerExpandEvent.unsubscribeAll();
+    this.typeAheadEvent.unsubscribeAll();
+    this.itemMouseOverEvent.unsubscribeAll();
+    this.itemMouseOutEvent.unsubscribeAll();
+    this.itemArrowToEvent.unsubscribeAll();
+    this.itemArrowFromEvent.unsubscribeAll();
+    this.itemSelectEvent.unsubscribeAll();
+    this.unmatchedItemSelectEvent.unsubscribeAll();
+    this.selectionEnforceEvent.unsubscribeAll();
+    this.containerCollapseEvent.unsubscribeAll();
+    this.textboxBlurEvent.unsubscribeAll();
 
     // Unhook DOM events
     YAHOO.util.Event.purgeElement(elInput, true);
@@ -745,13 +748,76 @@
 /**
  * Text input field DOM element.
  *
- * @property _oTextbox
+ * @property _elTextbox
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.AutoComplete.prototype._oTextbox = null;
+YAHOO.widget.AutoComplete.prototype._elTextbox = null;
 
 /**
+ * Container DOM element.
+ *
+ * @property _elContainer
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elContainer = null;
+
+/**
+ * Reference to content element within container element.
+ *
+ * @property _elContent
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elContent = null;
+
+/**
+ * Reference to header element within content element.
+ *
+ * @property _elHeader
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elHeader = null;
+
+/**
+ * Reference to body element within content element.
+ *
+ * @property _elBody
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elBody = null;
+
+/**
+ * Reference to footer element within content element.
+ *
+ * @property _elFooter
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elFooter = null;
+
+/**
+ * Reference to shadow element within container element.
+ *
+ * @property _elShadow
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elShadow = null;
+
+/**
+ * Reference to iframe element within container element.
+ *
+ * @property _elIFrame
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elIFrame = null;
+
+/**
  * Whether or not the input field is currently in focus. If query results come back
  * but the user has already moved on, do not proceed with auto complete behavior.
  *
@@ -771,15 +837,6 @@
 YAHOO.widget.AutoComplete.prototype._oAnim = null;
 
 /**
- * Container DOM element.
- *
- * @property _oContainer
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.AutoComplete.prototype._oContainer = null;
-
-/**
  * Whether or not the results container is currently open.
  *
  * @property _bContainerOpen
@@ -952,7 +1009,7 @@
             this.animSpeed = 0.3;
         }
         if(!this._oAnim ) {
-            this._oAnim = new YAHOO.util.Anim(this._oContainer._oContent, {}, this.animSpeed);
+            this._oAnim = new YAHOO.util.Anim(this._elContent, {}, this.animSpeed);
         }
         else {
             this._oAnim.duration = this.animSpeed;
@@ -971,21 +1028,21 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._initContainerHelpers = function() {
-    if(this.useShadow && !this._oContainer._oShadow) {
-        var oShadow = document.createElement("div");
-        oShadow.className = "yui-ac-shadow";
-        this._oContainer._oShadow = this._oContainer.appendChild(oShadow);
+    if(this.useShadow && !this._elShadow) {
+        var elShadow = document.createElement("div");
+        elShadow.className = "yui-ac-shadow";
+        this._elShadow = this._elContainer.appendChild(elShadow);
     }
-    if(this.useIFrame && !this._oContainer._oIFrame) {
-        var oIFrame = document.createElement("iframe");
-        oIFrame.src = this._iFrameSrc;
-        oIFrame.frameBorder = 0;
-        oIFrame.scrolling = "no";
-        oIFrame.style.position = "absolute";
-        oIFrame.style.width = "100%";
-        oIFrame.style.height = "100%";
-        oIFrame.tabIndex = -1;
-        this._oContainer._oIFrame = this._oContainer.appendChild(oIFrame);
+    if(this.useIFrame && !this._elIFrame) {
+        var elIFrame = document.createElement("iframe");
+        elIFrame.src = this._iFrameSrc;
+        elIFrame.frameBorder = 0;
+        elIFrame.scrolling = "no";
+        elIFrame.style.position = "absolute";
+        elIFrame.style.width = "100%";
+        elIFrame.style.height = "100%";
+        elIFrame.tabIndex = -1;
+        this._elIFrame = this._elContainer.appendChild(elIFrame);
     }
 };
 
@@ -996,28 +1053,28 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._initContainer = function() {
-    YAHOO.util.Dom.addClass(this._oContainer, "yui-ac-container");
+    YAHOO.util.Dom.addClass(this._elContainer, "yui-ac-container");
     
-    if(!this._oContainer._oContent) {
-        // The oContent div helps size the iframe and shadow properly
-        var oContent = document.createElement("div");
-        oContent.className = "yui-ac-content";
-        oContent.style.display = "none";
-        this._oContainer._oContent = this._oContainer.appendChild(oContent);
+    if(!this._elContent) {
+        // The elContent div helps size the iframe and shadow properly
+        var elContent = document.createElement("div");
+        elContent.className = "yui-ac-content";
+        elContent.style.display = "none";
+        this._elContent = this._elContainer.appendChild(elContent);
 
-        var oHeader = document.createElement("div");
-        oHeader.className = "yui-ac-hd";
-        oHeader.style.display = "none";
-        this._oContainer._oContent._oHeader = this._oContainer._oContent.appendChild(oHeader);
+        var elHeader = document.createElement("div");
+        elHeader.className = "yui-ac-hd";
+        elHeader.style.display = "none";
+        this._elHeader = this._elContent.appendChild(elHeader);
 
-        var oBody = document.createElement("div");
-        oBody.className = "yui-ac-bd";
-        this._oContainer._oContent._oBody = this._oContainer._oContent.appendChild(oBody);
+        var elBody = document.createElement("div");
+        elBody.className = "yui-ac-bd";
+        this._elBody = this._elContent.appendChild(elBody);
 
-        var oFooter = document.createElement("div");
-        oFooter.className = "yui-ac-ft";
-        oFooter.style.display = "none";
-        this._oContainer._oContent._oFooter = this._oContainer._oContent.appendChild(oFooter);
+        var elFooter = document.createElement("div");
+        elFooter.className = "yui-ac-ft";
+        elFooter.style.display = "none";
+        this._elFooter = this._elContent.appendChild(elFooter);
     }
     else {
         YAHOO.log("Could not initialize the container","warn",this.toString());
@@ -1034,18 +1091,18 @@
  */
 YAHOO.widget.AutoComplete.prototype._initList = function() {
     this._aListItems = [];
-    while(this._oContainer._oContent._oBody.hasChildNodes()) {
+    while(this._elBody.hasChildNodes()) {
         var oldListItems = this.getListItems();
         if(oldListItems) {
             for(var oldi = oldListItems.length-1; oldi >= 0; oldi--) {
                 oldListItems[oldi] = null;
             }
         }
-        this._oContainer._oContent._oBody.innerHTML = "";
+        this._elBody.innerHTML = "";
     }
 
     var oList = document.createElement("ul");
-    oList = this._oContainer._oContent._oBody.appendChild(oList);
+    oList = this._elBody.appendChild(oList);
     for(var i=0; i<this.maxResultsDisplayed; i++) {
         var oItem = document.createElement("li");
         oItem = oList.appendChild(oItem);
@@ -1093,7 +1150,7 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._enableIntervalDetection = function() {
-    var currValue = this._oTextbox.value;
+    var currValue = this._elTextbox.value;
     var lastValue = this._sLastTextboxValue;
     if(currValue != lastValue) {
         this._sLastTextboxValue = currValue;
@@ -1235,7 +1292,7 @@
     }
 
     var isOpera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1);
-    var contentStyle = oSelf._oContainer._oContent.style;
+    var contentStyle = oSelf._elContent.style;
     contentStyle.width = (!isOpera) ? null : "";
     contentStyle.height = (!isOpera) ? null : "";
 
@@ -1274,7 +1331,7 @@
         }
 
         // Expand the container
-        var ok = oSelf.doBeforeExpandContainer(oSelf._oTextbox, oSelf._oContainer, sQuery, aResults);
+        var ok = oSelf.doBeforeExpandContainer(oSelf._elTextbox, oSelf._elContainer, sQuery, aResults);
         oSelf._toggleContainer(ok);
         
         if(oSelf.autoHighlight) {
@@ -1306,16 +1363,16 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._clearSelection = function() {
-    var sValue = this._oTextbox.value;
+    var sValue = this._elTextbox.value;
     var sChar = (this.delimChar) ? this.delimChar[0] : null;
     var nIndex = (sChar) ? sValue.lastIndexOf(sChar, sValue.length-2) : -1;
     if(nIndex > -1) {
-        this._oTextbox.value = sValue.substring(0,nIndex);
+        this._elTextbox.value = sValue.substring(0,nIndex);
     }
     else {
-         this._oTextbox.value = "";
+         this._elTextbox.value = "";
     }
-    this._sSavedQuery = this._oTextbox.value;
+    this._sSavedQuery = this._elTextbox.value;
 
     // Fire custom event
     this.selectionEnforceEvent.fire(this);
@@ -1360,20 +1417,20 @@
         return;
     }
 
-    var oTextbox = this._oTextbox;
-    var sValue = this._oTextbox.value; // any saved queries plus what user has typed
+    var elTextbox = this._elTextbox;
+    var sValue = this._elTextbox.value; // any saved queries plus what user has typed
 
     // Don't update with type-ahead if text selection is not supported
-    if(!oTextbox.setSelectionRange && !oTextbox.createTextRange) {
+    if(!elTextbox.setSelectionRange && !elTextbox.createTextRange) {
         return;
     }
 
     // Select the portion of text that the user has not typed
     var nStart = sValue.length;
     this._updateValue(oItem);
-    var nEnd = oTextbox.value.length;
-    this._selectText(oTextbox,nStart,nEnd);
-    var sPrefill = oTextbox.value.substr(nStart,nEnd);
+    var nEnd = elTextbox.value.length;
+    this._selectText(elTextbox,nStart,nEnd);
+    var sPrefill = elTextbox.value.substr(nStart,nEnd);
     this.typeAheadEvent.fire(this,sQuery,sPrefill);
     YAHOO.log("Typeahead occured with prefill string \"" + sPrefill + "\"", "info", this.toString());
 };
@@ -1382,23 +1439,23 @@
  * Selects text in the input field.
  *
  * @method _selectText
- * @param oTextbox {HTMLElement} Text input box element in which to select text.
+ * @param elTextbox {HTMLElement} Text input box element in which to select text.
  * @param nStart {Number} Starting index of text string to select.
  * @param nEnd {Number} Ending index of text selection.
  * @private
  */
-YAHOO.widget.AutoComplete.prototype._selectText = function(oTextbox, nStart, nEnd) {
-    if(oTextbox.setSelectionRange) { // For Mozilla
-        oTextbox.setSelectionRange(nStart,nEnd);
+YAHOO.widget.AutoComplete.prototype._selectText = function(elTextbox, nStart, nEnd) {
+    if(elTextbox.setSelectionRange) { // For Mozilla
+        elTextbox.setSelectionRange(nStart,nEnd);
     }
-    else if(oTextbox.createTextRange) { // For IE
-        var oTextRange = oTextbox.createTextRange();
+    else if(elTextbox.createTextRange) { // For IE
+        var oTextRange = elTextbox.createTextRange();
         oTextRange.moveStart("character", nStart);
-        oTextRange.moveEnd("character", nEnd-oTextbox.value.length);
+        oTextRange.moveEnd("character", nEnd-elTextbox.value.length);
         oTextRange.select();
     }
     else {
-        oTextbox.select();
+        elTextbox.select();
     }
 };
 
@@ -1411,29 +1468,29 @@
  */
 YAHOO.widget.AutoComplete.prototype._toggleContainerHelpers = function(bShow) {
     var bFireEvent = false;
-    var width = this._oContainer._oContent.offsetWidth + "px";
-    var height = this._oContainer._oContent.offsetHeight + "px";
+    var width = this._elContent.offsetWidth + "px";
+    var height = this._elContent.offsetHeight + "px";
 
-    if(this.useIFrame && this._oContainer._oIFrame) {
+    if(this.useIFrame && this._elIFrame) {
         bFireEvent = true;
         if(bShow) {
-            this._oContainer._oIFrame.style.width = width;
-            this._oContainer._oIFrame.style.height = height;
+            this._elIFrame.style.width = width;
+            this._elIFrame.style.height = height;
         }
         else {
-            this._oContainer._oIFrame.style.width = 0;
-            this._oContainer._oIFrame.style.height = 0;
+            this._elIFrame.style.width = 0;
+            this._elIFrame.style.height = 0;
         }
     }
-    if(this.useShadow && this._oContainer._oShadow) {
+    if(this.useShadow && this._elShadow) {
         bFireEvent = true;
         if(bShow) {
-            this._oContainer._oShadow.style.width = width;
-            this._oContainer._oShadow.style.height = height;
+            this._elShadow.style.width = width;
+            this._elShadow.style.height = height;
         }
         else {
-           this._oContainer._oShadow.style.width = 0;
-            this._oContainer._oShadow.style.height = 0;
+           this._elShadow.style.width = 0;
+            this._elShadow.style.height = 0;
         }
     }
 };
@@ -1446,7 +1503,7 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._toggleContainer = function(bShow) {
-    var oContainer = this._oContainer;
+    var elContainer = this._elContainer;
 
     // Implementer has container always open so don't mess with it
     if(this.alwaysShowContainer && this._bContainerOpen) {
@@ -1455,7 +1512,7 @@
     
     // Clear contents of container
     if(!bShow) {
-        this._oContainer._oContent.scrollTop = 0;
+        this._elContent.scrollTop = 0;
         var aItems = this._aListItems;
 
         if(aItems && (aItems.length > 0)) {
@@ -1475,7 +1532,7 @@
 
     // Container is already closed
     if(!bShow && !this._bContainerOpen) {
-        oContainer._oContent.style.display = "none";
+        this._elContent.style.display = "none";
         return;
     }
 
@@ -1493,8 +1550,8 @@
         }
 
         // Clone container to grab current size offscreen
-        var oClone = oContainer._oContent.cloneNode(true);
-        oContainer.appendChild(oClone);
+        var oClone = this._elContent.cloneNode(true);
+        elContainer.appendChild(oClone);
         oClone.style.top = "-9000px";
         oClone.style.display = "block";
 
@@ -1513,16 +1570,16 @@
 
         // If opening anew, set to a collapsed size...
         if(bShow && !this._bContainerOpen) {
-            oContainer._oContent.style.width = wColl+"px";
-            oContainer._oContent.style.height = hColl+"px";
+            this._elContent.style.width = wColl+"px";
+            this._elContent.style.height = hColl+"px";
         }
         // Else, set it to its last known size.
         else {
-            oContainer._oContent.style.width = wExp+"px";
-            oContainer._oContent.style.height = hExp+"px";
+            this._elContent.style.width = wExp+"px";
+            this._elContent.style.height = hExp+"px";
         }
 
-        oContainer.removeChild(oClone);
+        elContainer.removeChild(oClone);
         oClone = null;
 
     	var oSelf = this;
@@ -1535,7 +1592,7 @@
                 YAHOO.log("Container expanded", "info", oSelf.toString());
             }
             else {
-                oContainer._oContent.style.display = "none";
+                oSelf._elContent.style.display = "none";
                 oSelf.containerCollapseEvent.fire(oSelf);
                 YAHOO.log("Container collapsed", "info", oSelf.toString());
             }
@@ -1543,7 +1600,7 @@
      	};
 
         // Display container and animate it
-        oContainer._oContent.style.display = "block";
+        this._elContent.style.display = "block";
         oAnim.onComplete.subscribe(onAnimComplete);
         oAnim.animate();
         this._bContainerOpen = bShow;
@@ -1551,12 +1608,12 @@
     // Else don't animate, just show or hide
     else {
         if(bShow) {
-            oContainer._oContent.style.display = "block";
+            this._elContent.style.display = "block";
             this.containerExpandEvent.fire(this);
             YAHOO.log("Container expanded", "info", this.toString());
         }
         else {
-            oContainer._oContent.style.display = "none";
+            this._elContent.style.display = "none";
             this.containerCollapseEvent.fire(this);
             YAHOO.log("Container collapsed", "info", this.toString());
         }
@@ -1622,34 +1679,34 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._updateValue = function(oItem) {
-    var oTextbox = this._oTextbox;
+    var elTextbox = this._elTextbox;
     var sDelimChar = (this.delimChar) ? (this.delimChar[0] || this.delimChar) : null;
     var sSavedQuery = this._sSavedQuery;
     var sResultKey = oItem._sResultKey;
-    oTextbox.focus();
+    elTextbox.focus();
 
     // First clear text field
-    oTextbox.value = "";
+    elTextbox.value = "";
     // Grab data to put into text field
     if(sDelimChar) {
         if(sSavedQuery) {
-            oTextbox.value = sSavedQuery;
+            elTextbox.value = sSavedQuery;
         }
-        oTextbox.value += sResultKey + sDelimChar;
+        elTextbox.value += sResultKey + sDelimChar;
         if(sDelimChar != " ") {
-            oTextbox.value += " ";
+            elTextbox.value += " ";
         }
     }
-    else { oTextbox.value = sResultKey; }
+    else { elTextbox.value = sResultKey; }
 
     // scroll to bottom of textarea if necessary
-    if(oTextbox.type == "textarea") {
-        oTextbox.scrollTop = oTextbox.scrollHeight;
+    if(elTextbox.type == "textarea") {
+        elTextbox.scrollTop = elTextbox.scrollHeight;
     }
 
     // move cursor to end
-    var end = oTextbox.value.length;
-    this._selectText(oTextbox,end,end);
+    var end = elTextbox.value.length;
+    this._selectText(elTextbox,end,end);
 
     this._oCurItem = oItem;
 };
@@ -1723,14 +1780,14 @@
            // Go back to query (remove type-ahead string)
             if(this.delimChar && this._sSavedQuery) {
                 if(!this._textMatchesOption()) {
-                    this._oTextbox.value = this._sSavedQuery;
+                    this._elTextbox.value = this._sSavedQuery;
                 }
                 else {
-                    this._oTextbox.value = this._sSavedQuery + this._sCurQuery;
+                    this._elTextbox.value = this._sSavedQuery + this._sCurQuery;
                 }
             }
             else {
-                this._oTextbox.value = this._sCurQuery;
+                this._elTextbox.value = this._sCurQuery;
             }
             this._oCurItem = null;
             return;
@@ -1744,36 +1801,36 @@
         var oNewItem = this._aListItems[nNewItemIndex];
 
         // Scroll the container if necessary
-        var oContent = this._oContainer._oContent;
-        var scrollOn = ((YAHOO.util.Dom.getStyle(oContent,"overflow") == "auto") ||
-            (YAHOO.util.Dom.getStyle(oContent,"overflowY") == "auto"));
+        var elContent = this._elContent;
+        var scrollOn = ((YAHOO.util.Dom.getStyle(elContent,"overflow") == "auto") ||
+            (YAHOO.util.Dom.getStyle(elContent,"overflowY") == "auto"));
         if(scrollOn && (nNewItemIndex > -1) &&
         (nNewItemIndex < this._nDisplayedItems)) {
             // User is keying down
             if(nKeyCode == 40) {
                 // Bottom of selected item is below scroll area...
-                if((oNewItem.offsetTop+oNewItem.offsetHeight) > (oContent.scrollTop + oContent.offsetHeight)) {
+                if((oNewItem.offsetTop+oNewItem.offsetHeight) > (elContent.scrollTop + elContent.offsetHeight)) {
                     // Set bottom of scroll area to bottom of selected item
-                    oContent.scrollTop = (oNewItem.offsetTop+oNewItem.offsetHeight) - oContent.offsetHeight;
+                    elContent.scrollTop = (oNewItem.offsetTop+oNewItem.offsetHeight) - elContent.offsetHeight;
                 }
                 // Bottom of selected item is above scroll area...
-                else if((oNewItem.offsetTop+oNewItem.offsetHeight) < oContent.scrollTop) {
+                else if((oNewItem.offsetTop+oNewItem.offsetHeight) < elContent.scrollTop) {
                     // Set top of selected item to top of scroll area
-                    oContent.scrollTop = oNewItem.offsetTop;
+                    elContent.scrollTop = oNewItem.offsetTop;
 
                 }
             }
             // User is keying up
             else {
                 // Top of selected item is above scroll area
-                if(oNewItem.offsetTop < oContent.scrollTop) {
+                if(oNewItem.offsetTop < elContent.scrollTop) {
                     // Set top of scroll area to top of selected item
-                    this._oContainer._oContent.scrollTop = oNewItem.offsetTop;
+                    this._elContent.scrollTop = oNewItem.offsetTop;
                 }
                 // Top of selected item is below scroll area
-                else if(oNewItem.offsetTop > (oContent.scrollTop + oContent.offsetHeight)) {
+                else if(oNewItem.offsetTop > (elContent.scrollTop + elContent.offsetHeight)) {
                     // Set bottom of selected item to bottom of scroll area
-                    this._oContainer._oContent.scrollTop = (oNewItem.offsetTop+oNewItem.offsetHeight) - oContent.offsetHeight;
+                    this._elContent.scrollTop = (oNewItem.offsetTop+oNewItem.offsetHeight) - elContent.offsetHeight;
                 }
             }
         }
@@ -1884,7 +1941,7 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._onContainerScroll = function(v,oSelf) {
-    oSelf._oTextbox.focus();
+    oSelf._elTextbox.focus();
 };
 
 /**
@@ -1927,8 +1984,7 @@
             }
             break;
         case 13: // enter
-            var isMac = (navigator.userAgent.toLowerCase().indexOf("mac") != -1);
-            if(!isMac) {
+            if(!YAHOO.env.ua.webkit) {
                 if(oSelf._oCurItem) {
                     if(oSelf._nKeyCode != nKeyCode) {
                         if(oSelf._bContainerOpen) {
@@ -1972,8 +2028,7 @@
     var nKeyCode = v.keyCode;
 
         //Expose only to Mac browsers, where stopEvent is ineffective on keydown events (bug 790337)
-        var isMac = (navigator.userAgent.toLowerCase().indexOf("mac") != -1);
-        if(isMac) {
+        if(YAHOO.env.ua.webkit) {
             switch (nKeyCode) {
             case 9: // tab
                 if(oSelf._oCurItem) {
@@ -1995,10 +2050,6 @@
                     oSelf._toggleContainer(false);
                 }
                 break;
-            case 38: // up
-            case 40: // down
-                YAHOO.util.Event.stopEvent(v);
-                break;
             default:
                 break;
             }
@@ -2024,6 +2075,7 @@
     oSelf._initProps();
 
     var nKeyCode = v.keyCode;
+
     oSelf._nKeyCode = nKeyCode;
     var sText = this.value; //string in textbox
 
@@ -2066,7 +2118,7 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._onTextboxFocus = function (v,oSelf) {
-    oSelf._oTextbox.setAttribute("autocomplete","off");
+    oSelf._elTextbox.setAttribute("autocomplete","off");
     oSelf._bFocused = true;
     if(!oSelf._bItemSelected) {
         oSelf.textboxFocusEvent.fire(oSelf);
@@ -2128,8 +2180,8 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._onWindowUnload = function(v,oSelf) {
-    if(oSelf && oSelf._oTextbox && oSelf.allowBrowserAutocomplete) {
-        oSelf._oTextbox.setAttribute("autocomplete","on");
+    if(oSelf && oSelf._elTextbox && oSelf.allowBrowserAutocomplete) {
+        oSelf._elTextbox.setAttribute("autocomplete","on");
     }
 };
 
@@ -2666,8 +2718,7 @@
 /////////////////////////////////////////////////////////////////////////////
 
 /**
- * Alias to YUI Connection Manager. Allows implementers to specify their own
- * subclasses of the YUI Connection Manager utility.
+ * Alias to YUI Connection Manager, to allow implementers to customize the utility.
  *
  * @property connMgr
  * @type Object
@@ -2859,13 +2910,13 @@
     switch (this.responseType) {
         case YAHOO.widget.DS_XHR.TYPE_JSON:
             var jsonList, jsonObjParsed;
-            // Check for JSON lib but divert KHTML clients
-            var isNotMac = (navigator.userAgent.toLowerCase().indexOf('khtml')== -1);
-            if(oResponse.parseJSON && isNotMac) {
-                // Use the new JSON utility if available
-                jsonObjParsed = oResponse.parseJSON();
+            // Check for YUI JSON
+            if(YAHOO.lang.JSON) {
+                // Use the JSON utility if available
+                jsonObjParsed = YAHOO.lang.JSON.parse(oResponse);
                 if(!jsonObjParsed) {
                     bError = true;
+                    break;
                 }
                 else {
                     try {
@@ -2878,13 +2929,12 @@
                    }
                 }
             }
-            // Check for YUI JSON lib but divert KHTML clients
-            else if(YAHOO.lang.JSON && isNotMac) {
-                // Use the JSON utility if available
-                jsonObjParsed = YAHOO.lang.JSON.parse(oResponse);
+            // Check for JSON lib
+            else if(oResponse.parseJSON) {
+                // Use the new JSON utility if available
+                jsonObjParsed = oResponse.parseJSON();
                 if(!jsonObjParsed) {
                     bError = true;
-                    break;
                 }
                 else {
                     try {
@@ -2897,8 +2947,8 @@
                    }
                 }
             }
-            else if(window.JSON && isNotMac) {
-                // Use older JSON lib if available
+            // Use older JSON lib if available
+            else if(window.JSON) {
                 jsonObjParsed = JSON.parse(oResponse);
                 if(!jsonObjParsed) {
                     bError = true;
@@ -3563,4 +3613,4 @@
     oCallbackFn(sQuery, aResults, oParent);
 };
 
-YAHOO.register("autocomplete", YAHOO.widget.AutoComplete, {version: "2.4.1", build: "742"});
+YAHOO.register("autocomplete", YAHOO.widget.AutoComplete, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/autocomplete/autocomplete-min.js
===================================================================
--- trunk/root/static/yui/autocomplete/autocomplete-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/autocomplete/autocomplete-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,12 +1,12 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-YAHOO.widget.AutoComplete=function(G,B,J,D){if(G&&B&&J){if(J instanceof YAHOO.widget.DataSource){this.dataSource=J;}else{return ;}if(YAHOO.util.Dom.inDocument(G)){if(YAHOO.lang.isString(G)){this._sName="instance"+YAHOO.widget.AutoComplete._nIndex+" "+G;this._oTextbox=document.getElementById(G);}else{this._sName=(G.id)?"instance"+YAHOO.widget.AutoComplete._nIndex+" "+G.id:"instance"+YAHOO.widget.AutoComplete._nIndex;this._oTextbox=G;}YAHOO.util.Dom.addClass(this._oTextbox,"yui-ac-input");}else{return ;}if(YAHOO.util.Dom.inDocument(B)){if(YAHOO.lang.isString(B)){this._oContainer=document.getElementById(B);}else{this._oContainer=B;}if(this._oContainer.style.display=="none"){}var E=this._oContainer.parentNode;var A=E.tagName.toLowerCase();if(A=="div"){YAHOO.util.Dom.addClass(E,"yui-ac");}else{}}else{return ;}if(D&&(D.constructor==Object)){for(var I in D){if(I){this[I]=D[I];}}}this._initContainer();this._initProps();this._initList();this._initContainerHelpers();var H=this;var F=!
 this._oTextbox;var C=this._oContainer._oContent;YAHOO.util.Event.addListener(F,"keyup",H._onTextboxKeyUp,H);YAHOO.util.Event.addListener(F,"keydown",H._onTextboxKeyDown,H);YAHOO.util.Event.addListener(F,"focus",H._onTextboxFocus,H);YAHOO.util.Event.addListener(F,"blur",H._onTextboxBlur,H);YAHOO.util.Event.addListener(C,"mouseover",H._onContainerMouseover,H);YAHOO.util.Event.addListener(C,"mouseout",H._onContainerMouseout,H);YAHOO.util.Event.addListener(C,"scroll",H._onContainerScroll,H);YAHOO.util.Event.addListener(C,"resize",H._onContainerResize,H);YAHOO.util.Event.addListener(F,"keypress",H._onTextboxKeyPress,H);YAHOO.util.Event.addListener(window,"unload",H._onWindowUnload,H);this.textboxFocusEvent=new YAHOO.util.CustomEvent("textboxFocus",this);this.textboxKeyEvent=new YAHOO.util.CustomEvent("textboxKey",this);this.dataRequestEvent=new YAHOO.util.CustomEvent("dataRequest",this);this.dataReturnEvent=new YAHOO.util.CustomEvent("dataReturn",this);this.dataErrorEvent=new YA!
 HOO.util.CustomEvent("dataError",this);this.containerExpandEve!
 nt=new Y
AHOO.util.CustomEvent("containerExpand",this);this.typeAheadEvent=new YAHOO.util.CustomEvent("typeAhead",this);this.itemMouseOverEvent=new YAHOO.util.CustomEvent("itemMouseOver",this);this.itemMouseOutEvent=new YAHOO.util.CustomEvent("itemMouseOut",this);this.itemArrowToEvent=new YAHOO.util.CustomEvent("itemArrowTo",this);this.itemArrowFromEvent=new YAHOO.util.CustomEvent("itemArrowFrom",this);this.itemSelectEvent=new YAHOO.util.CustomEvent("itemSelect",this);this.unmatchedItemSelectEvent=new YAHOO.util.CustomEvent("unmatchedItemSelect",this);this.selectionEnforceEvent=new YAHOO.util.CustomEvent("selectionEnforce",this);this.containerCollapseEvent=new YAHOO.util.CustomEvent("containerCollapse",this);this.textboxBlurEvent=new YAHOO.util.CustomEvent("textboxBlur",this);F.setAttribute("autocomplete","off");YAHOO.widget.AutoComplete._nIndex++;}else{}};YAHOO.widget.AutoComplete.prototype.dataSource=null;YAHOO.widget.AutoComplete.prototype.minQueryLength=1;YAHOO.widget.AutoComplet!
 e.prototype.maxResultsDisplayed=10;YAHOO.widget.AutoComplete.prototype.queryDelay=0.2;YAHOO.widget.AutoComplete.prototype.highlightClassName="yui-ac-highlight";YAHOO.widget.AutoComplete.prototype.prehighlightClassName=null;YAHOO.widget.AutoComplete.prototype.delimChar=null;YAHOO.widget.AutoComplete.prototype.autoHighlight=true;YAHOO.widget.AutoComplete.prototype.typeAhead=false;YAHOO.widget.AutoComplete.prototype.animHoriz=false;YAHOO.widget.AutoComplete.prototype.animVert=true;YAHOO.widget.AutoComplete.prototype.animSpeed=0.3;YAHOO.widget.AutoComplete.prototype.forceSelection=false;YAHOO.widget.AutoComplete.prototype.allowBrowserAutocomplete=true;YAHOO.widget.AutoComplete.prototype.alwaysShowContainer=false;YAHOO.widget.AutoComplete.prototype.useIFrame=false;YAHOO.widget.AutoComplete.prototype.useShadow=false;YAHOO.widget.AutoComplete.prototype.toString=function(){return"AutoComplete "+this._sName;};YAHOO.widget.AutoComplete.prototype.isContainerOpen=function(){return this!
 ._bContainerOpen;};YAHOO.widget.AutoComplete.prototype.getList!
 Items=fu
nction(){return this._aListItems;};YAHOO.widget.AutoComplete.prototype.getListItemData=function(A){if(A._oResultData){return A._oResultData;}else{return false;}};YAHOO.widget.AutoComplete.prototype.setHeader=function(A){if(A){if(this._oContainer._oContent._oHeader){this._oContainer._oContent._oHeader.innerHTML=A;this._oContainer._oContent._oHeader.style.display="block";}}else{this._oContainer._oContent._oHeader.innerHTML="";this._oContainer._oContent._oHeader.style.display="none";}};YAHOO.widget.AutoComplete.prototype.setFooter=function(A){if(A){if(this._oContainer._oContent._oFooter){this._oContainer._oContent._oFooter.innerHTML=A;this._oContainer._oContent._oFooter.style.display="block";}}else{this._oContainer._oContent._oFooter.innerHTML="";this._oContainer._oContent._oFooter.style.display="none";}};YAHOO.widget.AutoComplete.prototype.setBody=function(A){if(A){if(this._oContainer._oContent._oBody){this._oContainer._oContent._oBody.innerHTML=A;this._oContainer._oContent._o!
 Body.style.display="block";this._oContainer._oContent.style.display="block";}}else{this._oContainer._oContent._oBody.innerHTML="";this._oContainer._oContent.style.display="none";}this._maxResultsDisplayed=0;};YAHOO.widget.AutoComplete.prototype.formatResult=function(B,C){var A=B[0];if(A){return A;}else{return"";}};YAHOO.widget.AutoComplete.prototype.doBeforeExpandContainer=function(A,B,D,C){return true;};YAHOO.widget.AutoComplete.prototype.sendQuery=function(A){this._sendQuery(A);};YAHOO.widget.AutoComplete.prototype.doBeforeSendQuery=function(A){return A;};YAHOO.widget.AutoComplete.prototype.destroy=function(){var B=this.toString();var A=this._oTextbox;var D=this._oContainer;this.textboxFocusEvent.unsubscribe();this.textboxKeyEvent.unsubscribe();this.dataRequestEvent.unsubscribe();this.dataReturnEvent.unsubscribe();this.dataErrorEvent.unsubscribe();this.containerExpandEvent.unsubscribe();this.typeAheadEvent.unsubscribe();
-this.itemMouseOverEvent.unsubscribe();this.itemMouseOutEvent.unsubscribe();this.itemArrowToEvent.unsubscribe();this.itemArrowFromEvent.unsubscribe();this.itemSelectEvent.unsubscribe();this.unmatchedItemSelectEvent.unsubscribe();this.selectionEnforceEvent.unsubscribe();this.containerCollapseEvent.unsubscribe();this.textboxBlurEvent.unsubscribe();YAHOO.util.Event.purgeElement(A,true);YAHOO.util.Event.purgeElement(D,true);D.innerHTML="";for(var C in this){if(YAHOO.lang.hasOwnProperty(this,C)){this[C]=null;}}};YAHOO.widget.AutoComplete.prototype.textboxFocusEvent=null;YAHOO.widget.AutoComplete.prototype.textboxKeyEvent=null;YAHOO.widget.AutoComplete.prototype.dataRequestEvent=null;YAHOO.widget.AutoComplete.prototype.dataReturnEvent=null;YAHOO.widget.AutoComplete.prototype.dataErrorEvent=null;YAHOO.widget.AutoComplete.prototype.containerExpandEvent=null;YAHOO.widget.AutoComplete.prototype.typeAheadEvent=null;YAHOO.widget.AutoComplete.prototype.itemMouseOverEvent=null;YAHOO.widge!
 t.AutoComplete.prototype.itemMouseOutEvent=null;YAHOO.widget.AutoComplete.prototype.itemArrowToEvent=null;YAHOO.widget.AutoComplete.prototype.itemArrowFromEvent=null;YAHOO.widget.AutoComplete.prototype.itemSelectEvent=null;YAHOO.widget.AutoComplete.prototype.unmatchedItemSelectEvent=null;YAHOO.widget.AutoComplete.prototype.selectionEnforceEvent=null;YAHOO.widget.AutoComplete.prototype.containerCollapseEvent=null;YAHOO.widget.AutoComplete.prototype.textboxBlurEvent=null;YAHOO.widget.AutoComplete._nIndex=0;YAHOO.widget.AutoComplete.prototype._sName=null;YAHOO.widget.AutoComplete.prototype._oTextbox=null;YAHOO.widget.AutoComplete.prototype._bFocused=true;YAHOO.widget.AutoComplete.prototype._oAnim=null;YAHOO.widget.AutoComplete.prototype._oContainer=null;YAHOO.widget.AutoComplete.prototype._bContainerOpen=false;YAHOO.widget.AutoComplete.prototype._bOverContainer=false;YAHOO.widget.AutoComplete.prototype._aListItems=null;YAHOO.widget.AutoComplete.prototype._nDisplayedItems=0;YAH!
 OO.widget.AutoComplete.prototype._maxResultsDisplayed=0;YAHOO.!
 widget.A
utoComplete.prototype._sCurQuery=null;YAHOO.widget.AutoComplete.prototype._sSavedQuery=null;YAHOO.widget.AutoComplete.prototype._oCurItem=null;YAHOO.widget.AutoComplete.prototype._bItemSelected=false;YAHOO.widget.AutoComplete.prototype._nKeyCode=null;YAHOO.widget.AutoComplete.prototype._nDelayID=-1;YAHOO.widget.AutoComplete.prototype._iFrameSrc="javascript:false;";YAHOO.widget.AutoComplete.prototype._queryInterval=null;YAHOO.widget.AutoComplete.prototype._sLastTextboxValue=null;YAHOO.widget.AutoComplete.prototype._initProps=function(){var B=this.minQueryLength;if(!YAHOO.lang.isNumber(B)){this.minQueryLength=1;}var D=this.maxResultsDisplayed;if(!YAHOO.lang.isNumber(D)||(D<1)){this.maxResultsDisplayed=10;}var E=this.queryDelay;if(!YAHOO.lang.isNumber(E)||(E<0)){this.queryDelay=0.2;}var A=this.delimChar;if(YAHOO.lang.isString(A)&&(A.length>0)){this.delimChar=[A];}else{if(!YAHOO.lang.isArray(A)){this.delimChar=null;}}var C=this.animSpeed;if((this.animHoriz||this.animVert)&&YAHOO!
 .util.Anim){if(!YAHOO.lang.isNumber(C)||(C<0)){this.animSpeed=0.3;}if(!this._oAnim){this._oAnim=new YAHOO.util.Anim(this._oContainer._oContent,{},this.animSpeed);}else{this._oAnim.duration=this.animSpeed;}}if(this.forceSelection&&A){}};YAHOO.widget.AutoComplete.prototype._initContainerHelpers=function(){if(this.useShadow&&!this._oContainer._oShadow){var B=document.createElement("div");B.className="yui-ac-shadow";this._oContainer._oShadow=this._oContainer.appendChild(B);}if(this.useIFrame&&!this._oContainer._oIFrame){var A=document.createElement("iframe");A.src=this._iFrameSrc;A.frameBorder=0;A.scrolling="no";A.style.position="absolute";A.style.width="100%";A.style.height="100%";A.tabIndex=-1;this._oContainer._oIFrame=this._oContainer.appendChild(A);}};YAHOO.widget.AutoComplete.prototype._initContainer=function(){YAHOO.util.Dom.addClass(this._oContainer,"yui-ac-container");if(!this._oContainer._oContent){var D=document.createElement("div");D.className="yui-ac-content";D.styl!
 e.display="none";this._oContainer._oContent=this._oContainer.a!
 ppendChi
ld(D);var B=document.createElement("div");B.className="yui-ac-hd";B.style.display="none";this._oContainer._oContent._oHeader=this._oContainer._oContent.appendChild(B);var C=document.createElement("div");C.className="yui-ac-bd";this._oContainer._oContent._oBody=this._oContainer._oContent.appendChild(C);var A=document.createElement("div");A.className="yui-ac-ft";A.style.display="none";this._oContainer._oContent._oFooter=this._oContainer._oContent.appendChild(A);}else{}};YAHOO.widget.AutoComplete.prototype._initList=function(){this._aListItems=[];while(this._oContainer._oContent._oBody.hasChildNodes()){var B=this.getListItems();if(B){for(var A=B.length-1;A>=0;A--){B[A]=null;}}this._oContainer._oContent._oBody.innerHTML="";}var E=document.createElement("ul");E=this._oContainer._oContent._oBody.appendChild(E);for(var C=0;C<this.maxResultsDisplayed;C++){var D=document.createElement("li");D=E.appendChild(D);this._aListItems[C]=D;this._initListItem(D,C);}this._maxResultsDisplayed=th!
 is.maxResultsDisplayed;};YAHOO.widget.AutoComplete.prototype._initListItem=function(C,B){var A=this;C.style.display="none";C._nItemIndex=B;C.mouseover=C.mouseout=C.onclick=null;YAHOO.util.Event.addListener(C,"mouseover",A._onItemMouseover,A);YAHOO.util.Event.addListener(C,"mouseout",A._onItemMouseout,A);YAHOO.util.Event.addListener(C,"click",A._onItemMouseclick,A);};YAHOO.widget.AutoComplete.prototype._onIMEDetected=function(A){A._enableIntervalDetection();};YAHOO.widget.AutoComplete.prototype._enableIntervalDetection=function(){var A=this._oTextbox.value;var B=this._sLastTextboxValue;if(A!=B){this._sLastTextboxValue=A;this._sendQuery(A);}};YAHOO.widget.AutoComplete.prototype._cancelIntervalDetection=function(A){if(A._queryInterval){clearInterval(A._queryInterval);}};YAHOO.widget.AutoComplete.prototype._isIgnoreKey=function(A){if((A==9)||(A==13)||(A==16)||(A==17)||(A>=18&&A<=20)||(A==27)||(A>=33&&A<=35)||(A>=36&&A<=40)||(A>=44&&A<=45)){return true;
-}return false;};YAHOO.widget.AutoComplete.prototype._sendQuery=function(G){if(this.minQueryLength==-1){this._toggleContainer(false);return ;}var C=(this.delimChar)?this.delimChar:null;if(C){var E=-1;for(var B=C.length-1;B>=0;B--){var F=G.lastIndexOf(C[B]);if(F>E){E=F;}}if(C[B]==" "){for(var A=C.length-1;A>=0;A--){if(G[E-1]==C[A]){E--;break;}}}if(E>-1){var D=E+1;while(G.charAt(D)==" "){D+=1;}this._sSavedQuery=G.substring(0,D);G=G.substr(D);}else{if(G.indexOf(this._sSavedQuery)<0){this._sSavedQuery=null;}}}if((G&&(G.length<this.minQueryLength))||(!G&&this.minQueryLength>0)){if(this._nDelayID!=-1){clearTimeout(this._nDelayID);}this._toggleContainer(false);return ;}G=encodeURIComponent(G);this._nDelayID=-1;G=this.doBeforeSendQuery(G);this.dataRequestEvent.fire(this,G);this.dataSource.getResults(this._populateList,G,this);};YAHOO.widget.AutoComplete.prototype._populateList=function(K,L,I){if(L===null){I.dataErrorEvent.fire(I,K);}if(!I._bFocused||!L){return ;}var A=(navigator.use!
 rAgent.toLowerCase().indexOf("opera")!=-1);var O=I._oContainer._oContent.style;O.width=(!A)?null:"";O.height=(!A)?null:"";var H=decodeURIComponent(K);I._sCurQuery=H;I._bItemSelected=false;if(I._maxResultsDisplayed!=I.maxResultsDisplayed){I._initList();}var C=Math.min(L.length,I.maxResultsDisplayed);I._nDisplayedItems=C;if(C>0){I._initContainerHelpers();var D=I._aListItems;for(var G=C-1;G>=0;G--){var N=D[G];var B=L[G];N.innerHTML=I.formatResult(B,H);N.style.display="list-item";N._sResultKey=B[0];N._oResultData=B;}for(var F=D.length-1;F>=C;F--){var M=D[F];M.innerHTML=null;M.style.display="none";M._sResultKey=null;M._oResultData=null;}var J=I.doBeforeExpandContainer(I._oTextbox,I._oContainer,K,L);I._toggleContainer(J);if(I.autoHighlight){var E=D[0];I._toggleHighlight(E,"to");I.itemArrowToEvent.fire(I,E);I._typeAhead(E,K);}else{I._oCurItem=null;}}else{I._toggleContainer(false);}I.dataReturnEvent.fire(I,K,L);};YAHOO.widget.AutoComplete.prototype._clearSelection=function(){var C=!
 this._oTextbox.value;var B=(this.delimChar)?this.delimChar[0]:!
 null;var
 A=(B)?C.lastIndexOf(B,C.length-2):-1;if(A>-1){this._oTextbox.value=C.substring(0,A);}else{this._oTextbox.value="";}this._sSavedQuery=this._oTextbox.value;this.selectionEnforceEvent.fire(this);};YAHOO.widget.AutoComplete.prototype._textMatchesOption=function(){var D=null;for(var A=this._nDisplayedItems-1;A>=0;A--){var C=this._aListItems[A];var B=C._sResultKey.toLowerCase();if(B==this._sCurQuery.toLowerCase()){D=C;break;}}return(D);};YAHOO.widget.AutoComplete.prototype._typeAhead=function(E,G){if(!this.typeAhead||(this._nKeyCode==8)){return ;}var B=this._oTextbox;var F=this._oTextbox.value;if(!B.setSelectionRange&&!B.createTextRange){return ;}var C=F.length;this._updateValue(E);var D=B.value.length;this._selectText(B,C,D);var A=B.value.substr(C,D);this.typeAheadEvent.fire(this,G,A);};YAHOO.widget.AutoComplete.prototype._selectText=function(A,B,C){if(A.setSelectionRange){A.setSelectionRange(B,C);}else{if(A.createTextRange){var D=A.createTextRange();D.moveStart("character",B);D!
 .moveEnd("character",C-A.value.length);D.select();}else{A.select();}}};YAHOO.widget.AutoComplete.prototype._toggleContainerHelpers=function(B){var D=false;var C=this._oContainer._oContent.offsetWidth+"px";var A=this._oContainer._oContent.offsetHeight+"px";if(this.useIFrame&&this._oContainer._oIFrame){D=true;if(B){this._oContainer._oIFrame.style.width=C;this._oContainer._oIFrame.style.height=A;}else{this._oContainer._oIFrame.style.width=0;this._oContainer._oIFrame.style.height=0;}}if(this.useShadow&&this._oContainer._oShadow){D=true;if(B){this._oContainer._oShadow.style.width=C;this._oContainer._oShadow.style.height=A;}else{this._oContainer._oShadow.style.width=0;this._oContainer._oShadow.style.height=0;}}};YAHOO.widget.AutoComplete.prototype._toggleContainer=function(J){var L=this._oContainer;if(this.alwaysShowContainer&&this._bContainerOpen){return ;}if(!J){this._oContainer._oContent.scrollTop=0;var C=this._aListItems;if(C&&(C.length>0)){for(var G=C.length-1;G>=0;G--){C[G]!
 .style.display="none";}}if(this._oCurItem){this._toggleHighlig!
 ht(this.
_oCurItem,"from");}this._oCurItem=null;this._nDisplayedItems=0;this._sCurQuery=null;}if(!J&&!this._bContainerOpen){L._oContent.style.display="none";return ;}var B=this._oAnim;if(B&&B.getEl()&&(this.animHoriz||this.animVert)){if(!J){this._toggleContainerHelpers(J);}if(B.isAnimated()){B.stop();}var H=L._oContent.cloneNode(true);L.appendChild(H);H.style.top="-9000px";H.style.display="block";var F=H.offsetWidth;var D=H.offsetHeight;var A=(this.animHoriz)?0:F;var E=(this.animVert)?0:D;B.attributes=(J)?{width:{to:F},height:{to:D}}:{width:{to:A},height:{to:E}};if(J&&!this._bContainerOpen){L._oContent.style.width=A+"px";L._oContent.style.height=E+"px";}else{L._oContent.style.width=F+"px";L._oContent.style.height=D+"px";}L.removeChild(H);H=null;var I=this;var K=function(){B.onComplete.unsubscribeAll();if(J){I.containerExpandEvent.fire(I);}else{L._oContent.style.display="none";I.containerCollapseEvent.fire(I);}I._toggleContainerHelpers(J);};L._oContent.style.display="block";B.onComple!
 te.subscribe(K);B.animate();this._bContainerOpen=J;}else{if(J){L._oContent.style.display="block";this.containerExpandEvent.fire(this);}else{L._oContent.style.display="none";this.containerCollapseEvent.fire(this);}this._toggleContainerHelpers(J);this._bContainerOpen=J;}};YAHOO.widget.AutoComplete.prototype._toggleHighlight=function(A,C){var B=this.highlightClassName;if(this._oCurItem){YAHOO.util.Dom.removeClass(this._oCurItem,B);}if((C=="to")&&B){YAHOO.util.Dom.addClass(A,B);this._oCurItem=A;}};YAHOO.widget.AutoComplete.prototype._togglePrehighlight=function(A,C){if(A==this._oCurItem){return ;}var B=this.prehighlightClassName;if((C=="mouseover")&&B){YAHOO.util.Dom.addClass(A,B);}else{YAHOO.util.Dom.removeClass(A,B);}};YAHOO.widget.AutoComplete.prototype._updateValue=function(F){var C=this._oTextbox;var E=(this.delimChar)?(this.delimChar[0]||this.delimChar):null;var B=this._sSavedQuery;var D=F._sResultKey;C.focus();
-C.value="";if(E){if(B){C.value=B;}C.value+=D+E;if(E!=" "){C.value+=" ";}}else{C.value=D;}if(C.type=="textarea"){C.scrollTop=C.scrollHeight;}var A=C.value.length;this._selectText(C,A,A);this._oCurItem=F;};YAHOO.widget.AutoComplete.prototype._selectItem=function(A){this._bItemSelected=true;this._updateValue(A);this._cancelIntervalDetection(this);this.itemSelectEvent.fire(this,A,A._oResultData);this._toggleContainer(false);};YAHOO.widget.AutoComplete.prototype._jumpSelection=function(){if(this._oCurItem){this._selectItem(this._oCurItem);}else{this._toggleContainer(false);}};YAHOO.widget.AutoComplete.prototype._moveSelection=function(G){if(this._bContainerOpen){var D=this._oCurItem;var F=-1;if(D){F=D._nItemIndex;}var C=(G==40)?(F+1):(F-1);if(C<-2||C>=this._nDisplayedItems){return ;}if(D){this._toggleHighlight(D,"from");this.itemArrowFromEvent.fire(this,D);}if(C==-1){if(this.delimChar&&this._sSavedQuery){if(!this._textMatchesOption()){this._oTextbox.value=this._sSavedQuery;}else!
 {this._oTextbox.value=this._sSavedQuery+this._sCurQuery;}}else{this._oTextbox.value=this._sCurQuery;}this._oCurItem=null;return ;}if(C==-2){this._toggleContainer(false);return ;}var B=this._aListItems[C];var E=this._oContainer._oContent;var A=((YAHOO.util.Dom.getStyle(E,"overflow")=="auto")||(YAHOO.util.Dom.getStyle(E,"overflowY")=="auto"));if(A&&(C>-1)&&(C<this._nDisplayedItems)){if(G==40){if((B.offsetTop+B.offsetHeight)>(E.scrollTop+E.offsetHeight)){E.scrollTop=(B.offsetTop+B.offsetHeight)-E.offsetHeight;}else{if((B.offsetTop+B.offsetHeight)<E.scrollTop){E.scrollTop=B.offsetTop;}}}else{if(B.offsetTop<E.scrollTop){this._oContainer._oContent.scrollTop=B.offsetTop;}else{if(B.offsetTop>(E.scrollTop+E.offsetHeight)){this._oContainer._oContent.scrollTop=(B.offsetTop+B.offsetHeight)-E.offsetHeight;}}}}this._toggleHighlight(B,"to");this.itemArrowToEvent.fire(this,B);if(this.typeAhead){this._updateValue(B);}}};YAHOO.widget.AutoComplete.prototype._onItemMouseover=function(A,B){if(B!
 .prehighlightClassName){B._togglePrehighlight(this,"mouseover"!
 );}else{
B._toggleHighlight(this,"to");}B.itemMouseOverEvent.fire(B,this);};YAHOO.widget.AutoComplete.prototype._onItemMouseout=function(A,B){if(B.prehighlightClassName){B._togglePrehighlight(this,"mouseout");}else{B._toggleHighlight(this,"from");}B.itemMouseOutEvent.fire(B,this);};YAHOO.widget.AutoComplete.prototype._onItemMouseclick=function(A,B){B._toggleHighlight(this,"to");B._selectItem(this);};YAHOO.widget.AutoComplete.prototype._onContainerMouseover=function(A,B){B._bOverContainer=true;};YAHOO.widget.AutoComplete.prototype._onContainerMouseout=function(A,B){B._bOverContainer=false;if(B._oCurItem){B._toggleHighlight(B._oCurItem,"to");}};YAHOO.widget.AutoComplete.prototype._onContainerScroll=function(A,B){B._oTextbox.focus();};YAHOO.widget.AutoComplete.prototype._onContainerResize=function(A,B){B._toggleContainerHelpers(B._bContainerOpen);};YAHOO.widget.AutoComplete.prototype._onTextboxKeyDown=function(A,C){var D=A.keyCode;switch(D){case 9:if(C._oCurItem){if(C.delimChar&&(C._nKe!
 yCode!=D)){if(C._bContainerOpen){YAHOO.util.Event.stopEvent(A);}}C._selectItem(C._oCurItem);}else{C._toggleContainer(false);}break;case 13:var B=(navigator.userAgent.toLowerCase().indexOf("mac")!=-1);if(!B){if(C._oCurItem){if(C._nKeyCode!=D){if(C._bContainerOpen){YAHOO.util.Event.stopEvent(A);}}C._selectItem(C._oCurItem);}else{C._toggleContainer(false);}}break;case 27:C._toggleContainer(false);return ;case 39:C._jumpSelection();break;case 38:YAHOO.util.Event.stopEvent(A);C._moveSelection(D);break;case 40:YAHOO.util.Event.stopEvent(A);C._moveSelection(D);break;default:break;}};YAHOO.widget.AutoComplete.prototype._onTextboxKeyPress=function(A,C){var D=A.keyCode;var B=(navigator.userAgent.toLowerCase().indexOf("mac")!=-1);if(B){switch(D){case 9:if(C._oCurItem){if(C.delimChar&&(C._nKeyCode!=D)){YAHOO.util.Event.stopEvent(A);}}break;case 13:if(C._oCurItem){if(C._nKeyCode!=D){if(C._bContainerOpen){YAHOO.util.Event.stopEvent(A);}}C._selectItem(C._oCurItem);}else{C._toggleContainer!
 (false);}break;case 38:case 40:YAHOO.util.Event.stopEvent(A);b!
 reak;def
ault:break;}}else{if(D==229){C._queryInterval=setInterval(function(){C._onIMEDetected(C);},500);}}};YAHOO.widget.AutoComplete.prototype._onTextboxKeyUp=function(B,D){D._initProps();var E=B.keyCode;D._nKeyCode=E;var C=this.value;if(D._isIgnoreKey(E)||(C.toLowerCase()==D._sCurQuery)){return ;}else{D._bItemSelected=false;YAHOO.util.Dom.removeClass(D._oCurItem,D.highlightClassName);D._oCurItem=null;D.textboxKeyEvent.fire(D,E);}if(D.queryDelay>0){var A=setTimeout(function(){D._sendQuery(C);},(D.queryDelay*1000));if(D._nDelayID!=-1){clearTimeout(D._nDelayID);}D._nDelayID=A;}else{D._sendQuery(C);}};YAHOO.widget.AutoComplete.prototype._onTextboxFocus=function(A,B){B._oTextbox.setAttribute("autocomplete","off");B._bFocused=true;if(!B._bItemSelected){B.textboxFocusEvent.fire(B);}};YAHOO.widget.AutoComplete.prototype._onTextboxBlur=function(A,B){if(!B._bOverContainer||(B._nKeyCode==9)){if(!B._bItemSelected){var C=B._textMatchesOption();if(!B._bContainerOpen||(B._bContainerOpen&&(C===nu!
 ll))){if(B.forceSelection){B._clearSelection();}else{B.unmatchedItemSelectEvent.fire(B);}}else{if(B.forceSelection){B._selectItem(C);}}}if(B._bContainerOpen){B._toggleContainer(false);}B._cancelIntervalDetection(B);B._bFocused=false;B.textboxBlurEvent.fire(B);}};YAHOO.widget.AutoComplete.prototype._onWindowUnload=function(A,B){if(B&&B._oTextbox&&B.allowBrowserAutocomplete){B._oTextbox.setAttribute("autocomplete","on");}};YAHOO.widget.DataSource=function(){};YAHOO.widget.DataSource.ERROR_DATANULL="Response data was null";YAHOO.widget.DataSource.ERROR_DATAPARSE="Response data could not be parsed";YAHOO.widget.DataSource.prototype.maxCacheEntries=15;YAHOO.widget.DataSource.prototype.queryMatchContains=false;YAHOO.widget.DataSource.prototype.queryMatchSubset=false;YAHOO.widget.DataSource.prototype.queryMatchCase=false;YAHOO.widget.DataSource.prototype.toString=function(){return"DataSource "+this._sName;};YAHOO.widget.DataSource.prototype.getResults=function(A,D,B){var C=this._d!
 oQueryCache(A,D,B);
-if(C.length===0){this.queryEvent.fire(this,B,D);this.doQuery(A,D,B);}};YAHOO.widget.DataSource.prototype.doQuery=function(A,C,B){};YAHOO.widget.DataSource.prototype.flushCache=function(){if(this._aCache){this._aCache=[];}if(this._aCacheHelper){this._aCacheHelper=[];}this.cacheFlushEvent.fire(this);};YAHOO.widget.DataSource.prototype.queryEvent=null;YAHOO.widget.DataSource.prototype.cacheQueryEvent=null;YAHOO.widget.DataSource.prototype.getResultsEvent=null;YAHOO.widget.DataSource.prototype.getCachedResultsEvent=null;YAHOO.widget.DataSource.prototype.dataErrorEvent=null;YAHOO.widget.DataSource.prototype.cacheFlushEvent=null;YAHOO.widget.DataSource._nIndex=0;YAHOO.widget.DataSource.prototype._sName=null;YAHOO.widget.DataSource.prototype._aCache=null;YAHOO.widget.DataSource.prototype._init=function(){var A=this.maxCacheEntries;if(!YAHOO.lang.isNumber(A)||(A<0)){A=0;}if(A>0&&!this._aCache){this._aCache=[];}this._sName="instance"+YAHOO.widget.DataSource._nIndex;YAHOO.widget.Data!
 Source._nIndex++;this.queryEvent=new YAHOO.util.CustomEvent("query",this);this.cacheQueryEvent=new YAHOO.util.CustomEvent("cacheQuery",this);this.getResultsEvent=new YAHOO.util.CustomEvent("getResults",this);this.getCachedResultsEvent=new YAHOO.util.CustomEvent("getCachedResults",this);this.dataErrorEvent=new YAHOO.util.CustomEvent("dataError",this);this.cacheFlushEvent=new YAHOO.util.CustomEvent("cacheFlush",this);};YAHOO.widget.DataSource.prototype._addCacheElem=function(B){var A=this._aCache;if(!A||!B||!B.query||!B.results){return ;}if(A.length>=this.maxCacheEntries){A.shift();}A.push(B);};YAHOO.widget.DataSource.prototype._doQueryCache=function(A,I,N){var H=[];var G=false;var J=this._aCache;var F=(J)?J.length:0;var K=this.queryMatchContains;var D;if((this.maxCacheEntries>0)&&J&&(F>0)){this.cacheQueryEvent.fire(this,N,I);if(!this.queryMatchCase){D=I;I=I.toLowerCase();}for(var P=F-1;P>=0;P--){var E=J[P];var B=E.results;var C=(!this.queryMatchCase)?encodeURIComponent(E.que!
 ry).toLowerCase():encodeURIComponent(E.query);if(C==I){G=true;!
 H=B;if(P
!=F-1){J.splice(P,1);this._addCacheElem(E);}break;}else{if(this.queryMatchSubset){for(var O=I.length-1;O>=0;O--){var R=I.substr(0,O);if(C==R){G=true;for(var M=B.length-1;M>=0;M--){var Q=B[M];var L=(this.queryMatchCase)?encodeURIComponent(Q[0]).indexOf(I):encodeURIComponent(Q[0]).toLowerCase().indexOf(I);if((!K&&(L===0))||(K&&(L>-1))){H.unshift(Q);}}E={};E.query=I;E.results=H;this._addCacheElem(E);break;}}if(G){break;}}}}if(G){this.getCachedResultsEvent.fire(this,N,D,H);A(D,H,N);}}return H;};YAHOO.widget.DS_XHR=function(C,A,D){if(D&&(D.constructor==Object)){for(var B in D){this[B]=D[B];}}if(!YAHOO.lang.isArray(A)||!YAHOO.lang.isString(C)){return ;}this.schema=A;this.scriptURI=C;this._init();};YAHOO.widget.DS_XHR.prototype=new YAHOO.widget.DataSource();YAHOO.widget.DS_XHR.TYPE_JSON=0;YAHOO.widget.DS_XHR.TYPE_XML=1;YAHOO.widget.DS_XHR.TYPE_FLAT=2;YAHOO.widget.DS_XHR.ERROR_DATAXHR="XHR response failed";YAHOO.widget.DS_XHR.prototype.connMgr=YAHOO.util.Connect;YAHOO.widget.DS_XHR.!
 prototype.connTimeout=0;YAHOO.widget.DS_XHR.prototype.scriptURI=null;YAHOO.widget.DS_XHR.prototype.scriptQueryParam="query";YAHOO.widget.DS_XHR.prototype.scriptQueryAppend="";YAHOO.widget.DS_XHR.prototype.responseType=YAHOO.widget.DS_XHR.TYPE_JSON;YAHOO.widget.DS_XHR.prototype.responseStripAfter="\n<!-";YAHOO.widget.DS_XHR.prototype.doQuery=function(E,G,B){var J=(this.responseType==YAHOO.widget.DS_XHR.TYPE_XML);var D=this.scriptURI+"?"+this.scriptQueryParam+"="+G;if(this.scriptQueryAppend.length>0){D+="&"+this.scriptQueryAppend;}var C=null;var F=this;var I=function(K){if(!F._oConn||(K.tId!=F._oConn.tId)){F.dataErrorEvent.fire(F,B,G,YAHOO.widget.DataSource.ERROR_DATANULL);return ;}for(var N in K){}if(!J){K=K.responseText;}else{K=K.responseXML;}if(K===null){F.dataErrorEvent.fire(F,B,G,YAHOO.widget.DataSource.ERROR_DATANULL);return ;}var M=F.parseResponse(G,K,B);var L={};L.query=decodeURIComponent(G);L.results=M;if(M===null){F.dataErrorEvent.fire(F,B,G,YAHOO.widget.DataSource.!
 ERROR_DATAPARSE);M=[];}else{F.getResultsEvent.fire(F,B,G,M);F.!
 _addCach
eElem(L);}E(G,M,B);};var A=function(K){F.dataErrorEvent.fire(F,B,G,YAHOO.widget.DS_XHR.ERROR_DATAXHR);return ;};var H={success:I,failure:A};if(YAHOO.lang.isNumber(this.connTimeout)&&(this.connTimeout>0)){H.timeout=this.connTimeout;}if(this._oConn){this.connMgr.abort(this._oConn);}F._oConn=this.connMgr.asyncRequest("GET",D,H,null);};YAHOO.widget.DS_XHR.prototype.parseResponse=function(sQuery,oResponse,oParent){var aSchema=this.schema;var aResults=[];var bError=false;var nEnd=((this.responseStripAfter!=="")&&(oResponse.indexOf))?oResponse.indexOf(this.responseStripAfter):-1;if(nEnd!=-1){oResponse=oResponse.substring(0,nEnd);}switch(this.responseType){case YAHOO.widget.DS_XHR.TYPE_JSON:var jsonList,jsonObjParsed;var isNotMac=(navigator.userAgent.toLowerCase().indexOf("khtml")==-1);if(oResponse.parseJSON&&isNotMac){jsonObjParsed=oResponse.parseJSON();if(!jsonObjParsed){bError=true;}else{try{jsonList=eval("jsonObjParsed."+aSchema[0]);}catch(e){bError=true;break;}}}else{if(YAHOO.l!
 ang.JSON&&isNotMac){jsonObjParsed=YAHOO.lang.JSON.parse(oResponse);if(!jsonObjParsed){bError=true;break;}else{try{jsonList=eval("jsonObjParsed."+aSchema[0]);}catch(e){bError=true;break;}}}else{if(window.JSON&&isNotMac){jsonObjParsed=JSON.parse(oResponse);if(!jsonObjParsed){bError=true;break;}else{try{jsonList=eval("jsonObjParsed."+aSchema[0]);}catch(e){bError=true;break;}}}else{try{while(oResponse.substring(0,1)==" "){oResponse=oResponse.substring(1,oResponse.length);}if(oResponse.indexOf("{")<0){bError=true;break;}if(oResponse.indexOf("{}")===0){break;}var jsonObjRaw=eval("("+oResponse+")");if(!jsonObjRaw){bError=true;break;}jsonList=eval("(jsonObjRaw."+aSchema[0]+")");}catch(e){bError=true;break;}}}}if(!jsonList){bError=true;break;}if(!YAHOO.lang.isArray(jsonList)){jsonList=[jsonList];}for(var i=jsonList.length-1;i>=0;i--){var aResultItem=[];var jsonResult=jsonList[i];for(var j=aSchema.length-1;j>=1;j--){var dataFieldValue=jsonResult[aSchema[j]];
-if(!dataFieldValue){dataFieldValue="";}aResultItem.unshift(dataFieldValue);}if(aResultItem.length==1){aResultItem.push(jsonResult);}aResults.unshift(aResultItem);}break;case YAHOO.widget.DS_XHR.TYPE_XML:var xmlList=oResponse.getElementsByTagName(aSchema[0]);if(!xmlList){bError=true;break;}for(var k=xmlList.length-1;k>=0;k--){var result=xmlList.item(k);var aFieldSet=[];for(var m=aSchema.length-1;m>=1;m--){var sValue=null;var xmlAttr=result.attributes.getNamedItem(aSchema[m]);if(xmlAttr){sValue=xmlAttr.value;}else{var xmlNode=result.getElementsByTagName(aSchema[m]);if(xmlNode&&xmlNode.item(0)&&xmlNode.item(0).firstChild){sValue=xmlNode.item(0).firstChild.nodeValue;}else{sValue="";}}aFieldSet.unshift(sValue);}aResults.unshift(aFieldSet);}break;case YAHOO.widget.DS_XHR.TYPE_FLAT:if(oResponse.length>0){var newLength=oResponse.length-aSchema[0].length;if(oResponse.substr(newLength)==aSchema[0]){oResponse=oResponse.substr(0,newLength);}var aRecords=oResponse.split(aSchema[0]);for(!
 var n=aRecords.length-1;n>=0;n--){aResults[n]=aRecords[n].split(aSchema[1]);}}break;default:break;}sQuery=null;oResponse=null;oParent=null;if(bError){return null;}else{return aResults;}};YAHOO.widget.DS_XHR.prototype._oConn=null;YAHOO.widget.DS_ScriptNode=function(D,A,C){if(C&&(C.constructor==Object)){for(var B in C){this[B]=C[B];}}if(!YAHOO.lang.isArray(A)||!YAHOO.lang.isString(D)){return ;}this.schema=A;this.scriptURI=D;this._init();};YAHOO.widget.DS_ScriptNode.prototype=new YAHOO.widget.DataSource();YAHOO.widget.DS_ScriptNode.prototype.getUtility=YAHOO.util.Get;YAHOO.widget.DS_ScriptNode.prototype.scriptURI=null;YAHOO.widget.DS_ScriptNode.prototype.scriptQueryParam="query";YAHOO.widget.DS_ScriptNode.prototype.asyncMode="allowAll";YAHOO.widget.DS_ScriptNode.prototype.scriptCallbackParam="callback";YAHOO.widget.DS_ScriptNode.callbacks=[];YAHOO.widget.DS_ScriptNode._nId=0;YAHOO.widget.DS_ScriptNode._nPending=0;YAHOO.widget.DS_ScriptNode.prototype.doQuery=function(A,F,C){var!
  B=this;if(YAHOO.widget.DS_ScriptNode._nPending===0){YAHOO.wid!
 get.DS_S
criptNode.callbacks=[];YAHOO.widget.DS_ScriptNode._nId=0;}var E=YAHOO.widget.DS_ScriptNode._nId;YAHOO.widget.DS_ScriptNode._nId++;YAHOO.widget.DS_ScriptNode.callbacks[E]=function(G){if((B.asyncMode!=="ignoreStaleResponses")||(E===YAHOO.widget.DS_ScriptNode.callbacks.length-1)){B.handleResponse(G,A,F,C);}else{}delete YAHOO.widget.DS_ScriptNode.callbacks[E];};YAHOO.widget.DS_ScriptNode._nPending++;var D=this.scriptURI+"&"+this.scriptQueryParam+"="+F+"&"+this.scriptCallbackParam+"=YAHOO.widget.DS_ScriptNode.callbacks["+E+"]";this.getUtility.script(D,{autopurge:true,onsuccess:YAHOO.widget.DS_ScriptNode._bumpPendingDown,onfail:YAHOO.widget.DS_ScriptNode._bumpPendingDown});};YAHOO.widget.DS_ScriptNode.prototype.handleResponse=function(oResponse,oCallbackFn,sQuery,oParent){var aSchema=this.schema;var aResults=[];var bError=false;var jsonList,jsonObjParsed;try{jsonList=eval("(oResponse."+aSchema[0]+")");}catch(e){bError=true;}if(!jsonList){bError=true;jsonList=[];}else{if(!YAHOO.lan!
 g.isArray(jsonList)){jsonList=[jsonList];}}for(var i=jsonList.length-1;i>=0;i--){var aResultItem=[];var jsonResult=jsonList[i];for(var j=aSchema.length-1;j>=1;j--){var dataFieldValue=jsonResult[aSchema[j]];if(!dataFieldValue){dataFieldValue="";}aResultItem.unshift(dataFieldValue);}if(aResultItem.length==1){aResultItem.push(jsonResult);}aResults.unshift(aResultItem);}if(bError){aResults=null;}if(aResults===null){this.dataErrorEvent.fire(this,oParent,sQuery,YAHOO.widget.DataSource.ERROR_DATAPARSE);aResults=[];}else{var resultObj={};resultObj.query=decodeURIComponent(sQuery);resultObj.results=aResults;this._addCacheElem(resultObj);this.getResultsEvent.fire(this,oParent,sQuery,aResults);}oCallbackFn(sQuery,aResults,oParent);};YAHOO.widget.DS_ScriptNode._bumpPendingDown=function(){YAHOO.widget.DS_ScriptNode._nPending--;};YAHOO.widget.DS_JSFunction=function(A,C){if(C&&(C.constructor==Object)){for(var B in C){this[B]=C[B];}}if(!YAHOO.lang.isFunction(A)){return ;}else{this.dataFunc!
 tion=A;this._init();}};YAHOO.widget.DS_JSFunction.prototype=ne!
 w YAHOO.
widget.DataSource();YAHOO.widget.DS_JSFunction.prototype.dataFunction=null;YAHOO.widget.DS_JSFunction.prototype.doQuery=function(C,F,D){var B=this.dataFunction;var E=[];E=B(F);if(E===null){this.dataErrorEvent.fire(this,D,F,YAHOO.widget.DataSource.ERROR_DATANULL);return ;}var A={};A.query=decodeURIComponent(F);A.results=E;this._addCacheElem(A);this.getResultsEvent.fire(this,D,F,E);C(F,E,D);return ;};YAHOO.widget.DS_JSArray=function(A,C){if(C&&(C.constructor==Object)){for(var B in C){this[B]=C[B];}}if(!YAHOO.lang.isArray(A)){return ;}else{this.data=A;this._init();}};YAHOO.widget.DS_JSArray.prototype=new YAHOO.widget.DataSource();YAHOO.widget.DS_JSArray.prototype.data=null;YAHOO.widget.DS_JSArray.prototype.doQuery=function(E,I,A){var F;var C=this.data;var J=[];var D=false;var B=this.queryMatchContains;if(I){if(!this.queryMatchCase){I=I.toLowerCase();}for(F=C.length-1;F>=0;F--){var H=[];if(YAHOO.lang.isString(C[F])){H[0]=C[F];}else{if(YAHOO.lang.isArray(C[F])){H=C[F];}}if(YAHOO.!
 lang.isString(H[0])){var G=(this.queryMatchCase)?encodeURIComponent(H[0]).indexOf(I):encodeURIComponent(H[0]).toLowerCase().indexOf(I);if((!B&&(G===0))||(B&&(G>-1))){J.unshift(H);}}}}else{for(F=C.length-1;F>=0;F--){if(YAHOO.lang.isString(C[F])){J.unshift([C[F]]);}else{if(YAHOO.lang.isArray(C[F])){J.unshift(C[F]);}}}}this.getResultsEvent.fire(this,A,I,J);E(I,J,A);};YAHOO.register("autocomplete",YAHOO.widget.AutoComplete,{version:"2.4.1",build:"742"});
\ No newline at end of file
+YAHOO.widget.AutoComplete=function(G,B,J,C){if(G&&B&&J){if(J instanceof YAHOO.widget.DataSource){this.dataSource=J;}else{return ;}if(YAHOO.util.Dom.inDocument(G)){if(YAHOO.lang.isString(G)){this._sName="instance"+YAHOO.widget.AutoComplete._nIndex+" "+G;this._elTextbox=document.getElementById(G);}else{this._sName=(G.id)?"instance"+YAHOO.widget.AutoComplete._nIndex+" "+G.id:"instance"+YAHOO.widget.AutoComplete._nIndex;this._elTextbox=G;}YAHOO.util.Dom.addClass(this._elTextbox,"yui-ac-input");}else{return ;}if(YAHOO.util.Dom.inDocument(B)){if(YAHOO.lang.isString(B)){this._elContainer=document.getElementById(B);}else{this._elContainer=B;}if(this._elContainer.style.display=="none"){}var D=this._elContainer.parentNode;var A=D.tagName.toLowerCase();if(A=="div"){YAHOO.util.Dom.addClass(D,"yui-ac");}else{}}else{return ;}if(C&&(C.constructor==Object)){for(var I in C){if(I){this[I]=C[I];}}}this._initContainer();this._initProps();this._initList();this._initContainerHelpers();var H=this!
 ;var F=this._elTextbox;var E=this._elContent;YAHOO.util.Event.addListener(F,"keyup",H._onTextboxKeyUp,H);YAHOO.util.Event.addListener(F,"keydown",H._onTextboxKeyDown,H);YAHOO.util.Event.addListener(F,"focus",H._onTextboxFocus,H);YAHOO.util.Event.addListener(F,"blur",H._onTextboxBlur,H);YAHOO.util.Event.addListener(E,"mouseover",H._onContainerMouseover,H);YAHOO.util.Event.addListener(E,"mouseout",H._onContainerMouseout,H);YAHOO.util.Event.addListener(E,"scroll",H._onContainerScroll,H);YAHOO.util.Event.addListener(E,"resize",H._onContainerResize,H);YAHOO.util.Event.addListener(F,"keypress",H._onTextboxKeyPress,H);YAHOO.util.Event.addListener(window,"unload",H._onWindowUnload,H);this.textboxFocusEvent=new YAHOO.util.CustomEvent("textboxFocus",this);this.textboxKeyEvent=new YAHOO.util.CustomEvent("textboxKey",this);this.dataRequestEvent=new YAHOO.util.CustomEvent("dataRequest",this);this.dataReturnEvent=new YAHOO.util.CustomEvent("dataReturn",this);this.dataErrorEvent=new YAHOO!
 .util.CustomEvent("dataError",this);this.containerExpandEvent=!
 new YAHO
O.util.CustomEvent("containerExpand",this);this.typeAheadEvent=new YAHOO.util.CustomEvent("typeAhead",this);this.itemMouseOverEvent=new YAHOO.util.CustomEvent("itemMouseOver",this);this.itemMouseOutEvent=new YAHOO.util.CustomEvent("itemMouseOut",this);this.itemArrowToEvent=new YAHOO.util.CustomEvent("itemArrowTo",this);this.itemArrowFromEvent=new YAHOO.util.CustomEvent("itemArrowFrom",this);this.itemSelectEvent=new YAHOO.util.CustomEvent("itemSelect",this);this.unmatchedItemSelectEvent=new YAHOO.util.CustomEvent("unmatchedItemSelect",this);this.selectionEnforceEvent=new YAHOO.util.CustomEvent("selectionEnforce",this);this.containerCollapseEvent=new YAHOO.util.CustomEvent("containerCollapse",this);this.textboxBlurEvent=new YAHOO.util.CustomEvent("textboxBlur",this);F.setAttribute("autocomplete","off");YAHOO.widget.AutoComplete._nIndex++;}else{}};YAHOO.widget.AutoComplete.prototype.dataSource=null;YAHOO.widget.AutoComplete.prototype.minQueryLength=1;YAHOO.widget.AutoComplete.p!
 rototype.maxResultsDisplayed=10;YAHOO.widget.AutoComplete.prototype.queryDelay=0.2;YAHOO.widget.AutoComplete.prototype.highlightClassName="yui-ac-highlight";YAHOO.widget.AutoComplete.prototype.prehighlightClassName=null;YAHOO.widget.AutoComplete.prototype.delimChar=null;YAHOO.widget.AutoComplete.prototype.autoHighlight=true;YAHOO.widget.AutoComplete.prototype.typeAhead=false;YAHOO.widget.AutoComplete.prototype.animHoriz=false;YAHOO.widget.AutoComplete.prototype.animVert=true;YAHOO.widget.AutoComplete.prototype.animSpeed=0.3;YAHOO.widget.AutoComplete.prototype.forceSelection=false;YAHOO.widget.AutoComplete.prototype.allowBrowserAutocomplete=true;YAHOO.widget.AutoComplete.prototype.alwaysShowContainer=false;YAHOO.widget.AutoComplete.prototype.useIFrame=false;YAHOO.widget.AutoComplete.prototype.useShadow=false;YAHOO.widget.AutoComplete.prototype.toString=function(){return"AutoComplete "+this._sName;};YAHOO.widget.AutoComplete.prototype.isContainerOpen=function(){return this._b!
 ContainerOpen;};YAHOO.widget.AutoComplete.prototype.getListIte!
 ms=funct
ion(){return this._aListItems;};YAHOO.widget.AutoComplete.prototype.getListItemData=function(A){if(A._oResultData){return A._oResultData;}else{return false;}};YAHOO.widget.AutoComplete.prototype.setHeader=function(B){if(this._elHeader){var A=this._elHeader;if(B){A.innerHTML=B;A.style.display="block";}else{A.innerHTML="";A.style.display="none";}}};YAHOO.widget.AutoComplete.prototype.setFooter=function(B){if(this._elFooter){var A=this._elFooter;if(B){A.innerHTML=B;A.style.display="block";}else{A.innerHTML="";A.style.display="none";}}};YAHOO.widget.AutoComplete.prototype.setBody=function(A){if(this._elBody){var B=this._elBody;if(A){B.innerHTML=A;B.style.display="block";B.style.display="block";}else{B.innerHTML="";B.style.display="none";}this._maxResultsDisplayed=0;}};YAHOO.widget.AutoComplete.prototype.formatResult=function(B,C){var A=B[0];if(A){return A;}else{return"";}};YAHOO.widget.AutoComplete.prototype.doBeforeExpandContainer=function(D,A,C,B){return true;};YAHOO.widget.Au!
 toComplete.prototype.sendQuery=function(A){this._sendQuery(A);};YAHOO.widget.AutoComplete.prototype.doBeforeSendQuery=function(A){return A;};YAHOO.widget.AutoComplete.prototype.destroy=function(){var B=this.toString();var A=this._elTextbox;var D=this._elContainer;this.textboxFocusEvent.unsubscribeAll();this.textboxKeyEvent.unsubscribeAll();this.dataRequestEvent.unsubscribeAll();this.dataReturnEvent.unsubscribeAll();this.dataErrorEvent.unsubscribeAll();this.containerExpandEvent.unsubscribeAll();this.typeAheadEvent.unsubscribeAll();this.itemMouseOverEvent.unsubscribeAll();this.itemMouseOutEvent.unsubscribeAll();this.itemArrowToEvent.unsubscribeAll();this.itemArrowFromEvent.unsubscribeAll();this.itemSelectEvent.unsubscribeAll();this.unmatchedItemSelectEvent.unsubscribeAll();this.selectionEnforceEvent.unsubscribeAll();this.containerCollapseEvent.unsubscribeAll();this.textboxBlurEvent.unsubscribeAll();YAHOO.util.Event.purgeElement(A,true);
+YAHOO.util.Event.purgeElement(D,true);D.innerHTML="";for(var C in this){if(YAHOO.lang.hasOwnProperty(this,C)){this[C]=null;}}};YAHOO.widget.AutoComplete.prototype.textboxFocusEvent=null;YAHOO.widget.AutoComplete.prototype.textboxKeyEvent=null;YAHOO.widget.AutoComplete.prototype.dataRequestEvent=null;YAHOO.widget.AutoComplete.prototype.dataReturnEvent=null;YAHOO.widget.AutoComplete.prototype.dataErrorEvent=null;YAHOO.widget.AutoComplete.prototype.containerExpandEvent=null;YAHOO.widget.AutoComplete.prototype.typeAheadEvent=null;YAHOO.widget.AutoComplete.prototype.itemMouseOverEvent=null;YAHOO.widget.AutoComplete.prototype.itemMouseOutEvent=null;YAHOO.widget.AutoComplete.prototype.itemArrowToEvent=null;YAHOO.widget.AutoComplete.prototype.itemArrowFromEvent=null;YAHOO.widget.AutoComplete.prototype.itemSelectEvent=null;YAHOO.widget.AutoComplete.prototype.unmatchedItemSelectEvent=null;YAHOO.widget.AutoComplete.prototype.selectionEnforceEvent=null;YAHOO.widget.AutoComplete.prototy!
 pe.containerCollapseEvent=null;YAHOO.widget.AutoComplete.prototype.textboxBlurEvent=null;YAHOO.widget.AutoComplete._nIndex=0;YAHOO.widget.AutoComplete.prototype._sName=null;YAHOO.widget.AutoComplete.prototype._elTextbox=null;YAHOO.widget.AutoComplete.prototype._elContainer=null;YAHOO.widget.AutoComplete.prototype._elContent=null;YAHOO.widget.AutoComplete.prototype._elHeader=null;YAHOO.widget.AutoComplete.prototype._elBody=null;YAHOO.widget.AutoComplete.prototype._elFooter=null;YAHOO.widget.AutoComplete.prototype._elShadow=null;YAHOO.widget.AutoComplete.prototype._elIFrame=null;YAHOO.widget.AutoComplete.prototype._bFocused=true;YAHOO.widget.AutoComplete.prototype._oAnim=null;YAHOO.widget.AutoComplete.prototype._bContainerOpen=false;YAHOO.widget.AutoComplete.prototype._bOverContainer=false;YAHOO.widget.AutoComplete.prototype._aListItems=null;YAHOO.widget.AutoComplete.prototype._nDisplayedItems=0;YAHOO.widget.AutoComplete.prototype._maxResultsDisplayed=0;YAHOO.widget.AutoCompl!
 ete.prototype._sCurQuery=null;YAHOO.widget.AutoComplete.protot!
 ype._sSa
vedQuery=null;YAHOO.widget.AutoComplete.prototype._oCurItem=null;YAHOO.widget.AutoComplete.prototype._bItemSelected=false;YAHOO.widget.AutoComplete.prototype._nKeyCode=null;YAHOO.widget.AutoComplete.prototype._nDelayID=-1;YAHOO.widget.AutoComplete.prototype._iFrameSrc="javascript:false;";YAHOO.widget.AutoComplete.prototype._queryInterval=null;YAHOO.widget.AutoComplete.prototype._sLastTextboxValue=null;YAHOO.widget.AutoComplete.prototype._initProps=function(){var B=this.minQueryLength;if(!YAHOO.lang.isNumber(B)){this.minQueryLength=1;}var D=this.maxResultsDisplayed;if(!YAHOO.lang.isNumber(D)||(D<1)){this.maxResultsDisplayed=10;}var E=this.queryDelay;if(!YAHOO.lang.isNumber(E)||(E<0)){this.queryDelay=0.2;}var A=this.delimChar;if(YAHOO.lang.isString(A)&&(A.length>0)){this.delimChar=[A];}else{if(!YAHOO.lang.isArray(A)){this.delimChar=null;}}var C=this.animSpeed;if((this.animHoriz||this.animVert)&&YAHOO.util.Anim){if(!YAHOO.lang.isNumber(C)||(C<0)){this.animSpeed=0.3;}if(!this._o!
 Anim){this._oAnim=new YAHOO.util.Anim(this._elContent,{},this.animSpeed);}else{this._oAnim.duration=this.animSpeed;}}if(this.forceSelection&&A){}};YAHOO.widget.AutoComplete.prototype._initContainerHelpers=function(){if(this.useShadow&&!this._elShadow){var A=document.createElement("div");A.className="yui-ac-shadow";this._elShadow=this._elContainer.appendChild(A);}if(this.useIFrame&&!this._elIFrame){var B=document.createElement("iframe");B.src=this._iFrameSrc;B.frameBorder=0;B.scrolling="no";B.style.position="absolute";B.style.width="100%";B.style.height="100%";B.tabIndex=-1;this._elIFrame=this._elContainer.appendChild(B);}};YAHOO.widget.AutoComplete.prototype._initContainer=function(){YAHOO.util.Dom.addClass(this._elContainer,"yui-ac-container");if(!this._elContent){var C=document.createElement("div");C.className="yui-ac-content";C.style.display="none";this._elContent=this._elContainer.appendChild(C);var B=document.createElement("div");B.className="yui-ac-hd";B.style.display!
 ="none";this._elHeader=this._elContent.appendChild(B);var D=do!
 cument.c
reateElement("div");D.className="yui-ac-bd";this._elBody=this._elContent.appendChild(D);var A=document.createElement("div");A.className="yui-ac-ft";A.style.display="none";this._elFooter=this._elContent.appendChild(A);}else{}};YAHOO.widget.AutoComplete.prototype._initList=function(){this._aListItems=[];while(this._elBody.hasChildNodes()){var B=this.getListItems();if(B){for(var A=B.length-1;A>=0;A--){B[A]=null;}}this._elBody.innerHTML="";}var E=document.createElement("ul");E=this._elBody.appendChild(E);for(var C=0;C<this.maxResultsDisplayed;C++){var D=document.createElement("li");D=E.appendChild(D);this._aListItems[C]=D;this._initListItem(D,C);}this._maxResultsDisplayed=this.maxResultsDisplayed;};YAHOO.widget.AutoComplete.prototype._initListItem=function(C,B){var A=this;C.style.display="none";C._nItemIndex=B;C.mouseover=C.mouseout=C.onclick=null;YAHOO.util.Event.addListener(C,"mouseover",A._onItemMouseover,A);YAHOO.util.Event.addListener(C,"mouseout",A._onItemMouseout,A);YAHOO!
 .util.Event.addListener(C,"click",A._onItemMouseclick,A);};YAHOO.widget.AutoComplete.prototype._onIMEDetected=function(A){A._enableIntervalDetection();};YAHOO.widget.AutoComplete.prototype._enableIntervalDetection=function(){var A=this._elTextbox.value;var B=this._sLastTextboxValue;if(A!=B){this._sLastTextboxValue=A;this._sendQuery(A);}};YAHOO.widget.AutoComplete.prototype._cancelIntervalDetection=function(A){if(A._queryInterval){clearInterval(A._queryInterval);}};YAHOO.widget.AutoComplete.prototype._isIgnoreKey=function(A){if((A==9)||(A==13)||(A==16)||(A==17)||(A>=18&&A<=20)||(A==27)||(A>=33&&A<=35)||(A>=36&&A<=40)||(A>=44&&A<=45)){return true;}return false;};YAHOO.widget.AutoComplete.prototype._sendQuery=function(G){if(this.minQueryLength==-1){this._toggleContainer(false);return ;}var C=(this.delimChar)?this.delimChar:null;if(C){var E=-1;for(var B=C.length-1;B>=0;B--){var F=G.lastIndexOf(C[B]);if(F>E){E=F;
+}}if(C[B]==" "){for(var A=C.length-1;A>=0;A--){if(G[E-1]==C[A]){E--;break;}}}if(E>-1){var D=E+1;while(G.charAt(D)==" "){D+=1;}this._sSavedQuery=G.substring(0,D);G=G.substr(D);}else{if(G.indexOf(this._sSavedQuery)<0){this._sSavedQuery=null;}}}if((G&&(G.length<this.minQueryLength))||(!G&&this.minQueryLength>0)){if(this._nDelayID!=-1){clearTimeout(this._nDelayID);}this._toggleContainer(false);return ;}G=encodeURIComponent(G);this._nDelayID=-1;G=this.doBeforeSendQuery(G);this.dataRequestEvent.fire(this,G);this.dataSource.getResults(this._populateList,G,this);};YAHOO.widget.AutoComplete.prototype._populateList=function(K,L,I){if(L===null){I.dataErrorEvent.fire(I,K);}if(!I._bFocused||!L){return ;}var A=(navigator.userAgent.toLowerCase().indexOf("opera")!=-1);var O=I._elContent.style;O.width=(!A)?null:"";O.height=(!A)?null:"";var H=decodeURIComponent(K);I._sCurQuery=H;I._bItemSelected=false;if(I._maxResultsDisplayed!=I.maxResultsDisplayed){I._initList();}var C=Math.min(L.length,I.!
 maxResultsDisplayed);I._nDisplayedItems=C;if(C>0){I._initContainerHelpers();var D=I._aListItems;for(var G=C-1;G>=0;G--){var N=D[G];var B=L[G];N.innerHTML=I.formatResult(B,H);N.style.display="list-item";N._sResultKey=B[0];N._oResultData=B;}for(var F=D.length-1;F>=C;F--){var M=D[F];M.innerHTML=null;M.style.display="none";M._sResultKey=null;M._oResultData=null;}var J=I.doBeforeExpandContainer(I._elTextbox,I._elContainer,K,L);I._toggleContainer(J);if(I.autoHighlight){var E=D[0];I._toggleHighlight(E,"to");I.itemArrowToEvent.fire(I,E);I._typeAhead(E,K);}else{I._oCurItem=null;}}else{I._toggleContainer(false);}I.dataReturnEvent.fire(I,K,L);};YAHOO.widget.AutoComplete.prototype._clearSelection=function(){var C=this._elTextbox.value;var B=(this.delimChar)?this.delimChar[0]:null;var A=(B)?C.lastIndexOf(B,C.length-2):-1;if(A>-1){this._elTextbox.value=C.substring(0,A);}else{this._elTextbox.value="";}this._sSavedQuery=this._elTextbox.value;this.selectionEnforceEvent.fire(this);};YAHOO.wi!
 dget.AutoComplete.prototype._textMatchesOption=function(){var !
 D=null;f
or(var A=this._nDisplayedItems-1;A>=0;A--){var C=this._aListItems[A];var B=C._sResultKey.toLowerCase();if(B==this._sCurQuery.toLowerCase()){D=C;break;}}return(D);};YAHOO.widget.AutoComplete.prototype._typeAhead=function(D,G){if(!this.typeAhead||(this._nKeyCode==8)){return ;}var F=this._elTextbox;var E=this._elTextbox.value;if(!F.setSelectionRange&&!F.createTextRange){return ;}var B=E.length;this._updateValue(D);var C=F.value.length;this._selectText(F,B,C);var A=F.value.substr(B,C);this.typeAheadEvent.fire(this,G,A);};YAHOO.widget.AutoComplete.prototype._selectText=function(D,A,B){if(D.setSelectionRange){D.setSelectionRange(A,B);}else{if(D.createTextRange){var C=D.createTextRange();C.moveStart("character",A);C.moveEnd("character",B-D.value.length);C.select();}else{D.select();}}};YAHOO.widget.AutoComplete.prototype._toggleContainerHelpers=function(B){var D=false;var C=this._elContent.offsetWidth+"px";var A=this._elContent.offsetHeight+"px";if(this.useIFrame&&this._elIFrame){D=!
 true;if(B){this._elIFrame.style.width=C;this._elIFrame.style.height=A;}else{this._elIFrame.style.width=0;this._elIFrame.style.height=0;}}if(this.useShadow&&this._elShadow){D=true;if(B){this._elShadow.style.width=C;this._elShadow.style.height=A;}else{this._elShadow.style.width=0;this._elShadow.style.height=0;}}};YAHOO.widget.AutoComplete.prototype._toggleContainer=function(K){var E=this._elContainer;if(this.alwaysShowContainer&&this._bContainerOpen){return ;}if(!K){this._elContent.scrollTop=0;var C=this._aListItems;if(C&&(C.length>0)){for(var H=C.length-1;H>=0;H--){C[H].style.display="none";}}if(this._oCurItem){this._toggleHighlight(this._oCurItem,"from");}this._oCurItem=null;this._nDisplayedItems=0;this._sCurQuery=null;}if(!K&&!this._bContainerOpen){this._elContent.style.display="none";return ;}var B=this._oAnim;if(B&&B.getEl()&&(this.animHoriz||this.animVert)){if(!K){this._toggleContainerHelpers(K);}if(B.isAnimated()){B.stop();}var I=this._elContent.cloneNode(true);E.appen!
 dChild(I);I.style.top="-9000px";I.style.display="block";var G=!
 I.offset
Width;var D=I.offsetHeight;var A=(this.animHoriz)?0:G;var F=(this.animVert)?0:D;B.attributes=(K)?{width:{to:G},height:{to:D}}:{width:{to:A},height:{to:F}};if(K&&!this._bContainerOpen){this._elContent.style.width=A+"px";this._elContent.style.height=F+"px";}else{this._elContent.style.width=G+"px";this._elContent.style.height=D+"px";}E.removeChild(I);I=null;var J=this;var L=function(){B.onComplete.unsubscribeAll();if(K){J.containerExpandEvent.fire(J);}else{J._elContent.style.display="none";J.containerCollapseEvent.fire(J);}J._toggleContainerHelpers(K);};this._elContent.style.display="block";B.onComplete.subscribe(L);B.animate();this._bContainerOpen=K;}else{if(K){this._elContent.style.display="block";this.containerExpandEvent.fire(this);}else{this._elContent.style.display="none";this.containerCollapseEvent.fire(this);}this._toggleContainerHelpers(K);this._bContainerOpen=K;}};YAHOO.widget.AutoComplete.prototype._toggleHighlight=function(A,C){var B=this.highlightClassName;if(this.!
 _oCurItem){YAHOO.util.Dom.removeClass(this._oCurItem,B);}if((C=="to")&&B){YAHOO.util.Dom.addClass(A,B);this._oCurItem=A;}};YAHOO.widget.AutoComplete.prototype._togglePrehighlight=function(A,C){if(A==this._oCurItem){return ;}var B=this.prehighlightClassName;if((C=="mouseover")&&B){YAHOO.util.Dom.addClass(A,B);}else{YAHOO.util.Dom.removeClass(A,B);}};YAHOO.widget.AutoComplete.prototype._updateValue=function(E){var F=this._elTextbox;var D=(this.delimChar)?(this.delimChar[0]||this.delimChar):null;var B=this._sSavedQuery;var C=E._sResultKey;F.focus();F.value="";if(D){if(B){F.value=B;}F.value+=C+D;if(D!=" "){F.value+=" ";}}else{F.value=C;}if(F.type=="textarea"){F.scrollTop=F.scrollHeight;}var A=F.value.length;this._selectText(F,A,A);this._oCurItem=E;};YAHOO.widget.AutoComplete.prototype._selectItem=function(A){this._bItemSelected=true;this._updateValue(A);this._cancelIntervalDetection(this);this.itemSelectEvent.fire(this,A,A._oResultData);
+this._toggleContainer(false);};YAHOO.widget.AutoComplete.prototype._jumpSelection=function(){if(this._oCurItem){this._selectItem(this._oCurItem);}else{this._toggleContainer(false);}};YAHOO.widget.AutoComplete.prototype._moveSelection=function(G){if(this._bContainerOpen){var E=this._oCurItem;var F=-1;if(E){F=E._nItemIndex;}var D=(G==40)?(F+1):(F-1);if(D<-2||D>=this._nDisplayedItems){return ;}if(E){this._toggleHighlight(E,"from");this.itemArrowFromEvent.fire(this,E);}if(D==-1){if(this.delimChar&&this._sSavedQuery){if(!this._textMatchesOption()){this._elTextbox.value=this._sSavedQuery;}else{this._elTextbox.value=this._sSavedQuery+this._sCurQuery;}}else{this._elTextbox.value=this._sCurQuery;}this._oCurItem=null;return ;}if(D==-2){this._toggleContainer(false);return ;}var C=this._aListItems[D];var A=this._elContent;var B=((YAHOO.util.Dom.getStyle(A,"overflow")=="auto")||(YAHOO.util.Dom.getStyle(A,"overflowY")=="auto"));if(B&&(D>-1)&&(D<this._nDisplayedItems)){if(G==40){if((C.off!
 setTop+C.offsetHeight)>(A.scrollTop+A.offsetHeight)){A.scrollTop=(C.offsetTop+C.offsetHeight)-A.offsetHeight;}else{if((C.offsetTop+C.offsetHeight)<A.scrollTop){A.scrollTop=C.offsetTop;}}}else{if(C.offsetTop<A.scrollTop){this._elContent.scrollTop=C.offsetTop;}else{if(C.offsetTop>(A.scrollTop+A.offsetHeight)){this._elContent.scrollTop=(C.offsetTop+C.offsetHeight)-A.offsetHeight;}}}}this._toggleHighlight(C,"to");this.itemArrowToEvent.fire(this,C);if(this.typeAhead){this._updateValue(C);}}};YAHOO.widget.AutoComplete.prototype._onItemMouseover=function(A,B){if(B.prehighlightClassName){B._togglePrehighlight(this,"mouseover");}else{B._toggleHighlight(this,"to");}B.itemMouseOverEvent.fire(B,this);};YAHOO.widget.AutoComplete.prototype._onItemMouseout=function(A,B){if(B.prehighlightClassName){B._togglePrehighlight(this,"mouseout");}else{B._toggleHighlight(this,"from");}B.itemMouseOutEvent.fire(B,this);};YAHOO.widget.AutoComplete.prototype._onItemMouseclick=function(A,B){B._toggleHigh!
 light(this,"to");B._selectItem(this);};YAHOO.widget.AutoComple!
 te.proto
type._onContainerMouseover=function(A,B){B._bOverContainer=true;};YAHOO.widget.AutoComplete.prototype._onContainerMouseout=function(A,B){B._bOverContainer=false;if(B._oCurItem){B._toggleHighlight(B._oCurItem,"to");}};YAHOO.widget.AutoComplete.prototype._onContainerScroll=function(A,B){B._elTextbox.focus();};YAHOO.widget.AutoComplete.prototype._onContainerResize=function(A,B){B._toggleContainerHelpers(B._bContainerOpen);};YAHOO.widget.AutoComplete.prototype._onTextboxKeyDown=function(A,B){var C=A.keyCode;switch(C){case 9:if(B._oCurItem){if(B.delimChar&&(B._nKeyCode!=C)){if(B._bContainerOpen){YAHOO.util.Event.stopEvent(A);}}B._selectItem(B._oCurItem);}else{B._toggleContainer(false);}break;case 13:if(!YAHOO.env.ua.webkit){if(B._oCurItem){if(B._nKeyCode!=C){if(B._bContainerOpen){YAHOO.util.Event.stopEvent(A);}}B._selectItem(B._oCurItem);}else{B._toggleContainer(false);}}break;case 27:B._toggleContainer(false);return ;case 39:B._jumpSelection();break;case 38:YAHOO.util.Event.stop!
 Event(A);B._moveSelection(C);break;case 40:YAHOO.util.Event.stopEvent(A);B._moveSelection(C);break;default:break;}};YAHOO.widget.AutoComplete.prototype._onTextboxKeyPress=function(A,B){var C=A.keyCode;if(YAHOO.env.ua.webkit){switch(C){case 9:if(B._oCurItem){if(B.delimChar&&(B._nKeyCode!=C)){YAHOO.util.Event.stopEvent(A);}}break;case 13:if(B._oCurItem){if(B._nKeyCode!=C){if(B._bContainerOpen){YAHOO.util.Event.stopEvent(A);}}B._selectItem(B._oCurItem);}else{B._toggleContainer(false);}break;default:break;}}else{if(C==229){B._queryInterval=setInterval(function(){B._onIMEDetected(B);},500);}}};YAHOO.widget.AutoComplete.prototype._onTextboxKeyUp=function(B,D){D._initProps();var E=B.keyCode;D._nKeyCode=E;var C=this.value;if(D._isIgnoreKey(E)||(C.toLowerCase()==D._sCurQuery)){return ;}else{D._bItemSelected=false;YAHOO.util.Dom.removeClass(D._oCurItem,D.highlightClassName);D._oCurItem=null;D.textboxKeyEvent.fire(D,E);}if(D.queryDelay>0){var A=setTimeout(function(){D._sendQuery(C);},!
 (D.queryDelay*1000));if(D._nDelayID!=-1){clearTimeout(D._nDela!
 yID);}D.
_nDelayID=A;}else{D._sendQuery(C);}};YAHOO.widget.AutoComplete.prototype._onTextboxFocus=function(A,B){B._elTextbox.setAttribute("autocomplete","off");B._bFocused=true;if(!B._bItemSelected){B.textboxFocusEvent.fire(B);}};YAHOO.widget.AutoComplete.prototype._onTextboxBlur=function(A,B){if(!B._bOverContainer||(B._nKeyCode==9)){if(!B._bItemSelected){var C=B._textMatchesOption();if(!B._bContainerOpen||(B._bContainerOpen&&(C===null))){if(B.forceSelection){B._clearSelection();}else{B.unmatchedItemSelectEvent.fire(B);}}else{if(B.forceSelection){B._selectItem(C);}}}if(B._bContainerOpen){B._toggleContainer(false);}B._cancelIntervalDetection(B);B._bFocused=false;B.textboxBlurEvent.fire(B);}};YAHOO.widget.AutoComplete.prototype._onWindowUnload=function(A,B){if(B&&B._elTextbox&&B.allowBrowserAutocomplete){B._elTextbox.setAttribute("autocomplete","on");}};YAHOO.widget.DataSource=function(){};YAHOO.widget.DataSource.ERROR_DATANULL="Response data was null";YAHOO.widget.DataSource.ERROR_DAT!
 APARSE="Response data could not be parsed";YAHOO.widget.DataSource.prototype.maxCacheEntries=15;YAHOO.widget.DataSource.prototype.queryMatchContains=false;YAHOO.widget.DataSource.prototype.queryMatchSubset=false;YAHOO.widget.DataSource.prototype.queryMatchCase=false;YAHOO.widget.DataSource.prototype.toString=function(){return"DataSource "+this._sName;};YAHOO.widget.DataSource.prototype.getResults=function(A,D,B){var C=this._doQueryCache(A,D,B);if(C.length===0){this.queryEvent.fire(this,B,D);this.doQuery(A,D,B);}};YAHOO.widget.DataSource.prototype.doQuery=function(A,C,B){};YAHOO.widget.DataSource.prototype.flushCache=function(){if(this._aCache){this._aCache=[];}if(this._aCacheHelper){this._aCacheHelper=[];}this.cacheFlushEvent.fire(this);};YAHOO.widget.DataSource.prototype.queryEvent=null;YAHOO.widget.DataSource.prototype.cacheQueryEvent=null;YAHOO.widget.DataSource.prototype.getResultsEvent=null;YAHOO.widget.DataSource.prototype.getCachedResultsEvent=null;
+YAHOO.widget.DataSource.prototype.dataErrorEvent=null;YAHOO.widget.DataSource.prototype.cacheFlushEvent=null;YAHOO.widget.DataSource._nIndex=0;YAHOO.widget.DataSource.prototype._sName=null;YAHOO.widget.DataSource.prototype._aCache=null;YAHOO.widget.DataSource.prototype._init=function(){var A=this.maxCacheEntries;if(!YAHOO.lang.isNumber(A)||(A<0)){A=0;}if(A>0&&!this._aCache){this._aCache=[];}this._sName="instance"+YAHOO.widget.DataSource._nIndex;YAHOO.widget.DataSource._nIndex++;this.queryEvent=new YAHOO.util.CustomEvent("query",this);this.cacheQueryEvent=new YAHOO.util.CustomEvent("cacheQuery",this);this.getResultsEvent=new YAHOO.util.CustomEvent("getResults",this);this.getCachedResultsEvent=new YAHOO.util.CustomEvent("getCachedResults",this);this.dataErrorEvent=new YAHOO.util.CustomEvent("dataError",this);this.cacheFlushEvent=new YAHOO.util.CustomEvent("cacheFlush",this);};YAHOO.widget.DataSource.prototype._addCacheElem=function(B){var A=this._aCache;if(!A||!B||!B.query||!!
 B.results){return ;}if(A.length>=this.maxCacheEntries){A.shift();}A.push(B);};YAHOO.widget.DataSource.prototype._doQueryCache=function(A,I,N){var H=[];var G=false;var J=this._aCache;var F=(J)?J.length:0;var K=this.queryMatchContains;var D;if((this.maxCacheEntries>0)&&J&&(F>0)){this.cacheQueryEvent.fire(this,N,I);if(!this.queryMatchCase){D=I;I=I.toLowerCase();}for(var P=F-1;P>=0;P--){var E=J[P];var B=E.results;var C=(!this.queryMatchCase)?encodeURIComponent(E.query).toLowerCase():encodeURIComponent(E.query);if(C==I){G=true;H=B;if(P!=F-1){J.splice(P,1);this._addCacheElem(E);}break;}else{if(this.queryMatchSubset){for(var O=I.length-1;O>=0;O--){var R=I.substr(0,O);if(C==R){G=true;for(var M=B.length-1;M>=0;M--){var Q=B[M];var L=(this.queryMatchCase)?encodeURIComponent(Q[0]).indexOf(I):encodeURIComponent(Q[0]).toLowerCase().indexOf(I);if((!K&&(L===0))||(K&&(L>-1))){H.unshift(Q);}}E={};E.query=I;E.results=H;this._addCacheElem(E);break;}}if(G){break;}}}}if(G){this.getCachedResultsE!
 vent.fire(this,N,D,H);A(D,H,N);}}return H;};YAHOO.widget.DS_XH!
 R=functi
on(C,A,D){if(D&&(D.constructor==Object)){for(var B in D){this[B]=D[B];}}if(!YAHOO.lang.isArray(A)||!YAHOO.lang.isString(C)){return ;}this.schema=A;this.scriptURI=C;this._init();};YAHOO.widget.DS_XHR.prototype=new YAHOO.widget.DataSource();YAHOO.widget.DS_XHR.TYPE_JSON=0;YAHOO.widget.DS_XHR.TYPE_XML=1;YAHOO.widget.DS_XHR.TYPE_FLAT=2;YAHOO.widget.DS_XHR.ERROR_DATAXHR="XHR response failed";YAHOO.widget.DS_XHR.prototype.connMgr=YAHOO.util.Connect;YAHOO.widget.DS_XHR.prototype.connTimeout=0;YAHOO.widget.DS_XHR.prototype.scriptURI=null;YAHOO.widget.DS_XHR.prototype.scriptQueryParam="query";YAHOO.widget.DS_XHR.prototype.scriptQueryAppend="";YAHOO.widget.DS_XHR.prototype.responseType=YAHOO.widget.DS_XHR.TYPE_JSON;YAHOO.widget.DS_XHR.prototype.responseStripAfter="\n<!-";YAHOO.widget.DS_XHR.prototype.doQuery=function(E,G,B){var J=(this.responseType==YAHOO.widget.DS_XHR.TYPE_XML);var D=this.scriptURI+"?"+this.scriptQueryParam+"="+G;if(this.scriptQueryAppend.length>0){D+="&"+this.script!
 QueryAppend;}var C=null;var F=this;var I=function(K){if(!F._oConn||(K.tId!=F._oConn.tId)){F.dataErrorEvent.fire(F,B,G,YAHOO.widget.DataSource.ERROR_DATANULL);return ;}for(var N in K){}if(!J){K=K.responseText;}else{K=K.responseXML;}if(K===null){F.dataErrorEvent.fire(F,B,G,YAHOO.widget.DataSource.ERROR_DATANULL);return ;}var M=F.parseResponse(G,K,B);var L={};L.query=decodeURIComponent(G);L.results=M;if(M===null){F.dataErrorEvent.fire(F,B,G,YAHOO.widget.DataSource.ERROR_DATAPARSE);M=[];}else{F.getResultsEvent.fire(F,B,G,M);F._addCacheElem(L);}E(G,M,B);};var A=function(K){F.dataErrorEvent.fire(F,B,G,YAHOO.widget.DS_XHR.ERROR_DATAXHR);return ;};var H={success:I,failure:A};if(YAHOO.lang.isNumber(this.connTimeout)&&(this.connTimeout>0)){H.timeout=this.connTimeout;}if(this._oConn){this.connMgr.abort(this._oConn);}F._oConn=this.connMgr.asyncRequest("GET",D,H,null);};YAHOO.widget.DS_XHR.prototype.parseResponse=function(sQuery,oResponse,oParent){var aSchema=this.schema;var aResults=[]!
 ;var bError=false;var nEnd=((this.responseStripAfter!=="")&&(o!
 Response
.indexOf))?oResponse.indexOf(this.responseStripAfter):-1;if(nEnd!=-1){oResponse=oResponse.substring(0,nEnd);}switch(this.responseType){case YAHOO.widget.DS_XHR.TYPE_JSON:var jsonList,jsonObjParsed;if(YAHOO.lang.JSON){jsonObjParsed=YAHOO.lang.JSON.parse(oResponse);if(!jsonObjParsed){bError=true;break;}else{try{jsonList=eval("jsonObjParsed."+aSchema[0]);}catch(e){bError=true;break;}}}else{if(oResponse.parseJSON){jsonObjParsed=oResponse.parseJSON();if(!jsonObjParsed){bError=true;}else{try{jsonList=eval("jsonObjParsed."+aSchema[0]);}catch(e){bError=true;break;}}}else{if(window.JSON){jsonObjParsed=JSON.parse(oResponse);if(!jsonObjParsed){bError=true;break;}else{try{jsonList=eval("jsonObjParsed."+aSchema[0]);}catch(e){bError=true;break;}}}else{try{while(oResponse.substring(0,1)==" "){oResponse=oResponse.substring(1,oResponse.length);}if(oResponse.indexOf("{")<0){bError=true;break;}if(oResponse.indexOf("{}")===0){break;}var jsonObjRaw=eval("("+oResponse+")");if(!jsonObjRaw){bError=!
 true;break;}jsonList=eval("(jsonObjRaw."+aSchema[0]+")");}catch(e){bError=true;break;}}}}if(!jsonList){bError=true;break;}if(!YAHOO.lang.isArray(jsonList)){jsonList=[jsonList];}for(var i=jsonList.length-1;i>=0;i--){var aResultItem=[];var jsonResult=jsonList[i];for(var j=aSchema.length-1;j>=1;j--){var dataFieldValue=jsonResult[aSchema[j]];if(!dataFieldValue){dataFieldValue="";}aResultItem.unshift(dataFieldValue);}if(aResultItem.length==1){aResultItem.push(jsonResult);}aResults.unshift(aResultItem);}break;case YAHOO.widget.DS_XHR.TYPE_XML:var xmlList=oResponse.getElementsByTagName(aSchema[0]);if(!xmlList){bError=true;break;}for(var k=xmlList.length-1;k>=0;k--){var result=xmlList.item(k);var aFieldSet=[];for(var m=aSchema.length-1;m>=1;m--){var sValue=null;var xmlAttr=result.attributes.getNamedItem(aSchema[m]);if(xmlAttr){sValue=xmlAttr.value;}else{var xmlNode=result.getElementsByTagName(aSchema[m]);if(xmlNode&&xmlNode.item(0)&&xmlNode.item(0).firstChild){sValue=xmlNode.item(0!
 ).firstChild.nodeValue;
+}else{sValue="";}}aFieldSet.unshift(sValue);}aResults.unshift(aFieldSet);}break;case YAHOO.widget.DS_XHR.TYPE_FLAT:if(oResponse.length>0){var newLength=oResponse.length-aSchema[0].length;if(oResponse.substr(newLength)==aSchema[0]){oResponse=oResponse.substr(0,newLength);}var aRecords=oResponse.split(aSchema[0]);for(var n=aRecords.length-1;n>=0;n--){aResults[n]=aRecords[n].split(aSchema[1]);}}break;default:break;}sQuery=null;oResponse=null;oParent=null;if(bError){return null;}else{return aResults;}};YAHOO.widget.DS_XHR.prototype._oConn=null;YAHOO.widget.DS_ScriptNode=function(D,A,C){if(C&&(C.constructor==Object)){for(var B in C){this[B]=C[B];}}if(!YAHOO.lang.isArray(A)||!YAHOO.lang.isString(D)){return ;}this.schema=A;this.scriptURI=D;this._init();};YAHOO.widget.DS_ScriptNode.prototype=new YAHOO.widget.DataSource();YAHOO.widget.DS_ScriptNode.prototype.getUtility=YAHOO.util.Get;YAHOO.widget.DS_ScriptNode.prototype.scriptURI=null;YAHOO.widget.DS_ScriptNode.prototype.scriptQuery!
 Param="query";YAHOO.widget.DS_ScriptNode.prototype.asyncMode="allowAll";YAHOO.widget.DS_ScriptNode.prototype.scriptCallbackParam="callback";YAHOO.widget.DS_ScriptNode.callbacks=[];YAHOO.widget.DS_ScriptNode._nId=0;YAHOO.widget.DS_ScriptNode._nPending=0;YAHOO.widget.DS_ScriptNode.prototype.doQuery=function(A,F,C){var B=this;if(YAHOO.widget.DS_ScriptNode._nPending===0){YAHOO.widget.DS_ScriptNode.callbacks=[];YAHOO.widget.DS_ScriptNode._nId=0;}var E=YAHOO.widget.DS_ScriptNode._nId;YAHOO.widget.DS_ScriptNode._nId++;YAHOO.widget.DS_ScriptNode.callbacks[E]=function(G){if((B.asyncMode!=="ignoreStaleResponses")||(E===YAHOO.widget.DS_ScriptNode.callbacks.length-1)){B.handleResponse(G,A,F,C);}else{}delete YAHOO.widget.DS_ScriptNode.callbacks[E];};YAHOO.widget.DS_ScriptNode._nPending++;var D=this.scriptURI+"&"+this.scriptQueryParam+"="+F+"&"+this.scriptCallbackParam+"=YAHOO.widget.DS_ScriptNode.callbacks["+E+"]";this.getUtility.script(D,{autopurge:true,onsuccess:YAHOO.widget.DS_Script!
 Node._bumpPendingDown,onfail:YAHOO.widget.DS_ScriptNode._bumpP!
 endingDo
wn});};YAHOO.widget.DS_ScriptNode.prototype.handleResponse=function(oResponse,oCallbackFn,sQuery,oParent){var aSchema=this.schema;var aResults=[];var bError=false;var jsonList,jsonObjParsed;try{jsonList=eval("(oResponse."+aSchema[0]+")");}catch(e){bError=true;}if(!jsonList){bError=true;jsonList=[];}else{if(!YAHOO.lang.isArray(jsonList)){jsonList=[jsonList];}}for(var i=jsonList.length-1;i>=0;i--){var aResultItem=[];var jsonResult=jsonList[i];for(var j=aSchema.length-1;j>=1;j--){var dataFieldValue=jsonResult[aSchema[j]];if(!dataFieldValue){dataFieldValue="";}aResultItem.unshift(dataFieldValue);}if(aResultItem.length==1){aResultItem.push(jsonResult);}aResults.unshift(aResultItem);}if(bError){aResults=null;}if(aResults===null){this.dataErrorEvent.fire(this,oParent,sQuery,YAHOO.widget.DataSource.ERROR_DATAPARSE);aResults=[];}else{var resultObj={};resultObj.query=decodeURIComponent(sQuery);resultObj.results=aResults;this._addCacheElem(resultObj);this.getResultsEvent.fire(this,oPar!
 ent,sQuery,aResults);}oCallbackFn(sQuery,aResults,oParent);};YAHOO.widget.DS_ScriptNode._bumpPendingDown=function(){YAHOO.widget.DS_ScriptNode._nPending--;};YAHOO.widget.DS_JSFunction=function(A,C){if(C&&(C.constructor==Object)){for(var B in C){this[B]=C[B];}}if(!YAHOO.lang.isFunction(A)){return ;}else{this.dataFunction=A;this._init();}};YAHOO.widget.DS_JSFunction.prototype=new YAHOO.widget.DataSource();YAHOO.widget.DS_JSFunction.prototype.dataFunction=null;YAHOO.widget.DS_JSFunction.prototype.doQuery=function(C,F,D){var B=this.dataFunction;var E=[];E=B(F);if(E===null){this.dataErrorEvent.fire(this,D,F,YAHOO.widget.DataSource.ERROR_DATANULL);return ;}var A={};A.query=decodeURIComponent(F);A.results=E;this._addCacheElem(A);this.getResultsEvent.fire(this,D,F,E);C(F,E,D);return ;};YAHOO.widget.DS_JSArray=function(A,C){if(C&&(C.constructor==Object)){for(var B in C){this[B]=C[B];}}if(!YAHOO.lang.isArray(A)){return ;}else{this.data=A;this._init();}};YAHOO.widget.DS_JSArray.protot!
 ype=new YAHOO.widget.DataSource();YAHOO.widget.DS_JSArray.prot!
 otype.da
ta=null;YAHOO.widget.DS_JSArray.prototype.doQuery=function(E,I,A){var F;var C=this.data;var J=[];var D=false;var B=this.queryMatchContains;if(I){if(!this.queryMatchCase){I=I.toLowerCase();}for(F=C.length-1;F>=0;F--){var H=[];if(YAHOO.lang.isString(C[F])){H[0]=C[F];}else{if(YAHOO.lang.isArray(C[F])){H=C[F];}}if(YAHOO.lang.isString(H[0])){var G=(this.queryMatchCase)?encodeURIComponent(H[0]).indexOf(I):encodeURIComponent(H[0]).toLowerCase().indexOf(I);if((!B&&(G===0))||(B&&(G>-1))){J.unshift(H);}}}}else{for(F=C.length-1;F>=0;F--){if(YAHOO.lang.isString(C[F])){J.unshift([C[F]]);}else{if(YAHOO.lang.isArray(C[F])){J.unshift(C[F]);}}}}this.getResultsEvent.fire(this,A,I,J);E(I,J,A);};YAHOO.register("autocomplete",YAHOO.widget.AutoComplete,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/autocomplete/autocomplete.js
===================================================================
--- trunk/root/static/yui/autocomplete/autocomplete.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/autocomplete/autocomplete.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
  /**
  * The AutoComplete control provides the front-end logic for text-entry suggestion and
@@ -10,7 +10,7 @@
  *
  * @module autocomplete
  * @requires yahoo, dom, event, datasource
- * @optional animation, connection
+ * @optional animation, connection, get
  * @namespace YAHOO.widget
  * @title AutoComplete Widget
  */
@@ -53,15 +53,15 @@
         if(YAHOO.util.Dom.inDocument(elInput)) {
             if(YAHOO.lang.isString(elInput)) {
                     this._sName = "instance" + YAHOO.widget.AutoComplete._nIndex + " " + elInput;
-                    this._oTextbox = document.getElementById(elInput);
+                    this._elTextbox = document.getElementById(elInput);
             }
             else {
                 this._sName = (elInput.id) ?
                     "instance" + YAHOO.widget.AutoComplete._nIndex + " " + elInput.id:
                     "instance" + YAHOO.widget.AutoComplete._nIndex;
-                this._oTextbox = elInput;
+                this._elTextbox = elInput;
             }
-            YAHOO.util.Dom.addClass(this._oTextbox, "yui-ac-input");
+            YAHOO.util.Dom.addClass(this._elTextbox, "yui-ac-input");
         }
         else {
             return;
@@ -70,16 +70,16 @@
         // Validate container element
         if(YAHOO.util.Dom.inDocument(elContainer)) {
             if(YAHOO.lang.isString(elContainer)) {
-                    this._oContainer = document.getElementById(elContainer);
+                    this._elContainer = document.getElementById(elContainer);
             }
             else {
-                this._oContainer = elContainer;
+                this._elContainer = elContainer;
             }
-            if(this._oContainer.style.display == "none") {
+            if(this._elContainer.style.display == "none") {
             }
             
             // For skinning
-            var elParent = this._oContainer.parentNode;
+            var elParent = this._elContainer.parentNode;
             var elTag = elParent.tagName.toLowerCase();
             if(elTag == "div") {
                 YAHOO.util.Dom.addClass(elParent, "yui-ac");
@@ -108,20 +108,20 @@
 
         // Set up events
         var oSelf = this;
-        var oTextbox = this._oTextbox;
+        var elTextbox = this._elTextbox;
         // Events are actually for the content module within the container
-        var oContent = this._oContainer._oContent;
+        var elContent = this._elContent;
 
         // Dom events
-        YAHOO.util.Event.addListener(oTextbox,"keyup",oSelf._onTextboxKeyUp,oSelf);
-        YAHOO.util.Event.addListener(oTextbox,"keydown",oSelf._onTextboxKeyDown,oSelf);
-        YAHOO.util.Event.addListener(oTextbox,"focus",oSelf._onTextboxFocus,oSelf);
-        YAHOO.util.Event.addListener(oTextbox,"blur",oSelf._onTextboxBlur,oSelf);
-        YAHOO.util.Event.addListener(oContent,"mouseover",oSelf._onContainerMouseover,oSelf);
-        YAHOO.util.Event.addListener(oContent,"mouseout",oSelf._onContainerMouseout,oSelf);
-        YAHOO.util.Event.addListener(oContent,"scroll",oSelf._onContainerScroll,oSelf);
-        YAHOO.util.Event.addListener(oContent,"resize",oSelf._onContainerResize,oSelf);
-        YAHOO.util.Event.addListener(oTextbox,"keypress",oSelf._onTextboxKeyPress,oSelf);
+        YAHOO.util.Event.addListener(elTextbox,"keyup",oSelf._onTextboxKeyUp,oSelf);
+        YAHOO.util.Event.addListener(elTextbox,"keydown",oSelf._onTextboxKeyDown,oSelf);
+        YAHOO.util.Event.addListener(elTextbox,"focus",oSelf._onTextboxFocus,oSelf);
+        YAHOO.util.Event.addListener(elTextbox,"blur",oSelf._onTextboxBlur,oSelf);
+        YAHOO.util.Event.addListener(elContent,"mouseover",oSelf._onContainerMouseover,oSelf);
+        YAHOO.util.Event.addListener(elContent,"mouseout",oSelf._onContainerMouseout,oSelf);
+        YAHOO.util.Event.addListener(elContent,"scroll",oSelf._onContainerScroll,oSelf);
+        YAHOO.util.Event.addListener(elContent,"resize",oSelf._onContainerResize,oSelf);
+        YAHOO.util.Event.addListener(elTextbox,"keypress",oSelf._onTextboxKeyPress,oSelf);
         YAHOO.util.Event.addListener(window,"unload",oSelf._onWindowUnload,oSelf);
 
         // Custom events
@@ -143,7 +143,7 @@
         this.textboxBlurEvent = new YAHOO.util.CustomEvent("textboxBlur", this);
         
         // Finish up
-        oTextbox.setAttribute("autocomplete","off");
+        elTextbox.setAttribute("autocomplete","off");
         YAHOO.widget.AutoComplete._nIndex++;
     }
     // Required arguments were not found
@@ -399,16 +399,17 @@
  * @param sHeader {String} HTML markup for results container header.
  */
 YAHOO.widget.AutoComplete.prototype.setHeader = function(sHeader) {
-    if(sHeader) {
-        if(this._oContainer._oContent._oHeader) {
-            this._oContainer._oContent._oHeader.innerHTML = sHeader;
-            this._oContainer._oContent._oHeader.style.display = "block";
+    if(this._elHeader) {
+        var elHeader = this._elHeader;
+        if(sHeader) {
+            elHeader.innerHTML = sHeader;
+            elHeader.style.display = "block";
         }
+        else {
+            elHeader.innerHTML = "";
+            elHeader.style.display = "none";
+        }
     }
-    else {
-        this._oContainer._oContent._oHeader.innerHTML = "";
-        this._oContainer._oContent._oHeader.style.display = "none";
-    }
 };
 
 /**
@@ -419,16 +420,17 @@
  * @param sFooter {String} HTML markup for results container footer.
  */
 YAHOO.widget.AutoComplete.prototype.setFooter = function(sFooter) {
-    if(sFooter) {
-        if(this._oContainer._oContent._oFooter) {
-            this._oContainer._oContent._oFooter.innerHTML = sFooter;
-            this._oContainer._oContent._oFooter.style.display = "block";
+    if(this._elFooter) {
+        var elFooter = this._elFooter;
+        if(sFooter) {
+                elFooter.innerHTML = sFooter;
+                elFooter.style.display = "block";
         }
+        else {
+            elFooter.innerHTML = "";
+            elFooter.style.display = "none";
+        }
     }
-    else {
-        this._oContainer._oContent._oFooter.innerHTML = "";
-        this._oContainer._oContent._oFooter.style.display = "none";
-    }
 };
 
 /**
@@ -439,18 +441,19 @@
  * @param sBody {String} HTML markup for results container body.
  */
 YAHOO.widget.AutoComplete.prototype.setBody = function(sBody) {
-    if(sBody) {
-        if(this._oContainer._oContent._oBody) {
-            this._oContainer._oContent._oBody.innerHTML = sBody;
-            this._oContainer._oContent._oBody.style.display = "block";
-            this._oContainer._oContent.style.display = "block";
+    if(this._elBody) {
+        var elBody = this._elBody;
+        if(sBody) {
+                elBody.innerHTML = sBody;
+                elBody.style.display = "block";
+                elBody.style.display = "block";
         }
+        else {
+            elBody.innerHTML = "";
+            elBody.style.display = "none";
+        }
+        this._maxResultsDisplayed = 0;
     }
-    else {
-        this._oContainer._oContent._oBody.innerHTML = "";
-        this._oContainer._oContent.style.display = "none";
-    }
-    this._maxResultsDisplayed = 0;
 };
 
 /**
@@ -479,13 +482,13 @@
  * and DOM elements.
  *
  * @method doBeforeExpandContainer
- * @param oTextbox {HTMLElement} The text input box.
- * @param oContainer {HTMLElement} The container element.
+ * @param elTextbox {HTMLElement} The text input box.
+ * @param elContainer {HTMLElement} The container element.
  * @param sQuery {String} The query string.
  * @param aResults {Object[]}  An array of query results.
  * @return {Boolean} Return true to continue expanding container, false to cancel the expand.
  */
-YAHOO.widget.AutoComplete.prototype.doBeforeExpandContainer = function(oTextbox, oContainer, sQuery, aResults) {
+YAHOO.widget.AutoComplete.prototype.doBeforeExpandContainer = function(elTextbox, elContainer, sQuery, aResults) {
     return true;
 };
 
@@ -520,26 +523,26 @@
  */
 YAHOO.widget.AutoComplete.prototype.destroy = function() {
     var instanceName = this.toString();
-    var elInput = this._oTextbox;
-    var elContainer = this._oContainer;
+    var elInput = this._elTextbox;
+    var elContainer = this._elContainer;
 
     // Unhook custom events
-    this.textboxFocusEvent.unsubscribe();
-    this.textboxKeyEvent.unsubscribe();
-    this.dataRequestEvent.unsubscribe();
-    this.dataReturnEvent.unsubscribe();
-    this.dataErrorEvent.unsubscribe();
-    this.containerExpandEvent.unsubscribe();
-    this.typeAheadEvent.unsubscribe();
-    this.itemMouseOverEvent.unsubscribe();
-    this.itemMouseOutEvent.unsubscribe();
-    this.itemArrowToEvent.unsubscribe();
-    this.itemArrowFromEvent.unsubscribe();
-    this.itemSelectEvent.unsubscribe();
-    this.unmatchedItemSelectEvent.unsubscribe();
-    this.selectionEnforceEvent.unsubscribe();
-    this.containerCollapseEvent.unsubscribe();
-    this.textboxBlurEvent.unsubscribe();
+    this.textboxFocusEvent.unsubscribeAll();
+    this.textboxKeyEvent.unsubscribeAll();
+    this.dataRequestEvent.unsubscribeAll();
+    this.dataReturnEvent.unsubscribeAll();
+    this.dataErrorEvent.unsubscribeAll();
+    this.containerExpandEvent.unsubscribeAll();
+    this.typeAheadEvent.unsubscribeAll();
+    this.itemMouseOverEvent.unsubscribeAll();
+    this.itemMouseOutEvent.unsubscribeAll();
+    this.itemArrowToEvent.unsubscribeAll();
+    this.itemArrowFromEvent.unsubscribeAll();
+    this.itemSelectEvent.unsubscribeAll();
+    this.unmatchedItemSelectEvent.unsubscribeAll();
+    this.selectionEnforceEvent.unsubscribeAll();
+    this.containerCollapseEvent.unsubscribeAll();
+    this.textboxBlurEvent.unsubscribeAll();
 
     // Unhook DOM events
     YAHOO.util.Event.purgeElement(elInput, true);
@@ -737,13 +740,76 @@
 /**
  * Text input field DOM element.
  *
- * @property _oTextbox
+ * @property _elTextbox
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.AutoComplete.prototype._oTextbox = null;
+YAHOO.widget.AutoComplete.prototype._elTextbox = null;
 
 /**
+ * Container DOM element.
+ *
+ * @property _elContainer
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elContainer = null;
+
+/**
+ * Reference to content element within container element.
+ *
+ * @property _elContent
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elContent = null;
+
+/**
+ * Reference to header element within content element.
+ *
+ * @property _elHeader
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elHeader = null;
+
+/**
+ * Reference to body element within content element.
+ *
+ * @property _elBody
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elBody = null;
+
+/**
+ * Reference to footer element within content element.
+ *
+ * @property _elFooter
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elFooter = null;
+
+/**
+ * Reference to shadow element within container element.
+ *
+ * @property _elShadow
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elShadow = null;
+
+/**
+ * Reference to iframe element within container element.
+ *
+ * @property _elIFrame
+ * @type HTMLElement
+ * @private
+ */
+YAHOO.widget.AutoComplete.prototype._elIFrame = null;
+
+/**
  * Whether or not the input field is currently in focus. If query results come back
  * but the user has already moved on, do not proceed with auto complete behavior.
  *
@@ -763,15 +829,6 @@
 YAHOO.widget.AutoComplete.prototype._oAnim = null;
 
 /**
- * Container DOM element.
- *
- * @property _oContainer
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.AutoComplete.prototype._oContainer = null;
-
-/**
  * Whether or not the results container is currently open.
  *
  * @property _bContainerOpen
@@ -944,7 +1001,7 @@
             this.animSpeed = 0.3;
         }
         if(!this._oAnim ) {
-            this._oAnim = new YAHOO.util.Anim(this._oContainer._oContent, {}, this.animSpeed);
+            this._oAnim = new YAHOO.util.Anim(this._elContent, {}, this.animSpeed);
         }
         else {
             this._oAnim.duration = this.animSpeed;
@@ -962,21 +1019,21 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._initContainerHelpers = function() {
-    if(this.useShadow && !this._oContainer._oShadow) {
-        var oShadow = document.createElement("div");
-        oShadow.className = "yui-ac-shadow";
-        this._oContainer._oShadow = this._oContainer.appendChild(oShadow);
+    if(this.useShadow && !this._elShadow) {
+        var elShadow = document.createElement("div");
+        elShadow.className = "yui-ac-shadow";
+        this._elShadow = this._elContainer.appendChild(elShadow);
     }
-    if(this.useIFrame && !this._oContainer._oIFrame) {
-        var oIFrame = document.createElement("iframe");
-        oIFrame.src = this._iFrameSrc;
-        oIFrame.frameBorder = 0;
-        oIFrame.scrolling = "no";
-        oIFrame.style.position = "absolute";
-        oIFrame.style.width = "100%";
-        oIFrame.style.height = "100%";
-        oIFrame.tabIndex = -1;
-        this._oContainer._oIFrame = this._oContainer.appendChild(oIFrame);
+    if(this.useIFrame && !this._elIFrame) {
+        var elIFrame = document.createElement("iframe");
+        elIFrame.src = this._iFrameSrc;
+        elIFrame.frameBorder = 0;
+        elIFrame.scrolling = "no";
+        elIFrame.style.position = "absolute";
+        elIFrame.style.width = "100%";
+        elIFrame.style.height = "100%";
+        elIFrame.tabIndex = -1;
+        this._elIFrame = this._elContainer.appendChild(elIFrame);
     }
 };
 
@@ -987,28 +1044,28 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._initContainer = function() {
-    YAHOO.util.Dom.addClass(this._oContainer, "yui-ac-container");
+    YAHOO.util.Dom.addClass(this._elContainer, "yui-ac-container");
     
-    if(!this._oContainer._oContent) {
-        // The oContent div helps size the iframe and shadow properly
-        var oContent = document.createElement("div");
-        oContent.className = "yui-ac-content";
-        oContent.style.display = "none";
-        this._oContainer._oContent = this._oContainer.appendChild(oContent);
+    if(!this._elContent) {
+        // The elContent div helps size the iframe and shadow properly
+        var elContent = document.createElement("div");
+        elContent.className = "yui-ac-content";
+        elContent.style.display = "none";
+        this._elContent = this._elContainer.appendChild(elContent);
 
-        var oHeader = document.createElement("div");
-        oHeader.className = "yui-ac-hd";
-        oHeader.style.display = "none";
-        this._oContainer._oContent._oHeader = this._oContainer._oContent.appendChild(oHeader);
+        var elHeader = document.createElement("div");
+        elHeader.className = "yui-ac-hd";
+        elHeader.style.display = "none";
+        this._elHeader = this._elContent.appendChild(elHeader);
 
-        var oBody = document.createElement("div");
-        oBody.className = "yui-ac-bd";
-        this._oContainer._oContent._oBody = this._oContainer._oContent.appendChild(oBody);
+        var elBody = document.createElement("div");
+        elBody.className = "yui-ac-bd";
+        this._elBody = this._elContent.appendChild(elBody);
 
-        var oFooter = document.createElement("div");
-        oFooter.className = "yui-ac-ft";
-        oFooter.style.display = "none";
-        this._oContainer._oContent._oFooter = this._oContainer._oContent.appendChild(oFooter);
+        var elFooter = document.createElement("div");
+        elFooter.className = "yui-ac-ft";
+        elFooter.style.display = "none";
+        this._elFooter = this._elContent.appendChild(elFooter);
     }
     else {
     }
@@ -1024,18 +1081,18 @@
  */
 YAHOO.widget.AutoComplete.prototype._initList = function() {
     this._aListItems = [];
-    while(this._oContainer._oContent._oBody.hasChildNodes()) {
+    while(this._elBody.hasChildNodes()) {
         var oldListItems = this.getListItems();
         if(oldListItems) {
             for(var oldi = oldListItems.length-1; oldi >= 0; oldi--) {
                 oldListItems[oldi] = null;
             }
         }
-        this._oContainer._oContent._oBody.innerHTML = "";
+        this._elBody.innerHTML = "";
     }
 
     var oList = document.createElement("ul");
-    oList = this._oContainer._oContent._oBody.appendChild(oList);
+    oList = this._elBody.appendChild(oList);
     for(var i=0; i<this.maxResultsDisplayed; i++) {
         var oItem = document.createElement("li");
         oItem = oList.appendChild(oItem);
@@ -1083,7 +1140,7 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._enableIntervalDetection = function() {
-    var currValue = this._oTextbox.value;
+    var currValue = this._elTextbox.value;
     var lastValue = this._sLastTextboxValue;
     if(currValue != lastValue) {
         this._sLastTextboxValue = currValue;
@@ -1221,7 +1278,7 @@
     }
 
     var isOpera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1);
-    var contentStyle = oSelf._oContainer._oContent.style;
+    var contentStyle = oSelf._elContent.style;
     contentStyle.width = (!isOpera) ? null : "";
     contentStyle.height = (!isOpera) ? null : "";
 
@@ -1260,7 +1317,7 @@
         }
 
         // Expand the container
-        var ok = oSelf.doBeforeExpandContainer(oSelf._oTextbox, oSelf._oContainer, sQuery, aResults);
+        var ok = oSelf.doBeforeExpandContainer(oSelf._elTextbox, oSelf._elContainer, sQuery, aResults);
         oSelf._toggleContainer(ok);
         
         if(oSelf.autoHighlight) {
@@ -1290,16 +1347,16 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._clearSelection = function() {
-    var sValue = this._oTextbox.value;
+    var sValue = this._elTextbox.value;
     var sChar = (this.delimChar) ? this.delimChar[0] : null;
     var nIndex = (sChar) ? sValue.lastIndexOf(sChar, sValue.length-2) : -1;
     if(nIndex > -1) {
-        this._oTextbox.value = sValue.substring(0,nIndex);
+        this._elTextbox.value = sValue.substring(0,nIndex);
     }
     else {
-         this._oTextbox.value = "";
+         this._elTextbox.value = "";
     }
-    this._sSavedQuery = this._oTextbox.value;
+    this._sSavedQuery = this._elTextbox.value;
 
     // Fire custom event
     this.selectionEnforceEvent.fire(this);
@@ -1343,20 +1400,20 @@
         return;
     }
 
-    var oTextbox = this._oTextbox;
-    var sValue = this._oTextbox.value; // any saved queries plus what user has typed
+    var elTextbox = this._elTextbox;
+    var sValue = this._elTextbox.value; // any saved queries plus what user has typed
 
     // Don't update with type-ahead if text selection is not supported
-    if(!oTextbox.setSelectionRange && !oTextbox.createTextRange) {
+    if(!elTextbox.setSelectionRange && !elTextbox.createTextRange) {
         return;
     }
 
     // Select the portion of text that the user has not typed
     var nStart = sValue.length;
     this._updateValue(oItem);
-    var nEnd = oTextbox.value.length;
-    this._selectText(oTextbox,nStart,nEnd);
-    var sPrefill = oTextbox.value.substr(nStart,nEnd);
+    var nEnd = elTextbox.value.length;
+    this._selectText(elTextbox,nStart,nEnd);
+    var sPrefill = elTextbox.value.substr(nStart,nEnd);
     this.typeAheadEvent.fire(this,sQuery,sPrefill);
 };
 
@@ -1364,23 +1421,23 @@
  * Selects text in the input field.
  *
  * @method _selectText
- * @param oTextbox {HTMLElement} Text input box element in which to select text.
+ * @param elTextbox {HTMLElement} Text input box element in which to select text.
  * @param nStart {Number} Starting index of text string to select.
  * @param nEnd {Number} Ending index of text selection.
  * @private
  */
-YAHOO.widget.AutoComplete.prototype._selectText = function(oTextbox, nStart, nEnd) {
-    if(oTextbox.setSelectionRange) { // For Mozilla
-        oTextbox.setSelectionRange(nStart,nEnd);
+YAHOO.widget.AutoComplete.prototype._selectText = function(elTextbox, nStart, nEnd) {
+    if(elTextbox.setSelectionRange) { // For Mozilla
+        elTextbox.setSelectionRange(nStart,nEnd);
     }
-    else if(oTextbox.createTextRange) { // For IE
-        var oTextRange = oTextbox.createTextRange();
+    else if(elTextbox.createTextRange) { // For IE
+        var oTextRange = elTextbox.createTextRange();
         oTextRange.moveStart("character", nStart);
-        oTextRange.moveEnd("character", nEnd-oTextbox.value.length);
+        oTextRange.moveEnd("character", nEnd-elTextbox.value.length);
         oTextRange.select();
     }
     else {
-        oTextbox.select();
+        elTextbox.select();
     }
 };
 
@@ -1393,29 +1450,29 @@
  */
 YAHOO.widget.AutoComplete.prototype._toggleContainerHelpers = function(bShow) {
     var bFireEvent = false;
-    var width = this._oContainer._oContent.offsetWidth + "px";
-    var height = this._oContainer._oContent.offsetHeight + "px";
+    var width = this._elContent.offsetWidth + "px";
+    var height = this._elContent.offsetHeight + "px";
 
-    if(this.useIFrame && this._oContainer._oIFrame) {
+    if(this.useIFrame && this._elIFrame) {
         bFireEvent = true;
         if(bShow) {
-            this._oContainer._oIFrame.style.width = width;
-            this._oContainer._oIFrame.style.height = height;
+            this._elIFrame.style.width = width;
+            this._elIFrame.style.height = height;
         }
         else {
-            this._oContainer._oIFrame.style.width = 0;
-            this._oContainer._oIFrame.style.height = 0;
+            this._elIFrame.style.width = 0;
+            this._elIFrame.style.height = 0;
         }
     }
-    if(this.useShadow && this._oContainer._oShadow) {
+    if(this.useShadow && this._elShadow) {
         bFireEvent = true;
         if(bShow) {
-            this._oContainer._oShadow.style.width = width;
-            this._oContainer._oShadow.style.height = height;
+            this._elShadow.style.width = width;
+            this._elShadow.style.height = height;
         }
         else {
-           this._oContainer._oShadow.style.width = 0;
-            this._oContainer._oShadow.style.height = 0;
+           this._elShadow.style.width = 0;
+            this._elShadow.style.height = 0;
         }
     }
 };
@@ -1428,7 +1485,7 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._toggleContainer = function(bShow) {
-    var oContainer = this._oContainer;
+    var elContainer = this._elContainer;
 
     // Implementer has container always open so don't mess with it
     if(this.alwaysShowContainer && this._bContainerOpen) {
@@ -1437,7 +1494,7 @@
     
     // Clear contents of container
     if(!bShow) {
-        this._oContainer._oContent.scrollTop = 0;
+        this._elContent.scrollTop = 0;
         var aItems = this._aListItems;
 
         if(aItems && (aItems.length > 0)) {
@@ -1457,7 +1514,7 @@
 
     // Container is already closed
     if(!bShow && !this._bContainerOpen) {
-        oContainer._oContent.style.display = "none";
+        this._elContent.style.display = "none";
         return;
     }
 
@@ -1475,8 +1532,8 @@
         }
 
         // Clone container to grab current size offscreen
-        var oClone = oContainer._oContent.cloneNode(true);
-        oContainer.appendChild(oClone);
+        var oClone = this._elContent.cloneNode(true);
+        elContainer.appendChild(oClone);
         oClone.style.top = "-9000px";
         oClone.style.display = "block";
 
@@ -1495,16 +1552,16 @@
 
         // If opening anew, set to a collapsed size...
         if(bShow && !this._bContainerOpen) {
-            oContainer._oContent.style.width = wColl+"px";
-            oContainer._oContent.style.height = hColl+"px";
+            this._elContent.style.width = wColl+"px";
+            this._elContent.style.height = hColl+"px";
         }
         // Else, set it to its last known size.
         else {
-            oContainer._oContent.style.width = wExp+"px";
-            oContainer._oContent.style.height = hExp+"px";
+            this._elContent.style.width = wExp+"px";
+            this._elContent.style.height = hExp+"px";
         }
 
-        oContainer.removeChild(oClone);
+        elContainer.removeChild(oClone);
         oClone = null;
 
     	var oSelf = this;
@@ -1516,14 +1573,14 @@
                 oSelf.containerExpandEvent.fire(oSelf);
             }
             else {
-                oContainer._oContent.style.display = "none";
+                oSelf._elContent.style.display = "none";
                 oSelf.containerCollapseEvent.fire(oSelf);
             }
             oSelf._toggleContainerHelpers(bShow);
      	};
 
         // Display container and animate it
-        oContainer._oContent.style.display = "block";
+        this._elContent.style.display = "block";
         oAnim.onComplete.subscribe(onAnimComplete);
         oAnim.animate();
         this._bContainerOpen = bShow;
@@ -1531,11 +1588,11 @@
     // Else don't animate, just show or hide
     else {
         if(bShow) {
-            oContainer._oContent.style.display = "block";
+            this._elContent.style.display = "block";
             this.containerExpandEvent.fire(this);
         }
         else {
-            oContainer._oContent.style.display = "none";
+            this._elContent.style.display = "none";
             this.containerCollapseEvent.fire(this);
         }
         this._toggleContainerHelpers(bShow);
@@ -1600,34 +1657,34 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._updateValue = function(oItem) {
-    var oTextbox = this._oTextbox;
+    var elTextbox = this._elTextbox;
     var sDelimChar = (this.delimChar) ? (this.delimChar[0] || this.delimChar) : null;
     var sSavedQuery = this._sSavedQuery;
     var sResultKey = oItem._sResultKey;
-    oTextbox.focus();
+    elTextbox.focus();
 
     // First clear text field
-    oTextbox.value = "";
+    elTextbox.value = "";
     // Grab data to put into text field
     if(sDelimChar) {
         if(sSavedQuery) {
-            oTextbox.value = sSavedQuery;
+            elTextbox.value = sSavedQuery;
         }
-        oTextbox.value += sResultKey + sDelimChar;
+        elTextbox.value += sResultKey + sDelimChar;
         if(sDelimChar != " ") {
-            oTextbox.value += " ";
+            elTextbox.value += " ";
         }
     }
-    else { oTextbox.value = sResultKey; }
+    else { elTextbox.value = sResultKey; }
 
     // scroll to bottom of textarea if necessary
-    if(oTextbox.type == "textarea") {
-        oTextbox.scrollTop = oTextbox.scrollHeight;
+    if(elTextbox.type == "textarea") {
+        elTextbox.scrollTop = elTextbox.scrollHeight;
     }
 
     // move cursor to end
-    var end = oTextbox.value.length;
-    this._selectText(oTextbox,end,end);
+    var end = elTextbox.value.length;
+    this._selectText(elTextbox,end,end);
 
     this._oCurItem = oItem;
 };
@@ -1699,14 +1756,14 @@
            // Go back to query (remove type-ahead string)
             if(this.delimChar && this._sSavedQuery) {
                 if(!this._textMatchesOption()) {
-                    this._oTextbox.value = this._sSavedQuery;
+                    this._elTextbox.value = this._sSavedQuery;
                 }
                 else {
-                    this._oTextbox.value = this._sSavedQuery + this._sCurQuery;
+                    this._elTextbox.value = this._sSavedQuery + this._sCurQuery;
                 }
             }
             else {
-                this._oTextbox.value = this._sCurQuery;
+                this._elTextbox.value = this._sCurQuery;
             }
             this._oCurItem = null;
             return;
@@ -1720,36 +1777,36 @@
         var oNewItem = this._aListItems[nNewItemIndex];
 
         // Scroll the container if necessary
-        var oContent = this._oContainer._oContent;
-        var scrollOn = ((YAHOO.util.Dom.getStyle(oContent,"overflow") == "auto") ||
-            (YAHOO.util.Dom.getStyle(oContent,"overflowY") == "auto"));
+        var elContent = this._elContent;
+        var scrollOn = ((YAHOO.util.Dom.getStyle(elContent,"overflow") == "auto") ||
+            (YAHOO.util.Dom.getStyle(elContent,"overflowY") == "auto"));
         if(scrollOn && (nNewItemIndex > -1) &&
         (nNewItemIndex < this._nDisplayedItems)) {
             // User is keying down
             if(nKeyCode == 40) {
                 // Bottom of selected item is below scroll area...
-                if((oNewItem.offsetTop+oNewItem.offsetHeight) > (oContent.scrollTop + oContent.offsetHeight)) {
+                if((oNewItem.offsetTop+oNewItem.offsetHeight) > (elContent.scrollTop + elContent.offsetHeight)) {
                     // Set bottom of scroll area to bottom of selected item
-                    oContent.scrollTop = (oNewItem.offsetTop+oNewItem.offsetHeight) - oContent.offsetHeight;
+                    elContent.scrollTop = (oNewItem.offsetTop+oNewItem.offsetHeight) - elContent.offsetHeight;
                 }
                 // Bottom of selected item is above scroll area...
-                else if((oNewItem.offsetTop+oNewItem.offsetHeight) < oContent.scrollTop) {
+                else if((oNewItem.offsetTop+oNewItem.offsetHeight) < elContent.scrollTop) {
                     // Set top of selected item to top of scroll area
-                    oContent.scrollTop = oNewItem.offsetTop;
+                    elContent.scrollTop = oNewItem.offsetTop;
 
                 }
             }
             // User is keying up
             else {
                 // Top of selected item is above scroll area
-                if(oNewItem.offsetTop < oContent.scrollTop) {
+                if(oNewItem.offsetTop < elContent.scrollTop) {
                     // Set top of scroll area to top of selected item
-                    this._oContainer._oContent.scrollTop = oNewItem.offsetTop;
+                    this._elContent.scrollTop = oNewItem.offsetTop;
                 }
                 // Top of selected item is below scroll area
-                else if(oNewItem.offsetTop > (oContent.scrollTop + oContent.offsetHeight)) {
+                else if(oNewItem.offsetTop > (elContent.scrollTop + elContent.offsetHeight)) {
                     // Set bottom of selected item to bottom of scroll area
-                    this._oContainer._oContent.scrollTop = (oNewItem.offsetTop+oNewItem.offsetHeight) - oContent.offsetHeight;
+                    this._elContent.scrollTop = (oNewItem.offsetTop+oNewItem.offsetHeight) - elContent.offsetHeight;
                 }
             }
         }
@@ -1857,7 +1914,7 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._onContainerScroll = function(v,oSelf) {
-    oSelf._oTextbox.focus();
+    oSelf._elTextbox.focus();
 };
 
 /**
@@ -1900,8 +1957,7 @@
             }
             break;
         case 13: // enter
-            var isMac = (navigator.userAgent.toLowerCase().indexOf("mac") != -1);
-            if(!isMac) {
+            if(!YAHOO.env.ua.webkit) {
                 if(oSelf._oCurItem) {
                     if(oSelf._nKeyCode != nKeyCode) {
                         if(oSelf._bContainerOpen) {
@@ -1945,8 +2001,7 @@
     var nKeyCode = v.keyCode;
 
         //Expose only to Mac browsers, where stopEvent is ineffective on keydown events (bug 790337)
-        var isMac = (navigator.userAgent.toLowerCase().indexOf("mac") != -1);
-        if(isMac) {
+        if(YAHOO.env.ua.webkit) {
             switch (nKeyCode) {
             case 9: // tab
                 if(oSelf._oCurItem) {
@@ -1968,10 +2023,6 @@
                     oSelf._toggleContainer(false);
                 }
                 break;
-            case 38: // up
-            case 40: // down
-                YAHOO.util.Event.stopEvent(v);
-                break;
             default:
                 break;
             }
@@ -1997,6 +2048,7 @@
     oSelf._initProps();
 
     var nKeyCode = v.keyCode;
+
     oSelf._nKeyCode = nKeyCode;
     var sText = this.value; //string in textbox
 
@@ -2038,7 +2090,7 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._onTextboxFocus = function (v,oSelf) {
-    oSelf._oTextbox.setAttribute("autocomplete","off");
+    oSelf._elTextbox.setAttribute("autocomplete","off");
     oSelf._bFocused = true;
     if(!oSelf._bItemSelected) {
         oSelf.textboxFocusEvent.fire(oSelf);
@@ -2097,8 +2149,8 @@
  * @private
  */
 YAHOO.widget.AutoComplete.prototype._onWindowUnload = function(v,oSelf) {
-    if(oSelf && oSelf._oTextbox && oSelf.allowBrowserAutocomplete) {
-        oSelf._oTextbox.setAttribute("autocomplete","on");
+    if(oSelf && oSelf._elTextbox && oSelf.allowBrowserAutocomplete) {
+        oSelf._elTextbox.setAttribute("autocomplete","on");
     }
 };
 
@@ -2628,8 +2680,7 @@
 /////////////////////////////////////////////////////////////////////////////
 
 /**
- * Alias to YUI Connection Manager. Allows implementers to specify their own
- * subclasses of the YUI Connection Manager utility.
+ * Alias to YUI Connection Manager, to allow implementers to customize the utility.
  *
  * @property connMgr
  * @type Object
@@ -2811,13 +2862,13 @@
     switch (this.responseType) {
         case YAHOO.widget.DS_XHR.TYPE_JSON:
             var jsonList, jsonObjParsed;
-            // Check for JSON lib but divert KHTML clients
-            var isNotMac = (navigator.userAgent.toLowerCase().indexOf('khtml')== -1);
-            if(oResponse.parseJSON && isNotMac) {
-                // Use the new JSON utility if available
-                jsonObjParsed = oResponse.parseJSON();
+            // Check for YUI JSON
+            if(YAHOO.lang.JSON) {
+                // Use the JSON utility if available
+                jsonObjParsed = YAHOO.lang.JSON.parse(oResponse);
                 if(!jsonObjParsed) {
                     bError = true;
+                    break;
                 }
                 else {
                     try {
@@ -2830,13 +2881,12 @@
                    }
                 }
             }
-            // Check for YUI JSON lib but divert KHTML clients
-            else if(YAHOO.lang.JSON && isNotMac) {
-                // Use the JSON utility if available
-                jsonObjParsed = YAHOO.lang.JSON.parse(oResponse);
+            // Check for JSON lib
+            else if(oResponse.parseJSON) {
+                // Use the new JSON utility if available
+                jsonObjParsed = oResponse.parseJSON();
                 if(!jsonObjParsed) {
                     bError = true;
-                    break;
                 }
                 else {
                     try {
@@ -2849,8 +2899,8 @@
                    }
                 }
             }
-            else if(window.JSON && isNotMac) {
-                // Use older JSON lib if available
+            // Use older JSON lib if available
+            else if(window.JSON) {
                 jsonObjParsed = JSON.parse(oResponse);
                 if(!jsonObjParsed) {
                     bError = true;
@@ -3492,4 +3542,4 @@
     oCallbackFn(sQuery, aResults, oParent);
 };
 
-YAHOO.register("autocomplete", YAHOO.widget.AutoComplete, {version: "2.4.1", build: "742"});
+YAHOO.register("autocomplete", YAHOO.widget.AutoComplete, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/base/README
===================================================================
--- trunk/root/static/yui/base/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/base/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,13 @@
 YUI Library - Base - Release Notes
 
-Version 2.4.0
-  * No change
+Version 2.5.1
 
+  * No changes.
+
+Version 2.5.0
+
+  * No changes.
+
 Version 2.4.0
 
   * Fixed typo in comments.
@@ -13,4 +18,4 @@
   
 Version 2.3.0
 
-  * Initial release.
+  * Initial release.
\ No newline at end of file

Modified: trunk/root/static/yui/base/base-min.css
===================================================================
--- trunk/root/static/yui/base/base-min.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/base/base-min.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 h1{font-size:138.5%;}h2{font-size:123.1%;}h3{font-size:108%;}h1,h2,h3{margin:1em 0;}h1,h2,h3,h4,h5,h6,strong{font-weight:bold;}abbr,acronym{border-bottom:1px dotted #000;cursor:help;} em{font-style:italic;}blockquote,ul,ol,dl{margin:1em;}ol,ul,dl{margin-left:2em;}ol li{list-style:decimal outside;}ul li{list-style:disc outside;}dl dd{margin-left:1em;}th,td{border:1px solid #000;padding:.5em;}th{font-weight:bold;text-align:center;}caption{margin-bottom:.5em;text-align:center;}p,fieldset,table,pre{margin-bottom:1em;}input[type=text],input[type=password],textarea{width:12.25em;*width:11.9em;}

Modified: trunk/root/static/yui/base/base.css
===================================================================
--- trunk/root/static/yui/base/base.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/base/base.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* base.css, part of YUI's CSS Foundation */
 h1 {

Modified: trunk/root/static/yui/button/README
===================================================================
--- trunk/root/static/yui/button/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/button/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,6 +1,22 @@
+*** Version 2.5.1 ***
+
++ No changes.
+
+
+
+*** Version 2.5.0 ***
+
++ Fixed issue where returning false inside the scope of a listener for attribute "before" 
+  events (i.e "beforeCheckedChange") would not cancel the attribute's default setter.
+
+
+
 *** Version 2.4.1 ***
-No change
 
++ No changes.
+
+
+
 *** Version 2.4.0 ***
 
 Added the following features:

Modified: trunk/root/static/yui/button/assets/button-core.css
===================================================================
--- trunk/root/static/yui/button/assets/button-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/button/assets/button-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-button  {
 

Modified: trunk/root/static/yui/button/assets/skins/sam/button-skin.css
===================================================================
--- trunk/root/static/yui/button/assets/skins/sam/button-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/button/assets/skins/sam/button-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-skin-sam .yui-button  {
 

Modified: trunk/root/static/yui/button/assets/skins/sam/button.css
===================================================================
--- trunk/root/static/yui/button/assets/skins/sam/button.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/button/assets/skins/sam/button.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-button{display:-moz-inline-box;display:inline-block;vertical-align:text-bottom;}.yui-button .first-child{display:block;*display:inline-block;}.yui-button button,.yui-button a{display:block;*display:inline-block;border:none;margin:0;}.yui-button button{background-color:transparent;*overflow:visible;cursor:pointer;}.yui-button a{text-decoration:none;}.yui-skin-sam .yui-button{border-width:1px 0;border-style:solid;border-color:#808080;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;margin:auto .25em;}.yui-skin-sam .yui-button .first-child{border-width:0 1px;border-style:solid;border-color:#808080;margin:0 -1px;*position:relative;*left:-1px;}.yui-skin-sam .yui-button button,.yui-skin-sam .yui-button a{padding:0 10px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-button a{*line-height:2;}.yui-skin-sam .yui-split-button button,.yui-skin-sam .yui-menu-button button{padding-right:20px;background-!
 position:right center;background-repeat:no-repeat;}.yui-skin-sam .yui-menu-button button{background-image:url(menu-button-arrow.png);}.yui-skin-sam .yui-split-button button{background-image:url(split-button-arrow.png);}.yui-skin-sam .yui-button-focus{border-color:#7D98B8;background-position:0 -1300px;}.yui-skin-sam .yui-button-focus .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-button-focus button,.yui-skin-sam .yui-button-focus a{color:#000;}.yui-skin-sam .yui-split-button-focus button{background-image:url(split-button-arrow-focus.png);}.yui-skin-sam .yui-button-hover{border-color:#7D98B8;background-position:0 -1300px;}.yui-skin-sam .yui-button-hover .first-child{border-color:#7D98B8;}.yui-skin-sam .yui-button-hover button,.yui-skin-sam .yui-button-hover a{color:#000;}.yui-skin-sam .yui-split-button-hover button{background-image:url(split-button-arrow-hover.png);}.yui-skin-sam .yui-button-active{border-color:#7D98B8;background-position:0 -1700px;}.yui-skin-sam .yui!
 -button-active .first-child{border-color:#7D98B8;}.yui-skin-sa!
 m .yui-b
utton-active button,.yui-skin-sam .yui-button-active a{color:#000;}.yui-skin-sam .yui-split-button-activeoption{border-color:#808080;background-position:0 0;}.yui-skin-sam .yui-split-button-activeoption .first-child{border-color:#808080;}.yui-skin-sam .yui-split-button-activeoption button{background-image:url(split-button-arrow-active.png);}.yui-skin-sam .yui-radio-button-checked,.yui-skin-sam .yui-checkbox-button-checked{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-radio-button-checked .first-child,.yui-skin-sam .yui-checkbox-button-checked .first-child{border-color:#304369;}.yui-skin-sam .yui-radio-button-checked button,.yui-skin-sam .yui-checkbox-button-checked button{color:#fff;}.yui-skin-sam .yui-button-disabled{border-color:#ccc;background-position:0 -1500px;}.yui-skin-sam .yui-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-button-disabled button,.yui-skin-sam .yui-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-s!
 am .yui-menu-button-disabled button{background-image:url(menu-button-arrow-disabled.png);}.yui-skin-sam .yui-split-button-disabled button{background-image:url(split-button-arrow-disabled.png);}

Modified: trunk/root/static/yui/button/button-debug.js
===================================================================
--- trunk/root/static/yui/button/button-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/button/button-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
 * @module button
@@ -399,6 +399,20 @@
 
     YAHOO.widget.Button = function (p_oElement, p_oAttributes) {
     
+		if (!Overlay && YAHOO.widget.Overlay) {
+		
+			Overlay = YAHOO.widget.Overlay;
+		
+		}
+
+
+		if (!Menu && YAHOO.widget.Menu) {
+		
+			Menu = YAHOO.widget.Menu;
+		
+		}
+
+
         var fnSuperClass = YAHOO.widget.Button.superclass.constructor,
             oConfig,
             oElement;
@@ -3570,17 +3584,18 @@
         
         fireEvent: function (p_sType , p_aArgs) {
         
-            //  Disabled buttons should not respond to DOM events
+			var sType = arguments[0];
+		
+			//  Disabled buttons should not respond to DOM events
+		
+			if (this.DOM_EVENTS[sType] && this.get("disabled")) {
+		
+				return;
+		
+			}
+		
+			return YAHOO.widget.Button.superclass.fireEvent.apply(this, arguments);
         
-            if (this.DOM_EVENTS[p_sType] && this.get("disabled")) {
-        
-                return;
-        
-            }
-        
-            YAHOO.widget.Button.superclass.fireEvent.call(this, p_sType, 
-                p_aArgs);
-        
         },
         
         
@@ -4720,4 +4735,4 @@
     });
 
 })();
-YAHOO.register("button", YAHOO.widget.Button, {version: "2.4.1", build: "742"});
+YAHOO.register("button", YAHOO.widget.Button, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/button/button-min.js
===================================================================
--- trunk/root/static/yui/button/button-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/button/button-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,11 +1,11 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-(function(){var G=YAHOO.util.Dom,L=YAHOO.util.Event,I=YAHOO.lang,B=YAHOO.widget.Overlay,J=YAHOO.widget.Menu,D={},K=null,E=null,C=null;function F(N,M,Q,O){var R,P;if(I.isString(N)&&I.isString(M)){if(YAHOO.env.ua.ie){P="<input type=\""+N+"\" name=\""+M+"\"";if(O){P+=" checked";}P+=">";R=document.createElement(P);}else{R=document.createElement("input");R.name=M;R.type=N;if(O){R.checked=true;}}R.value=Q;return R;}}function H(N,T){var M=N.nodeName.toUpperCase(),R=this,S,O,P;function U(V){if(!(V in T)){S=N.getAttributeNode(V);if(S&&("value" in S)){T[V]=S.value;}}}function Q(){U("type");if(T.type=="button"){T.type="push";}if(!("disabled" in T)){T.disabled=N.disabled;}U("name");U("value");U("title");}switch(M){case"A":T.type="link";U("href");U("target");break;case"INPUT":Q();if(!("checked" in T)){T.checked=N.checked;}break;case"BUTTON":Q();O=N.parentNode.parentNode;if(G.hasClass(O,this.CSS_CLASS_NAME+"-checked")){T.checked=true;}if(G.hasClass(O,this.CSS_CLASS_NAME+"-disabled")){T.d!
 isabled=true;}N.removeAttribute("value");N.setAttribute("type","button");break;}N.removeAttribute("id");N.removeAttribute("name");if(!("tabindex" in T)){T.tabindex=N.tabIndex;}if(!("label" in T)){P=M=="INPUT"?N.value:N.innerHTML;if(P&&P.length>0){T.label=P;}}}function A(O){var N=O.attributes,M=N.srcelement,Q=M.nodeName.toUpperCase(),P=this;if(Q==this.NODE_NAME){O.element=M;O.id=M.id;G.getElementsBy(function(R){switch(R.nodeName.toUpperCase()){case"BUTTON":case"A":case"INPUT":H.call(P,R,N);break;}},"*",M);}else{switch(Q){case"BUTTON":case"A":case"INPUT":H.call(this,M,N);break;}}}YAHOO.widget.Button=function(Q,N){var P=YAHOO.widget.Button.superclass.constructor,O,M;if(arguments.length==1&&!I.isString(Q)&&!Q.nodeName){if(!Q.id){Q.id=G.generateId();}P.call(this,(this.createButtonElement(Q.type)),Q);}else{O={element:null,attributes:(N||{})};if(I.isString(Q)){M=G.get(Q);if(M){if(!O.attributes.id){O.attributes.id=Q;}O.attributes.srcelement=M;A.call(this,O);if(!O.element){O.element!
 =this.createButtonElement(O.attributes.type);}P.call(this,O.el!
 ement,O.
attributes);}}else{if(Q.nodeName){if(!O.attributes.id){if(Q.id){O.attributes.id=Q.id;}else{O.attributes.id=G.generateId();}}O.attributes.srcelement=Q;A.call(this,O);if(!O.element){O.element=this.createButtonElement(O.attributes.type);}P.call(this,O.element,O.attributes);}}}};YAHOO.extend(YAHOO.widget.Button,YAHOO.util.Element,{_button:null,_menu:null,_hiddenFields:null,_onclickAttributeValue:null,_activationKeyPressed:false,_activationButtonPressed:false,_hasKeyEventHandlers:false,_hasMouseEventHandlers:false,NODE_NAME:"SPAN",CHECK_ACTIVATION_KEYS:[32],ACTIVATION_KEYS:[13,32],OPTION_AREA_WIDTH:20,CSS_CLASS_NAME:"yui-button",RADIO_DEFAULT_TITLE:"Unchecked.  Click to check.",RADIO_CHECKED_TITLE:"Checked.  Click another button to uncheck",CHECKBOX_DEFAULT_TITLE:"Unchecked.  Click to check.",CHECKBOX_CHECKED_TITLE:"Checked.  Click to uncheck.",MENUBUTTON_DEFAULT_TITLE:"Menu collapsed.  Click to expand.",MENUBUTTON_MENU_VISIBLE_TITLE:"Menu expanded.  Click or press Esc to collaps!
 e.",SPLITBUTTON_DEFAULT_TITLE:("Menu collapsed.  Click inside option region or press Ctrl + Shift + M to show the menu."),SPLITBUTTON_OPTION_VISIBLE_TITLE:"Menu expanded.  Press Esc or Ctrl + Shift + M to hide the menu.",SUBMIT_TITLE:"Click to submit form.",_setType:function(M){if(M=="split"){this.on("option",this._onOption);}},_setLabel:function(M){this._button.innerHTML=M;var O,N;if(YAHOO.env.ua.gecko&&G.inDocument(this.get("element"))){N=this;O=this.CSS_CLASS_NAME;this.removeClass(O);window.setTimeout(function(){N.addClass(O);},0);}},_setTabIndex:function(M){this._button.tabIndex=M;},_setTitle:function(N){var M=N;if(this.get("type")!="link"){if(!M){switch(this.get("type")){case"radio":M=this.RADIO_DEFAULT_TITLE;break;case"checkbox":M=this.CHECKBOX_DEFAULT_TITLE;break;case"menu":M=this.MENUBUTTON_DEFAULT_TITLE;break;case"split":M=this.SPLITBUTTON_DEFAULT_TITLE;break;case"submit":M=this.SUBMIT_TITLE;break;}}this._button.title=M;}},_setDisabled:function(M){if(this.get("type!
 ")!="link"){if(M){if(this._menu){this._menu.hide();}if(this.ha!
 sFocus()
){this.blur();}this._button.setAttribute("disabled","disabled");this.addStateCSSClasses("disabled");this.removeStateCSSClasses("hover");this.removeStateCSSClasses("active");this.removeStateCSSClasses("focus");}else{this._button.removeAttribute("disabled");this.removeStateCSSClasses("disabled");}}},_setHref:function(M){if(this.get("type")=="link"){this._button.href=M;}},_setTarget:function(M){if(this.get("type")=="link"){this._button.setAttribute("target",M);}},_setChecked:function(N){var O=this.get("type"),M;if(O=="checkbox"||O=="radio"){if(N){this.addStateCSSClasses("checked");M=(O=="radio")?this.RADIO_CHECKED_TITLE:this.CHECKBOX_CHECKED_TITLE;}else{this.removeStateCSSClasses("checked");M=(O=="radio")?this.RADIO_DEFAULT_TITLE:this.CHECKBOX_DEFAULT_TITLE;}this.set("title",M);}},_setMenu:function(W){var Q=this.get("lazyloadmenu"),T=this.get("element"),M,Y=false,Z,P,S,O,N,V,R;if(!B){return false;}if(J){M=J.prototype.CSS_CLASS_NAME;}function X(){Z.render(T.parentNode);this.remo!
 veListener("appendTo",X);}function U(){if(Z){G.addClass(Z.element,this.get("menuclassname"));G.addClass(Z.element,"yui-"+this.get("type")+"-button-menu");Z.showEvent.subscribe(this._onMenuShow,null,this);Z.hideEvent.subscribe(this._onMenuHide,null,this);Z.renderEvent.subscribe(this._onMenuRender,null,this);if(J&&Z instanceof J){Z.keyDownEvent.subscribe(this._onMenuKeyDown,this,true);Z.subscribe("click",this._onMenuClick,this,true);Z.itemAddedEvent.subscribe(this._onMenuItemAdded,this,true);S=Z.srcElement;if(S&&S.nodeName.toUpperCase()=="SELECT"){S.style.display="none";S.parentNode.removeChild(S);}}else{if(B&&Z instanceof B){if(!K){K=new YAHOO.widget.OverlayManager();}K.register(Z);}}this._menu=Z;if(!Y){if(Q&&J&&!(Z instanceof J)){Z.beforeShowEvent.subscribe(this._onOverlayBeforeShow,null,this);}else{if(!Q){if(G.inDocument(T)){Z.render(T.parentNode);}else{this.on("appendTo",X);}}}}}}if(W&&J&&(W instanceof J)){Z=W;
-O=Z.getItems();N=O.length;Y=true;if(N>0){R=N-1;do{V=O[R];if(V){V.cfg.subscribeToConfigEvent("selected",this._onMenuItemSelected,V,this);}}while(R--);}U.call(this);}else{if(B&&W&&(W instanceof B)){Z=W;Y=true;Z.cfg.setProperty("visible",false);Z.cfg.setProperty("context",[T,"tl","bl"]);U.call(this);}else{if(J&&I.isArray(W)){this.on("appendTo",function(){Z=new J(G.generateId(),{lazyload:Q,itemdata:W});U.call(this);});}else{if(I.isString(W)){P=G.get(W);if(P){if(J&&G.hasClass(P,M)||P.nodeName.toUpperCase()=="SELECT"){Z=new J(W,{lazyload:Q});U.call(this);}else{if(B){Z=new B(W,{visible:false,context:[T,"tl","bl"]});U.call(this);}}}}else{if(W&&W.nodeName){if(J&&G.hasClass(W,M)||W.nodeName.toUpperCase()=="SELECT"){Z=new J(W,{lazyload:Q});U.call(this);}else{if(B){if(!W.id){G.generateId(W);}Z=new B(W,{visible:false,context:[T,"tl","bl"]});U.call(this);}}}}}}}},_setOnClick:function(M){if(this._onclickAttributeValue&&(this._onclickAttributeValue!=M)){this.removeListener("click",this._on!
 clickAttributeValue.fn);this._onclickAttributeValue=null;}if(!this._onclickAttributeValue&&I.isObject(M)&&I.isFunction(M.fn)){this.on("click",M.fn,M.obj,M.scope);this._onclickAttributeValue=M;}},_setSelectedMenuItem:function(N){var M=this._menu,O;if(J&&M&&M instanceof J){O=M.getItem(N);if(O&&!O.cfg.getProperty("selected")){O.cfg.setProperty("selected",true);}}},_isActivationKey:function(M){var Q=this.get("type"),N=(Q=="checkbox"||Q=="radio")?this.CHECK_ACTIVATION_KEYS:this.ACTIVATION_KEYS,P=N.length,O;if(P>0){O=P-1;do{if(M==N[O]){return true;}}while(O--);}},_isSplitButtonOptionKey:function(M){return(M.ctrlKey&&M.shiftKey&&L.getCharCode(M)==77);},_addListenersToForm:function(){var S=this.getForm(),R=YAHOO.widget.Button.onFormKeyPress,Q,M,P,O,N;if(S){L.on(S,"reset",this._onFormReset,null,this);L.on(S,"submit",this.createHiddenFields,null,this);M=this.get("srcelement");if(this.get("type")=="submit"||(M&&M.type=="submit")){P=L.getListeners(S,"keypress");Q=false;if(P){O=P.length!
 ;if(O>0){N=O-1;do{if(P[N].fn==R){Q=true;break;}}while(N--);}}i!
 f(!Q){L.
on(S,"keypress",R);}}}},_showMenu:function(R){if(YAHOO.widget.MenuManager){YAHOO.widget.MenuManager.hideVisible();}if(K){K.hideAll();}var P=B.VIEWPORT_OFFSET,Y=this._menu,W=this,Z=W.get("element"),T=false,V=G.getY(Z),U=G.getDocumentScrollTop(),M,Q,b;if(U){V=V-U;}var O=V,N=(G.getViewportHeight()-(V+Z.offsetHeight));function S(){if(T){return(O-P);}else{return(N-P);}}function a(){var c=S();if(Q>c){M=Y.cfg.getProperty("minscrollheight");if(c>M){Y.cfg.setProperty("maxheight",c);if(T){Y.align("bl","tl");}}if(c<M){if(T){Y.cfg.setProperty("context",[Z,"tl","bl"],true);Y.align("tl","bl");}else{Y.cfg.setProperty("context",[Z,"bl","tl"],true);Y.align("bl","tl");T=true;return a();}}}}if(J&&Y&&(Y instanceof J)){Y.cfg.applyConfig({context:[Z,"tl","bl"],clicktohide:false,visible:true});Y.cfg.fireQueue();Y.cfg.setProperty("maxheight",0);Y.align("tl","bl");if(R.type=="mousedown"){L.stopPropagation(R);}Q=Y.element.offsetHeight;b=Y.element.lastChild;a();if(this.get("focusmenu")){this._menu.foc!
 us();}}else{if(B&&Y&&(Y instanceof B)){Y.show();Y.align("tl","bl");var X=S();Q=Y.element.offsetHeight;if(X<Q){Y.align("bl","tl");T=true;X=S();if(X<Q){Y.align("tl","bl");}}}}},_hideMenu:function(){var M=this._menu;if(M){M.hide();}},_onMouseOver:function(M){if(!this._hasMouseEventHandlers){this.on("mouseout",this._onMouseOut);this.on("mousedown",this._onMouseDown);this.on("mouseup",this._onMouseUp);this._hasMouseEventHandlers=true;}this.addStateCSSClasses("hover");if(this._activationButtonPressed){this.addStateCSSClasses("active");}if(this._bOptionPressed){this.addStateCSSClasses("activeoption");}if(this._activationButtonPressed||this._bOptionPressed){L.removeListener(document,"mouseup",this._onDocumentMouseUp);}},_onMouseOut:function(M){this.removeStateCSSClasses("hover");if(this.get("type")!="menu"){this.removeStateCSSClasses("active");}if(this._activationButtonPressed||this._bOptionPressed){L.on(document,"mouseup",this._onDocumentMouseUp,null,this);}},_onDocumentMouseUp:fu!
 nction(O){this._activationButtonPressed=false;this._bOptionPre!
 ssed=fal
se;var P=this.get("type"),M,N;if(P=="menu"||P=="split"){M=L.getTarget(O);N=this._menu.element;if(M!=N&&!G.isAncestor(N,M)){this.removeStateCSSClasses((P=="menu"?"active":"activeoption"));this._hideMenu();}}L.removeListener(document,"mouseup",this._onDocumentMouseUp);},_onMouseDown:function(P){var R,N,Q,O;function M(){this._hideMenu();this.removeListener("mouseup",M);}if((P.which||P.button)==1){if(!this.hasFocus()){this.focus();}R=this.get("type");if(R=="split"){N=this.get("element");Q=L.getPageX(P)-G.getX(N);if((N.offsetWidth-this.OPTION_AREA_WIDTH)<Q){this.fireEvent("option",P);}else{this.addStateCSSClasses("active");this._activationButtonPressed=true;}}else{if(R=="menu"){if(this.isActive()){this._hideMenu();this._activationButtonPressed=false;}else{this._showMenu(P);this._activationButtonPressed=true;}}else{this.addStateCSSClasses("active");this._activationButtonPressed=true;}}if(R=="split"||R=="menu"){O=this;this._hideMenuTimerId=window.setTimeout(function(){O.on("mouseup!
 ",M);},250);}}},_onMouseUp:function(M){var N=this.get("type");if(this._hideMenuTimerId){window.clearTimeout(this._hideMenuTimerId);}if(N=="checkbox"||N=="radio"){this.set("checked",!(this.get("checked")));}this._activationButtonPressed=false;if(this.get("type")!="menu"){this.removeStateCSSClasses("active");}},_onFocus:function(N){var M;this.addStateCSSClasses("focus");if(this._activationKeyPressed){this.addStateCSSClasses("active");}C=this;if(!this._hasKeyEventHandlers){M=this._button;L.on(M,"blur",this._onBlur,null,this);L.on(M,"keydown",this._onKeyDown,null,this);L.on(M,"keyup",this._onKeyUp,null,this);this._hasKeyEventHandlers=true;}this.fireEvent("focus",N);},_onBlur:function(M){this.removeStateCSSClasses("focus");if(this.get("type")!="menu"){this.removeStateCSSClasses("active");}if(this._activationKeyPressed){L.on(document,"keyup",this._onDocumentKeyUp,null,this);}C=null;this.fireEvent("blur",M);},_onDocumentKeyUp:function(M){if(this._isActivationKey(L.getCharCode(M)))!
 {this._activationKeyPressed=false;
-L.removeListener(document,"keyup",this._onDocumentKeyUp);}},_onKeyDown:function(N){var M=this._menu;if(this.get("type")=="split"&&this._isSplitButtonOptionKey(N)){this.fireEvent("option",N);}else{if(this._isActivationKey(L.getCharCode(N))){if(this.get("type")=="menu"){this._showMenu(N);}else{this._activationKeyPressed=true;this.addStateCSSClasses("active");}}}if(M&&M.cfg.getProperty("visible")&&L.getCharCode(N)==27){M.hide();this.focus();}},_onKeyUp:function(M){var N;if(this._isActivationKey(L.getCharCode(M))){N=this.get("type");if(N=="checkbox"||N=="radio"){this.set("checked",!(this.get("checked")));}this._activationKeyPressed=false;if(this.get("type")!="menu"){this.removeStateCSSClasses("active");}}},_onClick:function(P){var S=this.get("type"),M,Q,N,O,R;switch(S){case"radio":case"checkbox":if(this.get("checked")){M=(S=="radio")?this.RADIO_CHECKED_TITLE:this.CHECKBOX_CHECKED_TITLE;}else{M=(S=="radio")?this.RADIO_DEFAULT_TITLE:this.CHECKBOX_DEFAULT_TITLE;}this.set("title",M!
 );break;case"submit":this.submitForm();break;case"reset":Q=this.getForm();if(Q){Q.reset();}break;case"menu":M=this._menu.cfg.getProperty("visible")?this.MENUBUTTON_MENU_VISIBLE_TITLE:this.MENUBUTTON_DEFAULT_TITLE;this.set("title",M);break;case"split":O=this.get("element");R=L.getPageX(P)-G.getX(O);if((O.offsetWidth-this.OPTION_AREA_WIDTH)<R){return false;}else{this._hideMenu();N=this.get("srcelement");if(N&&N.type=="submit"){this.submitForm();}}M=this._menu.cfg.getProperty("visible")?this.SPLITBUTTON_OPTION_VISIBLE_TITLE:this.SPLITBUTTON_DEFAULT_TITLE;this.set("title",M);break;}},_onAppendTo:function(N){var M=this;window.setTimeout(function(){M._addListenersToForm();},0);},_onFormReset:function(N){var O=this.get("type"),M=this._menu;if(O=="checkbox"||O=="radio"){this.resetValue("checked");}if(J&&M&&(M instanceof J)){this.resetValue("selectedMenuItem");}},_onDocumentMouseDown:function(P){var M=L.getTarget(P),O=this.get("element"),N=this._menu.element;if(M!=O&&!G.isAncestor(O!
 ,M)&&M!=N&&!G.isAncestor(N,M)){this._hideMenu();L.removeListen!
 er(docum
ent,"mousedown",this._onDocumentMouseDown);}},_onOption:function(M){if(this.hasClass("yui-split-button-activeoption")){this._hideMenu();this._bOptionPressed=false;}else{this._showMenu(M);this._bOptionPressed=true;}},_onOverlayBeforeShow:function(N){var M=this._menu;M.render(this.get("element").parentNode);M.beforeShowEvent.unsubscribe(this._onOverlayBeforeShow);},_onMenuShow:function(N){L.on(document,"mousedown",this._onDocumentMouseDown,null,this);var M,O;if(this.get("type")=="split"){M=this.SPLITBUTTON_OPTION_VISIBLE_TITLE;O="activeoption";}else{M=this.MENUBUTTON_MENU_VISIBLE_TITLE;O="active";}this.addStateCSSClasses(O);this.set("title",M);},_onMenuHide:function(O){var N=this._menu,M,P;if(this.get("type")=="split"){M=this.SPLITBUTTON_DEFAULT_TITLE;P="activeoption";}else{M=this.MENUBUTTON_DEFAULT_TITLE;P="active";}this.removeStateCSSClasses(P);this.set("title",M);if(this.get("type")=="split"){this._bOptionPressed=false;}},_onMenuKeyDown:function(O,N){var M=N[0];if(L.getChar!
 Code(M)==27){this.focus();if(this.get("type")=="split"){this._bOptionPressed=false;}}},_onMenuRender:function(N){var P=this.get("element"),M=P.parentNode,O=this._menu.element;if(M!=O.parentNode){M.appendChild(O);}this.set("selectedMenuItem",this.get("selectedMenuItem"));},_onMenuItemSelected:function(O,N,M){var P=N[0];if(P){this.set("selectedMenuItem",M);}},_onMenuItemAdded:function(O,N,M){var P=N[0];P.cfg.subscribeToConfigEvent("selected",this._onMenuItemSelected,P,this);},_onMenuClick:function(N,M){var P=M[1],O;if(P){O=this.get("srcelement");if(O&&O.type=="submit"){this.submitForm();}this._hideMenu();}},createButtonElement:function(M){var O=this.NODE_NAME,N=document.createElement(O);N.innerHTML="<"+O+" class=\"first-child\">"+(M=="link"?"<a></a>":"<button type=\"button\"></button>")+"</"+O+">";return N;},addStateCSSClasses:function(M){var N=this.get("type");if(I.isString(M)){if(M!="activeoption"){this.addClass(this.CSS_CLASS_NAME+("-"+M));}this.addClass("yui-"+N+("-button!
 -"+M));}},removeStateCSSClasses:function(M){var N=this.get("ty!
 pe");if(
I.isString(M)){this.removeClass(this.CSS_CLASS_NAME+("-"+M));this.removeClass("yui-"+N+("-button-"+M));}},createHiddenFields:function(){this.removeHiddenFields();var R=this.getForm(),U,N,P,S,T,O,Q,M;if(R&&!this.get("disabled")){N=this.get("type");P=(N=="checkbox"||N=="radio");if(P||(E==this)){U=F((P?N:"hidden"),this.get("name"),this.get("value"),this.get("checked"));if(U){if(P){U.style.display="none";}R.appendChild(U);}}S=this._menu;if(J&&S&&(S instanceof J)){M=S.srcElement;T=this.get("selectedMenuItem");if(T){if(M&&M.nodeName.toUpperCase()=="SELECT"){R.appendChild(M);M.selectedIndex=T.index;}else{Q=(T.value===null||T.value==="")?T.cfg.getProperty("text"):T.value;O=this.get("name");if(Q&&O){M=F("hidden",(O+"_options"),Q);R.appendChild(M);}}}}if(U&&M){this._hiddenFields=[U,M];}else{if(!U&&M){this._hiddenFields=M;}else{if(U&&!M){this._hiddenFields=U;}}}return this._hiddenFields;}},removeHiddenFields:function(){var P=this._hiddenFields,N,O;function M(Q){if(G.inDocument(Q)){Q.pa!
 rentNode.removeChild(Q);}}if(P){if(I.isArray(P)){N=P.length;if(N>0){O=N-1;do{M(P[O]);}while(O--);}}else{M(P);}this._hiddenFields=null;}},submitForm:function(){var P=this.getForm(),O=this.get("srcelement"),N=false,M;if(P){if(this.get("type")=="submit"||(O&&O.type=="submit")){E=this;}if(YAHOO.env.ua.ie){N=P.fireEvent("onsubmit");}else{M=document.createEvent("HTMLEvents");M.initEvent("submit",true,true);N=P.dispatchEvent(M);}if((YAHOO.env.ua.ie||YAHOO.env.ua.webkit)&&N){P.submit();}}return N;},init:function(M,T){var O=T.type=="link"?"a":"button",Q=T.srcelement,S=M.getElementsByTagName(O)[0],R;if(!S){R=M.getElementsByTagName("input")[0];if(R){S=document.createElement("button");S.setAttribute("type","button");R.parentNode.replaceChild(S,R);}}this._button=S;YAHOO.widget.Button.superclass.init.call(this,M,T);D[this.get("id")]=this;this.addClass(this.CSS_CLASS_NAME);this.addClass("yui-"+this.get("type")+"-button");
-L.on(this._button,"focus",this._onFocus,null,this);this.on("mouseover",this._onMouseOver);this.on("click",this._onClick);this.on("appendTo",this._onAppendTo);var V=this.get("container"),N=this.get("element"),U=G.inDocument(N),P;if(V){if(Q&&Q!=N){P=Q.parentNode;if(P){P.removeChild(Q);}}if(I.isString(V)){L.onContentReady(V,function(){this.appendTo(V);},null,this);}else{this.appendTo(V);}}else{if(!U&&Q&&Q!=N){P=Q.parentNode;if(P){this.fireEvent("beforeAppendTo",{type:"beforeAppendTo",target:P});P.replaceChild(N,Q);this.fireEvent("appendTo",{type:"appendTo",target:P});}}else{if(this.get("type")!="link"&&U&&Q&&Q==N){this._addListenersToForm();}}}},initAttributes:function(N){var M=N||{};YAHOO.widget.Button.superclass.initAttributes.call(this,M);this.setAttributeConfig("type",{value:(M.type||"push"),validator:I.isString,writeOnce:true,method:this._setType});this.setAttributeConfig("label",{value:M.label,validator:I.isString,method:this._setLabel});this.setAttributeConfig("value",{!
 value:M.value});this.setAttributeConfig("name",{value:M.name,validator:I.isString});this.setAttributeConfig("tabindex",{value:M.tabindex,validator:I.isNumber,method:this._setTabIndex});this.configureAttribute("title",{value:M.title,validator:I.isString,method:this._setTitle});this.setAttributeConfig("disabled",{value:(M.disabled||false),validator:I.isBoolean,method:this._setDisabled});this.setAttributeConfig("href",{value:M.href,validator:I.isString,method:this._setHref});this.setAttributeConfig("target",{value:M.target,validator:I.isString,method:this._setTarget});this.setAttributeConfig("checked",{value:(M.checked||false),validator:I.isBoolean,method:this._setChecked});this.setAttributeConfig("container",{value:M.container,writeOnce:true});this.setAttributeConfig("srcelement",{value:M.srcelement,writeOnce:true});this.setAttributeConfig("menu",{value:null,method:this._setMenu,writeOnce:true});this.setAttributeConfig("lazyloadmenu",{value:(M.lazyloadmenu===false?false:true)!
 ,validator:I.isBoolean,writeOnce:true});this.setAttributeConfi!
 g("menuc
lassname",{value:(M.menuclassname||"yui-button-menu"),validator:I.isString,method:this._setMenuClassName,writeOnce:true});this.setAttributeConfig("selectedMenuItem",{value:null,method:this._setSelectedMenuItem});this.setAttributeConfig("onclick",{value:M.onclick,method:this._setOnClick});this.setAttributeConfig("focusmenu",{value:(M.focusmenu===false?false:true),validator:I.isBoolean});},focus:function(){if(!this.get("disabled")){this._button.focus();}},blur:function(){if(!this.get("disabled")){this._button.blur();}},hasFocus:function(){return(C==this);},isActive:function(){return this.hasClass(this.CSS_CLASS_NAME+"-active");},getMenu:function(){return this._menu;},getForm:function(){return this._button.form;},getHiddenFields:function(){return this._hiddenFields;},destroy:function(){var O=this.get("element"),N=O.parentNode,M=this._menu,Q;if(M){if(K&&K.find(M)){K.remove(M);}M.destroy();}L.purgeElement(O);L.purgeElement(this._button);L.removeListener(document,"mouseup",this._o!
 nDocumentMouseUp);L.removeListener(document,"keyup",this._onDocumentKeyUp);L.removeListener(document,"mousedown",this._onDocumentMouseDown);var P=this.getForm();if(P){L.removeListener(P,"reset",this._onFormReset);L.removeListener(P,"submit",this.createHiddenFields);}this.unsubscribeAll();if(N){N.removeChild(O);}delete D[this.get("id")];Q=G.getElementsByClassName(this.CSS_CLASS_NAME,this.NODE_NAME,P);if(I.isArray(Q)&&Q.length===0){L.removeListener(P,"keypress",YAHOO.widget.Button.onFormKeyPress);}},fireEvent:function(N,M){if(this.DOM_EVENTS[N]&&this.get("disabled")){return ;}YAHOO.widget.Button.superclass.fireEvent.call(this,N,M);},toString:function(){return("Button "+this.get("id"));}});YAHOO.widget.Button.onFormKeyPress=function(Q){var O=L.getTarget(Q),R=L.getCharCode(Q),P=O.nodeName&&O.nodeName.toUpperCase(),M=O.type,S=false,U,V,N,W;function T(Z){var Y,X;switch(Z.nodeName.toUpperCase()){case"INPUT":case"BUTTON":if(Z.type=="submit"&&!Z.disabled){if(!S&&!N){N=Z;}if(V&&!W){W!
 =Z;}}break;default:Y=Z.id;if(Y){U=D[Y];if(U){S=true;if(!U.get(!
 "disable
d")){X=U.get("srcelement");if(!V&&(U.get("type")=="submit"||(X&&X.type=="submit"))){V=U;}}}}break;}}if(R==13&&((P=="INPUT"&&(M=="text"||M=="password"||M=="checkbox"||M=="radio"||M=="file"))||P=="SELECT")){G.getElementsBy(T,"*",this);if(N){N.focus();}else{if(!N&&V){if(W){L.preventDefault(Q);}V.submitForm();}}}};YAHOO.widget.Button.addHiddenFieldsToForm=function(M){var R=G.getElementsByClassName(YAHOO.widget.Button.prototype.CSS_CLASS_NAME,"*",M),P=R.length,Q,N,O;if(P>0){for(O=0;O<P;O++){N=R[O].id;if(N){Q=D[N];if(Q){Q.createHiddenFields();}}}}};YAHOO.widget.Button.getButton=function(M){var N=D[M];if(N){return N;}};})();(function(){var C=YAHOO.util.Dom,B=YAHOO.util.Event,D=YAHOO.lang,A=YAHOO.widget.Button,E={};YAHOO.widget.ButtonGroup=function(J,H){var I=YAHOO.widget.ButtonGroup.superclass.constructor,K,G,F;if(arguments.length==1&&!D.isString(J)&&!J.nodeName){if(!J.id){F=C.generateId();J.id=F;}I.call(this,(this._createGroupElement()),J);}else{if(D.isString(J)){G=C.get(J);if(G){!
 if(G.nodeName.toUpperCase()==this.NODE_NAME){I.call(this,G,H);}}}else{K=J.nodeName.toUpperCase();if(K&&K==this.NODE_NAME){if(!J.id){J.id=C.generateId();}I.call(this,J,H);}}}};YAHOO.extend(YAHOO.widget.ButtonGroup,YAHOO.util.Element,{_buttons:null,NODE_NAME:"DIV",CSS_CLASS_NAME:"yui-buttongroup",_createGroupElement:function(){var F=document.createElement(this.NODE_NAME);return F;},_setDisabled:function(G){var H=this.getCount(),F;if(H>0){F=H-1;do{this._buttons[F].set("disabled",G);}while(F--);}},_onKeyDown:function(K){var G=B.getTarget(K),I=B.getCharCode(K),H=G.parentNode.parentNode.id,J=E[H],F=-1;if(I==37||I==38){F=(J.index===0)?(this._buttons.length-1):(J.index-1);}else{if(I==39||I==40){F=(J.index===(this._buttons.length-1))?0:(J.index+1);}}if(F>-1){this.check(F);this.getButton(F).focus();}},_onAppendTo:function(H){var I=this._buttons,G=I.length,F;for(F=0;F<G;F++){I[F].appendTo(this.get("element"));}},_onButtonCheckedChange:function(G,F){var I=G.newValue,H=this.get("checked!
 Button");
-if(I&&H!=F){if(H){H.set("checked",false,true);}this.set("checkedButton",F);this.set("value",F.get("value"));}else{if(H&&!H.set("checked")){H.set("checked",true,true);}}},init:function(I,H){this._buttons=[];YAHOO.widget.ButtonGroup.superclass.init.call(this,I,H);this.addClass(this.CSS_CLASS_NAME);var J=this.getElementsByClassName("yui-radio-button");if(J.length>0){this.addButtons(J);}function F(K){return(K.type=="radio");}J=C.getElementsBy(F,"input",this.get("element"));if(J.length>0){this.addButtons(J);}this.on("keydown",this._onKeyDown);this.on("appendTo",this._onAppendTo);var G=this.get("container");if(G){if(D.isString(G)){B.onContentReady(G,function(){this.appendTo(G);},null,this);}else{this.appendTo(G);}}},initAttributes:function(G){var F=G||{};YAHOO.widget.ButtonGroup.superclass.initAttributes.call(this,F);this.setAttributeConfig("name",{value:F.name,validator:D.isString});this.setAttributeConfig("disabled",{value:(F.disabled||false),validator:D.isBoolean,method:this._!
 setDisabled});this.setAttributeConfig("value",{value:F.value});this.setAttributeConfig("container",{value:F.container,writeOnce:true});this.setAttributeConfig("checkedButton",{value:null});},addButton:function(J){var L,K,G,F,H,I;if(J instanceof A&&J.get("type")=="radio"){L=J;}else{if(!D.isString(J)&&!J.nodeName){J.type="radio";L=new A(J);}else{L=new A(J,{type:"radio"});}}if(L){F=this._buttons.length;H=L.get("name");I=this.get("name");L.index=F;this._buttons[F]=L;E[L.get("id")]=L;if(H!=I){L.set("name",I);}if(this.get("disabled")){L.set("disabled",true);}if(L.get("checked")){this.set("checkedButton",L);}K=L.get("element");G=this.get("element");if(K.parentNode!=G){G.appendChild(K);}L.on("checkedChange",this._onButtonCheckedChange,L,this);return L;}},addButtons:function(G){var H,I,J,F;if(D.isArray(G)){H=G.length;J=[];if(H>0){for(F=0;F<H;F++){I=this.addButton(G[F]);if(I){J[J.length]=I;}}if(J.length>0){return J;}}}},removeButton:function(H){var I=this.getButton(H),G,F;if(I){this.!
 _buttons.splice(H,1);delete E[I.get("id")];I.removeListener("c!
 heckedCh
ange",this._onButtonCheckedChange);I.destroy();G=this._buttons.length;if(G>0){F=this._buttons.length-1;do{this._buttons[F].index=F;}while(F--);}}},getButton:function(F){if(D.isNumber(F)){return this._buttons[F];}},getButtons:function(){return this._buttons;},getCount:function(){return this._buttons.length;},focus:function(H){var I,G,F;if(D.isNumber(H)){I=this._buttons[H];if(I){I.focus();}}else{G=this.getCount();for(F=0;F<G;F++){I=this._buttons[F];if(!I.get("disabled")){I.focus();break;}}}},check:function(F){var G=this.getButton(F);if(G){G.set("checked",true);}},destroy:function(){var I=this._buttons.length,H=this.get("element"),F=H.parentNode,G;if(I>0){G=this._buttons.length-1;do{this._buttons[G].destroy();}while(G--);}B.purgeElement(H);F.removeChild(H);},toString:function(){return("ButtonGroup "+this.get("id"));}});})();YAHOO.register("button",YAHOO.widget.Button,{version:"2.4.1",build:"742"});
\ No newline at end of file
+(function(){var G=YAHOO.util.Dom,L=YAHOO.util.Event,I=YAHOO.lang,B=YAHOO.widget.Overlay,J=YAHOO.widget.Menu,D={},K=null,E=null,C=null;function F(N,M,Q,O){var R,P;if(I.isString(N)&&I.isString(M)){if(YAHOO.env.ua.ie){P="<input type=\""+N+"\" name=\""+M+"\"";if(O){P+=" checked";}P+=">";R=document.createElement(P);}else{R=document.createElement("input");R.name=M;R.type=N;if(O){R.checked=true;}}R.value=Q;return R;}}function H(N,T){var M=N.nodeName.toUpperCase(),R=this,S,O,P;function U(V){if(!(V in T)){S=N.getAttributeNode(V);if(S&&("value" in S)){T[V]=S.value;}}}function Q(){U("type");if(T.type=="button"){T.type="push";}if(!("disabled" in T)){T.disabled=N.disabled;}U("name");U("value");U("title");}switch(M){case"A":T.type="link";U("href");U("target");break;case"INPUT":Q();if(!("checked" in T)){T.checked=N.checked;}break;case"BUTTON":Q();O=N.parentNode.parentNode;if(G.hasClass(O,this.CSS_CLASS_NAME+"-checked")){T.checked=true;}if(G.hasClass(O,this.CSS_CLASS_NAME+"-disabled")){T.d!
 isabled=true;}N.removeAttribute("value");N.setAttribute("type","button");break;}N.removeAttribute("id");N.removeAttribute("name");if(!("tabindex" in T)){T.tabindex=N.tabIndex;}if(!("label" in T)){P=M=="INPUT"?N.value:N.innerHTML;if(P&&P.length>0){T.label=P;}}}function A(O){var N=O.attributes,M=N.srcelement,Q=M.nodeName.toUpperCase(),P=this;if(Q==this.NODE_NAME){O.element=M;O.id=M.id;G.getElementsBy(function(R){switch(R.nodeName.toUpperCase()){case"BUTTON":case"A":case"INPUT":H.call(P,R,N);break;}},"*",M);}else{switch(Q){case"BUTTON":case"A":case"INPUT":H.call(this,M,N);break;}}}YAHOO.widget.Button=function(Q,N){if(!B&&YAHOO.widget.Overlay){B=YAHOO.widget.Overlay;}if(!J&&YAHOO.widget.Menu){J=YAHOO.widget.Menu;}var P=YAHOO.widget.Button.superclass.constructor,O,M;if(arguments.length==1&&!I.isString(Q)&&!Q.nodeName){if(!Q.id){Q.id=G.generateId();}P.call(this,(this.createButtonElement(Q.type)),Q);}else{O={element:null,attributes:(N||{})};if(I.isString(Q)){M=G.get(Q);if(M){if(!O!
 .attributes.id){O.attributes.id=Q;}O.attributes.srcelement=M;A!
 .call(th
is,O);if(!O.element){O.element=this.createButtonElement(O.attributes.type);}P.call(this,O.element,O.attributes);}}else{if(Q.nodeName){if(!O.attributes.id){if(Q.id){O.attributes.id=Q.id;}else{O.attributes.id=G.generateId();}}O.attributes.srcelement=Q;A.call(this,O);if(!O.element){O.element=this.createButtonElement(O.attributes.type);}P.call(this,O.element,O.attributes);}}}};YAHOO.extend(YAHOO.widget.Button,YAHOO.util.Element,{_button:null,_menu:null,_hiddenFields:null,_onclickAttributeValue:null,_activationKeyPressed:false,_activationButtonPressed:false,_hasKeyEventHandlers:false,_hasMouseEventHandlers:false,NODE_NAME:"SPAN",CHECK_ACTIVATION_KEYS:[32],ACTIVATION_KEYS:[13,32],OPTION_AREA_WIDTH:20,CSS_CLASS_NAME:"yui-button",RADIO_DEFAULT_TITLE:"Unchecked.  Click to check.",RADIO_CHECKED_TITLE:"Checked.  Click another button to uncheck",CHECKBOX_DEFAULT_TITLE:"Unchecked.  Click to check.",CHECKBOX_CHECKED_TITLE:"Checked.  Click to uncheck.",MENUBUTTON_DEFAULT_TITLE:"Menu collap!
 sed.  Click to expand.",MENUBUTTON_MENU_VISIBLE_TITLE:"Menu expanded.  Click or press Esc to collapse.",SPLITBUTTON_DEFAULT_TITLE:("Menu collapsed.  Click inside option region or press Ctrl + Shift + M to show the menu."),SPLITBUTTON_OPTION_VISIBLE_TITLE:"Menu expanded.  Press Esc or Ctrl + Shift + M to hide the menu.",SUBMIT_TITLE:"Click to submit form.",_setType:function(M){if(M=="split"){this.on("option",this._onOption);}},_setLabel:function(M){this._button.innerHTML=M;var O,N;if(YAHOO.env.ua.gecko&&G.inDocument(this.get("element"))){N=this;O=this.CSS_CLASS_NAME;this.removeClass(O);window.setTimeout(function(){N.addClass(O);},0);}},_setTabIndex:function(M){this._button.tabIndex=M;},_setTitle:function(N){var M=N;if(this.get("type")!="link"){if(!M){switch(this.get("type")){case"radio":M=this.RADIO_DEFAULT_TITLE;break;case"checkbox":M=this.CHECKBOX_DEFAULT_TITLE;break;case"menu":M=this.MENUBUTTON_DEFAULT_TITLE;break;case"split":M=this.SPLITBUTTON_DEFAULT_TITLE;break;case"su!
 bmit":M=this.SUBMIT_TITLE;break;}}this._button.title=M;}},_set!
 Disabled
:function(M){if(this.get("type")!="link"){if(M){if(this._menu){this._menu.hide();}if(this.hasFocus()){this.blur();}this._button.setAttribute("disabled","disabled");this.addStateCSSClasses("disabled");this.removeStateCSSClasses("hover");this.removeStateCSSClasses("active");this.removeStateCSSClasses("focus");}else{this._button.removeAttribute("disabled");this.removeStateCSSClasses("disabled");}}},_setHref:function(M){if(this.get("type")=="link"){this._button.href=M;}},_setTarget:function(M){if(this.get("type")=="link"){this._button.setAttribute("target",M);}},_setChecked:function(N){var O=this.get("type"),M;if(O=="checkbox"||O=="radio"){if(N){this.addStateCSSClasses("checked");M=(O=="radio")?this.RADIO_CHECKED_TITLE:this.CHECKBOX_CHECKED_TITLE;}else{this.removeStateCSSClasses("checked");M=(O=="radio")?this.RADIO_DEFAULT_TITLE:this.CHECKBOX_DEFAULT_TITLE;}this.set("title",M);}},_setMenu:function(W){var Q=this.get("lazyloadmenu"),T=this.get("element"),M,Y=false,Z,P,S,O,N,V,R;if!
 (!B){return false;}if(J){M=J.prototype.CSS_CLASS_NAME;}function X(){Z.render(T.parentNode);this.removeListener("appendTo",X);}function U(){if(Z){G.addClass(Z.element,this.get("menuclassname"));G.addClass(Z.element,"yui-"+this.get("type")+"-button-menu");Z.showEvent.subscribe(this._onMenuShow,null,this);Z.hideEvent.subscribe(this._onMenuHide,null,this);Z.renderEvent.subscribe(this._onMenuRender,null,this);if(J&&Z instanceof J){Z.keyDownEvent.subscribe(this._onMenuKeyDown,this,true);Z.subscribe("click",this._onMenuClick,this,true);Z.itemAddedEvent.subscribe(this._onMenuItemAdded,this,true);S=Z.srcElement;if(S&&S.nodeName.toUpperCase()=="SELECT"){S.style.display="none";S.parentNode.removeChild(S);}}else{if(B&&Z instanceof B){if(!K){K=new YAHOO.widget.OverlayManager();}K.register(Z);}}this._menu=Z;if(!Y){if(Q&&J&&!(Z instanceof J)){Z.beforeShowEvent.subscribe(this._onOverlayBeforeShow,null,this);}else{if(!Q){if(G.inDocument(T)){Z.render(T.parentNode);
+}else{this.on("appendTo",X);}}}}}}if(W&&J&&(W instanceof J)){Z=W;O=Z.getItems();N=O.length;Y=true;if(N>0){R=N-1;do{V=O[R];if(V){V.cfg.subscribeToConfigEvent("selected",this._onMenuItemSelected,V,this);}}while(R--);}U.call(this);}else{if(B&&W&&(W instanceof B)){Z=W;Y=true;Z.cfg.setProperty("visible",false);Z.cfg.setProperty("context",[T,"tl","bl"]);U.call(this);}else{if(J&&I.isArray(W)){this.on("appendTo",function(){Z=new J(G.generateId(),{lazyload:Q,itemdata:W});U.call(this);});}else{if(I.isString(W)){P=G.get(W);if(P){if(J&&G.hasClass(P,M)||P.nodeName.toUpperCase()=="SELECT"){Z=new J(W,{lazyload:Q});U.call(this);}else{if(B){Z=new B(W,{visible:false,context:[T,"tl","bl"]});U.call(this);}}}}else{if(W&&W.nodeName){if(J&&G.hasClass(W,M)||W.nodeName.toUpperCase()=="SELECT"){Z=new J(W,{lazyload:Q});U.call(this);}else{if(B){if(!W.id){G.generateId(W);}Z=new B(W,{visible:false,context:[T,"tl","bl"]});U.call(this);}}}}}}}},_setOnClick:function(M){if(this._onclickAttributeValue&&(this!
 ._onclickAttributeValue!=M)){this.removeListener("click",this._onclickAttributeValue.fn);this._onclickAttributeValue=null;}if(!this._onclickAttributeValue&&I.isObject(M)&&I.isFunction(M.fn)){this.on("click",M.fn,M.obj,M.scope);this._onclickAttributeValue=M;}},_setSelectedMenuItem:function(N){var M=this._menu,O;if(J&&M&&M instanceof J){O=M.getItem(N);if(O&&!O.cfg.getProperty("selected")){O.cfg.setProperty("selected",true);}}},_isActivationKey:function(M){var Q=this.get("type"),N=(Q=="checkbox"||Q=="radio")?this.CHECK_ACTIVATION_KEYS:this.ACTIVATION_KEYS,P=N.length,O;if(P>0){O=P-1;do{if(M==N[O]){return true;}}while(O--);}},_isSplitButtonOptionKey:function(M){return(M.ctrlKey&&M.shiftKey&&L.getCharCode(M)==77);},_addListenersToForm:function(){var S=this.getForm(),R=YAHOO.widget.Button.onFormKeyPress,Q,M,P,O,N;if(S){L.on(S,"reset",this._onFormReset,null,this);L.on(S,"submit",this.createHiddenFields,null,this);M=this.get("srcelement");if(this.get("type")=="submit"||(M&&M.type=="!
 submit")){P=L.getListeners(S,"keypress");Q=false;if(P){O=P.len!
 gth;if(O
>0){N=O-1;do{if(P[N].fn==R){Q=true;break;}}while(N--);}}if(!Q){L.on(S,"keypress",R);}}}},_showMenu:function(R){if(YAHOO.widget.MenuManager){YAHOO.widget.MenuManager.hideVisible();}if(K){K.hideAll();}var P=B.VIEWPORT_OFFSET,Y=this._menu,W=this,Z=W.get("element"),T=false,V=G.getY(Z),U=G.getDocumentScrollTop(),M,Q,b;if(U){V=V-U;}var O=V,N=(G.getViewportHeight()-(V+Z.offsetHeight));function S(){if(T){return(O-P);}else{return(N-P);}}function a(){var c=S();if(Q>c){M=Y.cfg.getProperty("minscrollheight");if(c>M){Y.cfg.setProperty("maxheight",c);if(T){Y.align("bl","tl");}}if(c<M){if(T){Y.cfg.setProperty("context",[Z,"tl","bl"],true);Y.align("tl","bl");}else{Y.cfg.setProperty("context",[Z,"bl","tl"],true);Y.align("bl","tl");T=true;return a();}}}}if(J&&Y&&(Y instanceof J)){Y.cfg.applyConfig({context:[Z,"tl","bl"],clicktohide:false,visible:true});Y.cfg.fireQueue();Y.cfg.setProperty("maxheight",0);Y.align("tl","bl");if(R.type=="mousedown"){L.stopPropagation(R);}Q=Y.element.offsetHeight;b!
 =Y.element.lastChild;a();if(this.get("focusmenu")){this._menu.focus();}}else{if(B&&Y&&(Y instanceof B)){Y.show();Y.align("tl","bl");var X=S();Q=Y.element.offsetHeight;if(X<Q){Y.align("bl","tl");T=true;X=S();if(X<Q){Y.align("tl","bl");}}}}},_hideMenu:function(){var M=this._menu;if(M){M.hide();}},_onMouseOver:function(M){if(!this._hasMouseEventHandlers){this.on("mouseout",this._onMouseOut);this.on("mousedown",this._onMouseDown);this.on("mouseup",this._onMouseUp);this._hasMouseEventHandlers=true;}this.addStateCSSClasses("hover");if(this._activationButtonPressed){this.addStateCSSClasses("active");}if(this._bOptionPressed){this.addStateCSSClasses("activeoption");}if(this._activationButtonPressed||this._bOptionPressed){L.removeListener(document,"mouseup",this._onDocumentMouseUp);}},_onMouseOut:function(M){this.removeStateCSSClasses("hover");if(this.get("type")!="menu"){this.removeStateCSSClasses("active");}if(this._activationButtonPressed||this._bOptionPressed){L.on(document,"mou!
 seup",this._onDocumentMouseUp,null,this);}},_onDocumentMouseUp!
 :functio
n(O){this._activationButtonPressed=false;this._bOptionPressed=false;var P=this.get("type"),M,N;if(P=="menu"||P=="split"){M=L.getTarget(O);N=this._menu.element;if(M!=N&&!G.isAncestor(N,M)){this.removeStateCSSClasses((P=="menu"?"active":"activeoption"));this._hideMenu();}}L.removeListener(document,"mouseup",this._onDocumentMouseUp);},_onMouseDown:function(P){var R,N,Q,O;function M(){this._hideMenu();this.removeListener("mouseup",M);}if((P.which||P.button)==1){if(!this.hasFocus()){this.focus();}R=this.get("type");if(R=="split"){N=this.get("element");Q=L.getPageX(P)-G.getX(N);if((N.offsetWidth-this.OPTION_AREA_WIDTH)<Q){this.fireEvent("option",P);}else{this.addStateCSSClasses("active");this._activationButtonPressed=true;}}else{if(R=="menu"){if(this.isActive()){this._hideMenu();this._activationButtonPressed=false;}else{this._showMenu(P);this._activationButtonPressed=true;}}else{this.addStateCSSClasses("active");this._activationButtonPressed=true;}}if(R=="split"||R=="menu"){O=this!
 ;this._hideMenuTimerId=window.setTimeout(function(){O.on("mouseup",M);},250);}}},_onMouseUp:function(M){var N=this.get("type");if(this._hideMenuTimerId){window.clearTimeout(this._hideMenuTimerId);}if(N=="checkbox"||N=="radio"){this.set("checked",!(this.get("checked")));}this._activationButtonPressed=false;if(this.get("type")!="menu"){this.removeStateCSSClasses("active");}},_onFocus:function(N){var M;this.addStateCSSClasses("focus");if(this._activationKeyPressed){this.addStateCSSClasses("active");}C=this;if(!this._hasKeyEventHandlers){M=this._button;L.on(M,"blur",this._onBlur,null,this);L.on(M,"keydown",this._onKeyDown,null,this);L.on(M,"keyup",this._onKeyUp,null,this);this._hasKeyEventHandlers=true;}this.fireEvent("focus",N);},_onBlur:function(M){this.removeStateCSSClasses("focus");if(this.get("type")!="menu"){this.removeStateCSSClasses("active");}if(this._activationKeyPressed){L.on(document,"keyup",this._onDocumentKeyUp,null,this);
+}C=null;this.fireEvent("blur",M);},_onDocumentKeyUp:function(M){if(this._isActivationKey(L.getCharCode(M))){this._activationKeyPressed=false;L.removeListener(document,"keyup",this._onDocumentKeyUp);}},_onKeyDown:function(N){var M=this._menu;if(this.get("type")=="split"&&this._isSplitButtonOptionKey(N)){this.fireEvent("option",N);}else{if(this._isActivationKey(L.getCharCode(N))){if(this.get("type")=="menu"){this._showMenu(N);}else{this._activationKeyPressed=true;this.addStateCSSClasses("active");}}}if(M&&M.cfg.getProperty("visible")&&L.getCharCode(N)==27){M.hide();this.focus();}},_onKeyUp:function(M){var N;if(this._isActivationKey(L.getCharCode(M))){N=this.get("type");if(N=="checkbox"||N=="radio"){this.set("checked",!(this.get("checked")));}this._activationKeyPressed=false;if(this.get("type")!="menu"){this.removeStateCSSClasses("active");}}},_onClick:function(P){var S=this.get("type"),M,Q,N,O,R;switch(S){case"radio":case"checkbox":if(this.get("checked")){M=(S=="radio")?this.!
 RADIO_CHECKED_TITLE:this.CHECKBOX_CHECKED_TITLE;}else{M=(S=="radio")?this.RADIO_DEFAULT_TITLE:this.CHECKBOX_DEFAULT_TITLE;}this.set("title",M);break;case"submit":this.submitForm();break;case"reset":Q=this.getForm();if(Q){Q.reset();}break;case"menu":M=this._menu.cfg.getProperty("visible")?this.MENUBUTTON_MENU_VISIBLE_TITLE:this.MENUBUTTON_DEFAULT_TITLE;this.set("title",M);break;case"split":O=this.get("element");R=L.getPageX(P)-G.getX(O);if((O.offsetWidth-this.OPTION_AREA_WIDTH)<R){return false;}else{this._hideMenu();N=this.get("srcelement");if(N&&N.type=="submit"){this.submitForm();}}M=this._menu.cfg.getProperty("visible")?this.SPLITBUTTON_OPTION_VISIBLE_TITLE:this.SPLITBUTTON_DEFAULT_TITLE;this.set("title",M);break;}},_onAppendTo:function(N){var M=this;window.setTimeout(function(){M._addListenersToForm();},0);},_onFormReset:function(N){var O=this.get("type"),M=this._menu;if(O=="checkbox"||O=="radio"){this.resetValue("checked");}if(J&&M&&(M instanceof J)){this.resetValue("se!
 lectedMenuItem");}},_onDocumentMouseDown:function(P){var M=L.g!
 etTarget
(P),O=this.get("element"),N=this._menu.element;if(M!=O&&!G.isAncestor(O,M)&&M!=N&&!G.isAncestor(N,M)){this._hideMenu();L.removeListener(document,"mousedown",this._onDocumentMouseDown);}},_onOption:function(M){if(this.hasClass("yui-split-button-activeoption")){this._hideMenu();this._bOptionPressed=false;}else{this._showMenu(M);this._bOptionPressed=true;}},_onOverlayBeforeShow:function(N){var M=this._menu;M.render(this.get("element").parentNode);M.beforeShowEvent.unsubscribe(this._onOverlayBeforeShow);},_onMenuShow:function(N){L.on(document,"mousedown",this._onDocumentMouseDown,null,this);var M,O;if(this.get("type")=="split"){M=this.SPLITBUTTON_OPTION_VISIBLE_TITLE;O="activeoption";}else{M=this.MENUBUTTON_MENU_VISIBLE_TITLE;O="active";}this.addStateCSSClasses(O);this.set("title",M);},_onMenuHide:function(O){var N=this._menu,M,P;if(this.get("type")=="split"){M=this.SPLITBUTTON_DEFAULT_TITLE;P="activeoption";}else{M=this.MENUBUTTON_DEFAULT_TITLE;P="active";}this.removeStateCSSCl!
 asses(P);this.set("title",M);if(this.get("type")=="split"){this._bOptionPressed=false;}},_onMenuKeyDown:function(O,N){var M=N[0];if(L.getCharCode(M)==27){this.focus();if(this.get("type")=="split"){this._bOptionPressed=false;}}},_onMenuRender:function(N){var P=this.get("element"),M=P.parentNode,O=this._menu.element;if(M!=O.parentNode){M.appendChild(O);}this.set("selectedMenuItem",this.get("selectedMenuItem"));},_onMenuItemSelected:function(O,N,M){var P=N[0];if(P){this.set("selectedMenuItem",M);}},_onMenuItemAdded:function(O,N,M){var P=N[0];P.cfg.subscribeToConfigEvent("selected",this._onMenuItemSelected,P,this);},_onMenuClick:function(N,M){var P=M[1],O;if(P){O=this.get("srcelement");if(O&&O.type=="submit"){this.submitForm();}this._hideMenu();}},createButtonElement:function(M){var O=this.NODE_NAME,N=document.createElement(O);N.innerHTML="<"+O+" class=\"first-child\">"+(M=="link"?"<a></a>":"<button type=\"button\"></button>")+"</"+O+">";return N;},addStateCSSClasses:function(M!
 ){var N=this.get("type");if(I.isString(M)){if(M!="activeoption!
 "){this.
addClass(this.CSS_CLASS_NAME+("-"+M));}this.addClass("yui-"+N+("-button-"+M));}},removeStateCSSClasses:function(M){var N=this.get("type");if(I.isString(M)){this.removeClass(this.CSS_CLASS_NAME+("-"+M));this.removeClass("yui-"+N+("-button-"+M));}},createHiddenFields:function(){this.removeHiddenFields();var R=this.getForm(),U,N,P,S,T,O,Q,M;if(R&&!this.get("disabled")){N=this.get("type");P=(N=="checkbox"||N=="radio");if(P||(E==this)){U=F((P?N:"hidden"),this.get("name"),this.get("value"),this.get("checked"));if(U){if(P){U.style.display="none";}R.appendChild(U);}}S=this._menu;if(J&&S&&(S instanceof J)){M=S.srcElement;T=this.get("selectedMenuItem");if(T){if(M&&M.nodeName.toUpperCase()=="SELECT"){R.appendChild(M);M.selectedIndex=T.index;}else{Q=(T.value===null||T.value==="")?T.cfg.getProperty("text"):T.value;O=this.get("name");if(Q&&O){M=F("hidden",(O+"_options"),Q);R.appendChild(M);}}}}if(U&&M){this._hiddenFields=[U,M];}else{if(!U&&M){this._hiddenFields=M;}else{if(U&&!M){this._hid!
 denFields=U;}}}return this._hiddenFields;}},removeHiddenFields:function(){var P=this._hiddenFields,N,O;function M(Q){if(G.inDocument(Q)){Q.parentNode.removeChild(Q);}}if(P){if(I.isArray(P)){N=P.length;if(N>0){O=N-1;do{M(P[O]);}while(O--);}}else{M(P);}this._hiddenFields=null;}},submitForm:function(){var P=this.getForm(),O=this.get("srcelement"),N=false,M;if(P){if(this.get("type")=="submit"||(O&&O.type=="submit")){E=this;}if(YAHOO.env.ua.ie){N=P.fireEvent("onsubmit");}else{M=document.createEvent("HTMLEvents");M.initEvent("submit",true,true);N=P.dispatchEvent(M);}if((YAHOO.env.ua.ie||YAHOO.env.ua.webkit)&&N){P.submit();}}return N;},init:function(M,T){var O=T.type=="link"?"a":"button",Q=T.srcelement,S=M.getElementsByTagName(O)[0],R;if(!S){R=M.getElementsByTagName("input")[0];if(R){S=document.createElement("button");S.setAttribute("type","button");R.parentNode.replaceChild(S,R);}}this._button=S;YAHOO.widget.Button.superclass.init.call(this,M,T);
+D[this.get("id")]=this;this.addClass(this.CSS_CLASS_NAME);this.addClass("yui-"+this.get("type")+"-button");L.on(this._button,"focus",this._onFocus,null,this);this.on("mouseover",this._onMouseOver);this.on("click",this._onClick);this.on("appendTo",this._onAppendTo);var V=this.get("container"),N=this.get("element"),U=G.inDocument(N),P;if(V){if(Q&&Q!=N){P=Q.parentNode;if(P){P.removeChild(Q);}}if(I.isString(V)){L.onContentReady(V,function(){this.appendTo(V);},null,this);}else{this.appendTo(V);}}else{if(!U&&Q&&Q!=N){P=Q.parentNode;if(P){this.fireEvent("beforeAppendTo",{type:"beforeAppendTo",target:P});P.replaceChild(N,Q);this.fireEvent("appendTo",{type:"appendTo",target:P});}}else{if(this.get("type")!="link"&&U&&Q&&Q==N){this._addListenersToForm();}}}},initAttributes:function(N){var M=N||{};YAHOO.widget.Button.superclass.initAttributes.call(this,M);this.setAttributeConfig("type",{value:(M.type||"push"),validator:I.isString,writeOnce:true,method:this._setType});this.setAttributeC!
 onfig("label",{value:M.label,validator:I.isString,method:this._setLabel});this.setAttributeConfig("value",{value:M.value});this.setAttributeConfig("name",{value:M.name,validator:I.isString});this.setAttributeConfig("tabindex",{value:M.tabindex,validator:I.isNumber,method:this._setTabIndex});this.configureAttribute("title",{value:M.title,validator:I.isString,method:this._setTitle});this.setAttributeConfig("disabled",{value:(M.disabled||false),validator:I.isBoolean,method:this._setDisabled});this.setAttributeConfig("href",{value:M.href,validator:I.isString,method:this._setHref});this.setAttributeConfig("target",{value:M.target,validator:I.isString,method:this._setTarget});this.setAttributeConfig("checked",{value:(M.checked||false),validator:I.isBoolean,method:this._setChecked});this.setAttributeConfig("container",{value:M.container,writeOnce:true});this.setAttributeConfig("srcelement",{value:M.srcelement,writeOnce:true});this.setAttributeConfig("menu",{value:null,method:this.!
 _setMenu,writeOnce:true});this.setAttributeConfig("lazyloadmen!
 u",{valu
e:(M.lazyloadmenu===false?false:true),validator:I.isBoolean,writeOnce:true});this.setAttributeConfig("menuclassname",{value:(M.menuclassname||"yui-button-menu"),validator:I.isString,method:this._setMenuClassName,writeOnce:true});this.setAttributeConfig("selectedMenuItem",{value:null,method:this._setSelectedMenuItem});this.setAttributeConfig("onclick",{value:M.onclick,method:this._setOnClick});this.setAttributeConfig("focusmenu",{value:(M.focusmenu===false?false:true),validator:I.isBoolean});},focus:function(){if(!this.get("disabled")){this._button.focus();}},blur:function(){if(!this.get("disabled")){this._button.blur();}},hasFocus:function(){return(C==this);},isActive:function(){return this.hasClass(this.CSS_CLASS_NAME+"-active");},getMenu:function(){return this._menu;},getForm:function(){return this._button.form;},getHiddenFields:function(){return this._hiddenFields;},destroy:function(){var O=this.get("element"),N=O.parentNode,M=this._menu,Q;if(M){if(K&&K.find(M)){K.remove(!
 M);}M.destroy();}L.purgeElement(O);L.purgeElement(this._button);L.removeListener(document,"mouseup",this._onDocumentMouseUp);L.removeListener(document,"keyup",this._onDocumentKeyUp);L.removeListener(document,"mousedown",this._onDocumentMouseDown);var P=this.getForm();if(P){L.removeListener(P,"reset",this._onFormReset);L.removeListener(P,"submit",this.createHiddenFields);}this.unsubscribeAll();if(N){N.removeChild(O);}delete D[this.get("id")];Q=G.getElementsByClassName(this.CSS_CLASS_NAME,this.NODE_NAME,P);if(I.isArray(Q)&&Q.length===0){L.removeListener(P,"keypress",YAHOO.widget.Button.onFormKeyPress);}},fireEvent:function(N,M){var O=arguments[0];if(this.DOM_EVENTS[O]&&this.get("disabled")){return ;}return YAHOO.widget.Button.superclass.fireEvent.apply(this,arguments);},toString:function(){return("Button "+this.get("id"));}});YAHOO.widget.Button.onFormKeyPress=function(Q){var O=L.getTarget(Q),R=L.getCharCode(Q),P=O.nodeName&&O.nodeName.toUpperCase(),M=O.type,S=false,U,V,N,W;f!
 unction T(Z){var Y,X;switch(Z.nodeName.toUpperCase()){case"INP!
 UT":case
"BUTTON":if(Z.type=="submit"&&!Z.disabled){if(!S&&!N){N=Z;}if(V&&!W){W=Z;}}break;default:Y=Z.id;if(Y){U=D[Y];if(U){S=true;if(!U.get("disabled")){X=U.get("srcelement");if(!V&&(U.get("type")=="submit"||(X&&X.type=="submit"))){V=U;}}}}break;}}if(R==13&&((P=="INPUT"&&(M=="text"||M=="password"||M=="checkbox"||M=="radio"||M=="file"))||P=="SELECT")){G.getElementsBy(T,"*",this);if(N){N.focus();}else{if(!N&&V){if(W){L.preventDefault(Q);}V.submitForm();}}}};YAHOO.widget.Button.addHiddenFieldsToForm=function(M){var R=G.getElementsByClassName(YAHOO.widget.Button.prototype.CSS_CLASS_NAME,"*",M),P=R.length,Q,N,O;if(P>0){for(O=0;O<P;O++){N=R[O].id;if(N){Q=D[N];if(Q){Q.createHiddenFields();}}}}};YAHOO.widget.Button.getButton=function(M){var N=D[M];if(N){return N;}};})();(function(){var C=YAHOO.util.Dom,B=YAHOO.util.Event,D=YAHOO.lang,A=YAHOO.widget.Button,E={};YAHOO.widget.ButtonGroup=function(J,H){var I=YAHOO.widget.ButtonGroup.superclass.constructor,K,G,F;if(arguments.length==1&&!D.isStri!
 ng(J)&&!J.nodeName){if(!J.id){F=C.generateId();J.id=F;}I.call(this,(this._createGroupElement()),J);}else{if(D.isString(J)){G=C.get(J);if(G){if(G.nodeName.toUpperCase()==this.NODE_NAME){I.call(this,G,H);}}}else{K=J.nodeName.toUpperCase();if(K&&K==this.NODE_NAME){if(!J.id){J.id=C.generateId();}I.call(this,J,H);}}}};YAHOO.extend(YAHOO.widget.ButtonGroup,YAHOO.util.Element,{_buttons:null,NODE_NAME:"DIV",CSS_CLASS_NAME:"yui-buttongroup",_createGroupElement:function(){var F=document.createElement(this.NODE_NAME);return F;},_setDisabled:function(G){var H=this.getCount(),F;if(H>0){F=H-1;do{this._buttons[F].set("disabled",G);}while(F--);}},_onKeyDown:function(K){var G=B.getTarget(K),I=B.getCharCode(K),H=G.parentNode.parentNode.id,J=E[H],F=-1;if(I==37||I==38){F=(J.index===0)?(this._buttons.length-1):(J.index-1);}else{if(I==39||I==40){F=(J.index===(this._buttons.length-1))?0:(J.index+1);}}if(F>-1){this.check(F);this.getButton(F).focus();
+}},_onAppendTo:function(H){var I=this._buttons,G=I.length,F;for(F=0;F<G;F++){I[F].appendTo(this.get("element"));}},_onButtonCheckedChange:function(G,F){var I=G.newValue,H=this.get("checkedButton");if(I&&H!=F){if(H){H.set("checked",false,true);}this.set("checkedButton",F);this.set("value",F.get("value"));}else{if(H&&!H.set("checked")){H.set("checked",true,true);}}},init:function(I,H){this._buttons=[];YAHOO.widget.ButtonGroup.superclass.init.call(this,I,H);this.addClass(this.CSS_CLASS_NAME);var J=this.getElementsByClassName("yui-radio-button");if(J.length>0){this.addButtons(J);}function F(K){return(K.type=="radio");}J=C.getElementsBy(F,"input",this.get("element"));if(J.length>0){this.addButtons(J);}this.on("keydown",this._onKeyDown);this.on("appendTo",this._onAppendTo);var G=this.get("container");if(G){if(D.isString(G)){B.onContentReady(G,function(){this.appendTo(G);},null,this);}else{this.appendTo(G);}}},initAttributes:function(G){var F=G||{};YAHOO.widget.ButtonGroup.supercl!
 ass.initAttributes.call(this,F);this.setAttributeConfig("name",{value:F.name,validator:D.isString});this.setAttributeConfig("disabled",{value:(F.disabled||false),validator:D.isBoolean,method:this._setDisabled});this.setAttributeConfig("value",{value:F.value});this.setAttributeConfig("container",{value:F.container,writeOnce:true});this.setAttributeConfig("checkedButton",{value:null});},addButton:function(J){var L,K,G,F,H,I;if(J instanceof A&&J.get("type")=="radio"){L=J;}else{if(!D.isString(J)&&!J.nodeName){J.type="radio";L=new A(J);}else{L=new A(J,{type:"radio"});}}if(L){F=this._buttons.length;H=L.get("name");I=this.get("name");L.index=F;this._buttons[F]=L;E[L.get("id")]=L;if(H!=I){L.set("name",I);}if(this.get("disabled")){L.set("disabled",true);}if(L.get("checked")){this.set("checkedButton",L);}K=L.get("element");G=this.get("element");if(K.parentNode!=G){G.appendChild(K);}L.on("checkedChange",this._onButtonCheckedChange,L,this);return L;}},addButtons:function(G){var H,I,J,F!
 ;if(D.isArray(G)){H=G.length;J=[];if(H>0){for(F=0;F<H;F++){I=t!
 his.addB
utton(G[F]);if(I){J[J.length]=I;}}if(J.length>0){return J;}}}},removeButton:function(H){var I=this.getButton(H),G,F;if(I){this._buttons.splice(H,1);delete E[I.get("id")];I.removeListener("checkedChange",this._onButtonCheckedChange);I.destroy();G=this._buttons.length;if(G>0){F=this._buttons.length-1;do{this._buttons[F].index=F;}while(F--);}}},getButton:function(F){if(D.isNumber(F)){return this._buttons[F];}},getButtons:function(){return this._buttons;},getCount:function(){return this._buttons.length;},focus:function(H){var I,G,F;if(D.isNumber(H)){I=this._buttons[H];if(I){I.focus();}}else{G=this.getCount();for(F=0;F<G;F++){I=this._buttons[F];if(!I.get("disabled")){I.focus();break;}}}},check:function(F){var G=this.getButton(F);if(G){G.set("checked",true);}},destroy:function(){var I=this._buttons.length,H=this.get("element"),F=H.parentNode,G;if(I>0){G=this._buttons.length-1;do{this._buttons[G].destroy();}while(G--);}B.purgeElement(H);F.removeChild(H);},toString:function(){return!
 ("ButtonGroup "+this.get("id"));}});})();YAHOO.register("button",YAHOO.widget.Button,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/button/button.js
===================================================================
--- trunk/root/static/yui/button/button.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/button/button.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
 * @module button
@@ -396,6 +396,20 @@
 
     YAHOO.widget.Button = function (p_oElement, p_oAttributes) {
     
+		if (!Overlay && YAHOO.widget.Overlay) {
+		
+			Overlay = YAHOO.widget.Overlay;
+		
+		}
+
+
+		if (!Menu && YAHOO.widget.Menu) {
+		
+			Menu = YAHOO.widget.Menu;
+		
+		}
+
+
         var fnSuperClass = YAHOO.widget.Button.superclass.constructor,
             oConfig,
             oElement;
@@ -3534,17 +3548,18 @@
         
         fireEvent: function (p_sType , p_aArgs) {
         
-            //  Disabled buttons should not respond to DOM events
+			var sType = arguments[0];
+		
+			//  Disabled buttons should not respond to DOM events
+		
+			if (this.DOM_EVENTS[sType] && this.get("disabled")) {
+		
+				return;
+		
+			}
+		
+			return YAHOO.widget.Button.superclass.fireEvent.apply(this, arguments);
         
-            if (this.DOM_EVENTS[p_sType] && this.get("disabled")) {
-        
-                return;
-        
-            }
-        
-            YAHOO.widget.Button.superclass.fireEvent.call(this, p_sType, 
-                p_aArgs);
-        
         },
         
         
@@ -4652,4 +4667,4 @@
     });
 
 })();
-YAHOO.register("button", YAHOO.widget.Button, {version: "2.4.1", build: "742"});
+YAHOO.register("button", YAHOO.widget.Button, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/calendar/README
===================================================================
--- trunk/root/static/yui/calendar/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/calendar/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +1,62 @@
-Calendar Release Notes 
+Calendar Release Notes
 
-*** version 2.4.1 *** 
+*** version 2.5.1 *** 
 
-No change
++ Fixed bug with mindate, maxdate being applied incorrectly if 
+  set to a day on which time change took place (DST, E.U Summertime) 
+  and the day is not the first day of the week.
 
++ Fixed DateMath.getWeekNumber implementation to return correct 
+  week numbers. The older implementation would return Week 0 for 
+  certain weeks (e.g. the week starting Sun Dec 28th 2008)
+
+  To suppor the fix, DateMath.getWeekNumber has a signature 
+  change in 2.5.1 and can now support U.S Week calculations based 
+  on Jan 1st identifying the first week of the year, as well as 
+  ISO8601 week calculations based on Jan 4th identifying the first 
+  week of the year
+
+  The arguments which the method expected prior to 2.5.1 were not 
+  being used in calculating the week number. The new signature is:
+
+  DateMath.getWeekNumber(Date dt, Number firstDayOfWeek, Number janDate)
+
+  Where:
+
+    dt is the date for which week number is required
+
+    firstDayOfWeek is the day index identifying the first 
+    day of the week. Default is 0 (Sunday).
+
+    janDate is the date in the first week of January, which
+    identifies the first week of the year. 
+    Default is YAHOO.widget.DateMath.WEEK_ONE_JAN_DATE (1)
+
+  NOTE: Calendar instances themselves do not currently expose a 
+  configuration property to change the week numbering system 
+  used. A "janDate" value is not passed to the getWeekNumber 
+  method, when used by Calendar, resulting in it using the default value.
+
+  Therefore, ISO8601 week numbering can be generated for Calendars 
+  by setting the value of YAHOO.widget.DateMath.WEEK_ONE_JAN_DATE
+  to 4.
+
+*** version 2.5.0 *** 
+
++ Prevent default event handling in CalendarNavigator enter key 
+  listener, to prevent automatic form submission when using Calendar
+  inside a form.
+
++ Added workaround to DateMath.add and subtract for Safari 2 (webkit) 
+  bug in Date.setDate(n) which doesn't handle value of n less than -128 
+  or greater than 127 correctly.
+
+  See: http://brianary.blogspot.com/2006/03/safari-date-bug.html
+
++ Added border, padding and margin rules to Calendar Sam Skin to 
+  protect Sam Skin's look and feel when Calendar is used with 
+  YUI base.css
+
 *** version 2.4.0 *** 
 
 + Added CalendarNavigator (year selector) feature to allow the user to 
@@ -88,7 +141,7 @@
 
 *** version 2.3.1 *** 
 
-- Changed Calendar/CalendarGroup to render an empty title bar element 
++ Changed Calendar/CalendarGroup to render an empty title bar element 
   when "close" is set to true, but "title" has not been set, to allow Sam 
   Skin to render a title bar correctly. 
 
@@ -342,4 +395,4 @@
 
 *** version 0.9.0 *** 
 
-* Initial release
+* Initial release
\ No newline at end of file

Modified: trunk/root/static/yui/calendar/assets/calendar-core.css
===================================================================
--- trunk/root/static/yui/calendar/assets/calendar-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/calendar/assets/calendar-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * CORE

Modified: trunk/root/static/yui/calendar/assets/calendar.css
===================================================================
--- trunk/root/static/yui/calendar/assets/calendar.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/calendar/assets/calendar.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-calcontainer {
 	position:relative;

Modified: trunk/root/static/yui/calendar/assets/skins/sam/calendar-skin.css
===================================================================
--- trunk/root/static/yui/calendar/assets/skins/sam/calendar-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/calendar/assets/skins/sam/calendar-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * SAM
@@ -79,6 +79,7 @@
 	border-collapse:collapse;
 	font:100% sans-serif;
 	text-align:center;
+	margin:0;
 }
 
 /* NAVBAR BOUNDING BOX */
@@ -86,6 +87,7 @@
 	background:transparent;
 	border:none;
 	vertical-align:middle;
+	padding:0;
 }
 
 /* NAVBAR TEXT CONTAINER */
@@ -129,6 +131,11 @@
 	height:2em;
 }
 
+.yui-skin-sam .yui-calendar .calweekdayrow th {
+	padding:0;
+	border:none;
+}
+
 /* WEEKDAY (Su, Mo, Tu...) HEADER CELLS */
 .yui-skin-sam .yui-calendar .calweekdaycell {
 	color:#000;
@@ -148,16 +155,17 @@
 	font-size:85%;
 	font-style:normal;
 	font-weight:normal;
+	border:none;
 }
 
 .yui-skin-sam .yui-calendar .calrowhead {
 	text-align:right;
-	padding-right:2px;
+	padding:0 2px 0 0;
 }
 
 .yui-skin-sam .yui-calendar .calrowfoot {
 	text-align:left;
-	padding-left:2px;
+	padding:0 0 0 2px;
 }
 
 /* NORMAL CELLS */

Modified: trunk/root/static/yui/calendar/assets/skins/sam/calendar.css
===================================================================
--- trunk/root/static/yui/calendar/assets/skins/sam/calendar.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/calendar/assets/skins/sam/calendar.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-.yui-calcontainer{position:relative;float:left;_overflow:hidden;}.yui-calcontainer iframe{position:absolute;border:none;margin:0;padding:0;z-index:0;width:100%;height:100%;left:0px;top:0px;}.yui-calcontainer iframe.fixedsize{width:50em;height:50em;top:-1px;left:-1px;}.yui-calcontainer.multi .groupcal{z-index:1;float:left;position:relative;}.yui-calcontainer .title{position:relative;z-index:1;}.yui-calcontainer .close-icon{position:absolute;z-index:1;}.yui-calendar{position:relative;}.yui-calendar .calnavleft{position:absolute;z-index:1;}.yui-calendar .calnavright{position:absolute;z-index:1;}.yui-calendar .calheader{position:relative;width:100%;text-align:center;}.yui-calcontainer .yui-cal-nav-mask{position:absolute;z-index:2;margin:0;padding:0;width:100%;height:100%;_width:0;_height:0;left:0;top:0;display:none;}.yui-calcontainer .yui-cal-nav{position:absolute;z-index:3;top:0;display:none;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{display:-moz-inline-box;display:inlin!
 e-block;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{display:block;*display:inline-block;*overflow:visible;border:none;background-color:transparent;cursor:pointer;}.yui-calendar .calbody a:hover{background:inherit;}p#clear{clear:left;padding-top:10px;}.yui-skin-sam .yui-calcontainer{background-color:#f2f2f2;border:1px solid #808080;padding:10px;}.yui-skin-sam .yui-calcontainer.multi{padding:0 5px 0 5px;}.yui-skin-sam .yui-calcontainer.multi .groupcal{background-color:transparent;border:none;padding:10px 5px 10px 5px;margin:0;}.yui-skin-sam .yui-calcontainer .title{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;border-bottom:1px solid #cccccc;font:100% sans-serif;color:#000;font-weight:bold;height:auto;padding:.4em;margin:0 -10px 10px -10px;top:0;left:0;text-align:left;}.yui-skin-sam .yui-calcontainer.multi .title{margin:0 -5px 0 -5px;}.yui-skin-sam .yui-calcontainer.withtitle{padding-top:0;}.yui-skin-sam .yui-calcontainer .calclose{backgroun!
 d:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -30!
 0px;widt
h:25px;height:15px;top:.4em;right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar{border-spacing:0;border-collapse:collapse;font:100% sans-serif;text-align:center;}.yui-skin-sam .yui-calendar .calhead{background:transparent;border:none;vertical-align:middle;}.yui-skin-sam .yui-calendar .calheader{background:transparent;font-weight:bold;padding:0 0 .6em 0;text-align:center;}.yui-skin-sam .yui-calendar .calheader img{border:none;}.yui-skin-sam .yui-calendar .calnavleft{background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -450px;width:25px;height:15px;top:0;bottom:0;left:-10px;margin-left:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calnavright{background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -500px;width:25px;height:15px;top:0;bottom:0;right:-10px;margin-right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calweekdayrow{height:2em;}.yui-skin-sam .yui-calendar .calweekdaycell{color:#000;font-weight:bold;text-align:center;width:2em;}.yu!
 i-skin-sam .yui-calendar .calfoot{background-color:#f2f2f2;}.yui-skin-sam .yui-calendar .calrowhead,.yui-skin-sam .yui-calendar .calrowfoot{color:#a6a6a6;font-size:85%;font-style:normal;font-weight:normal;}.yui-skin-sam .yui-calendar .calrowhead{text-align:right;padding-right:2px;}.yui-skin-sam .yui-calendar .calrowfoot{text-align:left;padding-left:2px;}.yui-skin-sam .yui-calendar td.calcell{border:1px solid #cccccc;background:#fff;padding:1px;height:1.6em;line-height:1.6em;text-align:center;white-space:nowrap;}.yui-skin-sam .yui-calendar td.calcell a{color:#0066cc;display:block;height:100%;text-decoration:none;}.yui-skin-sam .yui-calendar td.calcell.today{background-color:#000;}.yui-skin-sam .yui-calendar td.calcell.today a{background-color:#fff;}.yui-skin-sam .yui-calendar td.calcell.oom{background-color:#cccccc;color:#a6a6a6;cursor:default;}.yui-skin-sam .yui-calendar td.calcell.selected{background-color:#fff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.selected a{!
 background-color:#b3d4ff;color:#000;}.yui-skin-sam .yui-calend!
 ar td.ca
lcell.calcellhover{background-color:#426fd9;color:#fff;cursor:pointer;}.yui-skin-sam .yui-calendar td.calcell.calcellhover a{background-color:#426fd9;color:#fff;}.yui-skin-sam .yui-calendar td.calcell.previous{color:#e0e0e0;}.yui-skin-sam .yui-calendar td.calcell.restricted{text-decoration:line-through;}.yui-skin-sam .yui-calendar td.calcell.highlight1{background-color:#ccff99;}.yui-skin-sam .yui-calendar td.calcell.highlight2{background-color:#99ccff;}.yui-skin-sam .yui-calendar td.calcell.highlight3{background-color:#ffcccc;}.yui-skin-sam .yui-calendar td.calcell.highlight4{background-color:#ccff99;}.yui-skin-sam .yui-calendar a.calnav{border:1px solid #f2f2f2;padding:0 4px;text-decoration:none;color:#000;zoom:1;}.yui-skin-sam .yui-calendar a.calnav:hover{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;border-color:#A0A0A0;cursor:pointer;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mask{background-color:#000;opacity:0.25;*filter:alpha(opacity=25);}.yu!
 i-skin-sam .yui-calcontainer .yui-cal-nav{font-family:arial,helvetica,clean,sans-serif;font-size:93%;border:1px solid #808080;left:50%;margin-left:-7em;width:14em;padding:0;top:2.5em;background-color:#f2f2f2;}.yui-skin-sam .yui-calcontainer.withtitle .yui-cal-nav{top:4.5em;}.yui-skin-sam .yui-calcontainer.multi .yui-cal-nav{width:16em;margin-left:-8em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y,.yui-skin-sam .yui-calcontainer .yui-cal-nav-m,.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{padding:5px 10px 5px 10px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{text-align:center;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-e{margin-top:5px;padding:5px;background-color:#EDF5FF;border-top:1px solid black;display:none;}.yui-skin-sam .yui-calcontainer .yui-cal-nav label{display:block;font-weight:bold;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mc{width:100%;_width:auto;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y input.yui-invalid{background-color:#FFEE69;border:1px sol!
 id #000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-yc{width!
 :4em;}.y
ui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{border:1px solid #808080;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;background-color:#ccc;margin:auto .15em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{padding:0 8px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default{border:1px solid #304369;background-color:#426fd9;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1400px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default button{color:#fff;}
+.yui-calcontainer{position:relative;float:left;_overflow:hidden;}.yui-calcontainer iframe{position:absolute;border:none;margin:0;padding:0;z-index:0;width:100%;height:100%;left:0px;top:0px;}.yui-calcontainer iframe.fixedsize{width:50em;height:50em;top:-1px;left:-1px;}.yui-calcontainer.multi .groupcal{z-index:1;float:left;position:relative;}.yui-calcontainer .title{position:relative;z-index:1;}.yui-calcontainer .close-icon{position:absolute;z-index:1;}.yui-calendar{position:relative;}.yui-calendar .calnavleft{position:absolute;z-index:1;}.yui-calendar .calnavright{position:absolute;z-index:1;}.yui-calendar .calheader{position:relative;width:100%;text-align:center;}.yui-calcontainer .yui-cal-nav-mask{position:absolute;z-index:2;margin:0;padding:0;width:100%;height:100%;_width:0;_height:0;left:0;top:0;display:none;}.yui-calcontainer .yui-cal-nav{position:absolute;z-index:3;top:0;display:none;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{display:-moz-inline-box;display:inlin!
 e-block;}.yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{display:block;*display:inline-block;*overflow:visible;border:none;background-color:transparent;cursor:pointer;}.yui-calendar .calbody a:hover{background:inherit;}p#clear{clear:left;padding-top:10px;}.yui-skin-sam .yui-calcontainer{background-color:#f2f2f2;border:1px solid #808080;padding:10px;}.yui-skin-sam .yui-calcontainer.multi{padding:0 5px 0 5px;}.yui-skin-sam .yui-calcontainer.multi .groupcal{background-color:transparent;border:none;padding:10px 5px 10px 5px;margin:0;}.yui-skin-sam .yui-calcontainer .title{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;border-bottom:1px solid #cccccc;font:100% sans-serif;color:#000;font-weight:bold;height:auto;padding:.4em;margin:0 -10px 10px -10px;top:0;left:0;text-align:left;}.yui-skin-sam .yui-calcontainer.multi .title{margin:0 -5px 0 -5px;}.yui-skin-sam .yui-calcontainer.withtitle{padding-top:0;}.yui-skin-sam .yui-calcontainer .calclose{backgroun!
 d:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -30!
 0px;widt
h:25px;height:15px;top:.4em;right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar{border-spacing:0;border-collapse:collapse;font:100% sans-serif;text-align:center;margin:0;}.yui-skin-sam .yui-calendar .calhead{background:transparent;border:none;vertical-align:middle;padding:0;}.yui-skin-sam .yui-calendar .calheader{background:transparent;font-weight:bold;padding:0 0 .6em 0;text-align:center;}.yui-skin-sam .yui-calendar .calheader img{border:none;}.yui-skin-sam .yui-calendar .calnavleft{background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -450px;width:25px;height:15px;top:0;bottom:0;left:-10px;margin-left:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calnavright{background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -500px;width:25px;height:15px;top:0;bottom:0;right:-10px;margin-right:.4em;cursor:pointer;}.yui-skin-sam .yui-calendar .calweekdayrow{height:2em;}.yui-skin-sam .yui-calendar .calweekdayrow th{padding:0;border:none;}.yui-skin-sam .y!
 ui-calendar .calweekdaycell{color:#000;font-weight:bold;text-align:center;width:2em;}.yui-skin-sam .yui-calendar .calfoot{background-color:#f2f2f2;}.yui-skin-sam .yui-calendar .calrowhead,.yui-skin-sam .yui-calendar .calrowfoot{color:#a6a6a6;font-size:85%;font-style:normal;font-weight:normal;border:none;}.yui-skin-sam .yui-calendar .calrowhead{text-align:right;padding:0 2px 0 0;}.yui-skin-sam .yui-calendar .calrowfoot{text-align:left;padding:0 0 0 2px;}.yui-skin-sam .yui-calendar td.calcell{border:1px solid #cccccc;background:#fff;padding:1px;height:1.6em;line-height:1.6em;text-align:center;white-space:nowrap;}.yui-skin-sam .yui-calendar td.calcell a{color:#0066cc;display:block;height:100%;text-decoration:none;}.yui-skin-sam .yui-calendar td.calcell.today{background-color:#000;}.yui-skin-sam .yui-calendar td.calcell.today a{background-color:#fff;}.yui-skin-sam .yui-calendar td.calcell.oom{background-color:#cccccc;color:#a6a6a6;cursor:default;}.yui-skin-sam .yui-calendar td.!
 calcell.selected{background-color:#fff;color:#000;}.yui-skin-s!
 am .yui-
calendar td.calcell.selected a{background-color:#b3d4ff;color:#000;}.yui-skin-sam .yui-calendar td.calcell.calcellhover{background-color:#426fd9;color:#fff;cursor:pointer;}.yui-skin-sam .yui-calendar td.calcell.calcellhover a{background-color:#426fd9;color:#fff;}.yui-skin-sam .yui-calendar td.calcell.previous{color:#e0e0e0;}.yui-skin-sam .yui-calendar td.calcell.restricted{text-decoration:line-through;}.yui-skin-sam .yui-calendar td.calcell.highlight1{background-color:#ccff99;}.yui-skin-sam .yui-calendar td.calcell.highlight2{background-color:#99ccff;}.yui-skin-sam .yui-calendar td.calcell.highlight3{background-color:#ffcccc;}.yui-skin-sam .yui-calendar td.calcell.highlight4{background-color:#ccff99;}.yui-skin-sam .yui-calendar a.calnav{border:1px solid #f2f2f2;padding:0 4px;text-decoration:none;color:#000;zoom:1;}.yui-skin-sam .yui-calendar a.calnav:hover{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;border-color:#A0A0A0;cursor:pointer;}.yui-skin-sam !
 .yui-calcontainer .yui-cal-nav-mask{background-color:#000;opacity:0.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-calcontainer .yui-cal-nav{font-family:arial,helvetica,clean,sans-serif;font-size:93%;border:1px solid #808080;left:50%;margin-left:-7em;width:14em;padding:0;top:2.5em;background-color:#f2f2f2;}.yui-skin-sam .yui-calcontainer.withtitle .yui-cal-nav{top:4.5em;}.yui-skin-sam .yui-calcontainer.multi .yui-cal-nav{width:16em;margin-left:-8em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-y,.yui-skin-sam .yui-calcontainer .yui-cal-nav-m,.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{padding:5px 10px 5px 10px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-b{text-align:center;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-e{margin-top:5px;padding:5px;background-color:#EDF5FF;border-top:1px solid black;display:none;}.yui-skin-sam .yui-calcontainer .yui-cal-nav label{display:block;font-weight:bold;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-mc{width:100%;_width:auto;}.yu!
 i-skin-sam .yui-calcontainer .yui-cal-nav-y input.yui-invalid{!
 backgrou
nd-color:#FFEE69;border:1px solid #000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav-yc{width:4em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn{border:1px solid #808080;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;background-color:#ccc;margin:auto .15em;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn button{padding:0 8px;font-size:93%;line-height:2;*line-height:1.7;min-height:2em;*min-height:auto;color:#000;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default{border:1px solid #304369;background-color:#426fd9;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1400px;}.yui-skin-sam .yui-calcontainer .yui-cal-nav .yui-cal-nav-btn.yui-default button{color:#fff;}

Modified: trunk/root/static/yui/calendar/calendar-debug.js
===================================================================
--- trunk/root/static/yui/calendar/calendar-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/calendar/calendar-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 (function () {
 
@@ -737,6 +737,19 @@
 	* @type Number
 	*/
 	ONE_DAY_MS : 1000*60*60*24,
+	
+	/**
+	 * Constant field representing the date in first week of January
+	 * which identifies the first week of the year.
+	 * <p>
+	 * In the U.S, Jan 1st is normally used based on a Sunday start of week.
+	 * ISO 8601, used widely throughout Europe, uses Jan 4th, based on a Monday start of week.
+	 * </p>
+	 * @property WEEK_ONE_JAN_DATE
+	 * @static
+	 * @type Number
+	 */
+	WEEK_ONE_JAN_DATE : 1,
 
 	/**
 	* Adds the specified amount of time to the this instance.
@@ -753,7 +766,6 @@
 				var newMonth = date.getMonth() + amount;
 				var years = 0;
 
-
 				if (newMonth < 0) {
 					while (newMonth < 0) {
 						newMonth += 12;
@@ -765,24 +777,56 @@
 						years += 1;
 					}
 				}
-				
+
 				d.setMonth(newMonth);
 				d.setFullYear(date.getFullYear() + years);
 				break;
 			case this.DAY:
-				d.setDate(date.getDate() + amount);
+				this._addDays(d, amount);
+				// d.setDate(date.getDate() + amount);
 				break;
 			case this.YEAR:
 				d.setFullYear(date.getFullYear() + amount);
 				break;
 			case this.WEEK:
-				d.setDate(date.getDate() + (amount * 7));
+				this._addDays(d, (amount * 7));
+				// d.setDate(date.getDate() + (amount * 7));
 				break;
 		}
 		return d;
 	},
 
 	/**
+	 * Private helper method to account for bug in Safari 2 (webkit < 420)
+	 * when Date.setDate(n) is called with n less than -128 or greater than 127.
+	 * <p>
+	 * Fix approach and original findings are available here:
+	 * http://brianary.blogspot.com/2006/03/safari-date-bug.html
+	 * </p>
+	 * @method _addDays
+	 * @param {Date} d JavaScript date object
+	 * @param {Number} nDays The number of days to add to the date object (can be negative)
+	 * @private
+	 */
+	_addDays : function(d, nDays) {
+		if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 420) {
+			if (nDays < 0) {
+				// Ensure we don't go below -128 (getDate() is always 1 to 31, so we won't go above 127)
+				for(var min = -128; nDays < min; nDays -= min) {
+					d.setDate(d.getDate() + min);
+				}
+			} else {
+				// Ensure we don't go above 96 + 31 = 127
+				for(var max = 96; nDays > max; nDays -= max) {
+					d.setDate(d.getDate() + max);
+				}
+			}
+			// nDays should be remainder between -128 and 96
+		}
+		d.setDate(d.getDate() + nDays);
+	},
+
+	/**
 	* Subtracts the specified amount of time from the this instance.
 	* @method subtract
 	* @param {Date} date	The JavaScript Date object to perform subtraction on
@@ -869,30 +913,79 @@
 	},
 
 	/**
-	* Calculates the week number for the given date. This function assumes that week 1 is the
-	* week in which January 1 appears, regardless of whether the week consists of a full 7 days.
-	* The calendar year can be specified to help find what a the week number would be for a given
-	* date if the date overlaps years. For instance, a week may be considered week 1 of 2005, or
-	* week 53 of 2004. Specifying the optional calendarYear allows one to make this distinction
-	* easily.
+	* Calculates the week number for the given date. Can currently support standard
+	* U.S. week numbers, based on Jan 1st defining the 1st week of the year, and 
+	* ISO8601 week numbers, based on Jan 4th defining the 1st week of the year.
+	* 
 	* @method getWeekNumber
-	* @param {Date}	date	The JavaScript date for which to find the week number
-	* @param {Number} calendarYear	OPTIONAL - The calendar year to use for determining the week number. Default is
-	*											the calendar year of parameter "date".
-	* @return {Number}	The week number of the given date.
+	* @param {Date}	date The JavaScript date for which to find the week number
+	* @param {Number} firstDayOfWeek The index of the first day of the week (0 = Sun, 1 = Mon ... 6 = Sat).
+	* Defaults to 0
+	* @param {Number} janDate The date in the first week of January which defines week one for the year
+	* Defaults to the value of YAHOO.widget.DateMath.WEEK_ONE_JAN_DATE, which is 1 (Jan 1st). 
+	* For the U.S, this is normally Jan 1st. ISO8601 uses Jan 4th to define the first week of the year.
+	* 
+	* @return {Number} The number of the week containing the given date.
 	*/
-	getWeekNumber : function(date, calendarYear) {
-		date = this.clearTime(date);
-		var nearestThurs = new Date(date.getTime() + (4 * this.ONE_DAY_MS) - ((date.getDay()) * this.ONE_DAY_MS));
+	getWeekNumber : function(date, firstDayOfWeek, janDate) {
 
-		var jan1 = this.getDate(nearestThurs.getFullYear(),0,1);
-		var dayOfYear = ((nearestThurs.getTime() - jan1.getTime()) / this.ONE_DAY_MS) - 1;
+		// Setup Defaults
+		firstDayOfWeek = firstDayOfWeek || 0;
+		janDate = janDate || this.WEEK_ONE_JAN_DATE;
 
-		var weekNum = Math.ceil((dayOfYear)/ 7);
+		var targetDate = this.clearTime(date),
+			startOfWeek,
+			endOfWeek;
+
+		if (targetDate.getDay() === firstDayOfWeek) { 
+			startOfWeek = targetDate;
+		} else {
+			startOfWeek = this.getFirstDayOfWeek(targetDate, firstDayOfWeek);
+		}
+
+		var startYear = startOfWeek.getFullYear(),
+			startTime = startOfWeek.getTime();
+
+		// DST shouldn't be a problem here, math is quicker than setDate();
+		endOfWeek = new Date(startOfWeek.getTime() + 6*this.ONE_DAY_MS);
+
+		var weekNum;
+		if (startYear !== endOfWeek.getFullYear() && endOfWeek.getDate() >= janDate) {
+			// If years don't match, endOfWeek is in Jan. and if the 
+			// week has WEEK_ONE_JAN_DATE in it, it's week one by definition.
+			weekNum = 1;
+		} else {
+			// Get the 1st day of the 1st week, and 
+			// find how many days away we are from it.
+			var weekOne = this.clearTime(this.getDate(startYear, 0, janDate)),
+				weekOneDayOne = this.getFirstDayOfWeek(weekOne, firstDayOfWeek);
+
+			// Round days to smoothen out 1 hr DST diff
+			var daysDiff  = Math.round((targetDate.getTime() - weekOneDayOne.getTime())/this.ONE_DAY_MS);
+
+			// Calc. Full Weeks
+			var rem = daysDiff % 7;
+			var weeksDiff = (daysDiff - rem)/7;
+			weekNum = weeksDiff + 1;
+		}
 		return weekNum;
 	},
 
 	/**
+	 * Get the first day of the week, for the give date. 
+	 * @param {Date} dt The date in the week for which the first day is required.
+	 * @param {Number} startOfWeek The index for the first day of the week, 0 = Sun, 1 = Mon ... 6 = Sat (defaults to 0)
+	 * @return {Date} The first day of the week
+	 */
+	getFirstDayOfWeek : function (dt, startOfWeek) {
+		startOfWeek = startOfWeek || 0;
+		var dayOfWeekIndex = dt.getDay(),
+			dayOfWeek = (dayOfWeekIndex - startOfWeek + 7) % 7;
+
+		return this.subtract(dt, this.DAY, dayOfWeek);
+	},
+
+	/**
 	* Determines if a given week overlaps two different years.
 	* @method isYearOverlapWeek
 	* @param {Date}	weekBeginDate	The JavaScript Date representing the first day of the week.
@@ -1922,9 +2015,9 @@
 		* @default false
 		*/
 		this.cfg.addProperty(defCfg.MULTI_SELECT.key,	{ value:defCfg.MULTI_SELECT.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
-	
+
 		/**
-		* The weekday the week begins on. Default is 0 (Sunday).
+		* The weekday the week begins on. Default is 0 (Sunday = 0, Monday = 1 ... Saturday = 6).
 		* @config START_WEEKDAY
 		* @type number
 		* @default 0
@@ -2630,7 +2723,7 @@
 	renderHeader : function(html) {
 		this.logger.log("Rendering header", "render");
 		var colSpan = 7;
-		
+
 		var DEPR_NAV_LEFT = "us/tr/callt.gif";
 		var DEPR_NAV_RIGHT = "us/tr/calrt.gif";	
 		var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
@@ -2642,14 +2735,14 @@
 		if (this.cfg.getProperty(defCfg.SHOW_WEEK_FOOTER.key)) {
 			colSpan += 1;
 		}
-	
+
 		html[html.length] = "<thead>";
 		html[html.length] =		"<tr>";
 		html[html.length] =			'<th colspan="' + colSpan + '" class="' + this.Style.CSS_HEADER_TEXT + '">';
 		html[html.length] =				'<div class="' + this.Style.CSS_HEADER + '">';
-	
+
 		var renderLeft, renderRight = false;
-	
+
 		if (this.parent) {
 			if (this.index === 0) {
 				renderLeft = true;
@@ -2661,7 +2754,7 @@
 			renderLeft = true;
 			renderRight = true;
 		}
-	
+
 		if (renderLeft) {
 			var leftArrow = this.cfg.getProperty(defCfg.NAV_ARROW_LEFT.key);
 			// Check for deprecated customization - If someone set IMG_ROOT, but didn't set NAV_ARROW_LEFT, then set NAV_ARROW_LEFT to the old deprecated value
@@ -2737,10 +2830,14 @@
 	*/
 	renderBody : function(workingDate, html) {
 		this.logger.log("Rendering body", "render");
-		var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
-	
+
+		var DM = YAHOO.widget.DateMath,
+			CAL = YAHOO.widget.Calendar,
+			D = YAHOO.util.Dom,
+			defCfg = CAL._DEFAULT_CONFIG;
+
 		var startDay = this.cfg.getProperty(defCfg.START_WEEKDAY.key);
-	
+
 		this.preMonthDays = workingDate.getDay();
 		if (startDay > 0) {
 			this.preMonthDays -= startDay;
@@ -2748,71 +2845,68 @@
 		if (this.preMonthDays < 0) {
 			this.preMonthDays += 7;
 		}
-		
-		this.monthDays = YAHOO.widget.DateMath.findMonthEnd(workingDate).getDate();
-		this.postMonthDays = YAHOO.widget.Calendar.DISPLAY_DAYS-this.preMonthDays-this.monthDays;
+
+		this.monthDays = DM.findMonthEnd(workingDate).getDate();
+		this.postMonthDays = CAL.DISPLAY_DAYS-this.preMonthDays-this.monthDays;
+
 		this.logger.log(this.preMonthDays + " preciding out-of-month days", "render");
 		this.logger.log(this.monthDays + " month days", "render");
 		this.logger.log(this.postMonthDays + " post-month days", "render");
-		
-		workingDate = YAHOO.widget.DateMath.subtract(workingDate, YAHOO.widget.DateMath.DAY, this.preMonthDays);
+
+		workingDate = DM.subtract(workingDate, DM.DAY, this.preMonthDays);
 		this.logger.log("Calendar page starts on " + workingDate, "render");
 	
-		var weekNum,weekClass;
-		var weekPrefix = "w";
-		var cellPrefix = "_cell";
-		var workingDayPrefix = "wd";
-		var dayPrefix = "d";
-		
-		var cellRenderers;
-		var renderer;
-		
-		var todayYear = this.today.getFullYear();
-		var todayMonth = this.today.getMonth();
-		var todayDate = this.today.getDate();
-		
-		var useDate = this.cfg.getProperty(defCfg.PAGEDATE.key);
-		var hideBlankWeeks = this.cfg.getProperty(defCfg.HIDE_BLANK_WEEKS.key);
-		var showWeekFooter = this.cfg.getProperty(defCfg.SHOW_WEEK_FOOTER.key);
-		var showWeekHeader = this.cfg.getProperty(defCfg.SHOW_WEEK_HEADER.key);
-		var mindate = this.cfg.getProperty(defCfg.MINDATE.key);
-		var maxdate = this.cfg.getProperty(defCfg.MAXDATE.key);
-	
+		var weekNum,
+			weekClass,
+			weekPrefix = "w",
+			cellPrefix = "_cell",
+			workingDayPrefix = "wd",
+			dayPrefix = "d",
+			cellRenderers,
+			renderer,
+			todayYear = this.today.getFullYear(),
+			todayMonth = this.today.getMonth(),
+			todayDate = this.today.getDate(),
+			useDate = this.cfg.getProperty(defCfg.PAGEDATE.key),
+			hideBlankWeeks = this.cfg.getProperty(defCfg.HIDE_BLANK_WEEKS.key),
+			showWeekFooter = this.cfg.getProperty(defCfg.SHOW_WEEK_FOOTER.key),
+			showWeekHeader = this.cfg.getProperty(defCfg.SHOW_WEEK_HEADER.key),
+			mindate = this.cfg.getProperty(defCfg.MINDATE.key),
+			maxdate = this.cfg.getProperty(defCfg.MAXDATE.key);
+
 		if (mindate) {
-			mindate = YAHOO.widget.DateMath.clearTime(mindate);
+			mindate = DM.clearTime(mindate);
 		}
 		if (maxdate) {
-			maxdate = YAHOO.widget.DateMath.clearTime(maxdate);
+			maxdate = DM.clearTime(maxdate);
 		}
-		
+
 		html[html.length] = '<tbody class="m' + (useDate.getMonth()+1) + ' ' + this.Style.CSS_BODY + '">';
-		
-		var i = 0;
-	
-		var tempDiv = document.createElement("div");
-		var cell = document.createElement("td");
+
+		var i = 0,
+			tempDiv = document.createElement("div"),
+			cell = document.createElement("td");
+
 		tempDiv.appendChild(cell);
-	
+
 		var cal = this.parent || this;
-	
+
 		for (var r=0;r<6;r++) {
-	
-			weekNum = YAHOO.widget.DateMath.getWeekNumber(workingDate, useDate.getFullYear(), startDay);
+			weekNum = DM.getWeekNumber(workingDate, startDay);
 			weekClass = weekPrefix + weekNum;
-	
+
 			// Local OOM check for performance, since we already have pagedate
 			if (r !== 0 && hideBlankWeeks === true && workingDate.getMonth() != useDate.getMonth()) {
 				break;
 			} else {
-	
 				html[html.length] = '<tr class="' + weekClass + '">';
-				
+
 				if (showWeekHeader) { html = this.renderRowHeader(weekNum, html); }
-				
-				for (var d=0;d<7;d++){ // Render actual days
-	
+
+				for (var d=0; d < 7; d++){ // Render actual days
+
 					cellRenderers = [];
-	
+
 					this.clearElement(cell);
 					cell.className = this.Style.CSS_CELL;
 					cell.id = this.id + cellPrefix + i;
@@ -2823,64 +2917,59 @@
 						workingDate.getFullYear()	== todayYear) {
 						cellRenderers[cellRenderers.length]=cal.renderCellStyleToday;
 					}
-					
+
 					var workingArray = [workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()];
 					this.cellDates[this.cellDates.length] = workingArray; // Add this date to cellDates
-					
+
 					// Local OOM check for performance, since we already have pagedate
 					if (workingDate.getMonth() != useDate.getMonth()) {
 						cellRenderers[cellRenderers.length]=cal.renderCellNotThisMonth;
 					} else {
-						YAHOO.util.Dom.addClass(cell, workingDayPrefix + workingDate.getDay());
-						YAHOO.util.Dom.addClass(cell, dayPrefix + workingDate.getDate());
-					
+						D.addClass(cell, workingDayPrefix + workingDate.getDay());
+						D.addClass(cell, dayPrefix + workingDate.getDate());
+
 						for (var s=0;s<this.renderStack.length;++s) {
-	
+
 							renderer = null;
-	
-							var rArray = this.renderStack[s];
-							var type = rArray[0];
-							
-							var month;
-							var day;
-							var year;
-							
+
+							var rArray = this.renderStack[s],
+								type = rArray[0],
+								month,
+								day,
+								year;
+
 							switch (type) {
-								case YAHOO.widget.Calendar.DATE:
+								case CAL.DATE:
 									month = rArray[1][1];
 									day = rArray[1][2];
 									year = rArray[1][0];
-	
+
 									if (workingDate.getMonth()+1 == month && workingDate.getDate() == day && workingDate.getFullYear() == year) {
 										renderer = rArray[2];
 										this.renderStack.splice(s,1);
 									}
 									break;
-								case YAHOO.widget.Calendar.MONTH_DAY:
+								case CAL.MONTH_DAY:
 									month = rArray[1][0];
 									day = rArray[1][1];
-									
+
 									if (workingDate.getMonth()+1 == month && workingDate.getDate() == day) {
 										renderer = rArray[2];
 										this.renderStack.splice(s,1);
 									}
 									break;
-								case YAHOO.widget.Calendar.RANGE:
-									var date1 = rArray[1][0];
-									var date2 = rArray[1][1];
-	
-									var d1month = date1[1];
-									var d1day = date1[2];
-									var d1year = date1[0];
-									
-									var d1 = YAHOO.widget.DateMath.getDate(d1year, d1month-1, d1day);
-	
-									var d2month = date2[1];
-									var d2day = date2[2];
-									var d2year = date2[0];
-	
-									var d2 = YAHOO.widget.DateMath.getDate(d2year, d2month-1, d2day);
-	
+								case CAL.RANGE:
+									var date1 = rArray[1][0],
+										date2 = rArray[1][1],
+										d1month = date1[1],
+										d1day = date1[2],
+										d1year = date1[0],
+										d1 = DM.getDate(d1year, d1month-1, d1day),
+										d2month = date2[1],
+										d2day = date2[2],
+										d2year = date2[0],
+										d2 = DM.getDate(d2year, d2month-1, d2day);
+
 									if (workingDate.getTime() >= d1.getTime() && workingDate.getTime() <= d2.getTime()) {
 										renderer = rArray[2];
 	
@@ -2889,33 +2978,31 @@
 										}
 									}
 									break;
-								case YAHOO.widget.Calendar.WEEKDAY:
-									
+								case CAL.WEEKDAY:
 									var weekday = rArray[1][0];
 									if (workingDate.getDay()+1 == weekday) {
 										renderer = rArray[2];
 									}
 									break;
-								case YAHOO.widget.Calendar.MONTH:
-									
+								case CAL.MONTH:
 									month = rArray[1][0];
 									if (workingDate.getMonth()+1 == month) {
 										renderer = rArray[2];
 									}
 									break;
 							}
-							
+
 							if (renderer) {
 								cellRenderers[cellRenderers.length]=renderer;
 							}
 						}
-	
+
 					}
-	
+
 					if (this._indexOfSelectedFieldArray(workingArray) > -1) {
 						cellRenderers[cellRenderers.length]=cal.renderCellStyleSelected; 
 					}
-	
+
 					if ((mindate && (workingDate.getTime() < mindate.getTime())) ||
 						(maxdate && (workingDate.getTime() > maxdate.getTime()))
 					) {
@@ -2924,26 +3011,28 @@
 						cellRenderers[cellRenderers.length]=cal.styleCellDefault;
 						cellRenderers[cellRenderers.length]=cal.renderCellDefault;	
 					}
-					
+
 					for (var x=0; x < cellRenderers.length; ++x) {
 						this.logger.log("renderer[" + x + "] for (" + workingDate.getFullYear() + "-" + (workingDate.getMonth()+1) + "-" + workingDate.getDate() + ")", "cellrender");
-						if (cellRenderers[x].call(cal, workingDate, cell) == YAHOO.widget.Calendar.STOP_RENDER) {
+						if (cellRenderers[x].call(cal, workingDate, cell) == CAL.STOP_RENDER) {
 							break;
 						}
 					}
-	
-					workingDate.setTime(workingDate.getTime() + YAHOO.widget.DateMath.ONE_DAY_MS);
-	
+
+					workingDate.setTime(workingDate.getTime() + DM.ONE_DAY_MS);
+					// Just in case we crossed DST/Summertime boundaries
+					workingDate = DM.clearTime(workingDate);
+
 					if (i >= 0 && i <= 6) {
-						YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TOP);
+						D.addClass(cell, this.Style.CSS_CELL_TOP);
 					}
 					if ((i % 7) === 0) {
-						YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_LEFT);
+						D.addClass(cell, this.Style.CSS_CELL_LEFT);
 					}
 					if (((i+1) % 7) === 0) {
-						YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RIGHT);
+						D.addClass(cell, this.Style.CSS_CELL_RIGHT);
 					}
-					
+
 					var postDays = this.postMonthDays; 
 					if (hideBlankWeeks && postDays >= 7) {
 						var blankWeeks = Math.floor(postDays/7);
@@ -2953,7 +3042,7 @@
 					}
 					
 					if (i >= ((this.preMonthDays+postDays+this.monthDays)-7)) {
-						YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_BOTTOM);
+						D.addClass(cell, this.Style.CSS_CELL_BOTTOM);
 					}
 	
 					html[html.length] = tempDiv.innerHTML;
@@ -4103,13 +4192,13 @@
 	* Adds a weekday to the render stack. The function reference passed to this method will be executed
 	* when a date cell matches the weekday passed to this method.
 	* @method addWeekdayRenderer
-	* @param	{Number}	weekday		The weekday (0-6) to associate with this renderer
+	* @param	{Number}	weekday		The weekday (Sunday = 1, Monday = 2 ... Saturday = 7) to associate with this renderer
 	* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
 	*/
 	addWeekdayRenderer : function(weekday, fnRender) {
 		this._addRenderer(YAHOO.widget.Calendar.WEEKDAY,[weekday],fnRender);
 	},
-	
+
 	// END RENDERER METHODS
 	
 	// BEGIN CSS METHODS
@@ -6322,16 +6411,16 @@
 	 * @method applyKeyListeners
 	 */
 	applyKeyListeners : function() {
-		var E = YAHOO.util.Event;
+		var E = YAHOO.util.Event,
+			ua = YAHOO.env.ua;
 
-		// IE doesn't fire keypress for arrow/pg keys (non-char keys)
-		var ua = YAHOO.env.ua;
-		var arrowEvt = (ua.ie) ? "keydown" : "keypress";
+		// IE/Safari 3.1 doesn't fire keypress for arrow/pg keys (non-char keys)
+		var arrowEvt = (ua.ie || ua.webkit) ? "keydown" : "keypress";
 
-		// - IE doesn't fire keypress for non-char keys
+		// - IE/Safari 3.1 doesn't fire keypress for non-char keys
 		// - Opera doesn't allow us to cancel keydown or keypress for tab, but 
 		//   changes focus successfully on keydown (keypress is too late to change focus - opera's already moved on).
-		var tabEvt = (ua.ie || ua.opera) ? "keydown" : "keypress";
+		var tabEvt = (ua.ie || ua.opera || ua.webkit) ? "keydown" : "keypress";
 
 		// Everyone likes keypress for Enter (char keys) - whoo hoo!
 		E.on(this.yearEl, "keypress", this._handleEnterKey, this, true);
@@ -6347,10 +6436,11 @@
 	 * @method purgeKeyListeners
 	 */
 	purgeKeyListeners : function() {
-		var E = YAHOO.util.Event;
+		var E = YAHOO.util.Event,
+			ua = YAHOO.env.ua;
 
-		var arrowEvt = (YAHOO.env.ua.ie) ? "keydown" : "keypress";
-		var tabEvt = (YAHOO.env.ua.ie || YAHOO.env.ua.opera) ? "keydown" : "keypress";
+		var arrowEvt = (ua.ie || ua.webkit) ? "keydown" : "keypress";
+		var tabEvt = (ua.ie || ua.opera || ua.webkit) ? "keydown" : "keypress";
 
 		E.removeListener(this.yearEl, "keypress", this._handleEnterKey);
 		E.removeListener(this.yearEl, arrowEvt, this._handleDirectionKeys);
@@ -6658,6 +6748,7 @@
 		var KEYS = YAHOO.util.KeyListener.KEY;
 
 		if (YAHOO.util.Event.getCharCode(e) == KEYS.ENTER) {
+			YAHOO.util.Event.preventDefault(e);
 			this.submit();
 		}
 	},
@@ -6786,4 +6877,4 @@
 
 };
 
-YAHOO.register("calendar", YAHOO.widget.Calendar, {version: "2.4.1", build: "742"});
+YAHOO.register("calendar", YAHOO.widget.Calendar, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/calendar/calendar-min.js
===================================================================
--- trunk/root/static/yui/calendar/calendar-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/calendar/calendar-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,18 +1,18 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-(function(){YAHOO.util.Config=function(D){if(D){this.init(D);}};var B=YAHOO.lang,C=YAHOO.util.CustomEvent,A=YAHOO.util.Config;A.CONFIG_CHANGED_EVENT="configChanged";A.BOOLEAN_TYPE="boolean";A.prototype={owner:null,queueInProgress:false,config:null,initialConfig:null,eventQueue:null,configChangedEvent:null,init:function(D){this.owner=D;this.configChangedEvent=this.createEvent(A.CONFIG_CHANGED_EVENT);this.configChangedEvent.signature=C.LIST;this.queueInProgress=false;this.config={};this.initialConfig={};this.eventQueue=[];},checkBoolean:function(D){return(typeof D==A.BOOLEAN_TYPE);},checkNumber:function(D){return(!isNaN(D));},fireEvent:function(D,F){var E=this.config[D];if(E&&E.event){E.event.fire(F);}},addProperty:function(E,D){E=E.toLowerCase();this.config[E]=D;D.event=this.createEvent(E,{scope:this.owner});D.event.signature=C.LIST;D.key=E;if(D.handler){D.event.subscribe(D.handler,this.owner);}this.setProperty(E,D.value,true);if(!D.suppressEvent){this.queueProperty(E,D.valu!
 e);}},getConfig:function(){var D={},F,E;for(F in this.config){E=this.config[F];if(E&&E.event){D[F]=E.value;}}return D;},getProperty:function(D){var E=this.config[D.toLowerCase()];if(E&&E.event){return E.value;}else{return undefined;}},resetProperty:function(D){D=D.toLowerCase();var E=this.config[D];if(E&&E.event){if(this.initialConfig[D]&&!B.isUndefined(this.initialConfig[D])){this.setProperty(D,this.initialConfig[D]);return true;}}else{return false;}},setProperty:function(E,G,D){var F;E=E.toLowerCase();if(this.queueInProgress&&!D){this.queueProperty(E,G);return true;}else{F=this.config[E];if(F&&F.event){if(F.validator&&!F.validator(G)){return false;}else{F.value=G;if(!D){this.fireEvent(E,G);this.configChangedEvent.fire([E,G]);}return true;}}else{return false;}}},queueProperty:function(S,P){S=S.toLowerCase();var R=this.config[S],K=false,J,G,H,I,O,Q,F,M,N,D,L,T,E;if(R&&R.event){if(!B.isUndefined(P)&&R.validator&&!R.validator(P)){return false;}else{if(!B.isUndefined(P)){R.val!
 ue=P;}else{P=R.value;}K=false;J=this.eventQueue.length;for(L=0!
 ;L<J;L++
){G=this.eventQueue[L];if(G){H=G[0];I=G[1];if(H==S){this.eventQueue[L]=null;this.eventQueue.push([S,(!B.isUndefined(P)?P:I)]);K=true;break;}}}if(!K&&!B.isUndefined(P)){this.eventQueue.push([S,P]);}}if(R.supercedes){O=R.supercedes.length;for(T=0;T<O;T++){Q=R.supercedes[T];F=this.eventQueue.length;for(E=0;E<F;E++){M=this.eventQueue[E];if(M){N=M[0];D=M[1];if(N==Q.toLowerCase()){this.eventQueue.push([N,D]);this.eventQueue[E]=null;break;}}}}}return true;}else{return false;}},refireEvent:function(D){D=D.toLowerCase();var E=this.config[D];if(E&&E.event&&!B.isUndefined(E.value)){if(this.queueInProgress){this.queueProperty(D);}else{this.fireEvent(D,E.value);}}},applyConfig:function(D,G){var F,E;if(G){E={};for(F in D){if(B.hasOwnProperty(D,F)){E[F.toLowerCase()]=D[F];}}this.initialConfig=E;}for(F in D){if(B.hasOwnProperty(D,F)){this.queueProperty(F,D[F]);}}},refresh:function(){var D;for(D in this.config){this.refireEvent(D);}},fireQueue:function(){var E,H,D,G,F;this.queueInProgress=tr!
 ue;for(E=0;E<this.eventQueue.length;E++){H=this.eventQueue[E];if(H){D=H[0];G=H[1];F=this.config[D];F.value=G;this.fireEvent(D,G);}}this.queueInProgress=false;this.eventQueue=[];},subscribeToConfigEvent:function(E,F,H,D){var G=this.config[E.toLowerCase()];if(G&&G.event){if(!A.alreadySubscribed(G.event,F,H)){G.event.subscribe(F,H,D);}return true;}else{return false;}},unsubscribeFromConfigEvent:function(D,E,G){var F=this.config[D.toLowerCase()];if(F&&F.event){return F.event.unsubscribe(E,G);}else{return false;}},toString:function(){var D="Config";if(this.owner){D+=" ["+this.owner.toString()+"]";}return D;},outputEventQueue:function(){var D="",G,E,F=this.eventQueue.length;for(E=0;E<F;E++){G=this.eventQueue[E];if(G){D+=G[0]+"="+G[1]+", ";}}return D;},destroy:function(){var E=this.config,D,F;for(D in E){if(B.hasOwnProperty(E,D)){F=E[D];F.event.unsubscribeAll();F.event=null;}}this.configChangedEvent.unsubscribeAll();this.configChangedEvent=null;this.owner=null;this.config=null;thi!
 s.initialConfig=null;this.eventQueue=null;}};A.alreadySubscrib!
 ed=funct
ion(E,H,I){var F=E.subscribers.length,D,G;if(F>0){G=F-1;do{D=E.subscribers[G];if(D&&D.obj==I&&D.fn==H){return true;}}while(G--);}return false;};YAHOO.lang.augmentProto(A,YAHOO.util.EventProvider);}());YAHOO.widget.DateMath={DAY:"D",WEEK:"W",YEAR:"Y",MONTH:"M",ONE_DAY_MS:1000*60*60*24,add:function(A,D,C){var F=new Date(A.getTime());switch(D){case this.MONTH:var E=A.getMonth()+C;var B=0;if(E<0){while(E<0){E+=12;B-=1;}}else{if(E>11){while(E>11){E-=12;B+=1;}}}F.setMonth(E);F.setFullYear(A.getFullYear()+B);break;case this.DAY:F.setDate(A.getDate()+C);break;case this.YEAR:F.setFullYear(A.getFullYear()+C);break;case this.WEEK:F.setDate(A.getDate()+(C*7));break;}return F;},subtract:function(A,C,B){return this.add(A,C,(B*-1));},before:function(C,B){var A=B.getTime();if(C.getTime()<A){return true;}else{return false;}},after:function(C,B){var A=B.getTime();if(C.getTime()>A){return true;}else{return false;}},between:function(B,A,C){if(this.after(B,A)&&this.before(B,C)){return true;}else!
 {return false;}},getJan1:function(A){return this.getDate(A,0,1);},getDayOffset:function(B,D){var C=this.getJan1(D);var A=Math.ceil((B.getTime()-C.getTime())/this.ONE_DAY_MS);return A;},getWeekNumber:function(C,F){C=this.clearTime(C);var E=new Date(C.getTime()+(4*this.ONE_DAY_MS)-((C.getDay())*this.ONE_DAY_MS));var B=this.getDate(E.getFullYear(),0,1);var A=((E.getTime()-B.getTime())/this.ONE_DAY_MS)-1;var D=Math.ceil((A)/7);return D;},isYearOverlapWeek:function(A){var C=false;var B=this.add(A,this.DAY,6);if(B.getFullYear()!=A.getFullYear()){C=true;}return C;},isMonthOverlapWeek:function(A){var C=false;var B=this.add(A,this.DAY,6);if(B.getMonth()!=A.getMonth()){C=true;}return C;},findMonthStart:function(A){var B=this.getDate(A.getFullYear(),A.getMonth(),1);return B;},findMonthEnd:function(B){var D=this.findMonthStart(B);var C=this.add(D,this.MONTH,1);var A=this.subtract(C,this.DAY,1);return A;},clearTime:function(A){A.setHours(12,0,0,0);
-return A;},getDate:function(D,A,C){var B=null;if(YAHOO.lang.isUndefined(C)){C=1;}if(D>=100){B=new Date(D,A,C);}else{B=new Date();B.setFullYear(D);B.setMonth(A);B.setDate(C);B.setHours(0,0,0,0);}return B;}};YAHOO.widget.Calendar=function(C,A,B){this.init.apply(this,arguments);};YAHOO.widget.Calendar.IMG_ROOT=null;YAHOO.widget.Calendar.DATE="D";YAHOO.widget.Calendar.MONTH_DAY="MD";YAHOO.widget.Calendar.WEEKDAY="WD";YAHOO.widget.Calendar.RANGE="R";YAHOO.widget.Calendar.MONTH="M";YAHOO.widget.Calendar.DISPLAY_DAYS=42;YAHOO.widget.Calendar.STOP_RENDER="S";YAHOO.widget.Calendar.SHORT="short";YAHOO.widget.Calendar.LONG="long";YAHOO.widget.Calendar.MEDIUM="medium";YAHOO.widget.Calendar.ONE_CHAR="1char";YAHOO.widget.Calendar._DEFAULT_CONFIG={PAGEDATE:{key:"pagedate",value:null},SELECTED:{key:"selected",value:null},TITLE:{key:"title",value:""},CLOSE:{key:"close",value:false},IFRAME:{key:"iframe",value:(YAHOO.env.ua.ie&&YAHOO.env.ua.ie<=6)?true:false},MINDATE:{key:"mindate",value:null!
 },MAXDATE:{key:"maxdate",value:null},MULTI_SELECT:{key:"multi_select",value:false},START_WEEKDAY:{key:"start_weekday",value:0},SHOW_WEEKDAYS:{key:"show_weekdays",value:true},SHOW_WEEK_HEADER:{key:"show_week_header",value:false},SHOW_WEEK_FOOTER:{key:"show_week_footer",value:false},HIDE_BLANK_WEEKS:{key:"hide_blank_weeks",value:false},NAV_ARROW_LEFT:{key:"nav_arrow_left",value:null},NAV_ARROW_RIGHT:{key:"nav_arrow_right",value:null},MONTHS_SHORT:{key:"months_short",value:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]},MONTHS_LONG:{key:"months_long",value:["January","February","March","April","May","June","July","August","September","October","November","December"]},WEEKDAYS_1CHAR:{key:"weekdays_1char",value:["S","M","T","W","T","F","S"]},WEEKDAYS_SHORT:{key:"weekdays_short",value:["Su","Mo","Tu","We","Th","Fr","Sa"]},WEEKDAYS_MEDIUM:{key:"weekdays_medium",value:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]},WEEKDAYS_LONG:{key:"weekdays_long",value:["!
 Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Sa!
 turday"]
},LOCALE_MONTHS:{key:"locale_months",value:"long"},LOCALE_WEEKDAYS:{key:"locale_weekdays",value:"short"},DATE_DELIMITER:{key:"date_delimiter",value:","},DATE_FIELD_DELIMITER:{key:"date_field_delimiter",value:"/"},DATE_RANGE_DELIMITER:{key:"date_range_delimiter",value:"-"},MY_MONTH_POSITION:{key:"my_month_position",value:1},MY_YEAR_POSITION:{key:"my_year_position",value:2},MD_MONTH_POSITION:{key:"md_month_position",value:1},MD_DAY_POSITION:{key:"md_day_position",value:2},MDY_MONTH_POSITION:{key:"mdy_month_position",value:1},MDY_DAY_POSITION:{key:"mdy_day_position",value:2},MDY_YEAR_POSITION:{key:"mdy_year_position",value:3},MY_LABEL_MONTH_POSITION:{key:"my_label_month_position",value:1},MY_LABEL_YEAR_POSITION:{key:"my_label_year_position",value:2},MY_LABEL_MONTH_SUFFIX:{key:"my_label_month_suffix",value:" "},MY_LABEL_YEAR_SUFFIX:{key:"my_label_year_suffix",value:""},NAV:{key:"navigator",value:null}};YAHOO.widget.Calendar._EVENT_TYPES={BEFORE_SELECT:"beforeSelect",SELECT:"sele!
 ct",BEFORE_DESELECT:"beforeDeselect",DESELECT:"deselect",CHANGE_PAGE:"changePage",BEFORE_RENDER:"beforeRender",RENDER:"render",RESET:"reset",CLEAR:"clear",BEFORE_HIDE:"beforeHide",HIDE:"hide",BEFORE_SHOW:"beforeShow",SHOW:"show",BEFORE_HIDE_NAV:"beforeHideNav",HIDE_NAV:"hideNav",BEFORE_SHOW_NAV:"beforeShowNav",SHOW_NAV:"showNav",BEFORE_RENDER_NAV:"beforeRenderNav",RENDER_NAV:"renderNav"};YAHOO.widget.Calendar._STYLES={CSS_ROW_HEADER:"calrowhead",CSS_ROW_FOOTER:"calrowfoot",CSS_CELL:"calcell",CSS_CELL_SELECTOR:"selector",CSS_CELL_SELECTED:"selected",CSS_CELL_SELECTABLE:"selectable",CSS_CELL_RESTRICTED:"restricted",CSS_CELL_TODAY:"today",CSS_CELL_OOM:"oom",CSS_CELL_OOB:"previous",CSS_HEADER:"calheader",CSS_HEADER_TEXT:"calhead",CSS_BODY:"calbody",CSS_WEEKDAY_CELL:"calweekdaycell",CSS_WEEKDAY_ROW:"calweekdayrow",CSS_FOOTER:"calfoot",CSS_CALENDAR:"yui-calendar",CSS_SINGLE:"single",CSS_CONTAINER:"yui-calcontainer",CSS_NAV_LEFT:"calnavleft",CSS_NAV_RIGHT:"calnavright",CSS_NAV:"ca!
 lnav",CSS_CLOSE:"calclose",CSS_CELL_TOP:"calcelltop",CSS_CELL_!
 LEFT:"ca
lcellleft",CSS_CELL_RIGHT:"calcellright",CSS_CELL_BOTTOM:"calcellbottom",CSS_CELL_HOVER:"calcellhover",CSS_CELL_HIGHLIGHT1:"highlight1",CSS_CELL_HIGHLIGHT2:"highlight2",CSS_CELL_HIGHLIGHT3:"highlight3",CSS_CELL_HIGHLIGHT4:"highlight4"};YAHOO.widget.Calendar.prototype={Config:null,parent:null,index:-1,cells:null,cellDates:null,id:null,containerId:null,oDomContainer:null,today:null,renderStack:null,_renderStack:null,oNavigator:null,_selectedDates:null,domEventMap:null,_parseArgs:function(B){var A={id:null,container:null,config:null};if(B&&B.length&&B.length>0){switch(B.length){case 1:A.id=null;A.container=B[0];A.config=null;break;case 2:if(YAHOO.lang.isObject(B[1])&&!B[1].tagName&&!(B[1] instanceof String)){A.id=null;A.container=B[0];A.config=B[1];}else{A.id=B[0];A.container=B[1];A.config=null;}break;default:A.id=B[0];A.container=B[1];A.config=B[2];break;}}else{}return A;},init:function(D,B,C){var A=this._parseArgs(arguments);D=A.id;B=A.container;C=A.config;this.oDomContainer=!
 YAHOO.util.Dom.get(B);if(!this.oDomContainer.id){this.oDomContainer.id=YAHOO.util.Dom.generateId();}if(!D){D=this.oDomContainer.id+"_t";}this.id=D;this.containerId=this.oDomContainer.id;this.initEvents();this.today=new Date();YAHOO.widget.DateMath.clearTime(this.today);this.cfg=new YAHOO.util.Config(this);this.Options={};this.Locale={};this.initStyles();YAHOO.util.Dom.addClass(this.oDomContainer,this.Style.CSS_CONTAINER);YAHOO.util.Dom.addClass(this.oDomContainer,this.Style.CSS_SINGLE);this.cellDates=[];this.cells=[];this.renderStack=[];this._renderStack=[];this.setupConfig();if(C){this.cfg.applyConfig(C,true);}this.cfg.fireQueue();},configIframe:function(C,B,D){var A=B[0];if(!this.parent){if(YAHOO.util.Dom.inDocument(this.oDomContainer)){if(A){var E=YAHOO.util.Dom.getStyle(this.oDomContainer,"position");if(E=="absolute"||E=="relative"){if(!YAHOO.util.Dom.inDocument(this.iframe)){this.iframe=document.createElement("iframe");
-this.iframe.src="javascript:false;";YAHOO.util.Dom.setStyle(this.iframe,"opacity","0");if(YAHOO.env.ua.ie&&YAHOO.env.ua.ie<=6){YAHOO.util.Dom.addClass(this.iframe,"fixedsize");}this.oDomContainer.insertBefore(this.iframe,this.oDomContainer.firstChild);}}}else{if(this.iframe){if(this.iframe.parentNode){this.iframe.parentNode.removeChild(this.iframe);}this.iframe=null;}}}}},configTitle:function(B,A,C){var E=A[0];if(E){this.createTitleBar(E);}else{var D=this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.CLOSE.key);if(!D){this.removeTitleBar();}else{this.createTitleBar(" ");}}},configClose:function(B,A,C){var E=A[0],D=this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.TITLE.key);if(E){if(!D){this.createTitleBar(" ");}this.createCloseButton();}else{this.removeCloseButton();if(!D){this.removeTitleBar();}}},initEvents:function(){var A=YAHOO.widget.Calendar._EVENT_TYPES;this.beforeSelectEvent=new YAHOO.util.CustomEvent(A.BEFORE_SELECT);this.selectEvent=new!
  YAHOO.util.CustomEvent(A.SELECT);this.beforeDeselectEvent=new YAHOO.util.CustomEvent(A.BEFORE_DESELECT);this.deselectEvent=new YAHOO.util.CustomEvent(A.DESELECT);this.changePageEvent=new YAHOO.util.CustomEvent(A.CHANGE_PAGE);this.beforeRenderEvent=new YAHOO.util.CustomEvent(A.BEFORE_RENDER);this.renderEvent=new YAHOO.util.CustomEvent(A.RENDER);this.resetEvent=new YAHOO.util.CustomEvent(A.RESET);this.clearEvent=new YAHOO.util.CustomEvent(A.CLEAR);this.beforeShowEvent=new YAHOO.util.CustomEvent(A.BEFORE_SHOW);this.showEvent=new YAHOO.util.CustomEvent(A.SHOW);this.beforeHideEvent=new YAHOO.util.CustomEvent(A.BEFORE_HIDE);this.hideEvent=new YAHOO.util.CustomEvent(A.HIDE);this.beforeShowNavEvent=new YAHOO.util.CustomEvent(A.BEFORE_SHOW_NAV);this.showNavEvent=new YAHOO.util.CustomEvent(A.SHOW_NAV);this.beforeHideNavEvent=new YAHOO.util.CustomEvent(A.BEFORE_HIDE_NAV);this.hideNavEvent=new YAHOO.util.CustomEvent(A.HIDE_NAV);this.beforeRenderNavEvent=new YAHOO.util.CustomEvent(A.BE!
 FORE_RENDER_NAV);this.renderNavEvent=new YAHOO.util.CustomEven!
 t(A.REND
ER_NAV);this.beforeSelectEvent.subscribe(this.onBeforeSelect,this,true);this.selectEvent.subscribe(this.onSelect,this,true);this.beforeDeselectEvent.subscribe(this.onBeforeDeselect,this,true);this.deselectEvent.subscribe(this.onDeselect,this,true);this.changePageEvent.subscribe(this.onChangePage,this,true);this.renderEvent.subscribe(this.onRender,this,true);this.resetEvent.subscribe(this.onReset,this,true);this.clearEvent.subscribe(this.onClear,this,true);},doSelectCell:function(G,A){var L,F,I,C;var H=YAHOO.util.Event.getTarget(G);var B=H.tagName.toLowerCase();var E=false;while(B!="td"&&!YAHOO.util.Dom.hasClass(H,A.Style.CSS_CELL_SELECTABLE)){if(!E&&B=="a"&&YAHOO.util.Dom.hasClass(H,A.Style.CSS_CELL_SELECTOR)){E=true;}H=H.parentNode;B=H.tagName.toLowerCase();if(B=="html"){return ;}}if(E){YAHOO.util.Event.preventDefault(G);}L=H;if(YAHOO.util.Dom.hasClass(L,A.Style.CSS_CELL_SELECTABLE)){F=L.id.split("cell")[1];I=A.cellDates[F];C=YAHOO.widget.DateMath.getDate(I[0],I[1]-1,I[2]);!
 var K;if(A.Options.MULTI_SELECT){K=L.getElementsByTagName("a")[0];if(K){K.blur();}var D=A.cellDates[F];var J=A._indexOfSelectedFieldArray(D);if(J>-1){A.deselectCell(F);}else{A.selectCell(F);}}else{K=L.getElementsByTagName("a")[0];if(K){K.blur();}A.selectCell(F);}}},doCellMouseOver:function(C,B){var A;if(C){A=YAHOO.util.Event.getTarget(C);}else{A=this;}while(A.tagName&&A.tagName.toLowerCase()!="td"){A=A.parentNode;if(!A.tagName||A.tagName.toLowerCase()=="html"){return ;}}if(YAHOO.util.Dom.hasClass(A,B.Style.CSS_CELL_SELECTABLE)){YAHOO.util.Dom.addClass(A,B.Style.CSS_CELL_HOVER);}},doCellMouseOut:function(C,B){var A;if(C){A=YAHOO.util.Event.getTarget(C);}else{A=this;}while(A.tagName&&A.tagName.toLowerCase()!="td"){A=A.parentNode;if(!A.tagName||A.tagName.toLowerCase()=="html"){return ;}}if(YAHOO.util.Dom.hasClass(A,B.Style.CSS_CELL_SELECTABLE)){YAHOO.util.Dom.removeClass(A,B.Style.CSS_CELL_HOVER);}},setupConfig:function(){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;this.cfg.ad!
 dProperty(A.PAGEDATE.key,{value:new Date(),handler:this.config!
 PageDate
});this.cfg.addProperty(A.SELECTED.key,{value:[],handler:this.configSelected});this.cfg.addProperty(A.TITLE.key,{value:A.TITLE.value,handler:this.configTitle});this.cfg.addProperty(A.CLOSE.key,{value:A.CLOSE.value,handler:this.configClose});this.cfg.addProperty(A.IFRAME.key,{value:A.IFRAME.value,handler:this.configIframe,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.MINDATE.key,{value:A.MINDATE.value,handler:this.configMinDate});this.cfg.addProperty(A.MAXDATE.key,{value:A.MAXDATE.value,handler:this.configMaxDate});this.cfg.addProperty(A.MULTI_SELECT.key,{value:A.MULTI_SELECT.value,handler:this.configOptions,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.START_WEEKDAY.key,{value:A.START_WEEKDAY.value,handler:this.configOptions,validator:this.cfg.checkNumber});this.cfg.addProperty(A.SHOW_WEEKDAYS.key,{value:A.SHOW_WEEKDAYS.value,handler:this.configOptions,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.SHOW_WEEK_HEADER.key,{value:A.SHOW_WEEK_HEADE!
 R.value,handler:this.configOptions,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.SHOW_WEEK_FOOTER.key,{value:A.SHOW_WEEK_FOOTER.value,handler:this.configOptions,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.HIDE_BLANK_WEEKS.key,{value:A.HIDE_BLANK_WEEKS.value,handler:this.configOptions,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.NAV_ARROW_LEFT.key,{value:A.NAV_ARROW_LEFT.value,handler:this.configOptions});this.cfg.addProperty(A.NAV_ARROW_RIGHT.key,{value:A.NAV_ARROW_RIGHT.value,handler:this.configOptions});this.cfg.addProperty(A.MONTHS_SHORT.key,{value:A.MONTHS_SHORT.value,handler:this.configLocale});this.cfg.addProperty(A.MONTHS_LONG.key,{value:A.MONTHS_LONG.value,handler:this.configLocale});this.cfg.addProperty(A.WEEKDAYS_1CHAR.key,{value:A.WEEKDAYS_1CHAR.value,handler:this.configLocale});this.cfg.addProperty(A.WEEKDAYS_SHORT.key,{value:A.WEEKDAYS_SHORT.value,handler:this.configLocale});
-this.cfg.addProperty(A.WEEKDAYS_MEDIUM.key,{value:A.WEEKDAYS_MEDIUM.value,handler:this.configLocale});this.cfg.addProperty(A.WEEKDAYS_LONG.key,{value:A.WEEKDAYS_LONG.value,handler:this.configLocale});var B=function(){this.cfg.refireEvent(A.LOCALE_MONTHS.key);this.cfg.refireEvent(A.LOCALE_WEEKDAYS.key);};this.cfg.subscribeToConfigEvent(A.START_WEEKDAY.key,B,this,true);this.cfg.subscribeToConfigEvent(A.MONTHS_SHORT.key,B,this,true);this.cfg.subscribeToConfigEvent(A.MONTHS_LONG.key,B,this,true);this.cfg.subscribeToConfigEvent(A.WEEKDAYS_1CHAR.key,B,this,true);this.cfg.subscribeToConfigEvent(A.WEEKDAYS_SHORT.key,B,this,true);this.cfg.subscribeToConfigEvent(A.WEEKDAYS_MEDIUM.key,B,this,true);this.cfg.subscribeToConfigEvent(A.WEEKDAYS_LONG.key,B,this,true);this.cfg.addProperty(A.LOCALE_MONTHS.key,{value:A.LOCALE_MONTHS.value,handler:this.configLocaleValues});this.cfg.addProperty(A.LOCALE_WEEKDAYS.key,{value:A.LOCALE_WEEKDAYS.value,handler:this.configLocaleValues});this.cfg.addPro!
 perty(A.DATE_DELIMITER.key,{value:A.DATE_DELIMITER.value,handler:this.configLocale});this.cfg.addProperty(A.DATE_FIELD_DELIMITER.key,{value:A.DATE_FIELD_DELIMITER.value,handler:this.configLocale});this.cfg.addProperty(A.DATE_RANGE_DELIMITER.key,{value:A.DATE_RANGE_DELIMITER.value,handler:this.configLocale});this.cfg.addProperty(A.MY_MONTH_POSITION.key,{value:A.MY_MONTH_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MY_YEAR_POSITION.key,{value:A.MY_YEAR_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MD_MONTH_POSITION.key,{value:A.MD_MONTH_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MD_DAY_POSITION.key,{value:A.MD_DAY_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MDY_MONTH_POSITION.key,{value:A.MDY_MONTH_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber}!
 );this.cfg.addProperty(A.MDY_DAY_POSITION.key,{value:A.MDY_DAY!
 _POSITIO
N.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MDY_YEAR_POSITION.key,{value:A.MDY_YEAR_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MY_LABEL_MONTH_POSITION.key,{value:A.MY_LABEL_MONTH_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MY_LABEL_YEAR_POSITION.key,{value:A.MY_LABEL_YEAR_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MY_LABEL_MONTH_SUFFIX.key,{value:A.MY_LABEL_MONTH_SUFFIX.value,handler:this.configLocale});this.cfg.addProperty(A.MY_LABEL_YEAR_SUFFIX.key,{value:A.MY_LABEL_YEAR_SUFFIX.value,handler:this.configLocale});this.cfg.addProperty(A.NAV.key,{value:A.NAV.value,handler:this.configNavigator});},configPageDate:function(B,A,C){this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key,this._parsePageDate(A[0]),true);},configMinDate:function(B,A,C){var D=A[0];if!
 (YAHOO.lang.isString(D)){D=this._parseDate(D);this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MINDATE.key,YAHOO.widget.DateMath.getDate(D[0],(D[1]-1),D[2]));}},configMaxDate:function(B,A,C){var D=A[0];if(YAHOO.lang.isString(D)){D=this._parseDate(D);this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MAXDATE.key,YAHOO.widget.DateMath.getDate(D[0],(D[1]-1),D[2]));}},configSelected:function(C,A,E){var B=A[0];var D=YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;if(B){if(YAHOO.lang.isString(B)){this.cfg.setProperty(D,this._parseDates(B),true);}}if(!this._selectedDates){this._selectedDates=this.cfg.getProperty(D);}},configOptions:function(B,A,C){this.Options[B.toUpperCase()]=A[0];},configLocale:function(C,B,D){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;this.Locale[C.toUpperCase()]=B[0];this.cfg.refireEvent(A.LOCALE_MONTHS.key);this.cfg.refireEvent(A.LOCALE_WEEKDAYS.key);},configLocaleValues:function(D,C,E){var B=YAHOO.widget.Calendar._DEFAULT_CONFIG;D=D.toL!
 owerCase();var G=C[0];switch(D){case B.LOCALE_MONTHS.key:switc!
 h(G){cas
e YAHOO.widget.Calendar.SHORT:this.Locale.LOCALE_MONTHS=this.cfg.getProperty(B.MONTHS_SHORT.key).concat();break;case YAHOO.widget.Calendar.LONG:this.Locale.LOCALE_MONTHS=this.cfg.getProperty(B.MONTHS_LONG.key).concat();break;}break;case B.LOCALE_WEEKDAYS.key:switch(G){case YAHOO.widget.Calendar.ONE_CHAR:this.Locale.LOCALE_WEEKDAYS=this.cfg.getProperty(B.WEEKDAYS_1CHAR.key).concat();break;case YAHOO.widget.Calendar.SHORT:this.Locale.LOCALE_WEEKDAYS=this.cfg.getProperty(B.WEEKDAYS_SHORT.key).concat();break;case YAHOO.widget.Calendar.MEDIUM:this.Locale.LOCALE_WEEKDAYS=this.cfg.getProperty(B.WEEKDAYS_MEDIUM.key).concat();break;case YAHOO.widget.Calendar.LONG:this.Locale.LOCALE_WEEKDAYS=this.cfg.getProperty(B.WEEKDAYS_LONG.key).concat();break;}var F=this.cfg.getProperty(B.START_WEEKDAY.key);if(F>0){for(var A=0;A<F;++A){this.Locale.LOCALE_WEEKDAYS.push(this.Locale.LOCALE_WEEKDAYS.shift());}}break;}},configNavigator:function(C,A,D){var E=A[0];if(YAHOO.widget.CalendarNavigator&&(E==!
 =true||YAHOO.lang.isObject(E))){if(!this.oNavigator){this.oNavigator=new YAHOO.widget.CalendarNavigator(this);function B(){if(!this.pages){this.oNavigator.erase();}}this.beforeRenderEvent.subscribe(B,this,true);}}else{if(this.oNavigator){this.oNavigator.destroy();this.oNavigator=null;}}},initStyles:function(){var A=YAHOO.widget.Calendar._STYLES;this.Style={CSS_ROW_HEADER:A.CSS_ROW_HEADER,CSS_ROW_FOOTER:A.CSS_ROW_FOOTER,CSS_CELL:A.CSS_CELL,CSS_CELL_SELECTOR:A.CSS_CELL_SELECTOR,CSS_CELL_SELECTED:A.CSS_CELL_SELECTED,CSS_CELL_SELECTABLE:A.CSS_CELL_SELECTABLE,CSS_CELL_RESTRICTED:A.CSS_CELL_RESTRICTED,CSS_CELL_TODAY:A.CSS_CELL_TODAY,CSS_CELL_OOM:A.CSS_CELL_OOM,CSS_CELL_OOB:A.CSS_CELL_OOB,CSS_HEADER:A.CSS_HEADER,CSS_HEADER_TEXT:A.CSS_HEADER_TEXT,CSS_BODY:A.CSS_BODY,CSS_WEEKDAY_CELL:A.CSS_WEEKDAY_CELL,CSS_WEEKDAY_ROW:A.CSS_WEEKDAY_ROW,CSS_FOOTER:A.CSS_FOOTER,CSS_CALENDAR:A.CSS_CALENDAR,CSS_SINGLE:A.CSS_SINGLE,CSS_CONTAINER:A.CSS_CONTAINER,CSS_NAV_LEFT:A.CSS_NAV_LEFT,CSS_NAV_RIGHT:A!
 .CSS_NAV_RIGHT,CSS_NAV:A.CSS_NAV,CSS_CLOSE:A.CSS_CLOSE,CSS_CEL!
 L_TOP:A.
CSS_CELL_TOP,CSS_CELL_LEFT:A.CSS_CELL_LEFT,CSS_CELL_RIGHT:A.CSS_CELL_RIGHT,CSS_CELL_BOTTOM:A.CSS_CELL_BOTTOM,CSS_CELL_HOVER:A.CSS_CELL_HOVER,CSS_CELL_HIGHLIGHT1:A.CSS_CELL_HIGHLIGHT1,CSS_CELL_HIGHLIGHT2:A.CSS_CELL_HIGHLIGHT2,CSS_CELL_HIGHLIGHT3:A.CSS_CELL_HIGHLIGHT3,CSS_CELL_HIGHLIGHT4:A.CSS_CELL_HIGHLIGHT4};
-},buildMonthLabel:function(){var A=this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key);var C=this.Locale.LOCALE_MONTHS[A.getMonth()]+this.Locale.MY_LABEL_MONTH_SUFFIX;var B=A.getFullYear()+this.Locale.MY_LABEL_YEAR_SUFFIX;if(this.Locale.MY_LABEL_MONTH_POSITION==2||this.Locale.MY_LABEL_YEAR_POSITION==1){return B+C;}else{return C+B;}},buildDayLabel:function(A){return A.getDate();},createTitleBar:function(A){var B=YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE,"div",this.oDomContainer)[0]||document.createElement("div");B.className=YAHOO.widget.CalendarGroup.CSS_2UPTITLE;B.innerHTML=A;this.oDomContainer.insertBefore(B,this.oDomContainer.firstChild);YAHOO.util.Dom.addClass(this.oDomContainer,"withtitle");return B;},removeTitleBar:function(){var A=YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE,"div",this.oDomContainer)[0]||null;if(A){YAHOO.util.Event.purgeElement(A);this.oDomContainer.removeChild(A!
 );}YAHOO.util.Dom.removeClass(this.oDomContainer,"withtitle");},createCloseButton:function(){var D=YAHOO.util.Dom,A=YAHOO.util.Event,C=YAHOO.widget.CalendarGroup.CSS_2UPCLOSE,F="us/my/bn/x_d.gif";var E=D.getElementsByClassName("link-close","a",this.oDomContainer)[0];if(!E){E=document.createElement("a");A.addListener(E,"click",function(H,G){G.hide();A.preventDefault(H);},this);}E.href="#";E.className="link-close";if(YAHOO.widget.Calendar.IMG_ROOT!==null){var B=D.getElementsByClassName(C,"img",E)[0]||document.createElement("img");B.src=YAHOO.widget.Calendar.IMG_ROOT+F;B.className=C;E.appendChild(B);}else{E.innerHTML="<span class=\""+C+" "+this.Style.CSS_CLOSE+"\"></span>";}this.oDomContainer.appendChild(E);return E;},removeCloseButton:function(){var A=YAHOO.util.Dom.getElementsByClassName("link-close","a",this.oDomContainer)[0]||null;if(A){YAHOO.util.Event.purgeElement(A);this.oDomContainer.removeChild(A);}},renderHeader:function(E){var H=7;var F="us/tr/callt.gif";var G="us/t!
 r/calrt.gif";var M=YAHOO.widget.Calendar._DEFAULT_CONFIG;if(th!
 is.cfg.g
etProperty(M.SHOW_WEEK_HEADER.key)){H+=1;}if(this.cfg.getProperty(M.SHOW_WEEK_FOOTER.key)){H+=1;}E[E.length]="<thead>";E[E.length]="<tr>";E[E.length]="<th colspan=\""+H+"\" class=\""+this.Style.CSS_HEADER_TEXT+"\">";E[E.length]="<div class=\""+this.Style.CSS_HEADER+"\">";var K,L=false;if(this.parent){if(this.index===0){K=true;}if(this.index==(this.parent.cfg.getProperty("pages")-1)){L=true;}}else{K=true;L=true;}if(K){var A=this.cfg.getProperty(M.NAV_ARROW_LEFT.key);if(A===null&&YAHOO.widget.Calendar.IMG_ROOT!==null){A=YAHOO.widget.Calendar.IMG_ROOT+F;}var C=(A===null)?"":" style=\"background-image:url("+A+")\"";E[E.length]="<a class=\""+this.Style.CSS_NAV_LEFT+"\""+C+" > </a>";}var J=this.buildMonthLabel();var B=this.parent||this;if(B.cfg.getProperty("navigator")){J="<a class=\""+this.Style.CSS_NAV+"\" href=\"#\">"+J+"</a>";}E[E.length]=J;if(L){var D=this.cfg.getProperty(M.NAV_ARROW_RIGHT.key);if(D===null&&YAHOO.widget.Calendar.IMG_ROOT!==null){D=YAHOO.widget.Calendar.I!
 MG_ROOT+G;}var I=(D===null)?"":" style=\"background-image:url("+D+")\"";E[E.length]="<a class=\""+this.Style.CSS_NAV_RIGHT+"\""+I+" > </a>";}E[E.length]="</div>\n</th>\n</tr>";if(this.cfg.getProperty(M.SHOW_WEEKDAYS.key)){E=this.buildWeekdays(E);}E[E.length]="</thead>";return E;},buildWeekdays:function(C){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;C[C.length]="<tr class=\""+this.Style.CSS_WEEKDAY_ROW+"\">";if(this.cfg.getProperty(A.SHOW_WEEK_HEADER.key)){C[C.length]="<th> </th>";}for(var B=0;B<this.Locale.LOCALE_WEEKDAYS.length;++B){C[C.length]="<th class=\"calweekdaycell\">"+this.Locale.LOCALE_WEEKDAYS[B]+"</th>";}if(this.cfg.getProperty(A.SHOW_WEEK_FOOTER.key)){C[C.length]="<th> </th>";}C[C.length]="</tr>";return C;},renderBody:function(c,a){var m=YAHOO.widget.Calendar._DEFAULT_CONFIG;var AB=this.cfg.getProperty(m.START_WEEKDAY.key);this.preMonthDays=c.getDay();if(AB>0){this.preMonthDays-=AB;}if(this.preMonthDays<0){this.preMonthDays+=7;}this.monthDays=YAH!
 OO.widget.DateMath.findMonthEnd(c).getDate();this.postMonthDay!
 s=YAHOO.
widget.Calendar.DISPLAY_DAYS-this.preMonthDays-this.monthDays;c=YAHOO.widget.DateMath.subtract(c,YAHOO.widget.DateMath.DAY,this.preMonthDays);var Q,H;var G="w";var W="_cell";var U="wd";var k="d";var I;var h;var O=this.today.getFullYear();var j=this.today.getMonth();var D=this.today.getDate();var q=this.cfg.getProperty(m.PAGEDATE.key);var C=this.cfg.getProperty(m.HIDE_BLANK_WEEKS.key);var Z=this.cfg.getProperty(m.SHOW_WEEK_FOOTER.key);var T=this.cfg.getProperty(m.SHOW_WEEK_HEADER.key);var M=this.cfg.getProperty(m.MINDATE.key);var S=this.cfg.getProperty(m.MAXDATE.key);if(M){M=YAHOO.widget.DateMath.clearTime(M);}if(S){S=YAHOO.widget.DateMath.clearTime(S);}a[a.length]="<tbody class=\"m"+(q.getMonth()+1)+" "+this.Style.CSS_BODY+"\">";var z=0;var J=document.createElement("div");var b=document.createElement("td");J.appendChild(b);var o=this.parent||this;for(var u=0;u<6;u++){Q=YAHOO.widget.DateMath.getWeekNumber(c,q.getFullYear(),AB);H=G+Q;if(u!==0&&C===true&&c.getMonth()!=q.getMont!
 h()){break;}else{a[a.length]="<tr class=\""+H+"\">";if(T){a=this.renderRowHeader(Q,a);}for(var AA=0;AA<7;AA++){I=[];this.clearElement(b);b.className=this.Style.CSS_CELL;b.id=this.id+W+z;if(c.getDate()==D&&c.getMonth()==j&&c.getFullYear()==O){I[I.length]=o.renderCellStyleToday;}var R=[c.getFullYear(),c.getMonth()+1,c.getDate()];this.cellDates[this.cellDates.length]=R;if(c.getMonth()!=q.getMonth()){I[I.length]=o.renderCellNotThisMonth;}else{YAHOO.util.Dom.addClass(b,U+c.getDay());YAHOO.util.Dom.addClass(b,k+c.getDate());for(var t=0;t<this.renderStack.length;++t){h=null;var l=this.renderStack[t];var AC=l[0];var B;var V;var F;switch(AC){case YAHOO.widget.Calendar.DATE:B=l[1][1];V=l[1][2];F=l[1][0];if(c.getMonth()+1==B&&c.getDate()==V&&c.getFullYear()==F){h=l[2];this.renderStack.splice(t,1);}break;case YAHOO.widget.Calendar.MONTH_DAY:B=l[1][0];V=l[1][1];if(c.getMonth()+1==B&&c.getDate()==V){h=l[2];this.renderStack.splice(t,1);
-}break;case YAHOO.widget.Calendar.RANGE:var Y=l[1][0];var X=l[1][1];var e=Y[1];var L=Y[2];var P=Y[0];var y=YAHOO.widget.DateMath.getDate(P,e-1,L);var E=X[1];var g=X[2];var A=X[0];var w=YAHOO.widget.DateMath.getDate(A,E-1,g);if(c.getTime()>=y.getTime()&&c.getTime()<=w.getTime()){h=l[2];if(c.getTime()==w.getTime()){this.renderStack.splice(t,1);}}break;case YAHOO.widget.Calendar.WEEKDAY:var K=l[1][0];if(c.getDay()+1==K){h=l[2];}break;case YAHOO.widget.Calendar.MONTH:B=l[1][0];if(c.getMonth()+1==B){h=l[2];}break;}if(h){I[I.length]=h;}}}if(this._indexOfSelectedFieldArray(R)>-1){I[I.length]=o.renderCellStyleSelected;}if((M&&(c.getTime()<M.getTime()))||(S&&(c.getTime()>S.getTime()))){I[I.length]=o.renderOutOfBoundsDate;}else{I[I.length]=o.styleCellDefault;I[I.length]=o.renderCellDefault;}for(var n=0;n<I.length;++n){if(I[n].call(o,c,b)==YAHOO.widget.Calendar.STOP_RENDER){break;}}c.setTime(c.getTime()+YAHOO.widget.DateMath.ONE_DAY_MS);if(z>=0&&z<=6){YAHOO.util.Dom.addClass(b,this.St!
 yle.CSS_CELL_TOP);}if((z%7)===0){YAHOO.util.Dom.addClass(b,this.Style.CSS_CELL_LEFT);}if(((z+1)%7)===0){YAHOO.util.Dom.addClass(b,this.Style.CSS_CELL_RIGHT);}var f=this.postMonthDays;if(C&&f>=7){var N=Math.floor(f/7);for(var v=0;v<N;++v){f-=7;}}if(z>=((this.preMonthDays+f+this.monthDays)-7)){YAHOO.util.Dom.addClass(b,this.Style.CSS_CELL_BOTTOM);}a[a.length]=J.innerHTML;z++;}if(Z){a=this.renderRowFooter(Q,a);}a[a.length]="</tr>";}}a[a.length]="</tbody>";return a;},renderFooter:function(A){return A;},render:function(){this.beforeRenderEvent.fire();var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;var C=YAHOO.widget.DateMath.findMonthStart(this.cfg.getProperty(A.PAGEDATE.key));this.resetRenderers();this.cellDates.length=0;YAHOO.util.Event.purgeElement(this.oDomContainer,true);var B=[];B[B.length]="<table cellSpacing=\"0\" class=\""+this.Style.CSS_CALENDAR+" y"+C.getFullYear()+"\" id=\""+this.id+"\">";B=this.renderHeader(B);B=this.renderBody(C,B);B=this.renderFooter(B);B[B.length]="<!
 /table>";this.oDomContainer.innerHTML=B.join("\n");this.applyL!
 isteners
();this.cells=this.oDomContainer.getElementsByTagName("td");this.cfg.refireEvent(A.TITLE.key);this.cfg.refireEvent(A.CLOSE.key);this.cfg.refireEvent(A.IFRAME.key);this.renderEvent.fire();},applyListeners:function(){var K=this.oDomContainer;var B=this.parent||this;var G="a";var D="mousedown";var H=YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV_LEFT,G,K);var C=YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV_RIGHT,G,K);if(H&&H.length>0){this.linkLeft=H[0];YAHOO.util.Event.addListener(this.linkLeft,D,B.previousMonth,B,true);}if(C&&C.length>0){this.linkRight=C[0];YAHOO.util.Event.addListener(this.linkRight,D,B.nextMonth,B,true);}if(B.cfg.getProperty("navigator")!==null){this.applyNavListeners();}if(this.domEventMap){var E,A;for(var M in this.domEventMap){if(YAHOO.lang.hasOwnProperty(this.domEventMap,M)){var I=this.domEventMap[M];if(!(I instanceof Array)){I=[I];}for(var F=0;F<I.length;F++){var L=I[F];A=YAHOO.util.Dom.getElementsByClassName(M,L.tag,this.oDomConta!
 iner);for(var J=0;J<A.length;J++){E=A[J];YAHOO.util.Event.addListener(E,L.event,L.handler,L.scope,L.correct);}}}}}YAHOO.util.Event.addListener(this.oDomContainer,"click",this.doSelectCell,this);YAHOO.util.Event.addListener(this.oDomContainer,"mouseover",this.doCellMouseOver,this);YAHOO.util.Event.addListener(this.oDomContainer,"mouseout",this.doCellMouseOut,this);},applyNavListeners:function(){var D=YAHOO.util.Event;var C=this.parent||this;var F=this;var B=YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV,"a",this.oDomContainer);if(B.length>0){function A(J,I){var H=D.getTarget(J);if(this===H||YAHOO.util.Dom.isAncestor(this,H)){D.preventDefault(J);}var E=C.oNavigator;if(E){var G=F.cfg.getProperty("pagedate");E.setYear(G.getFullYear());E.setMonth(G.getMonth());E.show();}}D.addListener(B,"click",A);}},getDateByCellId:function(B){var A=this.getDateFieldsByCellId(B);return YAHOO.widget.DateMath.getDate(A[0],A[1]-1,A[2]);},getDateFieldsByCellId:function(A){A=A.toLowerCase(!
 ).split("_cell")[1];A=parseInt(A,10);return this.cellDates[A];!
 },getCel
lIndex:function(C){var B=-1;if(C){var A=C.getMonth(),H=C.getFullYear(),G=C.getDate(),E=this.cellDates;for(var D=0;D<E.length;++D){var F=E[D];if(F[0]===H&&F[1]===A+1&&F[2]===G){B=D;break;}}}return B;},renderOutOfBoundsDate:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_OOB);A.innerHTML=B.getDate();return YAHOO.widget.Calendar.STOP_RENDER;},renderRowHeader:function(B,A){A[A.length]="<th class=\"calrowhead\">"+B+"</th>";return A;},renderRowFooter:function(B,A){A[A.length]="<th class=\"calrowfoot\">"+B+"</th>";return A;},renderCellDefault:function(B,A){A.innerHTML="<a href=\"#\" class=\""+this.Style.CSS_CELL_SELECTOR+"\">"+this.buildDayLabel(B)+"</a>";},styleCellDefault:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_SELECTABLE);},renderCellStyleHighlight1:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_HIGHLIGHT1);},renderCellStyleHighlight2:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_HIGHLIGHT2);},renderCellStyleHighlight3:f!
 unction(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_HIGHLIGHT3);},renderCellStyleHighlight4:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_HIGHLIGHT4);},renderCellStyleToday:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_TODAY);},renderCellStyleSelected:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_SELECTED);},renderCellNotThisMonth:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_OOM);A.innerHTML=B.getDate();return YAHOO.widget.Calendar.STOP_RENDER;},renderBodyCellRestricted:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL);YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_RESTRICTED);A.innerHTML=B.getDate();return YAHOO.widget.Calendar.STOP_RENDER;},addMonths:function(B){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;this.cfg.setProperty(A,YAHOO.widget.DateMath.add(this.cfg.getProperty(A),YAHOO.widget.DateMath.MONTH,B));this.resetRenderers();
-this.changePageEvent.fire();},subtractMonths:function(B){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;this.cfg.setProperty(A,YAHOO.widget.DateMath.subtract(this.cfg.getProperty(A),YAHOO.widget.DateMath.MONTH,B));this.resetRenderers();this.changePageEvent.fire();},addYears:function(B){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;this.cfg.setProperty(A,YAHOO.widget.DateMath.add(this.cfg.getProperty(A),YAHOO.widget.DateMath.YEAR,B));this.resetRenderers();this.changePageEvent.fire();},subtractYears:function(B){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;this.cfg.setProperty(A,YAHOO.widget.DateMath.subtract(this.cfg.getProperty(A),YAHOO.widget.DateMath.YEAR,B));this.resetRenderers();this.changePageEvent.fire();},nextMonth:function(){this.addMonths(1);},previousMonth:function(){this.subtractMonths(1);},nextYear:function(){this.addYears(1);},previousYear:function(){this.subtractYears(1);},reset:function(){var A=YAHOO.widget.Calendar._DEFAULT_CO!
 NFIG;this.cfg.resetProperty(A.SELECTED.key);this.cfg.resetProperty(A.PAGEDATE.key);this.resetEvent.fire();},clear:function(){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;this.cfg.setProperty(A.SELECTED.key,[]);this.cfg.setProperty(A.PAGEDATE.key,new Date(this.today.getTime()));this.clearEvent.fire();},select:function(C){var F=this._toFieldArray(C);var B=[];var E=[];var G=YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;for(var A=0;A<F.length;++A){var D=F[A];if(!this.isDateOOB(this._toDate(D))){if(B.length===0){this.beforeSelectEvent.fire();E=this.cfg.getProperty(G);}B.push(D);if(this._indexOfSelectedFieldArray(D)==-1){E[E.length]=D;}}}if(B.length>0){if(this.parent){this.parent.cfg.setProperty(G,E);}else{this.cfg.setProperty(G,E);}this.selectEvent.fire(B);}return this.getSelectedDates();},selectCell:function(D){var B=this.cells[D];var H=this.cellDates[D];var G=this._toDate(H);var C=YAHOO.util.Dom.hasClass(B,this.Style.CSS_CELL_SELECTABLE);if(C){this.beforeSelectEvent.fire()!
 ;var F=YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;var !
 E=this.c
fg.getProperty(F);var A=H.concat();if(this._indexOfSelectedFieldArray(A)==-1){E[E.length]=A;}if(this.parent){this.parent.cfg.setProperty(F,E);}else{this.cfg.setProperty(F,E);}this.renderCellStyleSelected(G,B);this.selectEvent.fire([A]);this.doCellMouseOut.call(B,null,this);}return this.getSelectedDates();},deselect:function(E){var A=this._toFieldArray(E);var D=[];var G=[];var H=YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;for(var B=0;B<A.length;++B){var F=A[B];if(!this.isDateOOB(this._toDate(F))){if(D.length===0){this.beforeDeselectEvent.fire();G=this.cfg.getProperty(H);}D.push(F);var C=this._indexOfSelectedFieldArray(F);if(C!=-1){G.splice(C,1);}}}if(D.length>0){if(this.parent){this.parent.cfg.setProperty(H,G);}else{this.cfg.setProperty(H,G);}this.deselectEvent.fire(D);}return this.getSelectedDates();},deselectCell:function(E){var H=this.cells[E];var B=this.cellDates[E];var F=this._indexOfSelectedFieldArray(B);var G=YAHOO.util.Dom.hasClass(H,this.Style.CSS_CELL_SELECTA!
 BLE);if(G){this.beforeDeselectEvent.fire();var I=YAHOO.widget.Calendar._DEFAULT_CONFIG;var D=this.cfg.getProperty(I.SELECTED.key);var C=this._toDate(B);var A=B.concat();if(F>-1){if(this.cfg.getProperty(I.PAGEDATE.key).getMonth()==C.getMonth()&&this.cfg.getProperty(I.PAGEDATE.key).getFullYear()==C.getFullYear()){YAHOO.util.Dom.removeClass(H,this.Style.CSS_CELL_SELECTED);}D.splice(F,1);}if(this.parent){this.parent.cfg.setProperty(I.SELECTED.key,D);}else{this.cfg.setProperty(I.SELECTED.key,D);}this.deselectEvent.fire(A);}return this.getSelectedDates();},deselectAll:function(){this.beforeDeselectEvent.fire();var D=YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;var A=this.cfg.getProperty(D);var B=A.length;var C=A.concat();if(this.parent){this.parent.cfg.setProperty(D,[]);}else{this.cfg.setProperty(D,[]);}if(B>0){this.deselectEvent.fire(C);}return this.getSelectedDates();},_toFieldArray:function(B){var A=[];if(B instanceof Date){A=[[B.getFullYear(),B.getMonth()+1,B.getDate()]!
 ];}else{if(YAHOO.lang.isString(B)){A=this._parseDates(B);}else!
 {if(YAHO
O.lang.isArray(B)){for(var C=0;C<B.length;++C){var D=B[C];A[A.length]=[D.getFullYear(),D.getMonth()+1,D.getDate()];}}}}return A;},toDate:function(A){return this._toDate(A);},_toDate:function(A){if(A instanceof Date){return A;}else{return YAHOO.widget.DateMath.getDate(A[0],A[1]-1,A[2]);}},_fieldArraysAreEqual:function(C,B){var A=false;if(C[0]==B[0]&&C[1]==B[1]&&C[2]==B[2]){A=true;}return A;},_indexOfSelectedFieldArray:function(E){var D=-1;var A=this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key);for(var C=0;C<A.length;++C){var B=A[C];if(E[0]==B[0]&&E[1]==B[1]&&E[2]==B[2]){D=C;break;}}return D;},isDateOOM:function(A){return(A.getMonth()!=this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key).getMonth());},isDateOOB:function(D){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;var E=this.cfg.getProperty(A.MINDATE.key);var F=this.cfg.getProperty(A.MAXDATE.key);var C=YAHOO.widget.DateMath;if(E){E=C.clearTime(E);}if(F){F=C.clearTime(F);}var B=new D!
 ate(D.getTime());B=C.clearTime(B);return((E&&B.getTime()<E.getTime())||(F&&B.getTime()>F.getTime()));},_parsePageDate:function(B){var E;var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;if(B){if(B instanceof Date){E=YAHOO.widget.DateMath.findMonthStart(B);}else{var F,D,C;C=B.split(this.cfg.getProperty(A.DATE_FIELD_DELIMITER.key));F=parseInt(C[this.cfg.getProperty(A.MY_MONTH_POSITION.key)-1],10)-1;D=parseInt(C[this.cfg.getProperty(A.MY_YEAR_POSITION.key)-1],10);E=YAHOO.widget.DateMath.getDate(D,F,1);}}else{E=YAHOO.widget.DateMath.getDate(this.today.getFullYear(),this.today.getMonth(),1);}return E;},onBeforeSelect:function(){if(this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MULTI_SELECT.key)===false){if(this.parent){this.parent.callChildFunction("clearAllBodyCellStyles",this.Style.CSS_CELL_SELECTED);this.parent.deselectAll();}else{this.clearAllBodyCellStyles(this.Style.CSS_CELL_SELECTED);this.deselectAll();
-}}},onSelect:function(A){},onBeforeDeselect:function(){},onDeselect:function(A){},onChangePage:function(){this.render();},onRender:function(){},onReset:function(){this.render();},onClear:function(){this.render();},validate:function(){return true;},_parseDate:function(C){var D=C.split(this.Locale.DATE_FIELD_DELIMITER);var A;if(D.length==2){A=[D[this.Locale.MD_MONTH_POSITION-1],D[this.Locale.MD_DAY_POSITION-1]];A.type=YAHOO.widget.Calendar.MONTH_DAY;}else{A=[D[this.Locale.MDY_YEAR_POSITION-1],D[this.Locale.MDY_MONTH_POSITION-1],D[this.Locale.MDY_DAY_POSITION-1]];A.type=YAHOO.widget.Calendar.DATE;}for(var B=0;B<A.length;B++){A[B]=parseInt(A[B],10);}return A;},_parseDates:function(B){var I=[];var H=B.split(this.Locale.DATE_DELIMITER);for(var G=0;G<H.length;++G){var F=H[G];if(F.indexOf(this.Locale.DATE_RANGE_DELIMITER)!=-1){var A=F.split(this.Locale.DATE_RANGE_DELIMITER);var E=this._parseDate(A[0]);var J=this._parseDate(A[1]);var D=this._parseRange(E,J);I=I.concat(D);}else{var C!
 =this._parseDate(F);I.push(C);}}return I;},_parseRange:function(A,E){var B=YAHOO.widget.DateMath.add(YAHOO.widget.DateMath.getDate(A[0],A[1]-1,A[2]),YAHOO.widget.DateMath.DAY,1);var D=YAHOO.widget.DateMath.getDate(E[0],E[1]-1,E[2]);var C=[];C.push(A);while(B.getTime()<=D.getTime()){C.push([B.getFullYear(),B.getMonth()+1,B.getDate()]);B=YAHOO.widget.DateMath.add(B,YAHOO.widget.DateMath.DAY,1);}return C;},resetRenderers:function(){this.renderStack=this._renderStack.concat();},removeRenderers:function(){this._renderStack=[];this.renderStack=[];},clearElement:function(A){A.innerHTML=" ";A.className="";},addRenderer:function(A,B){var D=this._parseDates(A);for(var C=0;C<D.length;++C){var E=D[C];if(E.length==2){if(E[0] instanceof Array){this._addRenderer(YAHOO.widget.Calendar.RANGE,E,B);}else{this._addRenderer(YAHOO.widget.Calendar.MONTH_DAY,E,B);}}else{if(E.length==3){this._addRenderer(YAHOO.widget.Calendar.DATE,E,B);}}}},_addRenderer:function(B,C,A){var D=[B,C,A];this.rende!
 rStack.unshift(D);this._renderStack=this.renderStack.concat();!
 },addMon
thRenderer:function(B,A){this._addRenderer(YAHOO.widget.Calendar.MONTH,[B],A);},addWeekdayRenderer:function(B,A){this._addRenderer(YAHOO.widget.Calendar.WEEKDAY,[B],A);},clearAllBodyCellStyles:function(A){for(var B=0;B<this.cells.length;++B){YAHOO.util.Dom.removeClass(this.cells[B],A);}},setMonth:function(C){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;var B=this.cfg.getProperty(A);B.setMonth(parseInt(C,10));this.cfg.setProperty(A,B);},setYear:function(B){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;var C=this.cfg.getProperty(A);C.setFullYear(parseInt(B,10));this.cfg.setProperty(A,C);},getSelectedDates:function(){var C=[];var B=this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key);for(var E=0;E<B.length;++E){var D=B[E];var A=YAHOO.widget.DateMath.getDate(D[0],D[1]-1,D[2]);C.push(A);}C.sort(function(G,F){return G-F;});return C;},hide:function(){if(this.beforeHideEvent.fire()){this.oDomContainer.style.display="none";this.hideEvent.fir!
 e();}},show:function(){if(this.beforeShowEvent.fire()){this.oDomContainer.style.display="block";this.showEvent.fire();}},browser:(function(){var A=navigator.userAgent.toLowerCase();if(A.indexOf("opera")!=-1){return"opera";}else{if(A.indexOf("msie 7")!=-1){return"ie7";}else{if(A.indexOf("msie")!=-1){return"ie";}else{if(A.indexOf("safari")!=-1){return"safari";}else{if(A.indexOf("gecko")!=-1){return"gecko";}else{return false;}}}}}})(),toString:function(){return"Calendar "+this.id;}};YAHOO.widget.Calendar_Core=YAHOO.widget.Calendar;YAHOO.widget.Cal_Core=YAHOO.widget.Calendar;YAHOO.widget.CalendarGroup=function(C,A,B){if(arguments.length>0){this.init.apply(this,arguments);}};YAHOO.widget.CalendarGroup.prototype={init:function(D,B,C){var A=this._parseArgs(arguments);D=A.id;B=A.container;C=A.config;this.oDomContainer=YAHOO.util.Dom.get(B);if(!this.oDomContainer.id){this.oDomContainer.id=YAHOO.util.Dom.generateId();}if(!D){D=this.oDomContainer.id+"_t";}this.id=D;this.containerId=th!
 is.oDomContainer.id;this.initEvents();this.initStyles();this.p!
 ages=[];
YAHOO.util.Dom.addClass(this.oDomContainer,YAHOO.widget.CalendarGroup.CSS_CONTAINER);YAHOO.util.Dom.addClass(this.oDomContainer,YAHOO.widget.CalendarGroup.CSS_MULTI_UP);this.cfg=new YAHOO.util.Config(this);this.Options={};this.Locale={};this.setupConfig();if(C){this.cfg.applyConfig(C,true);}this.cfg.fireQueue();if(YAHOO.env.ua.opera){this.renderEvent.subscribe(this._fixWidth,this,true);this.showEvent.subscribe(this._fixWidth,this,true);}},setupConfig:function(){var A=YAHOO.widget.CalendarGroup._DEFAULT_CONFIG;this.cfg.addProperty(A.PAGES.key,{value:A.PAGES.value,validator:this.cfg.checkNumber,handler:this.configPages});this.cfg.addProperty(A.PAGEDATE.key,{value:new Date(),handler:this.configPageDate});this.cfg.addProperty(A.SELECTED.key,{value:[],handler:this.configSelected});this.cfg.addProperty(A.TITLE.key,{value:A.TITLE.value,handler:this.configTitle});this.cfg.addProperty(A.CLOSE.key,{value:A.CLOSE.value,handler:this.configClose});this.cfg.addProperty(A.IFRAME.key,{value!
 :A.IFRAME.value,handler:this.configIframe,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.MINDATE.key,{value:A.MINDATE.value,handler:this.delegateConfig});this.cfg.addProperty(A.MAXDATE.key,{value:A.MAXDATE.value,handler:this.delegateConfig});this.cfg.addProperty(A.MULTI_SELECT.key,{value:A.MULTI_SELECT.value,handler:this.delegateConfig,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.START_WEEKDAY.key,{value:A.START_WEEKDAY.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.SHOW_WEEKDAYS.key,{value:A.SHOW_WEEKDAYS.value,handler:this.delegateConfig,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.SHOW_WEEK_HEADER.key,{value:A.SHOW_WEEK_HEADER.value,handler:this.delegateConfig,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.SHOW_WEEK_FOOTER.key,{value:A.SHOW_WEEK_FOOTER.value,handler:this.delegateConfig,validator:this.cfg.checkBoolean});
-this.cfg.addProperty(A.HIDE_BLANK_WEEKS.key,{value:A.HIDE_BLANK_WEEKS.value,handler:this.delegateConfig,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.NAV_ARROW_LEFT.key,{value:A.NAV_ARROW_LEFT.value,handler:this.delegateConfig});this.cfg.addProperty(A.NAV_ARROW_RIGHT.key,{value:A.NAV_ARROW_RIGHT.value,handler:this.delegateConfig});this.cfg.addProperty(A.MONTHS_SHORT.key,{value:A.MONTHS_SHORT.value,handler:this.delegateConfig});this.cfg.addProperty(A.MONTHS_LONG.key,{value:A.MONTHS_LONG.value,handler:this.delegateConfig});this.cfg.addProperty(A.WEEKDAYS_1CHAR.key,{value:A.WEEKDAYS_1CHAR.value,handler:this.delegateConfig});this.cfg.addProperty(A.WEEKDAYS_SHORT.key,{value:A.WEEKDAYS_SHORT.value,handler:this.delegateConfig});this.cfg.addProperty(A.WEEKDAYS_MEDIUM.key,{value:A.WEEKDAYS_MEDIUM.value,handler:this.delegateConfig});this.cfg.addProperty(A.WEEKDAYS_LONG.key,{value:A.WEEKDAYS_LONG.value,handler:this.delegateConfig});this.cfg.addProperty(A.LOCALE_MONTHS.key,{!
 value:A.LOCALE_MONTHS.value,handler:this.delegateConfig});this.cfg.addProperty(A.LOCALE_WEEKDAYS.key,{value:A.LOCALE_WEEKDAYS.value,handler:this.delegateConfig});this.cfg.addProperty(A.DATE_DELIMITER.key,{value:A.DATE_DELIMITER.value,handler:this.delegateConfig});this.cfg.addProperty(A.DATE_FIELD_DELIMITER.key,{value:A.DATE_FIELD_DELIMITER.value,handler:this.delegateConfig});this.cfg.addProperty(A.DATE_RANGE_DELIMITER.key,{value:A.DATE_RANGE_DELIMITER.value,handler:this.delegateConfig});this.cfg.addProperty(A.MY_MONTH_POSITION.key,{value:A.MY_MONTH_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MY_YEAR_POSITION.key,{value:A.MY_YEAR_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MD_MONTH_POSITION.key,{value:A.MD_MONTH_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MD_DAY_POSITION.key,{value:A.MD_DAY_POSITION.value,handler!
 :this.delegateConfig,validator:this.cfg.checkNumber});this.cfg!
 .addProp
erty(A.MDY_MONTH_POSITION.key,{value:A.MDY_MONTH_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MDY_DAY_POSITION.key,{value:A.MDY_DAY_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MDY_YEAR_POSITION.key,{value:A.MDY_YEAR_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MY_LABEL_MONTH_POSITION.key,{value:A.MY_LABEL_MONTH_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MY_LABEL_YEAR_POSITION.key,{value:A.MY_LABEL_YEAR_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MY_LABEL_MONTH_SUFFIX.key,{value:A.MY_LABEL_MONTH_SUFFIX.value,handler:this.delegateConfig});this.cfg.addProperty(A.MY_LABEL_YEAR_SUFFIX.key,{value:A.MY_LABEL_YEAR_SUFFIX.value,handler:this.delegateConfig});this.cfg.addProperty(A.NAV.key,{value:A.NAV.value,handler:!
 this.configNavigator});},initEvents:function(){var C=this;var E="Event";var B=function(G,J,F){for(var I=0;I<C.pages.length;++I){var H=C.pages[I];H[this.type+E].subscribe(G,J,F);}};var A=function(F,I){for(var H=0;H<C.pages.length;++H){var G=C.pages[H];G[this.type+E].unsubscribe(F,I);}};var D=YAHOO.widget.Calendar._EVENT_TYPES;this.beforeSelectEvent=new YAHOO.util.CustomEvent(D.BEFORE_SELECT);this.beforeSelectEvent.subscribe=B;this.beforeSelectEvent.unsubscribe=A;this.selectEvent=new YAHOO.util.CustomEvent(D.SELECT);this.selectEvent.subscribe=B;this.selectEvent.unsubscribe=A;this.beforeDeselectEvent=new YAHOO.util.CustomEvent(D.BEFORE_DESELECT);this.beforeDeselectEvent.subscribe=B;this.beforeDeselectEvent.unsubscribe=A;this.deselectEvent=new YAHOO.util.CustomEvent(D.DESELECT);this.deselectEvent.subscribe=B;this.deselectEvent.unsubscribe=A;this.changePageEvent=new YAHOO.util.CustomEvent(D.CHANGE_PAGE);this.changePageEvent.subscribe=B;this.changePageEvent.unsubscribe=A;this.bef!
 oreRenderEvent=new YAHOO.util.CustomEvent(D.BEFORE_RENDER);thi!
 s.before
RenderEvent.subscribe=B;this.beforeRenderEvent.unsubscribe=A;this.renderEvent=new YAHOO.util.CustomEvent(D.RENDER);this.renderEvent.subscribe=B;this.renderEvent.unsubscribe=A;this.resetEvent=new YAHOO.util.CustomEvent(D.RESET);this.resetEvent.subscribe=B;this.resetEvent.unsubscribe=A;this.clearEvent=new YAHOO.util.CustomEvent(D.CLEAR);this.clearEvent.subscribe=B;this.clearEvent.unsubscribe=A;this.beforeShowEvent=new YAHOO.util.CustomEvent(D.BEFORE_SHOW);this.showEvent=new YAHOO.util.CustomEvent(D.SHOW);this.beforeHideEvent=new YAHOO.util.CustomEvent(D.BEFORE_HIDE);this.hideEvent=new YAHOO.util.CustomEvent(D.HIDE);this.beforeShowNavEvent=new YAHOO.util.CustomEvent(D.BEFORE_SHOW_NAV);this.showNavEvent=new YAHOO.util.CustomEvent(D.SHOW_NAV);this.beforeHideNavEvent=new YAHOO.util.CustomEvent(D.BEFORE_HIDE_NAV);this.hideNavEvent=new YAHOO.util.CustomEvent(D.HIDE_NAV);this.beforeRenderNavEvent=new YAHOO.util.CustomEvent(D.BEFORE_RENDER_NAV);this.renderNavEvent=new YAHOO.util.Custo!
 mEvent(D.RENDER_NAV);},configPages:function(K,J,G){var E=J[0];var C=YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;var O="_";var L="groupcal";var N="first-of-type";var D="last-of-type";for(var B=0;B<E;++B){var M=this.id+O+B;var I=this.containerId+O+B;var H=this.cfg.getConfig();H.close=false;H.title=false;H.navigator=null;var A=this.constructChild(M,I,H);var F=A.cfg.getProperty(C);this._setMonthOnDate(F,F.getMonth()+B);A.cfg.setProperty(C,F);YAHOO.util.Dom.removeClass(A.oDomContainer,this.Style.CSS_SINGLE);YAHOO.util.Dom.addClass(A.oDomContainer,L);if(B===0){YAHOO.util.Dom.addClass(A.oDomContainer,N);}if(B==(E-1)){YAHOO.util.Dom.addClass(A.oDomContainer,D);}A.parent=this;A.index=B;this.pages[this.pages.length]=A;}},configPageDate:function(H,G,E){var C=G[0];var F;var D=YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;for(var B=0;B<this.pages.length;++B){var A=this.pages[B];if(B===0){F=A._parsePageDate(C);
-A.cfg.setProperty(D,F);}else{var I=new Date(F);this._setMonthOnDate(I,I.getMonth()+B);A.cfg.setProperty(D,I);}}},configSelected:function(C,A,E){var D=YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.SELECTED.key;this.delegateConfig(C,A,E);var B=(this.pages.length>0)?this.pages[0].cfg.getProperty(D):[];this.cfg.setProperty(D,B,true);},delegateConfig:function(B,A,E){var F=A[0];var D;for(var C=0;C<this.pages.length;C++){D=this.pages[C];D.cfg.setProperty(B,F);}},setChildFunction:function(D,B){var A=this.cfg.getProperty(YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES.key);for(var C=0;C<A;++C){this.pages[C][D]=B;}},callChildFunction:function(F,B){var A=this.cfg.getProperty(YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES.key);for(var E=0;E<A;++E){var D=this.pages[E];if(D[F]){var C=D[F];C.call(D,B);}}},constructChild:function(D,B,C){var A=document.getElementById(B);if(!A){A=document.createElement("div");A.id=B;this.oDomContainer.appendChild(A);}return new YAHOO.widget.Calendar(D,B,C);}!
 ,setMonth:function(E){E=parseInt(E,10);var F;var B=YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;for(var D=0;D<this.pages.length;++D){var C=this.pages[D];var A=C.cfg.getProperty(B);if(D===0){F=A.getFullYear();}else{A.setFullYear(F);}this._setMonthOnDate(A,E+D);C.cfg.setProperty(B,A);}},setYear:function(C){var B=YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;C=parseInt(C,10);for(var E=0;E<this.pages.length;++E){var D=this.pages[E];var A=D.cfg.getProperty(B);if((A.getMonth()+1)==1&&E>0){C+=1;}D.setYear(C);}},render:function(){this.renderHeader();for(var B=0;B<this.pages.length;++B){var A=this.pages[B];A.render();}this.renderFooter();},select:function(A){for(var C=0;C<this.pages.length;++C){var B=this.pages[C];B.select(A);}return this.getSelectedDates();},selectCell:function(A){for(var C=0;C<this.pages.length;++C){var B=this.pages[C];B.selectCell(A);}return this.getSelectedDates();},deselect:function(A){for(var C=0;C<this.pages.length;++C){var B=this.pages[C!
 ];B.deselect(A);}return this.getSelectedDates();},deselectAll:!
 function
(){for(var B=0;B<this.pages.length;++B){var A=this.pages[B];A.deselectAll();}return this.getSelectedDates();},deselectCell:function(A){for(var C=0;C<this.pages.length;++C){var B=this.pages[C];B.deselectCell(A);}return this.getSelectedDates();},reset:function(){for(var B=0;B<this.pages.length;++B){var A=this.pages[B];A.reset();}},clear:function(){for(var B=0;B<this.pages.length;++B){var A=this.pages[B];A.clear();}},nextMonth:function(){for(var B=0;B<this.pages.length;++B){var A=this.pages[B];A.nextMonth();}},previousMonth:function(){for(var B=this.pages.length-1;B>=0;--B){var A=this.pages[B];A.previousMonth();}},nextYear:function(){for(var B=0;B<this.pages.length;++B){var A=this.pages[B];A.nextYear();}},previousYear:function(){for(var B=0;B<this.pages.length;++B){var A=this.pages[B];A.previousYear();}},getSelectedDates:function(){var C=[];var B=this.cfg.getProperty(YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.SELECTED.key);for(var E=0;E<B.length;++E){var D=B[E];var A=YAHOO.widg!
 et.DateMath.getDate(D[0],D[1]-1,D[2]);C.push(A);}C.sort(function(G,F){return G-F;});return C;},addRenderer:function(A,B){for(var D=0;D<this.pages.length;++D){var C=this.pages[D];C.addRenderer(A,B);}},addMonthRenderer:function(D,A){for(var C=0;C<this.pages.length;++C){var B=this.pages[C];B.addMonthRenderer(D,A);}},addWeekdayRenderer:function(B,A){for(var D=0;D<this.pages.length;++D){var C=this.pages[D];C.addWeekdayRenderer(B,A);}},removeRenderers:function(){this.callChildFunction("removeRenderers");},renderHeader:function(){},renderFooter:function(){},addMonths:function(A){this.callChildFunction("addMonths",A);},subtractMonths:function(A){this.callChildFunction("subtractMonths",A);},addYears:function(A){this.callChildFunction("addYears",A);},subtractYears:function(A){this.callChildFunction("subtractYears",A);},getCalendarPage:function(D){var F=null;if(D){var G=D.getFullYear(),C=D.getMonth();var B=this.pages;for(var E=0;E<B.length;++E){var A=B[E].cfg.getProperty("pagedate");i!
 f(A.getFullYear()===G&&A.getMonth()===C){F=B[E];break;}}}retur!
 n F;},_s
etMonthOnDate:function(C,D){if(YAHOO.env.ua.webkit&&YAHOO.env.ua.webkit<420&&(D<0||D>11)){var B=YAHOO.widget.DateMath;var A=B.add(C,B.MONTH,D-C.getMonth());C.setTime(A.getTime());}else{C.setMonth(D);}},_fixWidth:function(){var A=0;for(var C=0;C<this.pages.length;++C){var B=this.pages[C];A+=B.oDomContainer.offsetWidth;}if(A>0){this.oDomContainer.style.width=A+"px";}},toString:function(){return"CalendarGroup "+this.id;}};YAHOO.widget.CalendarGroup.CSS_CONTAINER="yui-calcontainer";YAHOO.widget.CalendarGroup.CSS_MULTI_UP="multi";YAHOO.widget.CalendarGroup.CSS_2UPTITLE="title";YAHOO.widget.CalendarGroup.CSS_2UPCLOSE="close-icon";YAHOO.lang.augmentProto(YAHOO.widget.CalendarGroup,YAHOO.widget.Calendar,"buildDayLabel","buildMonthLabel","renderOutOfBoundsDate","renderRowHeader","renderRowFooter","renderCellDefault","styleCellDefault","renderCellStyleHighlight1","renderCellStyleHighlight2","renderCellStyleHighlight3","renderCellStyleHighlight4","renderCellStyleToday","renderCellStyle!
 Selected","renderCellNotThisMonth","renderBodyCellRestricted","initStyles","configTitle","configClose","configIframe","configNavigator","createTitleBar","createCloseButton","removeTitleBar","removeCloseButton","hide","show","toDate","_parseArgs","browser");YAHOO.widget.CalendarGroup._DEFAULT_CONFIG=YAHOO.widget.Calendar._DEFAULT_CONFIG;YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES={key:"pages",value:2};YAHOO.widget.CalGrp=YAHOO.widget.CalendarGroup;YAHOO.widget.Calendar2up=function(C,A,B){this.init(C,A,B);};YAHOO.extend(YAHOO.widget.Calendar2up,YAHOO.widget.CalendarGroup);YAHOO.widget.Cal2up=YAHOO.widget.Calendar2up;YAHOO.widget.CalendarNavigator=function(A){this.init(A);};(function(){var A=YAHOO.widget.CalendarNavigator;A.CLASSES={NAV:"yui-cal-nav",NAV_VISIBLE:"yui-cal-nav-visible",MASK:"yui-cal-nav-mask",YEAR:"yui-cal-nav-y",MONTH:"yui-cal-nav-m",BUTTONS:"yui-cal-nav-b",BUTTON:"yui-cal-nav-btn",ERROR:"yui-cal-nav-e",YEAR_CTRL:"yui-cal-nav-yc",MONTH_CTRL:"yui-cal-nav-mc!
 ",INVALID:"yui-invalid",DEFAULT:"yui-default"};
-A._DEFAULT_CFG={strings:{month:"Month",year:"Year",submit:"Okay",cancel:"Cancel",invalidYear:"Year needs to be a number"},monthFormat:YAHOO.widget.Calendar.LONG,initialFocus:"year"};A.ID_SUFFIX="_nav";A.MONTH_SUFFIX="_month";A.YEAR_SUFFIX="_year";A.ERROR_SUFFIX="_error";A.CANCEL_SUFFIX="_cancel";A.SUBMIT_SUFFIX="_submit";A.YR_MAX_DIGITS=4;A.YR_MINOR_INC=1;A.YR_MAJOR_INC=10;A.UPDATE_DELAY=50;A.YR_PATTERN=/^\d+$/;A.TRIM=/^\s*(.*?)\s*$/;})();YAHOO.widget.CalendarNavigator.prototype={id:null,cal:null,navEl:null,maskEl:null,yearEl:null,monthEl:null,errorEl:null,submitEl:null,cancelEl:null,firstCtrl:null,lastCtrl:null,_doc:null,_year:null,_month:0,__rendered:false,init:function(A){var C=A.oDomContainer;this.cal=A;this.id=C.id+YAHOO.widget.CalendarNavigator.ID_SUFFIX;this._doc=C.ownerDocument;var B=YAHOO.env.ua.ie;this.__isIEQuirks=(B&&((B<=6)||(B===7&&this._doc.compatMode=="BackCompat")));},show:function(){var A=YAHOO.widget.CalendarNavigator.CLASSES;if(this.cal.beforeShowNavEven!
 t.fire()){if(!this.__rendered){this.render();}this.clearErrors();this._updateMonthUI();this._updateYearUI();this._show(this.navEl,true);this.setInitialFocus();this.showMask();YAHOO.util.Dom.addClass(this.cal.oDomContainer,A.NAV_VISIBLE);this.cal.showNavEvent.fire();}},hide:function(){var A=YAHOO.widget.CalendarNavigator.CLASSES;if(this.cal.beforeHideNavEvent.fire()){this._show(this.navEl,false);this.hideMask();YAHOO.util.Dom.removeClass(this.cal.oDomContainer,A.NAV_VISIBLE);this.cal.hideNavEvent.fire();}},showMask:function(){this._show(this.maskEl,true);if(this.__isIEQuirks){this._syncMask();}},hideMask:function(){this._show(this.maskEl,false);},getMonth:function(){return this._month;},getYear:function(){return this._year;},setMonth:function(A){if(A>=0&&A<12){this._month=A;}this._updateMonthUI();},setYear:function(B){var A=YAHOO.widget.CalendarNavigator.YR_PATTERN;if(YAHOO.lang.isNumber(B)&&A.test(B+"")){this._year=B;}this._updateYearUI();},render:function(){this.cal.before!
 RenderNavEvent.fire();if(!this.__rendered){this.createNav();th!
 is.creat
eMask();this.applyListeners();this.__rendered=true;}this.cal.renderNavEvent.fire();},createNav:function(){var B=YAHOO.widget.CalendarNavigator;var C=this._doc;var D=C.createElement("div");D.className=B.CLASSES.NAV;var A=this.renderNavContents([]);D.innerHTML=A.join("");this.cal.oDomContainer.appendChild(D);this.navEl=D;this.yearEl=C.getElementById(this.id+B.YEAR_SUFFIX);this.monthEl=C.getElementById(this.id+B.MONTH_SUFFIX);this.errorEl=C.getElementById(this.id+B.ERROR_SUFFIX);this.submitEl=C.getElementById(this.id+B.SUBMIT_SUFFIX);this.cancelEl=C.getElementById(this.id+B.CANCEL_SUFFIX);if(YAHOO.env.ua.gecko&&this.yearEl&&this.yearEl.type=="text"){this.yearEl.setAttribute("autocomplete","off");}this._setFirstLastElements();},createMask:function(){var B=YAHOO.widget.CalendarNavigator.CLASSES;var A=this._doc.createElement("div");A.className=B.MASK;this.cal.oDomContainer.appendChild(A);this.maskEl=A;},_syncMask:function(){var B=this.cal.oDomContainer;if(B&&this.maskEl){var A=YAH!
 OO.util.Dom.getRegion(B);YAHOO.util.Dom.setStyle(this.maskEl,"width",A.right-A.left+"px");YAHOO.util.Dom.setStyle(this.maskEl,"height",A.bottom-A.top+"px");}},renderNavContents:function(A){var D=YAHOO.widget.CalendarNavigator,E=D.CLASSES,B=A;B[B.length]="<div class=\""+E.MONTH+"\">";this.renderMonth(B);B[B.length]="</div>";B[B.length]="<div class=\""+E.YEAR+"\">";this.renderYear(B);B[B.length]="</div>";B[B.length]="<div class=\""+E.BUTTONS+"\">";this.renderButtons(B);B[B.length]="</div>";B[B.length]="<div class=\""+E.ERROR+"\" id=\""+this.id+D.ERROR_SUFFIX+"\"></div>";return B;},renderMonth:function(D){var G=YAHOO.widget.CalendarNavigator,H=G.CLASSES;var I=this.id+G.MONTH_SUFFIX,F=this.__getCfg("monthFormat"),A=this.cal.cfg.getProperty((F==YAHOO.widget.Calendar.SHORT)?"MONTHS_SHORT":"MONTHS_LONG"),E=D;if(A&&A.length>0){E[E.length]="<label for=\""+I+"\">";E[E.length]=this.__getCfg("month",true);E[E.length]="</label>";E[E.length]="<select name=\""+I+"\" id=\""+I+"\" class=\""!
 +H.MONTH_CTRL+"\">";for(var B=0;B<A.length;B++){E[E.length]="<!
 option v
alue=\""+B+"\">";E[E.length]=A[B];E[E.length]="</option>";}E[E.length]="</select>";}return E;},renderYear:function(B){var E=YAHOO.widget.CalendarNavigator,F=E.CLASSES;var G=this.id+E.YEAR_SUFFIX,A=E.YR_MAX_DIGITS,D=B;D[D.length]="<label for=\""+G+"\">";D[D.length]=this.__getCfg("year",true);D[D.length]="</label>";D[D.length]="<input type=\"text\" name=\""+G+"\" id=\""+G+"\" class=\""+F.YEAR_CTRL+"\" maxlength=\""+A+"\"/>";return D;},renderButtons:function(A){var D=YAHOO.widget.CalendarNavigator.CLASSES;var B=A;B[B.length]="<span class=\""+D.BUTTON+" "+D.DEFAULT+"\">";B[B.length]="<button type=\"button\" id=\""+this.id+"_submit\">";B[B.length]=this.__getCfg("submit",true);B[B.length]="</button>";B[B.length]="</span>";B[B.length]="<span class=\""+D.BUTTON+"\">";B[B.length]="<button type=\"button\" id=\""+this.id+"_cancel\">";B[B.length]=this.__getCfg("cancel",true);B[B.length]="</button>";B[B.length]="</span>";return B;},applyListeners:function(){var B=YAHOO.util.Event;functio!
 n A(){if(this.validate()){this.setYear(this._getYearFromUI());}}function C(){this.setMonth(this._getMonthFromUI());}B.on(this.submitEl,"click",this.submit,this,true);B.on(this.cancelEl,"click",this.cancel,this,true);B.on(this.yearEl,"blur",A,this,true);B.on(this.monthEl,"change",C,this,true);if(this.__isIEQuirks){YAHOO.util.Event.on(this.cal.oDomContainer,"resize",this._syncMask,this,true);}this.applyKeyListeners();},purgeListeners:function(){var A=YAHOO.util.Event;A.removeListener(this.submitEl,"click",this.submit);A.removeListener(this.cancelEl,"click",this.cancel);A.removeListener(this.yearEl,"blur");A.removeListener(this.monthEl,"change");if(this.__isIEQuirks){A.removeListener(this.cal.oDomContainer,"resize",this._syncMask);}this.purgeKeyListeners();},applyKeyListeners:function(){var D=YAHOO.util.Event;var A=YAHOO.env.ua;var C=(A.ie)?"keydown":"keypress";var B=(A.ie||A.opera)?"keydown":"keypress";D.on(this.yearEl,"keypress",this._handleEnterKey,this,true);
-D.on(this.yearEl,C,this._handleDirectionKeys,this,true);D.on(this.lastCtrl,B,this._handleTabKey,this,true);D.on(this.firstCtrl,B,this._handleShiftTabKey,this,true);},purgeKeyListeners:function(){var C=YAHOO.util.Event;var B=(YAHOO.env.ua.ie)?"keydown":"keypress";var A=(YAHOO.env.ua.ie||YAHOO.env.ua.opera)?"keydown":"keypress";C.removeListener(this.yearEl,"keypress",this._handleEnterKey);C.removeListener(this.yearEl,B,this._handleDirectionKeys);C.removeListener(this.lastCtrl,A,this._handleTabKey);C.removeListener(this.firstCtrl,A,this._handleShiftTabKey);},submit:function(){if(this.validate()){this.hide();this.setMonth(this._getMonthFromUI());this.setYear(this._getYearFromUI());var B=this.cal;var C=this;function D(){B.setYear(C.getYear());B.setMonth(C.getMonth());B.render();}var A=YAHOO.widget.CalendarNavigator.UPDATE_DELAY;if(A>0){window.setTimeout(D,A);}else{D();}}},cancel:function(){this.hide();},validate:function(){if(this._getYearFromUI()!==null){this.clearErrors();retu!
 rn true;}else{this.setYearError();this.setError(this.__getCfg("invalidYear",true));return false;}},setError:function(A){if(this.errorEl){this.errorEl.innerHTML=A;this._show(this.errorEl,true);}},clearError:function(){if(this.errorEl){this.errorEl.innerHTML="";this._show(this.errorEl,false);}},setYearError:function(){YAHOO.util.Dom.addClass(this.yearEl,YAHOO.widget.CalendarNavigator.CLASSES.INVALID);},clearYearError:function(){YAHOO.util.Dom.removeClass(this.yearEl,YAHOO.widget.CalendarNavigator.CLASSES.INVALID);},clearErrors:function(){this.clearError();this.clearYearError();},setInitialFocus:function(){var A=this.submitEl;var B=this.__getCfg("initialFocus");if(B&&B.toLowerCase){B=B.toLowerCase();if(B=="year"){A=this.yearEl;try{this.yearEl.select();}catch(C){}}else{if(B=="month"){A=this.monthEl;}}}if(A&&YAHOO.lang.isFunction(A.focus)){try{A.focus();}catch(C){}}},erase:function(){if(this.__rendered){this.purgeListeners();this.yearEl=null;this.monthEl=null;this.errorEl=null;t!
 his.submitEl=null;this.cancelEl=null;this.firstCtrl=null;this.!
 lastCtrl
=null;if(this.navEl){this.navEl.innerHTML="";}var B=this.navEl.parentNode;if(B){B.removeChild(this.navEl);}this.navEl=null;var A=this.maskEl.parentNode;if(A){A.removeChild(this.maskEl);}this.maskEl=null;this.__rendered=false;}},destroy:function(){this.erase();this._doc=null;this.cal=null;this.id=null;},_show:function(B,A){if(B){YAHOO.util.Dom.setStyle(B,"display",(A)?"block":"none");}},_getMonthFromUI:function(){if(this.monthEl){return this.monthEl.selectedIndex;}else{return 0;}},_getYearFromUI:function(){var B=YAHOO.widget.CalendarNavigator;var A=null;if(this.yearEl){var C=this.yearEl.value;C=C.replace(B.TRIM,"$1");if(B.YR_PATTERN.test(C)){A=parseInt(C,10);}}return A;},_updateYearUI:function(){if(this.yearEl&&this._year!==null){this.yearEl.value=this._year;}},_updateMonthUI:function(){if(this.monthEl){this.monthEl.selectedIndex=this._month;}},_setFirstLastElements:function(){this.firstCtrl=this.monthEl;this.lastCtrl=this.cancelEl;if(this.__isMac){if(YAHOO.env.ua.webkit&&YAH!
 OO.env.ua.webkit<420){this.firstCtrl=this.monthEl;this.lastCtrl=this.yearEl;}if(YAHOO.env.ua.gecko){this.firstCtrl=this.yearEl;this.lastCtrl=this.yearEl;}}},_handleEnterKey:function(B){var A=YAHOO.util.KeyListener.KEY;if(YAHOO.util.Event.getCharCode(B)==A.ENTER){this.submit();}},_handleDirectionKeys:function(G){var F=YAHOO.util.Event;var A=YAHOO.util.KeyListener.KEY;var C=YAHOO.widget.CalendarNavigator;var D=(this.yearEl.value)?parseInt(this.yearEl.value,10):null;if(isFinite(D)){var B=false;switch(F.getCharCode(G)){case A.UP:this.yearEl.value=D+C.YR_MINOR_INC;B=true;break;case A.DOWN:this.yearEl.value=Math.max(D-C.YR_MINOR_INC,0);B=true;break;case A.PAGE_UP:this.yearEl.value=D+C.YR_MAJOR_INC;B=true;break;case A.PAGE_DOWN:this.yearEl.value=Math.max(D-C.YR_MAJOR_INC,0);B=true;break;default:break;}if(B){F.preventDefault(G);try{this.yearEl.select();}catch(G){}}}},_handleTabKey:function(C){var B=YAHOO.util.Event;var A=YAHOO.util.KeyListener.KEY;if(B.getCharCode(C)==A.TAB&&!C.shi!
 ftKey){try{B.preventDefault(C);this.firstCtrl.focus();}catch(C!
 ){}}},_h
andleShiftTabKey:function(C){var B=YAHOO.util.Event;var A=YAHOO.util.KeyListener.KEY;if(C.shiftKey&&B.getCharCode(C)==A.TAB){try{B.preventDefault(C);this.lastCtrl.focus();}catch(C){}}},__getCfg:function(D,B){var C=YAHOO.widget.CalendarNavigator._DEFAULT_CFG;var A=this.cal.cfg.getProperty("navigator");if(B){return(A!==true&&A.strings&&A.strings[D])?A.strings[D]:C.strings[D];}else{return(A!==true&&A[D])?A[D]:C[D];}},__isMac:(navigator.userAgent.toLowerCase().indexOf("macintosh")!=-1)};YAHOO.register("calendar",YAHOO.widget.Calendar,{version:"2.4.1",build:"742"});
\ No newline at end of file
+(function(){YAHOO.util.Config=function(D){if(D){this.init(D);}};var B=YAHOO.lang,C=YAHOO.util.CustomEvent,A=YAHOO.util.Config;A.CONFIG_CHANGED_EVENT="configChanged";A.BOOLEAN_TYPE="boolean";A.prototype={owner:null,queueInProgress:false,config:null,initialConfig:null,eventQueue:null,configChangedEvent:null,init:function(D){this.owner=D;this.configChangedEvent=this.createEvent(A.CONFIG_CHANGED_EVENT);this.configChangedEvent.signature=C.LIST;this.queueInProgress=false;this.config={};this.initialConfig={};this.eventQueue=[];},checkBoolean:function(D){return(typeof D==A.BOOLEAN_TYPE);},checkNumber:function(D){return(!isNaN(D));},fireEvent:function(D,F){var E=this.config[D];if(E&&E.event){E.event.fire(F);}},addProperty:function(E,D){E=E.toLowerCase();this.config[E]=D;D.event=this.createEvent(E,{scope:this.owner});D.event.signature=C.LIST;D.key=E;if(D.handler){D.event.subscribe(D.handler,this.owner);}this.setProperty(E,D.value,true);if(!D.suppressEvent){this.queueProperty(E,D.valu!
 e);}},getConfig:function(){var D={},F,E;for(F in this.config){E=this.config[F];if(E&&E.event){D[F]=E.value;}}return D;},getProperty:function(D){var E=this.config[D.toLowerCase()];if(E&&E.event){return E.value;}else{return undefined;}},resetProperty:function(D){D=D.toLowerCase();var E=this.config[D];if(E&&E.event){if(this.initialConfig[D]&&!B.isUndefined(this.initialConfig[D])){this.setProperty(D,this.initialConfig[D]);return true;}}else{return false;}},setProperty:function(E,G,D){var F;E=E.toLowerCase();if(this.queueInProgress&&!D){this.queueProperty(E,G);return true;}else{F=this.config[E];if(F&&F.event){if(F.validator&&!F.validator(G)){return false;}else{F.value=G;if(!D){this.fireEvent(E,G);this.configChangedEvent.fire([E,G]);}return true;}}else{return false;}}},queueProperty:function(S,P){S=S.toLowerCase();var R=this.config[S],K=false,J,G,H,I,O,Q,F,M,N,D,L,T,E;if(R&&R.event){if(!B.isUndefined(P)&&R.validator&&!R.validator(P)){return false;}else{if(!B.isUndefined(P)){R.val!
 ue=P;}else{P=R.value;}K=false;J=this.eventQueue.length;for(L=0!
 ;L<J;L++
){G=this.eventQueue[L];if(G){H=G[0];I=G[1];if(H==S){this.eventQueue[L]=null;this.eventQueue.push([S,(!B.isUndefined(P)?P:I)]);K=true;break;}}}if(!K&&!B.isUndefined(P)){this.eventQueue.push([S,P]);}}if(R.supercedes){O=R.supercedes.length;for(T=0;T<O;T++){Q=R.supercedes[T];F=this.eventQueue.length;for(E=0;E<F;E++){M=this.eventQueue[E];if(M){N=M[0];D=M[1];if(N==Q.toLowerCase()){this.eventQueue.push([N,D]);this.eventQueue[E]=null;break;}}}}}return true;}else{return false;}},refireEvent:function(D){D=D.toLowerCase();var E=this.config[D];if(E&&E.event&&!B.isUndefined(E.value)){if(this.queueInProgress){this.queueProperty(D);}else{this.fireEvent(D,E.value);}}},applyConfig:function(D,G){var F,E;if(G){E={};for(F in D){if(B.hasOwnProperty(D,F)){E[F.toLowerCase()]=D[F];}}this.initialConfig=E;}for(F in D){if(B.hasOwnProperty(D,F)){this.queueProperty(F,D[F]);}}},refresh:function(){var D;for(D in this.config){this.refireEvent(D);}},fireQueue:function(){var E,H,D,G,F;this.queueInProgress=tr!
 ue;for(E=0;E<this.eventQueue.length;E++){H=this.eventQueue[E];if(H){D=H[0];G=H[1];F=this.config[D];F.value=G;this.fireEvent(D,G);}}this.queueInProgress=false;this.eventQueue=[];},subscribeToConfigEvent:function(E,F,H,D){var G=this.config[E.toLowerCase()];if(G&&G.event){if(!A.alreadySubscribed(G.event,F,H)){G.event.subscribe(F,H,D);}return true;}else{return false;}},unsubscribeFromConfigEvent:function(D,E,G){var F=this.config[D.toLowerCase()];if(F&&F.event){return F.event.unsubscribe(E,G);}else{return false;}},toString:function(){var D="Config";if(this.owner){D+=" ["+this.owner.toString()+"]";}return D;},outputEventQueue:function(){var D="",G,E,F=this.eventQueue.length;for(E=0;E<F;E++){G=this.eventQueue[E];if(G){D+=G[0]+"="+G[1]+", ";}}return D;},destroy:function(){var E=this.config,D,F;for(D in E){if(B.hasOwnProperty(E,D)){F=E[D];F.event.unsubscribeAll();F.event=null;}}this.configChangedEvent.unsubscribeAll();this.configChangedEvent=null;this.owner=null;this.config=null;thi!
 s.initialConfig=null;this.eventQueue=null;}};A.alreadySubscrib!
 ed=funct
ion(E,H,I){var F=E.subscribers.length,D,G;if(F>0){G=F-1;do{D=E.subscribers[G];if(D&&D.obj==I&&D.fn==H){return true;}}while(G--);}return false;};YAHOO.lang.augmentProto(A,YAHOO.util.EventProvider);}());YAHOO.widget.DateMath={DAY:"D",WEEK:"W",YEAR:"Y",MONTH:"M",ONE_DAY_MS:1000*60*60*24,WEEK_ONE_JAN_DATE:1,add:function(A,D,C){var F=new Date(A.getTime());switch(D){case this.MONTH:var E=A.getMonth()+C;var B=0;if(E<0){while(E<0){E+=12;B-=1;}}else{if(E>11){while(E>11){E-=12;B+=1;}}}F.setMonth(E);F.setFullYear(A.getFullYear()+B);break;case this.DAY:this._addDays(F,C);break;case this.YEAR:F.setFullYear(A.getFullYear()+C);break;case this.WEEK:this._addDays(F,(C*7));break;}return F;},_addDays:function(D,C){if(YAHOO.env.ua.webkit&&YAHOO.env.ua.webkit<420){if(C<0){for(var B=-128;C<B;C-=B){D.setDate(D.getDate()+B);}}else{for(var A=96;C>A;C-=A){D.setDate(D.getDate()+A);}}}D.setDate(D.getDate()+C);},subtract:function(A,C,B){return this.add(A,C,(B*-1));},before:function(C,B){var A=B.getTime(!
 );if(C.getTime()<A){return true;}else{return false;}},after:function(C,B){var A=B.getTime();if(C.getTime()>A){return true;}else{return false;}},between:function(B,A,C){if(this.after(B,A)&&this.before(B,C)){return true;}else{return false;}},getJan1:function(A){return this.getDate(A,0,1);},getDayOffset:function(B,D){var C=this.getJan1(D);var A=Math.ceil((B.getTime()-C.getTime())/this.ONE_DAY_MS);return A;},getWeekNumber:function(E,B,H){B=B||0;H=H||this.WEEK_ONE_JAN_DATE;var I=this.clearTime(E),M,N;if(I.getDay()===B){M=I;}else{M=this.getFirstDayOfWeek(I,B);}var J=M.getFullYear(),C=M.getTime();N=new Date(M.getTime()+6*this.ONE_DAY_MS);var G;if(J!==N.getFullYear()&&N.getDate()>=H){G=1;}else{var F=this.clearTime(this.getDate(J,0,H)),A=this.getFirstDayOfWeek(F,B);var K=Math.round((I.getTime()-A.getTime())/this.ONE_DAY_MS);var L=K%7;var D=(K-L)/7;G=D+1;}return G;},getFirstDayOfWeek:function(D,A){A=A||0;var B=D.getDay(),C=(B-A+7)%7;
+return this.subtract(D,this.DAY,C);},isYearOverlapWeek:function(A){var C=false;var B=this.add(A,this.DAY,6);if(B.getFullYear()!=A.getFullYear()){C=true;}return C;},isMonthOverlapWeek:function(A){var C=false;var B=this.add(A,this.DAY,6);if(B.getMonth()!=A.getMonth()){C=true;}return C;},findMonthStart:function(A){var B=this.getDate(A.getFullYear(),A.getMonth(),1);return B;},findMonthEnd:function(B){var D=this.findMonthStart(B);var C=this.add(D,this.MONTH,1);var A=this.subtract(C,this.DAY,1);return A;},clearTime:function(A){A.setHours(12,0,0,0);return A;},getDate:function(D,A,C){var B=null;if(YAHOO.lang.isUndefined(C)){C=1;}if(D>=100){B=new Date(D,A,C);}else{B=new Date();B.setFullYear(D);B.setMonth(A);B.setDate(C);B.setHours(0,0,0,0);}return B;}};YAHOO.widget.Calendar=function(C,A,B){this.init.apply(this,arguments);};YAHOO.widget.Calendar.IMG_ROOT=null;YAHOO.widget.Calendar.DATE="D";YAHOO.widget.Calendar.MONTH_DAY="MD";YAHOO.widget.Calendar.WEEKDAY="WD";YAHOO.widget.Calendar.R!
 ANGE="R";YAHOO.widget.Calendar.MONTH="M";YAHOO.widget.Calendar.DISPLAY_DAYS=42;YAHOO.widget.Calendar.STOP_RENDER="S";YAHOO.widget.Calendar.SHORT="short";YAHOO.widget.Calendar.LONG="long";YAHOO.widget.Calendar.MEDIUM="medium";YAHOO.widget.Calendar.ONE_CHAR="1char";YAHOO.widget.Calendar._DEFAULT_CONFIG={PAGEDATE:{key:"pagedate",value:null},SELECTED:{key:"selected",value:null},TITLE:{key:"title",value:""},CLOSE:{key:"close",value:false},IFRAME:{key:"iframe",value:(YAHOO.env.ua.ie&&YAHOO.env.ua.ie<=6)?true:false},MINDATE:{key:"mindate",value:null},MAXDATE:{key:"maxdate",value:null},MULTI_SELECT:{key:"multi_select",value:false},START_WEEKDAY:{key:"start_weekday",value:0},SHOW_WEEKDAYS:{key:"show_weekdays",value:true},SHOW_WEEK_HEADER:{key:"show_week_header",value:false},SHOW_WEEK_FOOTER:{key:"show_week_footer",value:false},HIDE_BLANK_WEEKS:{key:"hide_blank_weeks",value:false},NAV_ARROW_LEFT:{key:"nav_arrow_left",value:null},NAV_ARROW_RIGHT:{key:"nav_arrow_right",value:null},MONT!
 HS_SHORT:{key:"months_short",value:["Jan","Feb","Mar","Apr","M!
 ay","Jun
","Jul","Aug","Sep","Oct","Nov","Dec"]},MONTHS_LONG:{key:"months_long",value:["January","February","March","April","May","June","July","August","September","October","November","December"]},WEEKDAYS_1CHAR:{key:"weekdays_1char",value:["S","M","T","W","T","F","S"]},WEEKDAYS_SHORT:{key:"weekdays_short",value:["Su","Mo","Tu","We","Th","Fr","Sa"]},WEEKDAYS_MEDIUM:{key:"weekdays_medium",value:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]},WEEKDAYS_LONG:{key:"weekdays_long",value:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},LOCALE_MONTHS:{key:"locale_months",value:"long"},LOCALE_WEEKDAYS:{key:"locale_weekdays",value:"short"},DATE_DELIMITER:{key:"date_delimiter",value:","},DATE_FIELD_DELIMITER:{key:"date_field_delimiter",value:"/"},DATE_RANGE_DELIMITER:{key:"date_range_delimiter",value:"-"},MY_MONTH_POSITION:{key:"my_month_position",value:1},MY_YEAR_POSITION:{key:"my_year_position",value:2},MD_MONTH_POSITION:{key:"md_month_position",value:1},MD_DAY_POSITIO!
 N:{key:"md_day_position",value:2},MDY_MONTH_POSITION:{key:"mdy_month_position",value:1},MDY_DAY_POSITION:{key:"mdy_day_position",value:2},MDY_YEAR_POSITION:{key:"mdy_year_position",value:3},MY_LABEL_MONTH_POSITION:{key:"my_label_month_position",value:1},MY_LABEL_YEAR_POSITION:{key:"my_label_year_position",value:2},MY_LABEL_MONTH_SUFFIX:{key:"my_label_month_suffix",value:" "},MY_LABEL_YEAR_SUFFIX:{key:"my_label_year_suffix",value:""},NAV:{key:"navigator",value:null}};YAHOO.widget.Calendar._EVENT_TYPES={BEFORE_SELECT:"beforeSelect",SELECT:"select",BEFORE_DESELECT:"beforeDeselect",DESELECT:"deselect",CHANGE_PAGE:"changePage",BEFORE_RENDER:"beforeRender",RENDER:"render",RESET:"reset",CLEAR:"clear",BEFORE_HIDE:"beforeHide",HIDE:"hide",BEFORE_SHOW:"beforeShow",SHOW:"show",BEFORE_HIDE_NAV:"beforeHideNav",HIDE_NAV:"hideNav",BEFORE_SHOW_NAV:"beforeShowNav",SHOW_NAV:"showNav",BEFORE_RENDER_NAV:"beforeRenderNav",RENDER_NAV:"renderNav"};YAHOO.widget.Calendar._STYLES={CSS_ROW_HEADER:"ca!
 lrowhead",CSS_ROW_FOOTER:"calrowfoot",CSS_CELL:"calcell",CSS_C!
 ELL_SELE
CTOR:"selector",CSS_CELL_SELECTED:"selected",CSS_CELL_SELECTABLE:"selectable",CSS_CELL_RESTRICTED:"restricted",CSS_CELL_TODAY:"today",CSS_CELL_OOM:"oom",CSS_CELL_OOB:"previous",CSS_HEADER:"calheader",CSS_HEADER_TEXT:"calhead",CSS_BODY:"calbody",CSS_WEEKDAY_CELL:"calweekdaycell",CSS_WEEKDAY_ROW:"calweekdayrow",CSS_FOOTER:"calfoot",CSS_CALENDAR:"yui-calendar",CSS_SINGLE:"single",CSS_CONTAINER:"yui-calcontainer",CSS_NAV_LEFT:"calnavleft",CSS_NAV_RIGHT:"calnavright",CSS_NAV:"calnav",CSS_CLOSE:"calclose",CSS_CELL_TOP:"calcelltop",CSS_CELL_LEFT:"calcellleft",CSS_CELL_RIGHT:"calcellright",CSS_CELL_BOTTOM:"calcellbottom",CSS_CELL_HOVER:"calcellhover",CSS_CELL_HIGHLIGHT1:"highlight1",CSS_CELL_HIGHLIGHT2:"highlight2",CSS_CELL_HIGHLIGHT3:"highlight3",CSS_CELL_HIGHLIGHT4:"highlight4"};YAHOO.widget.Calendar.prototype={Config:null,parent:null,index:-1,cells:null,cellDates:null,id:null,containerId:null,oDomContainer:null,today:null,renderStack:null,_renderStack:null,oNavigator:null,_select!
 edDates:null,domEventMap:null,_parseArgs:function(B){var A={id:null,container:null,config:null};if(B&&B.length&&B.length>0){switch(B.length){case 1:A.id=null;A.container=B[0];A.config=null;break;case 2:if(YAHOO.lang.isObject(B[1])&&!B[1].tagName&&!(B[1] instanceof String)){A.id=null;A.container=B[0];A.config=B[1];}else{A.id=B[0];A.container=B[1];A.config=null;}break;default:A.id=B[0];A.container=B[1];A.config=B[2];break;}}else{}return A;},init:function(D,B,C){var A=this._parseArgs(arguments);D=A.id;B=A.container;C=A.config;this.oDomContainer=YAHOO.util.Dom.get(B);if(!this.oDomContainer.id){this.oDomContainer.id=YAHOO.util.Dom.generateId();}if(!D){D=this.oDomContainer.id+"_t";}this.id=D;this.containerId=this.oDomContainer.id;this.initEvents();this.today=new Date();YAHOO.widget.DateMath.clearTime(this.today);this.cfg=new YAHOO.util.Config(this);this.Options={};this.Locale={};this.initStyles();YAHOO.util.Dom.addClass(this.oDomContainer,this.Style.CSS_CONTAINER);
+YAHOO.util.Dom.addClass(this.oDomContainer,this.Style.CSS_SINGLE);this.cellDates=[];this.cells=[];this.renderStack=[];this._renderStack=[];this.setupConfig();if(C){this.cfg.applyConfig(C,true);}this.cfg.fireQueue();},configIframe:function(C,B,D){var A=B[0];if(!this.parent){if(YAHOO.util.Dom.inDocument(this.oDomContainer)){if(A){var E=YAHOO.util.Dom.getStyle(this.oDomContainer,"position");if(E=="absolute"||E=="relative"){if(!YAHOO.util.Dom.inDocument(this.iframe)){this.iframe=document.createElement("iframe");this.iframe.src="javascript:false;";YAHOO.util.Dom.setStyle(this.iframe,"opacity","0");if(YAHOO.env.ua.ie&&YAHOO.env.ua.ie<=6){YAHOO.util.Dom.addClass(this.iframe,"fixedsize");}this.oDomContainer.insertBefore(this.iframe,this.oDomContainer.firstChild);}}}else{if(this.iframe){if(this.iframe.parentNode){this.iframe.parentNode.removeChild(this.iframe);}this.iframe=null;}}}}},configTitle:function(B,A,C){var E=A[0];if(E){this.createTitleBar(E);}else{var D=this.cfg.getProperty!
 (YAHOO.widget.Calendar._DEFAULT_CONFIG.CLOSE.key);if(!D){this.removeTitleBar();}else{this.createTitleBar(" ");}}},configClose:function(B,A,C){var E=A[0],D=this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.TITLE.key);if(E){if(!D){this.createTitleBar(" ");}this.createCloseButton();}else{this.removeCloseButton();if(!D){this.removeTitleBar();}}},initEvents:function(){var A=YAHOO.widget.Calendar._EVENT_TYPES;this.beforeSelectEvent=new YAHOO.util.CustomEvent(A.BEFORE_SELECT);this.selectEvent=new YAHOO.util.CustomEvent(A.SELECT);this.beforeDeselectEvent=new YAHOO.util.CustomEvent(A.BEFORE_DESELECT);this.deselectEvent=new YAHOO.util.CustomEvent(A.DESELECT);this.changePageEvent=new YAHOO.util.CustomEvent(A.CHANGE_PAGE);this.beforeRenderEvent=new YAHOO.util.CustomEvent(A.BEFORE_RENDER);this.renderEvent=new YAHOO.util.CustomEvent(A.RENDER);this.resetEvent=new YAHOO.util.CustomEvent(A.RESET);this.clearEvent=new YAHOO.util.CustomEvent(A.CLEAR);this.beforeShowEvent=new!
  YAHOO.util.CustomEvent(A.BEFORE_SHOW);this.showEvent=new YAHO!
 O.util.C
ustomEvent(A.SHOW);this.beforeHideEvent=new YAHOO.util.CustomEvent(A.BEFORE_HIDE);this.hideEvent=new YAHOO.util.CustomEvent(A.HIDE);this.beforeShowNavEvent=new YAHOO.util.CustomEvent(A.BEFORE_SHOW_NAV);this.showNavEvent=new YAHOO.util.CustomEvent(A.SHOW_NAV);this.beforeHideNavEvent=new YAHOO.util.CustomEvent(A.BEFORE_HIDE_NAV);this.hideNavEvent=new YAHOO.util.CustomEvent(A.HIDE_NAV);this.beforeRenderNavEvent=new YAHOO.util.CustomEvent(A.BEFORE_RENDER_NAV);this.renderNavEvent=new YAHOO.util.CustomEvent(A.RENDER_NAV);this.beforeSelectEvent.subscribe(this.onBeforeSelect,this,true);this.selectEvent.subscribe(this.onSelect,this,true);this.beforeDeselectEvent.subscribe(this.onBeforeDeselect,this,true);this.deselectEvent.subscribe(this.onDeselect,this,true);this.changePageEvent.subscribe(this.onChangePage,this,true);this.renderEvent.subscribe(this.onRender,this,true);this.resetEvent.subscribe(this.onReset,this,true);this.clearEvent.subscribe(this.onClear,this,true);},doSelectCell:f!
 unction(G,A){var L,F,I,C;var H=YAHOO.util.Event.getTarget(G);var B=H.tagName.toLowerCase();var E=false;while(B!="td"&&!YAHOO.util.Dom.hasClass(H,A.Style.CSS_CELL_SELECTABLE)){if(!E&&B=="a"&&YAHOO.util.Dom.hasClass(H,A.Style.CSS_CELL_SELECTOR)){E=true;}H=H.parentNode;B=H.tagName.toLowerCase();if(B=="html"){return ;}}if(E){YAHOO.util.Event.preventDefault(G);}L=H;if(YAHOO.util.Dom.hasClass(L,A.Style.CSS_CELL_SELECTABLE)){F=L.id.split("cell")[1];I=A.cellDates[F];C=YAHOO.widget.DateMath.getDate(I[0],I[1]-1,I[2]);var K;if(A.Options.MULTI_SELECT){K=L.getElementsByTagName("a")[0];if(K){K.blur();}var D=A.cellDates[F];var J=A._indexOfSelectedFieldArray(D);if(J>-1){A.deselectCell(F);}else{A.selectCell(F);}}else{K=L.getElementsByTagName("a")[0];if(K){K.blur();}A.selectCell(F);}}},doCellMouseOver:function(C,B){var A;if(C){A=YAHOO.util.Event.getTarget(C);}else{A=this;}while(A.tagName&&A.tagName.toLowerCase()!="td"){A=A.parentNode;if(!A.tagName||A.tagName.toLowerCase()=="html"){return ;}}!
 if(YAHOO.util.Dom.hasClass(A,B.Style.CSS_CELL_SELECTABLE)){YAH!
 OO.util.
Dom.addClass(A,B.Style.CSS_CELL_HOVER);}},doCellMouseOut:function(C,B){var A;if(C){A=YAHOO.util.Event.getTarget(C);}else{A=this;}while(A.tagName&&A.tagName.toLowerCase()!="td"){A=A.parentNode;if(!A.tagName||A.tagName.toLowerCase()=="html"){return ;}}if(YAHOO.util.Dom.hasClass(A,B.Style.CSS_CELL_SELECTABLE)){YAHOO.util.Dom.removeClass(A,B.Style.CSS_CELL_HOVER);}},setupConfig:function(){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;this.cfg.addProperty(A.PAGEDATE.key,{value:new Date(),handler:this.configPageDate});this.cfg.addProperty(A.SELECTED.key,{value:[],handler:this.configSelected});this.cfg.addProperty(A.TITLE.key,{value:A.TITLE.value,handler:this.configTitle});this.cfg.addProperty(A.CLOSE.key,{value:A.CLOSE.value,handler:this.configClose});this.cfg.addProperty(A.IFRAME.key,{value:A.IFRAME.value,handler:this.configIframe,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.MINDATE.key,{value:A.MINDATE.value,handler:this.configMinDate});this.cfg.addProperty(A.MAXDATE.k!
 ey,{value:A.MAXDATE.value,handler:this.configMaxDate});this.cfg.addProperty(A.MULTI_SELECT.key,{value:A.MULTI_SELECT.value,handler:this.configOptions,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.START_WEEKDAY.key,{value:A.START_WEEKDAY.value,handler:this.configOptions,validator:this.cfg.checkNumber});this.cfg.addProperty(A.SHOW_WEEKDAYS.key,{value:A.SHOW_WEEKDAYS.value,handler:this.configOptions,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.SHOW_WEEK_HEADER.key,{value:A.SHOW_WEEK_HEADER.value,handler:this.configOptions,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.SHOW_WEEK_FOOTER.key,{value:A.SHOW_WEEK_FOOTER.value,handler:this.configOptions,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.HIDE_BLANK_WEEKS.key,{value:A.HIDE_BLANK_WEEKS.value,handler:this.configOptions,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.NAV_ARROW_LEFT.key,{value:A.NAV_ARROW_LEFT.value,handler:this.configOptions});
+this.cfg.addProperty(A.NAV_ARROW_RIGHT.key,{value:A.NAV_ARROW_RIGHT.value,handler:this.configOptions});this.cfg.addProperty(A.MONTHS_SHORT.key,{value:A.MONTHS_SHORT.value,handler:this.configLocale});this.cfg.addProperty(A.MONTHS_LONG.key,{value:A.MONTHS_LONG.value,handler:this.configLocale});this.cfg.addProperty(A.WEEKDAYS_1CHAR.key,{value:A.WEEKDAYS_1CHAR.value,handler:this.configLocale});this.cfg.addProperty(A.WEEKDAYS_SHORT.key,{value:A.WEEKDAYS_SHORT.value,handler:this.configLocale});this.cfg.addProperty(A.WEEKDAYS_MEDIUM.key,{value:A.WEEKDAYS_MEDIUM.value,handler:this.configLocale});this.cfg.addProperty(A.WEEKDAYS_LONG.key,{value:A.WEEKDAYS_LONG.value,handler:this.configLocale});var B=function(){this.cfg.refireEvent(A.LOCALE_MONTHS.key);this.cfg.refireEvent(A.LOCALE_WEEKDAYS.key);};this.cfg.subscribeToConfigEvent(A.START_WEEKDAY.key,B,this,true);this.cfg.subscribeToConfigEvent(A.MONTHS_SHORT.key,B,this,true);this.cfg.subscribeToConfigEvent(A.MONTHS_LONG.key,B,this,true!
 );this.cfg.subscribeToConfigEvent(A.WEEKDAYS_1CHAR.key,B,this,true);this.cfg.subscribeToConfigEvent(A.WEEKDAYS_SHORT.key,B,this,true);this.cfg.subscribeToConfigEvent(A.WEEKDAYS_MEDIUM.key,B,this,true);this.cfg.subscribeToConfigEvent(A.WEEKDAYS_LONG.key,B,this,true);this.cfg.addProperty(A.LOCALE_MONTHS.key,{value:A.LOCALE_MONTHS.value,handler:this.configLocaleValues});this.cfg.addProperty(A.LOCALE_WEEKDAYS.key,{value:A.LOCALE_WEEKDAYS.value,handler:this.configLocaleValues});this.cfg.addProperty(A.DATE_DELIMITER.key,{value:A.DATE_DELIMITER.value,handler:this.configLocale});this.cfg.addProperty(A.DATE_FIELD_DELIMITER.key,{value:A.DATE_FIELD_DELIMITER.value,handler:this.configLocale});this.cfg.addProperty(A.DATE_RANGE_DELIMITER.key,{value:A.DATE_RANGE_DELIMITER.value,handler:this.configLocale});this.cfg.addProperty(A.MY_MONTH_POSITION.key,{value:A.MY_MONTH_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MY_YEAR_POSITION.key,{valu!
 e:A.MY_YEAR_POSITION.value,handler:this.configLocale,validator!
 :this.cf
g.checkNumber});this.cfg.addProperty(A.MD_MONTH_POSITION.key,{value:A.MD_MONTH_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MD_DAY_POSITION.key,{value:A.MD_DAY_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MDY_MONTH_POSITION.key,{value:A.MDY_MONTH_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MDY_DAY_POSITION.key,{value:A.MDY_DAY_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MDY_YEAR_POSITION.key,{value:A.MDY_YEAR_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MY_LABEL_MONTH_POSITION.key,{value:A.MY_LABEL_MONTH_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MY_LABEL_YEAR_POSITION.key,{value:A.MY_LABEL_YEAR_POSITION.value,handler:this.configLocale,validator:this.cfg.checkNumbe!
 r});this.cfg.addProperty(A.MY_LABEL_MONTH_SUFFIX.key,{value:A.MY_LABEL_MONTH_SUFFIX.value,handler:this.configLocale});this.cfg.addProperty(A.MY_LABEL_YEAR_SUFFIX.key,{value:A.MY_LABEL_YEAR_SUFFIX.value,handler:this.configLocale});this.cfg.addProperty(A.NAV.key,{value:A.NAV.value,handler:this.configNavigator});},configPageDate:function(B,A,C){this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key,this._parsePageDate(A[0]),true);},configMinDate:function(B,A,C){var D=A[0];if(YAHOO.lang.isString(D)){D=this._parseDate(D);this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MINDATE.key,YAHOO.widget.DateMath.getDate(D[0],(D[1]-1),D[2]));}},configMaxDate:function(B,A,C){var D=A[0];if(YAHOO.lang.isString(D)){D=this._parseDate(D);this.cfg.setProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MAXDATE.key,YAHOO.widget.DateMath.getDate(D[0],(D[1]-1),D[2]));}},configSelected:function(C,A,E){var B=A[0];var D=YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;if(B){if(YA!
 HOO.lang.isString(B)){this.cfg.setProperty(D,this._parseDates(!
 B),true)
;}}if(!this._selectedDates){this._selectedDates=this.cfg.getProperty(D);}},configOptions:function(B,A,C){this.Options[B.toUpperCase()]=A[0];},configLocale:function(C,B,D){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;this.Locale[C.toUpperCase()]=B[0];this.cfg.refireEvent(A.LOCALE_MONTHS.key);this.cfg.refireEvent(A.LOCALE_WEEKDAYS.key);},configLocaleValues:function(D,C,E){var B=YAHOO.widget.Calendar._DEFAULT_CONFIG;D=D.toLowerCase();var G=C[0];switch(D){case B.LOCALE_MONTHS.key:switch(G){case YAHOO.widget.Calendar.SHORT:this.Locale.LOCALE_MONTHS=this.cfg.getProperty(B.MONTHS_SHORT.key).concat();break;case YAHOO.widget.Calendar.LONG:this.Locale.LOCALE_MONTHS=this.cfg.getProperty(B.MONTHS_LONG.key).concat();break;}break;case B.LOCALE_WEEKDAYS.key:switch(G){case YAHOO.widget.Calendar.ONE_CHAR:this.Locale.LOCALE_WEEKDAYS=this.cfg.getProperty(B.WEEKDAYS_1CHAR.key).concat();break;case YAHOO.widget.Calendar.SHORT:this.Locale.LOCALE_WEEKDAYS=this.cfg.getProperty(B.WEEKDAYS_SHORT.key).c!
 oncat();break;case YAHOO.widget.Calendar.MEDIUM:this.Locale.LOCALE_WEEKDAYS=this.cfg.getProperty(B.WEEKDAYS_MEDIUM.key).concat();break;case YAHOO.widget.Calendar.LONG:this.Locale.LOCALE_WEEKDAYS=this.cfg.getProperty(B.WEEKDAYS_LONG.key).concat();break;}var F=this.cfg.getProperty(B.START_WEEKDAY.key);if(F>0){for(var A=0;A<F;++A){this.Locale.LOCALE_WEEKDAYS.push(this.Locale.LOCALE_WEEKDAYS.shift());}}break;}},configNavigator:function(C,A,D){var E=A[0];if(YAHOO.widget.CalendarNavigator&&(E===true||YAHOO.lang.isObject(E))){if(!this.oNavigator){this.oNavigator=new YAHOO.widget.CalendarNavigator(this);function B(){if(!this.pages){this.oNavigator.erase();}}this.beforeRenderEvent.subscribe(B,this,true);}}else{if(this.oNavigator){this.oNavigator.destroy();this.oNavigator=null;}}},initStyles:function(){var A=YAHOO.widget.Calendar._STYLES;this.Style={CSS_ROW_HEADER:A.CSS_ROW_HEADER,CSS_ROW_FOOTER:A.CSS_ROW_FOOTER,CSS_CELL:A.CSS_CELL,CSS_CELL_SELECTOR:A.CSS_CELL_SELECTOR,CSS_CELL_SELEC!
 TED:A.CSS_CELL_SELECTED,CSS_CELL_SELECTABLE:A.CSS_CELL_SELECTA!
 BLE,CSS_
CELL_RESTRICTED:A.CSS_CELL_RESTRICTED,CSS_CELL_TODAY:A.CSS_CELL_TODAY,CSS_CELL_OOM:A.CSS_CELL_OOM,CSS_CELL_OOB:A.CSS_CELL_OOB,CSS_HEADER:A.CSS_HEADER,CSS_HEADER_TEXT:A.CSS_HEADER_TEXT,CSS_BODY:A.CSS_BODY,CSS_WEEKDAY_CELL:A.CSS_WEEKDAY_CELL,CSS_WEEKDAY_ROW:A.CSS_WEEKDAY_ROW,CSS_FOOTER:A.CSS_FOOTER,CSS_CALENDAR:A.CSS_CALENDAR,CSS_SINGLE:A.CSS_SINGLE,CSS_CONTAINER:A.CSS_CONTAINER,CSS_NAV_LEFT:A.CSS_NAV_LEFT,CSS_NAV_RIGHT:A.CSS_NAV_RIGHT,CSS_NAV:A.CSS_NAV,CSS_CLOSE:A.CSS_CLOSE,CSS_CELL_TOP:A.CSS_CELL_TOP,CSS_CELL_LEFT:A.CSS_CELL_LEFT,CSS_CELL_RIGHT:A.CSS_CELL_RIGHT,CSS_CELL_BOTTOM:A.CSS_CELL_BOTTOM,CSS_CELL_HOVER:A.CSS_CELL_HOVER,CSS_CELL_HIGHLIGHT1:A.CSS_CELL_HIGHLIGHT1,CSS_CELL_HIGHLIGHT2:A.CSS_CELL_HIGHLIGHT2,CSS_CELL_HIGHLIGHT3:A.CSS_CELL_HIGHLIGHT3,CSS_CELL_HIGHLIGHT4:A.CSS_CELL_HIGHLIGHT4};
+},buildMonthLabel:function(){var A=this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key);var C=this.Locale.LOCALE_MONTHS[A.getMonth()]+this.Locale.MY_LABEL_MONTH_SUFFIX;var B=A.getFullYear()+this.Locale.MY_LABEL_YEAR_SUFFIX;if(this.Locale.MY_LABEL_MONTH_POSITION==2||this.Locale.MY_LABEL_YEAR_POSITION==1){return B+C;}else{return C+B;}},buildDayLabel:function(A){return A.getDate();},createTitleBar:function(A){var B=YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE,"div",this.oDomContainer)[0]||document.createElement("div");B.className=YAHOO.widget.CalendarGroup.CSS_2UPTITLE;B.innerHTML=A;this.oDomContainer.insertBefore(B,this.oDomContainer.firstChild);YAHOO.util.Dom.addClass(this.oDomContainer,"withtitle");return B;},removeTitleBar:function(){var A=YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE,"div",this.oDomContainer)[0]||null;if(A){YAHOO.util.Event.purgeElement(A);this.oDomContainer.removeChild(A!
 );}YAHOO.util.Dom.removeClass(this.oDomContainer,"withtitle");},createCloseButton:function(){var D=YAHOO.util.Dom,A=YAHOO.util.Event,C=YAHOO.widget.CalendarGroup.CSS_2UPCLOSE,F="us/my/bn/x_d.gif";var E=D.getElementsByClassName("link-close","a",this.oDomContainer)[0];if(!E){E=document.createElement("a");A.addListener(E,"click",function(H,G){G.hide();A.preventDefault(H);},this);}E.href="#";E.className="link-close";if(YAHOO.widget.Calendar.IMG_ROOT!==null){var B=D.getElementsByClassName(C,"img",E)[0]||document.createElement("img");B.src=YAHOO.widget.Calendar.IMG_ROOT+F;B.className=C;E.appendChild(B);}else{E.innerHTML='<span class="'+C+" "+this.Style.CSS_CLOSE+'"></span>';}this.oDomContainer.appendChild(E);return E;},removeCloseButton:function(){var A=YAHOO.util.Dom.getElementsByClassName("link-close","a",this.oDomContainer)[0]||null;if(A){YAHOO.util.Event.purgeElement(A);this.oDomContainer.removeChild(A);}},renderHeader:function(E){var H=7;var F="us/tr/callt.gif";var G="us/tr/!
 calrt.gif";var M=YAHOO.widget.Calendar._DEFAULT_CONFIG;if(this!
 .cfg.get
Property(M.SHOW_WEEK_HEADER.key)){H+=1;}if(this.cfg.getProperty(M.SHOW_WEEK_FOOTER.key)){H+=1;}E[E.length]="<thead>";E[E.length]="<tr>";E[E.length]='<th colspan="'+H+'" class="'+this.Style.CSS_HEADER_TEXT+'">';E[E.length]='<div class="'+this.Style.CSS_HEADER+'">';var K,L=false;if(this.parent){if(this.index===0){K=true;}if(this.index==(this.parent.cfg.getProperty("pages")-1)){L=true;}}else{K=true;L=true;}if(K){var A=this.cfg.getProperty(M.NAV_ARROW_LEFT.key);if(A===null&&YAHOO.widget.Calendar.IMG_ROOT!==null){A=YAHOO.widget.Calendar.IMG_ROOT+F;}var C=(A===null)?"":' style="background-image:url('+A+')"';E[E.length]='<a class="'+this.Style.CSS_NAV_LEFT+'"'+C+" > </a>";}var J=this.buildMonthLabel();var B=this.parent||this;if(B.cfg.getProperty("navigator")){J='<a class="'+this.Style.CSS_NAV+'" href="#">'+J+"</a>";}E[E.length]=J;if(L){var D=this.cfg.getProperty(M.NAV_ARROW_RIGHT.key);if(D===null&&YAHOO.widget.Calendar.IMG_ROOT!==null){D=YAHOO.widget.Calendar.IMG_ROOT+G;}var I!
 =(D===null)?"":' style="background-image:url('+D+')"';E[E.length]='<a class="'+this.Style.CSS_NAV_RIGHT+'"'+I+" > </a>";}E[E.length]="</div>\n</th>\n</tr>";if(this.cfg.getProperty(M.SHOW_WEEKDAYS.key)){E=this.buildWeekdays(E);}E[E.length]="</thead>";return E;},buildWeekdays:function(C){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;C[C.length]='<tr class="'+this.Style.CSS_WEEKDAY_ROW+'">';if(this.cfg.getProperty(A.SHOW_WEEK_HEADER.key)){C[C.length]="<th> </th>";}for(var B=0;B<this.Locale.LOCALE_WEEKDAYS.length;++B){C[C.length]='<th class="calweekdaycell">'+this.Locale.LOCALE_WEEKDAYS[B]+"</th>";}if(this.cfg.getProperty(A.SHOW_WEEK_FOOTER.key)){C[C.length]="<th> </th>";}C[C.length]="</tr>";return C;},renderBody:function(g,e){var AF=YAHOO.widget.DateMath,M=YAHOO.widget.Calendar,Q=YAHOO.util.Dom,q=M._DEFAULT_CONFIG;var AE=this.cfg.getProperty(q.START_WEEKDAY.key);this.preMonthDays=g.getDay();if(AE>0){this.preMonthDays-=AE;}if(this.preMonthDays<0){this.preMonthDays+!
 =7;}this.monthDays=AF.findMonthEnd(g).getDate();this.postMonth!
 Days=M.D
ISPLAY_DAYS-this.preMonthDays-this.monthDays;g=AF.subtract(g,AF.DAY,this.preMonthDays);var T,I,H="w",Z="_cell",X="wd",n="d",J,l,R=this.today.getFullYear(),m=this.today.getMonth(),E=this.today.getDate(),v=this.cfg.getProperty(q.PAGEDATE.key),C=this.cfg.getProperty(q.HIDE_BLANK_WEEKS.key),c=this.cfg.getProperty(q.SHOW_WEEK_FOOTER.key),W=this.cfg.getProperty(q.SHOW_WEEK_HEADER.key),O=this.cfg.getProperty(q.MINDATE.key),V=this.cfg.getProperty(q.MAXDATE.key);if(O){O=AF.clearTime(O);}if(V){V=AF.clearTime(V);}e[e.length]='<tbody class="m'+(v.getMonth()+1)+" "+this.Style.CSS_BODY+'">';var AC=0,K=document.createElement("div"),f=document.createElement("td");K.appendChild(f);var u=this.parent||this;for(var y=0;y<6;y++){T=AF.getWeekNumber(g,AE);I=H+T;if(y!==0&&C===true&&g.getMonth()!=v.getMonth()){break;}else{e[e.length]='<tr class="'+I+'">';if(W){e=this.renderRowHeader(T,e);}for(var AD=0;AD<7;AD++){J=[];this.clearElement(f);f.className=this.Style.CSS_CELL;f.id=this.id+Z+AC;if(g.getDate!
 ()==E&&g.getMonth()==m&&g.getFullYear()==R){J[J.length]=u.renderCellStyleToday;}var U=[g.getFullYear(),g.getMonth()+1,g.getDate()];this.cellDates[this.cellDates.length]=U;if(g.getMonth()!=v.getMonth()){J[J.length]=u.renderCellNotThisMonth;}else{Q.addClass(f,X+g.getDay());Q.addClass(f,n+g.getDate());for(var w=0;w<this.renderStack.length;++w){l=null;var o=this.renderStack[w],AG=o[0],B,Y,G;switch(AG){case M.DATE:B=o[1][1];Y=o[1][2];G=o[1][0];if(g.getMonth()+1==B&&g.getDate()==Y&&g.getFullYear()==G){l=o[2];this.renderStack.splice(w,1);}break;case M.MONTH_DAY:B=o[1][0];Y=o[1][1];if(g.getMonth()+1==B&&g.getDate()==Y){l=o[2];this.renderStack.splice(w,1);}break;case M.RANGE:var b=o[1][0],a=o[1][1],h=b[1],N=b[2],S=b[0],AB=AF.getDate(S,h-1,N),F=a[1],k=a[2],A=a[0],AA=AF.getDate(A,F-1,k);if(g.getTime()>=AB.getTime()&&g.getTime()<=AA.getTime()){l=o[2];if(g.getTime()==AA.getTime()){this.renderStack.splice(w,1);}}break;case M.WEEKDAY:var L=o[1][0];
+if(g.getDay()+1==L){l=o[2];}break;case M.MONTH:B=o[1][0];if(g.getMonth()+1==B){l=o[2];}break;}if(l){J[J.length]=l;}}}if(this._indexOfSelectedFieldArray(U)>-1){J[J.length]=u.renderCellStyleSelected;}if((O&&(g.getTime()<O.getTime()))||(V&&(g.getTime()>V.getTime()))){J[J.length]=u.renderOutOfBoundsDate;}else{J[J.length]=u.styleCellDefault;J[J.length]=u.renderCellDefault;}for(var t=0;t<J.length;++t){if(J[t].call(u,g,f)==M.STOP_RENDER){break;}}g.setTime(g.getTime()+AF.ONE_DAY_MS);g=AF.clearTime(g);if(AC>=0&&AC<=6){Q.addClass(f,this.Style.CSS_CELL_TOP);}if((AC%7)===0){Q.addClass(f,this.Style.CSS_CELL_LEFT);}if(((AC+1)%7)===0){Q.addClass(f,this.Style.CSS_CELL_RIGHT);}var j=this.postMonthDays;if(C&&j>=7){var P=Math.floor(j/7);for(var z=0;z<P;++z){j-=7;}}if(AC>=((this.preMonthDays+j+this.monthDays)-7)){Q.addClass(f,this.Style.CSS_CELL_BOTTOM);}e[e.length]=K.innerHTML;AC++;}if(c){e=this.renderRowFooter(T,e);}e[e.length]="</tr>";}}e[e.length]="</tbody>";return e;},renderFooter:functio!
 n(A){return A;},render:function(){this.beforeRenderEvent.fire();var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;var C=YAHOO.widget.DateMath.findMonthStart(this.cfg.getProperty(A.PAGEDATE.key));this.resetRenderers();this.cellDates.length=0;YAHOO.util.Event.purgeElement(this.oDomContainer,true);var B=[];B[B.length]='<table cellSpacing="0" class="'+this.Style.CSS_CALENDAR+" y"+C.getFullYear()+'" id="'+this.id+'">';B=this.renderHeader(B);B=this.renderBody(C,B);B=this.renderFooter(B);B[B.length]="</table>";this.oDomContainer.innerHTML=B.join("\n");this.applyListeners();this.cells=this.oDomContainer.getElementsByTagName("td");this.cfg.refireEvent(A.TITLE.key);this.cfg.refireEvent(A.CLOSE.key);this.cfg.refireEvent(A.IFRAME.key);this.renderEvent.fire();},applyListeners:function(){var K=this.oDomContainer;var B=this.parent||this;var G="a";var D="mousedown";var H=YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_NAV_LEFT,G,K);var C=YAHOO.util.Dom.getElementsByClassName(this.Style.CSS_!
 NAV_RIGHT,G,K);if(H&&H.length>0){this.linkLeft=H[0];YAHOO.util!
 .Event.a
ddListener(this.linkLeft,D,B.previousMonth,B,true);}if(C&&C.length>0){this.linkRight=C[0];YAHOO.util.Event.addListener(this.linkRight,D,B.nextMonth,B,true);}if(B.cfg.getProperty("navigator")!==null){this.applyNavListeners();}if(this.domEventMap){var E,A;for(var M in this.domEventMap){if(YAHOO.lang.hasOwnProperty(this.domEventMap,M)){var I=this.domEventMap[M];if(!(I instanceof Array)){I=[I];}for(var F=0;F<I.length;F++){var L=I[F];A=YAHOO.util.Dom.getElementsByClassName(M,L.tag,this.oDomContainer);for(var J=0;J<A.length;J++){E=A[J];YAHOO.util.Event.addListener(E,L.event,L.handler,L.scope,L.correct);}}}}}YAHOO.util.Event.addListener(this.oDomContainer,"click",this.doSelectCell,this);YAHOO.util.Event.addListener(this.oDomContainer,"mouseover",this.doCellMouseOver,this);YAHOO.util.Event.addListener(this.oDomContainer,"mouseout",this.doCellMouseOut,this);},applyNavListeners:function(){var D=YAHOO.util.Event;var C=this.parent||this;var F=this;var B=YAHOO.util.Dom.getElementsByClass!
 Name(this.Style.CSS_NAV,"a",this.oDomContainer);if(B.length>0){function A(J,I){var H=D.getTarget(J);if(this===H||YAHOO.util.Dom.isAncestor(this,H)){D.preventDefault(J);}var E=C.oNavigator;if(E){var G=F.cfg.getProperty("pagedate");E.setYear(G.getFullYear());E.setMonth(G.getMonth());E.show();}}D.addListener(B,"click",A);}},getDateByCellId:function(B){var A=this.getDateFieldsByCellId(B);return YAHOO.widget.DateMath.getDate(A[0],A[1]-1,A[2]);},getDateFieldsByCellId:function(A){A=A.toLowerCase().split("_cell")[1];A=parseInt(A,10);return this.cellDates[A];},getCellIndex:function(C){var B=-1;if(C){var A=C.getMonth(),H=C.getFullYear(),G=C.getDate(),E=this.cellDates;for(var D=0;D<E.length;++D){var F=E[D];if(F[0]===H&&F[1]===A+1&&F[2]===G){B=D;break;}}}return B;},renderOutOfBoundsDate:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_OOB);A.innerHTML=B.getDate();return YAHOO.widget.Calendar.STOP_RENDER;},renderRowHeader:function(B,A){A[A.length]='<th class="calrowhead">'+B+!
 "</th>";return A;},renderRowFooter:function(B,A){A[A.length]='!
 <th clas
s="calrowfoot">'+B+"</th>";return A;},renderCellDefault:function(B,A){A.innerHTML='<a href="#" class="'+this.Style.CSS_CELL_SELECTOR+'">'+this.buildDayLabel(B)+"</a>";},styleCellDefault:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_SELECTABLE);},renderCellStyleHighlight1:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_HIGHLIGHT1);},renderCellStyleHighlight2:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_HIGHLIGHT2);},renderCellStyleHighlight3:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_HIGHLIGHT3);},renderCellStyleHighlight4:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_HIGHLIGHT4);},renderCellStyleToday:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_TODAY);},renderCellStyleSelected:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_SELECTED);},renderCellNotThisMonth:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_OOM);A.innerHTML=B.getDate();return YAHOO.widget.Calendar.ST!
 OP_RENDER;},renderBodyCellRestricted:function(B,A){YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL);YAHOO.util.Dom.addClass(A,this.Style.CSS_CELL_RESTRICTED);A.innerHTML=B.getDate();return YAHOO.widget.Calendar.STOP_RENDER;},addMonths:function(B){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;this.cfg.setProperty(A,YAHOO.widget.DateMath.add(this.cfg.getProperty(A),YAHOO.widget.DateMath.MONTH,B));this.resetRenderers();this.changePageEvent.fire();},subtractMonths:function(B){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;this.cfg.setProperty(A,YAHOO.widget.DateMath.subtract(this.cfg.getProperty(A),YAHOO.widget.DateMath.MONTH,B));this.resetRenderers();this.changePageEvent.fire();},addYears:function(B){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;this.cfg.setProperty(A,YAHOO.widget.DateMath.add(this.cfg.getProperty(A),YAHOO.widget.DateMath.YEAR,B));this.resetRenderers();this.changePageEvent.fire();
+},subtractYears:function(B){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;this.cfg.setProperty(A,YAHOO.widget.DateMath.subtract(this.cfg.getProperty(A),YAHOO.widget.DateMath.YEAR,B));this.resetRenderers();this.changePageEvent.fire();},nextMonth:function(){this.addMonths(1);},previousMonth:function(){this.subtractMonths(1);},nextYear:function(){this.addYears(1);},previousYear:function(){this.subtractYears(1);},reset:function(){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;this.cfg.resetProperty(A.SELECTED.key);this.cfg.resetProperty(A.PAGEDATE.key);this.resetEvent.fire();},clear:function(){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;this.cfg.setProperty(A.SELECTED.key,[]);this.cfg.setProperty(A.PAGEDATE.key,new Date(this.today.getTime()));this.clearEvent.fire();},select:function(C){var F=this._toFieldArray(C);var B=[];var E=[];var G=YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;for(var A=0;A<F.length;++A){var D=F[A];if(!this.isDateOOB(this._toDate(D))){if(B.len!
 gth===0){this.beforeSelectEvent.fire();E=this.cfg.getProperty(G);}B.push(D);if(this._indexOfSelectedFieldArray(D)==-1){E[E.length]=D;}}}if(B.length>0){if(this.parent){this.parent.cfg.setProperty(G,E);}else{this.cfg.setProperty(G,E);}this.selectEvent.fire(B);}return this.getSelectedDates();},selectCell:function(D){var B=this.cells[D];var H=this.cellDates[D];var G=this._toDate(H);var C=YAHOO.util.Dom.hasClass(B,this.Style.CSS_CELL_SELECTABLE);if(C){this.beforeSelectEvent.fire();var F=YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;var E=this.cfg.getProperty(F);var A=H.concat();if(this._indexOfSelectedFieldArray(A)==-1){E[E.length]=A;}if(this.parent){this.parent.cfg.setProperty(F,E);}else{this.cfg.setProperty(F,E);}this.renderCellStyleSelected(G,B);this.selectEvent.fire([A]);this.doCellMouseOut.call(B,null,this);}return this.getSelectedDates();},deselect:function(E){var A=this._toFieldArray(E);var D=[];var G=[];var H=YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;for(va!
 r B=0;B<A.length;++B){var F=A[B];if(!this.isDateOOB(this._toDa!
 te(F))){
if(D.length===0){this.beforeDeselectEvent.fire();G=this.cfg.getProperty(H);}D.push(F);var C=this._indexOfSelectedFieldArray(F);if(C!=-1){G.splice(C,1);}}}if(D.length>0){if(this.parent){this.parent.cfg.setProperty(H,G);}else{this.cfg.setProperty(H,G);}this.deselectEvent.fire(D);}return this.getSelectedDates();},deselectCell:function(E){var H=this.cells[E];var B=this.cellDates[E];var F=this._indexOfSelectedFieldArray(B);var G=YAHOO.util.Dom.hasClass(H,this.Style.CSS_CELL_SELECTABLE);if(G){this.beforeDeselectEvent.fire();var I=YAHOO.widget.Calendar._DEFAULT_CONFIG;var D=this.cfg.getProperty(I.SELECTED.key);var C=this._toDate(B);var A=B.concat();if(F>-1){if(this.cfg.getProperty(I.PAGEDATE.key).getMonth()==C.getMonth()&&this.cfg.getProperty(I.PAGEDATE.key).getFullYear()==C.getFullYear()){YAHOO.util.Dom.removeClass(H,this.Style.CSS_CELL_SELECTED);}D.splice(F,1);}if(this.parent){this.parent.cfg.setProperty(I.SELECTED.key,D);}else{this.cfg.setProperty(I.SELECTED.key,D);}this.deselec!
 tEvent.fire(A);}return this.getSelectedDates();},deselectAll:function(){this.beforeDeselectEvent.fire();var D=YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key;var A=this.cfg.getProperty(D);var B=A.length;var C=A.concat();if(this.parent){this.parent.cfg.setProperty(D,[]);}else{this.cfg.setProperty(D,[]);}if(B>0){this.deselectEvent.fire(C);}return this.getSelectedDates();},_toFieldArray:function(B){var A=[];if(B instanceof Date){A=[[B.getFullYear(),B.getMonth()+1,B.getDate()]];}else{if(YAHOO.lang.isString(B)){A=this._parseDates(B);}else{if(YAHOO.lang.isArray(B)){for(var C=0;C<B.length;++C){var D=B[C];A[A.length]=[D.getFullYear(),D.getMonth()+1,D.getDate()];}}}}return A;},toDate:function(A){return this._toDate(A);},_toDate:function(A){if(A instanceof Date){return A;}else{return YAHOO.widget.DateMath.getDate(A[0],A[1]-1,A[2]);}},_fieldArraysAreEqual:function(C,B){var A=false;if(C[0]==B[0]&&C[1]==B[1]&&C[2]==B[2]){A=true;}return A;},_indexOfSelectedFieldArray:function(E){var D!
 =-1;var A=this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_!
 CONFIG.S
ELECTED.key);for(var C=0;C<A.length;++C){var B=A[C];if(E[0]==B[0]&&E[1]==B[1]&&E[2]==B[2]){D=C;break;}}return D;},isDateOOM:function(A){return(A.getMonth()!=this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key).getMonth());},isDateOOB:function(D){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;var E=this.cfg.getProperty(A.MINDATE.key);var F=this.cfg.getProperty(A.MAXDATE.key);var C=YAHOO.widget.DateMath;if(E){E=C.clearTime(E);}if(F){F=C.clearTime(F);}var B=new Date(D.getTime());B=C.clearTime(B);return((E&&B.getTime()<E.getTime())||(F&&B.getTime()>F.getTime()));},_parsePageDate:function(B){var E;var A=YAHOO.widget.Calendar._DEFAULT_CONFIG;if(B){if(B instanceof Date){E=YAHOO.widget.DateMath.findMonthStart(B);}else{var F,D,C;C=B.split(this.cfg.getProperty(A.DATE_FIELD_DELIMITER.key));F=parseInt(C[this.cfg.getProperty(A.MY_MONTH_POSITION.key)-1],10)-1;D=parseInt(C[this.cfg.getProperty(A.MY_YEAR_POSITION.key)-1],10);E=YAHOO.widget.DateMath.getDate(D,F,1);}}else{E=Y!
 AHOO.widget.DateMath.getDate(this.today.getFullYear(),this.today.getMonth(),1);}return E;},onBeforeSelect:function(){if(this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.MULTI_SELECT.key)===false){if(this.parent){this.parent.callChildFunction("clearAllBodyCellStyles",this.Style.CSS_CELL_SELECTED);this.parent.deselectAll();}else{this.clearAllBodyCellStyles(this.Style.CSS_CELL_SELECTED);this.deselectAll();}}},onSelect:function(A){},onBeforeDeselect:function(){},onDeselect:function(A){},onChangePage:function(){this.render();},onRender:function(){},onReset:function(){this.render();},onClear:function(){this.render();},validate:function(){return true;},_parseDate:function(C){var D=C.split(this.Locale.DATE_FIELD_DELIMITER);var A;if(D.length==2){A=[D[this.Locale.MD_MONTH_POSITION-1],D[this.Locale.MD_DAY_POSITION-1]];A.type=YAHOO.widget.Calendar.MONTH_DAY;}else{A=[D[this.Locale.MDY_YEAR_POSITION-1],D[this.Locale.MDY_MONTH_POSITION-1],D[this.Locale.MDY_DAY_POSITION-1]];
+A.type=YAHOO.widget.Calendar.DATE;}for(var B=0;B<A.length;B++){A[B]=parseInt(A[B],10);}return A;},_parseDates:function(B){var I=[];var H=B.split(this.Locale.DATE_DELIMITER);for(var G=0;G<H.length;++G){var F=H[G];if(F.indexOf(this.Locale.DATE_RANGE_DELIMITER)!=-1){var A=F.split(this.Locale.DATE_RANGE_DELIMITER);var E=this._parseDate(A[0]);var J=this._parseDate(A[1]);var D=this._parseRange(E,J);I=I.concat(D);}else{var C=this._parseDate(F);I.push(C);}}return I;},_parseRange:function(A,E){var B=YAHOO.widget.DateMath.add(YAHOO.widget.DateMath.getDate(A[0],A[1]-1,A[2]),YAHOO.widget.DateMath.DAY,1);var D=YAHOO.widget.DateMath.getDate(E[0],E[1]-1,E[2]);var C=[];C.push(A);while(B.getTime()<=D.getTime()){C.push([B.getFullYear(),B.getMonth()+1,B.getDate()]);B=YAHOO.widget.DateMath.add(B,YAHOO.widget.DateMath.DAY,1);}return C;},resetRenderers:function(){this.renderStack=this._renderStack.concat();},removeRenderers:function(){this._renderStack=[];this.renderStack=[];},clearElement:funct!
 ion(A){A.innerHTML=" ";A.className="";},addRenderer:function(A,B){var D=this._parseDates(A);for(var C=0;C<D.length;++C){var E=D[C];if(E.length==2){if(E[0] instanceof Array){this._addRenderer(YAHOO.widget.Calendar.RANGE,E,B);}else{this._addRenderer(YAHOO.widget.Calendar.MONTH_DAY,E,B);}}else{if(E.length==3){this._addRenderer(YAHOO.widget.Calendar.DATE,E,B);}}}},_addRenderer:function(B,C,A){var D=[B,C,A];this.renderStack.unshift(D);this._renderStack=this.renderStack.concat();},addMonthRenderer:function(B,A){this._addRenderer(YAHOO.widget.Calendar.MONTH,[B],A);},addWeekdayRenderer:function(B,A){this._addRenderer(YAHOO.widget.Calendar.WEEKDAY,[B],A);},clearAllBodyCellStyles:function(A){for(var B=0;B<this.cells.length;++B){YAHOO.util.Dom.removeClass(this.cells[B],A);}},setMonth:function(C){var A=YAHOO.widget.Calendar._DEFAULT_CONFIG.PAGEDATE.key;var B=this.cfg.getProperty(A);B.setMonth(parseInt(C,10));this.cfg.setProperty(A,B);},setYear:function(B){var A=YAHOO.widget.Calend!
 ar._DEFAULT_CONFIG.PAGEDATE.key;var C=this.cfg.getProperty(A);!
 C.setFul
lYear(parseInt(B,10));this.cfg.setProperty(A,C);},getSelectedDates:function(){var C=[];var B=this.cfg.getProperty(YAHOO.widget.Calendar._DEFAULT_CONFIG.SELECTED.key);for(var E=0;E<B.length;++E){var D=B[E];var A=YAHOO.widget.DateMath.getDate(D[0],D[1]-1,D[2]);C.push(A);}C.sort(function(G,F){return G-F;});return C;},hide:function(){if(this.beforeHideEvent.fire()){this.oDomContainer.style.display="none";this.hideEvent.fire();}},show:function(){if(this.beforeShowEvent.fire()){this.oDomContainer.style.display="block";this.showEvent.fire();}},browser:(function(){var A=navigator.userAgent.toLowerCase();if(A.indexOf("opera")!=-1){return"opera";}else{if(A.indexOf("msie 7")!=-1){return"ie7";}else{if(A.indexOf("msie")!=-1){return"ie";}else{if(A.indexOf("safari")!=-1){return"safari";}else{if(A.indexOf("gecko")!=-1){return"gecko";}else{return false;}}}}}})(),toString:function(){return"Calendar "+this.id;}};YAHOO.widget.Calendar_Core=YAHOO.widget.Calendar;YAHOO.widget.Cal_Core=YAHOO.widge!
 t.Calendar;YAHOO.widget.CalendarGroup=function(C,A,B){if(arguments.length>0){this.init.apply(this,arguments);}};YAHOO.widget.CalendarGroup.prototype={init:function(D,B,C){var A=this._parseArgs(arguments);D=A.id;B=A.container;C=A.config;this.oDomContainer=YAHOO.util.Dom.get(B);if(!this.oDomContainer.id){this.oDomContainer.id=YAHOO.util.Dom.generateId();}if(!D){D=this.oDomContainer.id+"_t";}this.id=D;this.containerId=this.oDomContainer.id;this.initEvents();this.initStyles();this.pages=[];YAHOO.util.Dom.addClass(this.oDomContainer,YAHOO.widget.CalendarGroup.CSS_CONTAINER);YAHOO.util.Dom.addClass(this.oDomContainer,YAHOO.widget.CalendarGroup.CSS_MULTI_UP);this.cfg=new YAHOO.util.Config(this);this.Options={};this.Locale={};this.setupConfig();if(C){this.cfg.applyConfig(C,true);}this.cfg.fireQueue();if(YAHOO.env.ua.opera){this.renderEvent.subscribe(this._fixWidth,this,true);this.showEvent.subscribe(this._fixWidth,this,true);}},setupConfig:function(){var A=YAHOO.widget.CalendarGrou!
 p._DEFAULT_CONFIG;this.cfg.addProperty(A.PAGES.key,{value:A.PA!
 GES.valu
e,validator:this.cfg.checkNumber,handler:this.configPages});this.cfg.addProperty(A.PAGEDATE.key,{value:new Date(),handler:this.configPageDate});this.cfg.addProperty(A.SELECTED.key,{value:[],handler:this.configSelected});this.cfg.addProperty(A.TITLE.key,{value:A.TITLE.value,handler:this.configTitle});this.cfg.addProperty(A.CLOSE.key,{value:A.CLOSE.value,handler:this.configClose});this.cfg.addProperty(A.IFRAME.key,{value:A.IFRAME.value,handler:this.configIframe,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.MINDATE.key,{value:A.MINDATE.value,handler:this.delegateConfig});this.cfg.addProperty(A.MAXDATE.key,{value:A.MAXDATE.value,handler:this.delegateConfig});this.cfg.addProperty(A.MULTI_SELECT.key,{value:A.MULTI_SELECT.value,handler:this.delegateConfig,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.START_WEEKDAY.key,{value:A.START_WEEKDAY.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.SHOW_WEEKDAYS.key,{value:A.SHOW!
 _WEEKDAYS.value,handler:this.delegateConfig,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.SHOW_WEEK_HEADER.key,{value:A.SHOW_WEEK_HEADER.value,handler:this.delegateConfig,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.SHOW_WEEK_FOOTER.key,{value:A.SHOW_WEEK_FOOTER.value,handler:this.delegateConfig,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.HIDE_BLANK_WEEKS.key,{value:A.HIDE_BLANK_WEEKS.value,handler:this.delegateConfig,validator:this.cfg.checkBoolean});this.cfg.addProperty(A.NAV_ARROW_LEFT.key,{value:A.NAV_ARROW_LEFT.value,handler:this.delegateConfig});this.cfg.addProperty(A.NAV_ARROW_RIGHT.key,{value:A.NAV_ARROW_RIGHT.value,handler:this.delegateConfig});this.cfg.addProperty(A.MONTHS_SHORT.key,{value:A.MONTHS_SHORT.value,handler:this.delegateConfig});this.cfg.addProperty(A.MONTHS_LONG.key,{value:A.MONTHS_LONG.value,handler:this.delegateConfig});this.cfg.addProperty(A.WEEKDAYS_1CHAR.key,{value:A.WEEKDAYS_1CHAR.value,handler:this.delegateCon!
 fig});
+this.cfg.addProperty(A.WEEKDAYS_SHORT.key,{value:A.WEEKDAYS_SHORT.value,handler:this.delegateConfig});this.cfg.addProperty(A.WEEKDAYS_MEDIUM.key,{value:A.WEEKDAYS_MEDIUM.value,handler:this.delegateConfig});this.cfg.addProperty(A.WEEKDAYS_LONG.key,{value:A.WEEKDAYS_LONG.value,handler:this.delegateConfig});this.cfg.addProperty(A.LOCALE_MONTHS.key,{value:A.LOCALE_MONTHS.value,handler:this.delegateConfig});this.cfg.addProperty(A.LOCALE_WEEKDAYS.key,{value:A.LOCALE_WEEKDAYS.value,handler:this.delegateConfig});this.cfg.addProperty(A.DATE_DELIMITER.key,{value:A.DATE_DELIMITER.value,handler:this.delegateConfig});this.cfg.addProperty(A.DATE_FIELD_DELIMITER.key,{value:A.DATE_FIELD_DELIMITER.value,handler:this.delegateConfig});this.cfg.addProperty(A.DATE_RANGE_DELIMITER.key,{value:A.DATE_RANGE_DELIMITER.value,handler:this.delegateConfig});this.cfg.addProperty(A.MY_MONTH_POSITION.key,{value:A.MY_MONTH_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.!
 addProperty(A.MY_YEAR_POSITION.key,{value:A.MY_YEAR_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MD_MONTH_POSITION.key,{value:A.MD_MONTH_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MD_DAY_POSITION.key,{value:A.MD_DAY_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MDY_MONTH_POSITION.key,{value:A.MDY_MONTH_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MDY_DAY_POSITION.key,{value:A.MDY_DAY_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MDY_YEAR_POSITION.key,{value:A.MDY_YEAR_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MY_LABEL_MONTH_POSITION.key,{value:A.MY_LABEL_MONTH_POSITION.value,handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProper!
 ty(A.MY_LABEL_YEAR_POSITION.key,{value:A.MY_LABEL_YEAR_POSITIO!
 N.value,
handler:this.delegateConfig,validator:this.cfg.checkNumber});this.cfg.addProperty(A.MY_LABEL_MONTH_SUFFIX.key,{value:A.MY_LABEL_MONTH_SUFFIX.value,handler:this.delegateConfig});this.cfg.addProperty(A.MY_LABEL_YEAR_SUFFIX.key,{value:A.MY_LABEL_YEAR_SUFFIX.value,handler:this.delegateConfig});this.cfg.addProperty(A.NAV.key,{value:A.NAV.value,handler:this.configNavigator});},initEvents:function(){var C=this;var E="Event";var B=function(G,J,F){for(var I=0;I<C.pages.length;++I){var H=C.pages[I];H[this.type+E].subscribe(G,J,F);}};var A=function(F,I){for(var H=0;H<C.pages.length;++H){var G=C.pages[H];G[this.type+E].unsubscribe(F,I);}};var D=YAHOO.widget.Calendar._EVENT_TYPES;this.beforeSelectEvent=new YAHOO.util.CustomEvent(D.BEFORE_SELECT);this.beforeSelectEvent.subscribe=B;this.beforeSelectEvent.unsubscribe=A;this.selectEvent=new YAHOO.util.CustomEvent(D.SELECT);this.selectEvent.subscribe=B;this.selectEvent.unsubscribe=A;this.beforeDeselectEvent=new YAHOO.util.CustomEvent(D.BEFORE!
 _DESELECT);this.beforeDeselectEvent.subscribe=B;this.beforeDeselectEvent.unsubscribe=A;this.deselectEvent=new YAHOO.util.CustomEvent(D.DESELECT);this.deselectEvent.subscribe=B;this.deselectEvent.unsubscribe=A;this.changePageEvent=new YAHOO.util.CustomEvent(D.CHANGE_PAGE);this.changePageEvent.subscribe=B;this.changePageEvent.unsubscribe=A;this.beforeRenderEvent=new YAHOO.util.CustomEvent(D.BEFORE_RENDER);this.beforeRenderEvent.subscribe=B;this.beforeRenderEvent.unsubscribe=A;this.renderEvent=new YAHOO.util.CustomEvent(D.RENDER);this.renderEvent.subscribe=B;this.renderEvent.unsubscribe=A;this.resetEvent=new YAHOO.util.CustomEvent(D.RESET);this.resetEvent.subscribe=B;this.resetEvent.unsubscribe=A;this.clearEvent=new YAHOO.util.CustomEvent(D.CLEAR);this.clearEvent.subscribe=B;this.clearEvent.unsubscribe=A;this.beforeShowEvent=new YAHOO.util.CustomEvent(D.BEFORE_SHOW);this.showEvent=new YAHOO.util.CustomEvent(D.SHOW);this.beforeHideEvent=new YAHOO.util.CustomEvent(D.BEFORE_HIDE)!
 ;this.hideEvent=new YAHOO.util.CustomEvent(D.HIDE);this.before!
 ShowNavE
vent=new YAHOO.util.CustomEvent(D.BEFORE_SHOW_NAV);this.showNavEvent=new YAHOO.util.CustomEvent(D.SHOW_NAV);this.beforeHideNavEvent=new YAHOO.util.CustomEvent(D.BEFORE_HIDE_NAV);this.hideNavEvent=new YAHOO.util.CustomEvent(D.HIDE_NAV);this.beforeRenderNavEvent=new YAHOO.util.CustomEvent(D.BEFORE_RENDER_NAV);this.renderNavEvent=new YAHOO.util.CustomEvent(D.RENDER_NAV);},configPages:function(K,J,G){var E=J[0];var C=YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;var O="_";var L="groupcal";var N="first-of-type";var D="last-of-type";for(var B=0;B<E;++B){var M=this.id+O+B;var I=this.containerId+O+B;var H=this.cfg.getConfig();H.close=false;H.title=false;H.navigator=null;var A=this.constructChild(M,I,H);var F=A.cfg.getProperty(C);this._setMonthOnDate(F,F.getMonth()+B);A.cfg.setProperty(C,F);YAHOO.util.Dom.removeClass(A.oDomContainer,this.Style.CSS_SINGLE);YAHOO.util.Dom.addClass(A.oDomContainer,L);if(B===0){YAHOO.util.Dom.addClass(A.oDomContainer,N);}if(B==(E-1)){YAHOO.util!
 .Dom.addClass(A.oDomContainer,D);}A.parent=this;A.index=B;this.pages[this.pages.length]=A;}},configPageDate:function(H,G,E){var C=G[0];var F;var D=YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;for(var B=0;B<this.pages.length;++B){var A=this.pages[B];if(B===0){F=A._parsePageDate(C);A.cfg.setProperty(D,F);}else{var I=new Date(F);this._setMonthOnDate(I,I.getMonth()+B);A.cfg.setProperty(D,I);}}},configSelected:function(C,A,E){var D=YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.SELECTED.key;this.delegateConfig(C,A,E);var B=(this.pages.length>0)?this.pages[0].cfg.getProperty(D):[];this.cfg.setProperty(D,B,true);},delegateConfig:function(B,A,E){var F=A[0];var D;for(var C=0;C<this.pages.length;C++){D=this.pages[C];D.cfg.setProperty(B,F);}},setChildFunction:function(D,B){var A=this.cfg.getProperty(YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES.key);for(var C=0;C<A;++C){this.pages[C][D]=B;}},callChildFunction:function(F,B){var A=this.cfg.getProperty(YAHOO.widget.CalendarGrou!
 p._DEFAULT_CONFIG.PAGES.key);
+for(var E=0;E<A;++E){var D=this.pages[E];if(D[F]){var C=D[F];C.call(D,B);}}},constructChild:function(D,B,C){var A=document.getElementById(B);if(!A){A=document.createElement("div");A.id=B;this.oDomContainer.appendChild(A);}return new YAHOO.widget.Calendar(D,B,C);},setMonth:function(E){E=parseInt(E,10);var F;var B=YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;for(var D=0;D<this.pages.length;++D){var C=this.pages[D];var A=C.cfg.getProperty(B);if(D===0){F=A.getFullYear();}else{A.setFullYear(F);}this._setMonthOnDate(A,E+D);C.cfg.setProperty(B,A);}},setYear:function(C){var B=YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGEDATE.key;C=parseInt(C,10);for(var E=0;E<this.pages.length;++E){var D=this.pages[E];var A=D.cfg.getProperty(B);if((A.getMonth()+1)==1&&E>0){C+=1;}D.setYear(C);}},render:function(){this.renderHeader();for(var B=0;B<this.pages.length;++B){var A=this.pages[B];A.render();}this.renderFooter();},select:function(A){for(var C=0;C<this.pages.length;++C){var B=thi!
 s.pages[C];B.select(A);}return this.getSelectedDates();},selectCell:function(A){for(var C=0;C<this.pages.length;++C){var B=this.pages[C];B.selectCell(A);}return this.getSelectedDates();},deselect:function(A){for(var C=0;C<this.pages.length;++C){var B=this.pages[C];B.deselect(A);}return this.getSelectedDates();},deselectAll:function(){for(var B=0;B<this.pages.length;++B){var A=this.pages[B];A.deselectAll();}return this.getSelectedDates();},deselectCell:function(A){for(var C=0;C<this.pages.length;++C){var B=this.pages[C];B.deselectCell(A);}return this.getSelectedDates();},reset:function(){for(var B=0;B<this.pages.length;++B){var A=this.pages[B];A.reset();}},clear:function(){for(var B=0;B<this.pages.length;++B){var A=this.pages[B];A.clear();}},nextMonth:function(){for(var B=0;B<this.pages.length;++B){var A=this.pages[B];A.nextMonth();}},previousMonth:function(){for(var B=this.pages.length-1;B>=0;--B){var A=this.pages[B];A.previousMonth();}},nextYear:function(){for(var B=0;B<th!
 is.pages.length;++B){var A=this.pages[B];A.nextYear();}},previ!
 ousYear:
function(){for(var B=0;B<this.pages.length;++B){var A=this.pages[B];A.previousYear();}},getSelectedDates:function(){var C=[];var B=this.cfg.getProperty(YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.SELECTED.key);for(var E=0;E<B.length;++E){var D=B[E];var A=YAHOO.widget.DateMath.getDate(D[0],D[1]-1,D[2]);C.push(A);}C.sort(function(G,F){return G-F;});return C;},addRenderer:function(A,B){for(var D=0;D<this.pages.length;++D){var C=this.pages[D];C.addRenderer(A,B);}},addMonthRenderer:function(D,A){for(var C=0;C<this.pages.length;++C){var B=this.pages[C];B.addMonthRenderer(D,A);}},addWeekdayRenderer:function(B,A){for(var D=0;D<this.pages.length;++D){var C=this.pages[D];C.addWeekdayRenderer(B,A);}},removeRenderers:function(){this.callChildFunction("removeRenderers");},renderHeader:function(){},renderFooter:function(){},addMonths:function(A){this.callChildFunction("addMonths",A);},subtractMonths:function(A){this.callChildFunction("subtractMonths",A);},addYears:function(A){this.callChil!
 dFunction("addYears",A);},subtractYears:function(A){this.callChildFunction("subtractYears",A);},getCalendarPage:function(D){var F=null;if(D){var G=D.getFullYear(),C=D.getMonth();var B=this.pages;for(var E=0;E<B.length;++E){var A=B[E].cfg.getProperty("pagedate");if(A.getFullYear()===G&&A.getMonth()===C){F=B[E];break;}}}return F;},_setMonthOnDate:function(C,D){if(YAHOO.env.ua.webkit&&YAHOO.env.ua.webkit<420&&(D<0||D>11)){var B=YAHOO.widget.DateMath;var A=B.add(C,B.MONTH,D-C.getMonth());C.setTime(A.getTime());}else{C.setMonth(D);}},_fixWidth:function(){var A=0;for(var C=0;C<this.pages.length;++C){var B=this.pages[C];A+=B.oDomContainer.offsetWidth;}if(A>0){this.oDomContainer.style.width=A+"px";}},toString:function(){return"CalendarGroup "+this.id;}};YAHOO.widget.CalendarGroup.CSS_CONTAINER="yui-calcontainer";YAHOO.widget.CalendarGroup.CSS_MULTI_UP="multi";YAHOO.widget.CalendarGroup.CSS_2UPTITLE="title";YAHOO.widget.CalendarGroup.CSS_2UPCLOSE="close-icon";YAHOO.lang.augmentProto!
 (YAHOO.widget.CalendarGroup,YAHOO.widget.Calendar,"buildDayLab!
 el","bui
ldMonthLabel","renderOutOfBoundsDate","renderRowHeader","renderRowFooter","renderCellDefault","styleCellDefault","renderCellStyleHighlight1","renderCellStyleHighlight2","renderCellStyleHighlight3","renderCellStyleHighlight4","renderCellStyleToday","renderCellStyleSelected","renderCellNotThisMonth","renderBodyCellRestricted","initStyles","configTitle","configClose","configIframe","configNavigator","createTitleBar","createCloseButton","removeTitleBar","removeCloseButton","hide","show","toDate","_parseArgs","browser");YAHOO.widget.CalendarGroup._DEFAULT_CONFIG=YAHOO.widget.Calendar._DEFAULT_CONFIG;YAHOO.widget.CalendarGroup._DEFAULT_CONFIG.PAGES={key:"pages",value:2};YAHOO.widget.CalGrp=YAHOO.widget.CalendarGroup;YAHOO.widget.Calendar2up=function(C,A,B){this.init(C,A,B);};YAHOO.extend(YAHOO.widget.Calendar2up,YAHOO.widget.CalendarGroup);YAHOO.widget.Cal2up=YAHOO.widget.Calendar2up;YAHOO.widget.CalendarNavigator=function(A){this.init(A);};(function(){var A=YAHOO.widget.CalendarN!
 avigator;A.CLASSES={NAV:"yui-cal-nav",NAV_VISIBLE:"yui-cal-nav-visible",MASK:"yui-cal-nav-mask",YEAR:"yui-cal-nav-y",MONTH:"yui-cal-nav-m",BUTTONS:"yui-cal-nav-b",BUTTON:"yui-cal-nav-btn",ERROR:"yui-cal-nav-e",YEAR_CTRL:"yui-cal-nav-yc",MONTH_CTRL:"yui-cal-nav-mc",INVALID:"yui-invalid",DEFAULT:"yui-default"};A._DEFAULT_CFG={strings:{month:"Month",year:"Year",submit:"Okay",cancel:"Cancel",invalidYear:"Year needs to be a number"},monthFormat:YAHOO.widget.Calendar.LONG,initialFocus:"year"};A.ID_SUFFIX="_nav";A.MONTH_SUFFIX="_month";A.YEAR_SUFFIX="_year";A.ERROR_SUFFIX="_error";A.CANCEL_SUFFIX="_cancel";A.SUBMIT_SUFFIX="_submit";A.YR_MAX_DIGITS=4;A.YR_MINOR_INC=1;A.YR_MAJOR_INC=10;A.UPDATE_DELAY=50;A.YR_PATTERN=/^\d+$/;A.TRIM=/^\s*(.*?)\s*$/;})();YAHOO.widget.CalendarNavigator.prototype={id:null,cal:null,navEl:null,maskEl:null,yearEl:null,monthEl:null,errorEl:null,submitEl:null,cancelEl:null,firstCtrl:null,lastCtrl:null,_doc:null,_year:null,_month:0,__rendered:false,init:functi!
 on(A){var C=A.oDomContainer;
+this.cal=A;this.id=C.id+YAHOO.widget.CalendarNavigator.ID_SUFFIX;this._doc=C.ownerDocument;var B=YAHOO.env.ua.ie;this.__isIEQuirks=(B&&((B<=6)||(B===7&&this._doc.compatMode=="BackCompat")));},show:function(){var A=YAHOO.widget.CalendarNavigator.CLASSES;if(this.cal.beforeShowNavEvent.fire()){if(!this.__rendered){this.render();}this.clearErrors();this._updateMonthUI();this._updateYearUI();this._show(this.navEl,true);this.setInitialFocus();this.showMask();YAHOO.util.Dom.addClass(this.cal.oDomContainer,A.NAV_VISIBLE);this.cal.showNavEvent.fire();}},hide:function(){var A=YAHOO.widget.CalendarNavigator.CLASSES;if(this.cal.beforeHideNavEvent.fire()){this._show(this.navEl,false);this.hideMask();YAHOO.util.Dom.removeClass(this.cal.oDomContainer,A.NAV_VISIBLE);this.cal.hideNavEvent.fire();}},showMask:function(){this._show(this.maskEl,true);if(this.__isIEQuirks){this._syncMask();}},hideMask:function(){this._show(this.maskEl,false);},getMonth:function(){return this._month;},getYear:fun!
 ction(){return this._year;},setMonth:function(A){if(A>=0&&A<12){this._month=A;}this._updateMonthUI();},setYear:function(B){var A=YAHOO.widget.CalendarNavigator.YR_PATTERN;if(YAHOO.lang.isNumber(B)&&A.test(B+"")){this._year=B;}this._updateYearUI();},render:function(){this.cal.beforeRenderNavEvent.fire();if(!this.__rendered){this.createNav();this.createMask();this.applyListeners();this.__rendered=true;}this.cal.renderNavEvent.fire();},createNav:function(){var B=YAHOO.widget.CalendarNavigator;var C=this._doc;var D=C.createElement("div");D.className=B.CLASSES.NAV;var A=this.renderNavContents([]);D.innerHTML=A.join("");this.cal.oDomContainer.appendChild(D);this.navEl=D;this.yearEl=C.getElementById(this.id+B.YEAR_SUFFIX);this.monthEl=C.getElementById(this.id+B.MONTH_SUFFIX);this.errorEl=C.getElementById(this.id+B.ERROR_SUFFIX);this.submitEl=C.getElementById(this.id+B.SUBMIT_SUFFIX);this.cancelEl=C.getElementById(this.id+B.CANCEL_SUFFIX);if(YAHOO.env.ua.gecko&&this.yearEl&&this.ye!
 arEl.type=="text"){this.yearEl.setAttribute("autocomplete","of!
 f");}thi
s._setFirstLastElements();},createMask:function(){var B=YAHOO.widget.CalendarNavigator.CLASSES;var A=this._doc.createElement("div");A.className=B.MASK;this.cal.oDomContainer.appendChild(A);this.maskEl=A;},_syncMask:function(){var B=this.cal.oDomContainer;if(B&&this.maskEl){var A=YAHOO.util.Dom.getRegion(B);YAHOO.util.Dom.setStyle(this.maskEl,"width",A.right-A.left+"px");YAHOO.util.Dom.setStyle(this.maskEl,"height",A.bottom-A.top+"px");}},renderNavContents:function(A){var D=YAHOO.widget.CalendarNavigator,E=D.CLASSES,B=A;B[B.length]='<div class="'+E.MONTH+'">';this.renderMonth(B);B[B.length]="</div>";B[B.length]='<div class="'+E.YEAR+'">';this.renderYear(B);B[B.length]="</div>";B[B.length]='<div class="'+E.BUTTONS+'">';this.renderButtons(B);B[B.length]="</div>";B[B.length]='<div class="'+E.ERROR+'" id="'+this.id+D.ERROR_SUFFIX+'"></div>';return B;},renderMonth:function(D){var G=YAHOO.widget.CalendarNavigator,H=G.CLASSES;var I=this.id+G.MONTH_SUFFIX,F=this.__getCfg("monthFormat!
 "),A=this.cal.cfg.getProperty((F==YAHOO.widget.Calendar.SHORT)?"MONTHS_SHORT":"MONTHS_LONG"),E=D;if(A&&A.length>0){E[E.length]='<label for="'+I+'">';E[E.length]=this.__getCfg("month",true);E[E.length]="</label>";E[E.length]='<select name="'+I+'" id="'+I+'" class="'+H.MONTH_CTRL+'">';for(var B=0;B<A.length;B++){E[E.length]='<option value="'+B+'">';E[E.length]=A[B];E[E.length]="</option>";}E[E.length]="</select>";}return E;},renderYear:function(B){var E=YAHOO.widget.CalendarNavigator,F=E.CLASSES;var G=this.id+E.YEAR_SUFFIX,A=E.YR_MAX_DIGITS,D=B;D[D.length]='<label for="'+G+'">';D[D.length]=this.__getCfg("year",true);D[D.length]="</label>";D[D.length]='<input type="text" name="'+G+'" id="'+G+'" class="'+F.YEAR_CTRL+'" maxlength="'+A+'"/>';return D;},renderButtons:function(A){var D=YAHOO.widget.CalendarNavigator.CLASSES;var B=A;B[B.length]='<span class="'+D.BUTTON+" "+D.DEFAULT+'">';B[B.length]='<button type="button" id="'+this.id+"_submit"+'">';B[B.length]=this.__getCfg("submi!
 t",true);B[B.length]="</button>";B[B.length]="</span>";B[B.len!
 gth]='<s
pan class="'+D.BUTTON+'">';B[B.length]='<button type="button" id="'+this.id+"_cancel"+'">';B[B.length]=this.__getCfg("cancel",true);B[B.length]="</button>";B[B.length]="</span>";return B;},applyListeners:function(){var B=YAHOO.util.Event;function A(){if(this.validate()){this.setYear(this._getYearFromUI());}}function C(){this.setMonth(this._getMonthFromUI());}B.on(this.submitEl,"click",this.submit,this,true);B.on(this.cancelEl,"click",this.cancel,this,true);B.on(this.yearEl,"blur",A,this,true);B.on(this.monthEl,"change",C,this,true);if(this.__isIEQuirks){YAHOO.util.Event.on(this.cal.oDomContainer,"resize",this._syncMask,this,true);}this.applyKeyListeners();},purgeListeners:function(){var A=YAHOO.util.Event;A.removeListener(this.submitEl,"click",this.submit);A.removeListener(this.cancelEl,"click",this.cancel);A.removeListener(this.yearEl,"blur");A.removeListener(this.monthEl,"change");if(this.__isIEQuirks){A.removeListener(this.cal.oDomContainer,"resize",this._syncMask);}this.!
 purgeKeyListeners();},applyKeyListeners:function(){var D=YAHOO.util.Event,A=YAHOO.env.ua;var C=(A.ie||A.webkit)?"keydown":"keypress";var B=(A.ie||A.opera||A.webkit)?"keydown":"keypress";D.on(this.yearEl,"keypress",this._handleEnterKey,this,true);D.on(this.yearEl,C,this._handleDirectionKeys,this,true);D.on(this.lastCtrl,B,this._handleTabKey,this,true);D.on(this.firstCtrl,B,this._handleShiftTabKey,this,true);},purgeKeyListeners:function(){var D=YAHOO.util.Event,A=YAHOO.env.ua;var C=(A.ie||A.webkit)?"keydown":"keypress";var B=(A.ie||A.opera||A.webkit)?"keydown":"keypress";D.removeListener(this.yearEl,"keypress",this._handleEnterKey);D.removeListener(this.yearEl,C,this._handleDirectionKeys);D.removeListener(this.lastCtrl,B,this._handleTabKey);D.removeListener(this.firstCtrl,B,this._handleShiftTabKey);},submit:function(){if(this.validate()){this.hide();this.setMonth(this._getMonthFromUI());this.setYear(this._getYearFromUI());
+var B=this.cal;var C=this;function D(){B.setYear(C.getYear());B.setMonth(C.getMonth());B.render();}var A=YAHOO.widget.CalendarNavigator.UPDATE_DELAY;if(A>0){window.setTimeout(D,A);}else{D();}}},cancel:function(){this.hide();},validate:function(){if(this._getYearFromUI()!==null){this.clearErrors();return true;}else{this.setYearError();this.setError(this.__getCfg("invalidYear",true));return false;}},setError:function(A){if(this.errorEl){this.errorEl.innerHTML=A;this._show(this.errorEl,true);}},clearError:function(){if(this.errorEl){this.errorEl.innerHTML="";this._show(this.errorEl,false);}},setYearError:function(){YAHOO.util.Dom.addClass(this.yearEl,YAHOO.widget.CalendarNavigator.CLASSES.INVALID);},clearYearError:function(){YAHOO.util.Dom.removeClass(this.yearEl,YAHOO.widget.CalendarNavigator.CLASSES.INVALID);},clearErrors:function(){this.clearError();this.clearYearError();},setInitialFocus:function(){var A=this.submitEl;var B=this.__getCfg("initialFocus");if(B&&B.toLowerCase!
 ){B=B.toLowerCase();if(B=="year"){A=this.yearEl;try{this.yearEl.select();}catch(C){}}else{if(B=="month"){A=this.monthEl;}}}if(A&&YAHOO.lang.isFunction(A.focus)){try{A.focus();}catch(C){}}},erase:function(){if(this.__rendered){this.purgeListeners();this.yearEl=null;this.monthEl=null;this.errorEl=null;this.submitEl=null;this.cancelEl=null;this.firstCtrl=null;this.lastCtrl=null;if(this.navEl){this.navEl.innerHTML="";}var B=this.navEl.parentNode;if(B){B.removeChild(this.navEl);}this.navEl=null;var A=this.maskEl.parentNode;if(A){A.removeChild(this.maskEl);}this.maskEl=null;this.__rendered=false;}},destroy:function(){this.erase();this._doc=null;this.cal=null;this.id=null;},_show:function(B,A){if(B){YAHOO.util.Dom.setStyle(B,"display",(A)?"block":"none");}},_getMonthFromUI:function(){if(this.monthEl){return this.monthEl.selectedIndex;}else{return 0;}},_getYearFromUI:function(){var B=YAHOO.widget.CalendarNavigator;var A=null;if(this.yearEl){var C=this.yearEl.value;C=C.replace(B.TRI!
 M,"$1");if(B.YR_PATTERN.test(C)){A=parseInt(C,10);}}return A;}!
 ,_update
YearUI:function(){if(this.yearEl&&this._year!==null){this.yearEl.value=this._year;}},_updateMonthUI:function(){if(this.monthEl){this.monthEl.selectedIndex=this._month;}},_setFirstLastElements:function(){this.firstCtrl=this.monthEl;this.lastCtrl=this.cancelEl;if(this.__isMac){if(YAHOO.env.ua.webkit&&YAHOO.env.ua.webkit<420){this.firstCtrl=this.monthEl;this.lastCtrl=this.yearEl;}if(YAHOO.env.ua.gecko){this.firstCtrl=this.yearEl;this.lastCtrl=this.yearEl;}}},_handleEnterKey:function(B){var A=YAHOO.util.KeyListener.KEY;if(YAHOO.util.Event.getCharCode(B)==A.ENTER){YAHOO.util.Event.preventDefault(B);this.submit();}},_handleDirectionKeys:function(G){var F=YAHOO.util.Event;var A=YAHOO.util.KeyListener.KEY;var C=YAHOO.widget.CalendarNavigator;var D=(this.yearEl.value)?parseInt(this.yearEl.value,10):null;if(isFinite(D)){var B=false;switch(F.getCharCode(G)){case A.UP:this.yearEl.value=D+C.YR_MINOR_INC;B=true;break;case A.DOWN:this.yearEl.value=Math.max(D-C.YR_MINOR_INC,0);B=true;break;!
 case A.PAGE_UP:this.yearEl.value=D+C.YR_MAJOR_INC;B=true;break;case A.PAGE_DOWN:this.yearEl.value=Math.max(D-C.YR_MAJOR_INC,0);B=true;break;default:break;}if(B){F.preventDefault(G);try{this.yearEl.select();}catch(G){}}}},_handleTabKey:function(C){var B=YAHOO.util.Event;var A=YAHOO.util.KeyListener.KEY;if(B.getCharCode(C)==A.TAB&&!C.shiftKey){try{B.preventDefault(C);this.firstCtrl.focus();}catch(C){}}},_handleShiftTabKey:function(C){var B=YAHOO.util.Event;var A=YAHOO.util.KeyListener.KEY;if(C.shiftKey&&B.getCharCode(C)==A.TAB){try{B.preventDefault(C);this.lastCtrl.focus();}catch(C){}}},__getCfg:function(D,B){var C=YAHOO.widget.CalendarNavigator._DEFAULT_CFG;var A=this.cal.cfg.getProperty("navigator");if(B){return(A!==true&&A.strings&&A.strings[D])?A.strings[D]:C.strings[D];}else{return(A!==true&&A[D])?A[D]:C[D];}},__isMac:(navigator.userAgent.toLowerCase().indexOf("macintosh")!=-1)};YAHOO.register("calendar",YAHOO.widget.Calendar,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/calendar/calendar.js
===================================================================
--- trunk/root/static/yui/calendar/calendar.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/calendar/calendar.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 (function () {
 
@@ -731,6 +731,19 @@
 	* @type Number
 	*/
 	ONE_DAY_MS : 1000*60*60*24,
+	
+	/**
+	 * Constant field representing the date in first week of January
+	 * which identifies the first week of the year.
+	 * <p>
+	 * In the U.S, Jan 1st is normally used based on a Sunday start of week.
+	 * ISO 8601, used widely throughout Europe, uses Jan 4th, based on a Monday start of week.
+	 * </p>
+	 * @property WEEK_ONE_JAN_DATE
+	 * @static
+	 * @type Number
+	 */
+	WEEK_ONE_JAN_DATE : 1,
 
 	/**
 	* Adds the specified amount of time to the this instance.
@@ -747,7 +760,6 @@
 				var newMonth = date.getMonth() + amount;
 				var years = 0;
 
-
 				if (newMonth < 0) {
 					while (newMonth < 0) {
 						newMonth += 12;
@@ -759,24 +771,56 @@
 						years += 1;
 					}
 				}
-				
+
 				d.setMonth(newMonth);
 				d.setFullYear(date.getFullYear() + years);
 				break;
 			case this.DAY:
-				d.setDate(date.getDate() + amount);
+				this._addDays(d, amount);
+				// d.setDate(date.getDate() + amount);
 				break;
 			case this.YEAR:
 				d.setFullYear(date.getFullYear() + amount);
 				break;
 			case this.WEEK:
-				d.setDate(date.getDate() + (amount * 7));
+				this._addDays(d, (amount * 7));
+				// d.setDate(date.getDate() + (amount * 7));
 				break;
 		}
 		return d;
 	},
 
 	/**
+	 * Private helper method to account for bug in Safari 2 (webkit < 420)
+	 * when Date.setDate(n) is called with n less than -128 or greater than 127.
+	 * <p>
+	 * Fix approach and original findings are available here:
+	 * http://brianary.blogspot.com/2006/03/safari-date-bug.html
+	 * </p>
+	 * @method _addDays
+	 * @param {Date} d JavaScript date object
+	 * @param {Number} nDays The number of days to add to the date object (can be negative)
+	 * @private
+	 */
+	_addDays : function(d, nDays) {
+		if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 420) {
+			if (nDays < 0) {
+				// Ensure we don't go below -128 (getDate() is always 1 to 31, so we won't go above 127)
+				for(var min = -128; nDays < min; nDays -= min) {
+					d.setDate(d.getDate() + min);
+				}
+			} else {
+				// Ensure we don't go above 96 + 31 = 127
+				for(var max = 96; nDays > max; nDays -= max) {
+					d.setDate(d.getDate() + max);
+				}
+			}
+			// nDays should be remainder between -128 and 96
+		}
+		d.setDate(d.getDate() + nDays);
+	},
+
+	/**
 	* Subtracts the specified amount of time from the this instance.
 	* @method subtract
 	* @param {Date} date	The JavaScript Date object to perform subtraction on
@@ -863,30 +907,79 @@
 	},
 
 	/**
-	* Calculates the week number for the given date. This function assumes that week 1 is the
-	* week in which January 1 appears, regardless of whether the week consists of a full 7 days.
-	* The calendar year can be specified to help find what a the week number would be for a given
-	* date if the date overlaps years. For instance, a week may be considered week 1 of 2005, or
-	* week 53 of 2004. Specifying the optional calendarYear allows one to make this distinction
-	* easily.
+	* Calculates the week number for the given date. Can currently support standard
+	* U.S. week numbers, based on Jan 1st defining the 1st week of the year, and 
+	* ISO8601 week numbers, based on Jan 4th defining the 1st week of the year.
+	* 
 	* @method getWeekNumber
-	* @param {Date}	date	The JavaScript date for which to find the week number
-	* @param {Number} calendarYear	OPTIONAL - The calendar year to use for determining the week number. Default is
-	*											the calendar year of parameter "date".
-	* @return {Number}	The week number of the given date.
+	* @param {Date}	date The JavaScript date for which to find the week number
+	* @param {Number} firstDayOfWeek The index of the first day of the week (0 = Sun, 1 = Mon ... 6 = Sat).
+	* Defaults to 0
+	* @param {Number} janDate The date in the first week of January which defines week one for the year
+	* Defaults to the value of YAHOO.widget.DateMath.WEEK_ONE_JAN_DATE, which is 1 (Jan 1st). 
+	* For the U.S, this is normally Jan 1st. ISO8601 uses Jan 4th to define the first week of the year.
+	* 
+	* @return {Number} The number of the week containing the given date.
 	*/
-	getWeekNumber : function(date, calendarYear) {
-		date = this.clearTime(date);
-		var nearestThurs = new Date(date.getTime() + (4 * this.ONE_DAY_MS) - ((date.getDay()) * this.ONE_DAY_MS));
+	getWeekNumber : function(date, firstDayOfWeek, janDate) {
 
-		var jan1 = this.getDate(nearestThurs.getFullYear(),0,1);
-		var dayOfYear = ((nearestThurs.getTime() - jan1.getTime()) / this.ONE_DAY_MS) - 1;
+		// Setup Defaults
+		firstDayOfWeek = firstDayOfWeek || 0;
+		janDate = janDate || this.WEEK_ONE_JAN_DATE;
 
-		var weekNum = Math.ceil((dayOfYear)/ 7);
+		var targetDate = this.clearTime(date),
+			startOfWeek,
+			endOfWeek;
+
+		if (targetDate.getDay() === firstDayOfWeek) { 
+			startOfWeek = targetDate;
+		} else {
+			startOfWeek = this.getFirstDayOfWeek(targetDate, firstDayOfWeek);
+		}
+
+		var startYear = startOfWeek.getFullYear(),
+			startTime = startOfWeek.getTime();
+
+		// DST shouldn't be a problem here, math is quicker than setDate();
+		endOfWeek = new Date(startOfWeek.getTime() + 6*this.ONE_DAY_MS);
+
+		var weekNum;
+		if (startYear !== endOfWeek.getFullYear() && endOfWeek.getDate() >= janDate) {
+			// If years don't match, endOfWeek is in Jan. and if the 
+			// week has WEEK_ONE_JAN_DATE in it, it's week one by definition.
+			weekNum = 1;
+		} else {
+			// Get the 1st day of the 1st week, and 
+			// find how many days away we are from it.
+			var weekOne = this.clearTime(this.getDate(startYear, 0, janDate)),
+				weekOneDayOne = this.getFirstDayOfWeek(weekOne, firstDayOfWeek);
+
+			// Round days to smoothen out 1 hr DST diff
+			var daysDiff  = Math.round((targetDate.getTime() - weekOneDayOne.getTime())/this.ONE_DAY_MS);
+
+			// Calc. Full Weeks
+			var rem = daysDiff % 7;
+			var weeksDiff = (daysDiff - rem)/7;
+			weekNum = weeksDiff + 1;
+		}
 		return weekNum;
 	},
 
 	/**
+	 * Get the first day of the week, for the give date. 
+	 * @param {Date} dt The date in the week for which the first day is required.
+	 * @param {Number} startOfWeek The index for the first day of the week, 0 = Sun, 1 = Mon ... 6 = Sat (defaults to 0)
+	 * @return {Date} The first day of the week
+	 */
+	getFirstDayOfWeek : function (dt, startOfWeek) {
+		startOfWeek = startOfWeek || 0;
+		var dayOfWeekIndex = dt.getDay(),
+			dayOfWeek = (dayOfWeekIndex - startOfWeek + 7) % 7;
+
+		return this.subtract(dt, this.DAY, dayOfWeek);
+	},
+
+	/**
 	* Determines if a given week overlaps two different years.
 	* @method isYearOverlapWeek
 	* @param {Date}	weekBeginDate	The JavaScript Date representing the first day of the week.
@@ -1912,9 +2005,9 @@
 		* @default false
 		*/
 		this.cfg.addProperty(defCfg.MULTI_SELECT.key,	{ value:defCfg.MULTI_SELECT.value, handler:this.configOptions, validator:this.cfg.checkBoolean } );
-	
+
 		/**
-		* The weekday the week begins on. Default is 0 (Sunday).
+		* The weekday the week begins on. Default is 0 (Sunday = 0, Monday = 1 ... Saturday = 6).
 		* @config START_WEEKDAY
 		* @type number
 		* @default 0
@@ -2619,7 +2712,7 @@
 	*/
 	renderHeader : function(html) {
 		var colSpan = 7;
-		
+
 		var DEPR_NAV_LEFT = "us/tr/callt.gif";
 		var DEPR_NAV_RIGHT = "us/tr/calrt.gif";	
 		var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
@@ -2631,14 +2724,14 @@
 		if (this.cfg.getProperty(defCfg.SHOW_WEEK_FOOTER.key)) {
 			colSpan += 1;
 		}
-	
+
 		html[html.length] = "<thead>";
 		html[html.length] =		"<tr>";
 		html[html.length] =			'<th colspan="' + colSpan + '" class="' + this.Style.CSS_HEADER_TEXT + '">';
 		html[html.length] =				'<div class="' + this.Style.CSS_HEADER + '">';
-	
+
 		var renderLeft, renderRight = false;
-	
+
 		if (this.parent) {
 			if (this.index === 0) {
 				renderLeft = true;
@@ -2650,7 +2743,7 @@
 			renderLeft = true;
 			renderRight = true;
 		}
-	
+
 		if (renderLeft) {
 			var leftArrow = this.cfg.getProperty(defCfg.NAV_ARROW_LEFT.key);
 			// Check for deprecated customization - If someone set IMG_ROOT, but didn't set NAV_ARROW_LEFT, then set NAV_ARROW_LEFT to the old deprecated value
@@ -2725,10 +2818,14 @@
 	* @return {Array} The current working HTML array
 	*/
 	renderBody : function(workingDate, html) {
-		var defCfg = YAHOO.widget.Calendar._DEFAULT_CONFIG;
-	
+
+		var DM = YAHOO.widget.DateMath,
+			CAL = YAHOO.widget.Calendar,
+			D = YAHOO.util.Dom,
+			defCfg = CAL._DEFAULT_CONFIG;
+
 		var startDay = this.cfg.getProperty(defCfg.START_WEEKDAY.key);
-	
+
 		this.preMonthDays = workingDate.getDay();
 		if (startDay > 0) {
 			this.preMonthDays -= startDay;
@@ -2736,67 +2833,64 @@
 		if (this.preMonthDays < 0) {
 			this.preMonthDays += 7;
 		}
-		
-		this.monthDays = YAHOO.widget.DateMath.findMonthEnd(workingDate).getDate();
-		this.postMonthDays = YAHOO.widget.Calendar.DISPLAY_DAYS-this.preMonthDays-this.monthDays;
-		
-		workingDate = YAHOO.widget.DateMath.subtract(workingDate, YAHOO.widget.DateMath.DAY, this.preMonthDays);
+
+		this.monthDays = DM.findMonthEnd(workingDate).getDate();
+		this.postMonthDays = CAL.DISPLAY_DAYS-this.preMonthDays-this.monthDays;
+
+
+		workingDate = DM.subtract(workingDate, DM.DAY, this.preMonthDays);
 	
-		var weekNum,weekClass;
-		var weekPrefix = "w";
-		var cellPrefix = "_cell";
-		var workingDayPrefix = "wd";
-		var dayPrefix = "d";
-		
-		var cellRenderers;
-		var renderer;
-		
-		var todayYear = this.today.getFullYear();
-		var todayMonth = this.today.getMonth();
-		var todayDate = this.today.getDate();
-		
-		var useDate = this.cfg.getProperty(defCfg.PAGEDATE.key);
-		var hideBlankWeeks = this.cfg.getProperty(defCfg.HIDE_BLANK_WEEKS.key);
-		var showWeekFooter = this.cfg.getProperty(defCfg.SHOW_WEEK_FOOTER.key);
-		var showWeekHeader = this.cfg.getProperty(defCfg.SHOW_WEEK_HEADER.key);
-		var mindate = this.cfg.getProperty(defCfg.MINDATE.key);
-		var maxdate = this.cfg.getProperty(defCfg.MAXDATE.key);
-	
+		var weekNum,
+			weekClass,
+			weekPrefix = "w",
+			cellPrefix = "_cell",
+			workingDayPrefix = "wd",
+			dayPrefix = "d",
+			cellRenderers,
+			renderer,
+			todayYear = this.today.getFullYear(),
+			todayMonth = this.today.getMonth(),
+			todayDate = this.today.getDate(),
+			useDate = this.cfg.getProperty(defCfg.PAGEDATE.key),
+			hideBlankWeeks = this.cfg.getProperty(defCfg.HIDE_BLANK_WEEKS.key),
+			showWeekFooter = this.cfg.getProperty(defCfg.SHOW_WEEK_FOOTER.key),
+			showWeekHeader = this.cfg.getProperty(defCfg.SHOW_WEEK_HEADER.key),
+			mindate = this.cfg.getProperty(defCfg.MINDATE.key),
+			maxdate = this.cfg.getProperty(defCfg.MAXDATE.key);
+
 		if (mindate) {
-			mindate = YAHOO.widget.DateMath.clearTime(mindate);
+			mindate = DM.clearTime(mindate);
 		}
 		if (maxdate) {
-			maxdate = YAHOO.widget.DateMath.clearTime(maxdate);
+			maxdate = DM.clearTime(maxdate);
 		}
-		
+
 		html[html.length] = '<tbody class="m' + (useDate.getMonth()+1) + ' ' + this.Style.CSS_BODY + '">';
-		
-		var i = 0;
-	
-		var tempDiv = document.createElement("div");
-		var cell = document.createElement("td");
+
+		var i = 0,
+			tempDiv = document.createElement("div"),
+			cell = document.createElement("td");
+
 		tempDiv.appendChild(cell);
-	
+
 		var cal = this.parent || this;
-	
+
 		for (var r=0;r<6;r++) {
-	
-			weekNum = YAHOO.widget.DateMath.getWeekNumber(workingDate, useDate.getFullYear(), startDay);
+			weekNum = DM.getWeekNumber(workingDate, startDay);
 			weekClass = weekPrefix + weekNum;
-	
+
 			// Local OOM check for performance, since we already have pagedate
 			if (r !== 0 && hideBlankWeeks === true && workingDate.getMonth() != useDate.getMonth()) {
 				break;
 			} else {
-	
 				html[html.length] = '<tr class="' + weekClass + '">';
-				
+
 				if (showWeekHeader) { html = this.renderRowHeader(weekNum, html); }
-				
-				for (var d=0;d<7;d++){ // Render actual days
-	
+
+				for (var d=0; d < 7; d++){ // Render actual days
+
 					cellRenderers = [];
-	
+
 					this.clearElement(cell);
 					cell.className = this.Style.CSS_CELL;
 					cell.id = this.id + cellPrefix + i;
@@ -2806,64 +2900,59 @@
 						workingDate.getFullYear()	== todayYear) {
 						cellRenderers[cellRenderers.length]=cal.renderCellStyleToday;
 					}
-					
+
 					var workingArray = [workingDate.getFullYear(),workingDate.getMonth()+1,workingDate.getDate()];
 					this.cellDates[this.cellDates.length] = workingArray; // Add this date to cellDates
-					
+
 					// Local OOM check for performance, since we already have pagedate
 					if (workingDate.getMonth() != useDate.getMonth()) {
 						cellRenderers[cellRenderers.length]=cal.renderCellNotThisMonth;
 					} else {
-						YAHOO.util.Dom.addClass(cell, workingDayPrefix + workingDate.getDay());
-						YAHOO.util.Dom.addClass(cell, dayPrefix + workingDate.getDate());
-					
+						D.addClass(cell, workingDayPrefix + workingDate.getDay());
+						D.addClass(cell, dayPrefix + workingDate.getDate());
+
 						for (var s=0;s<this.renderStack.length;++s) {
-	
+
 							renderer = null;
-	
-							var rArray = this.renderStack[s];
-							var type = rArray[0];
-							
-							var month;
-							var day;
-							var year;
-							
+
+							var rArray = this.renderStack[s],
+								type = rArray[0],
+								month,
+								day,
+								year;
+
 							switch (type) {
-								case YAHOO.widget.Calendar.DATE:
+								case CAL.DATE:
 									month = rArray[1][1];
 									day = rArray[1][2];
 									year = rArray[1][0];
-	
+
 									if (workingDate.getMonth()+1 == month && workingDate.getDate() == day && workingDate.getFullYear() == year) {
 										renderer = rArray[2];
 										this.renderStack.splice(s,1);
 									}
 									break;
-								case YAHOO.widget.Calendar.MONTH_DAY:
+								case CAL.MONTH_DAY:
 									month = rArray[1][0];
 									day = rArray[1][1];
-									
+
 									if (workingDate.getMonth()+1 == month && workingDate.getDate() == day) {
 										renderer = rArray[2];
 										this.renderStack.splice(s,1);
 									}
 									break;
-								case YAHOO.widget.Calendar.RANGE:
-									var date1 = rArray[1][0];
-									var date2 = rArray[1][1];
-	
-									var d1month = date1[1];
-									var d1day = date1[2];
-									var d1year = date1[0];
-									
-									var d1 = YAHOO.widget.DateMath.getDate(d1year, d1month-1, d1day);
-	
-									var d2month = date2[1];
-									var d2day = date2[2];
-									var d2year = date2[0];
-	
-									var d2 = YAHOO.widget.DateMath.getDate(d2year, d2month-1, d2day);
-	
+								case CAL.RANGE:
+									var date1 = rArray[1][0],
+										date2 = rArray[1][1],
+										d1month = date1[1],
+										d1day = date1[2],
+										d1year = date1[0],
+										d1 = DM.getDate(d1year, d1month-1, d1day),
+										d2month = date2[1],
+										d2day = date2[2],
+										d2year = date2[0],
+										d2 = DM.getDate(d2year, d2month-1, d2day);
+
 									if (workingDate.getTime() >= d1.getTime() && workingDate.getTime() <= d2.getTime()) {
 										renderer = rArray[2];
 	
@@ -2872,33 +2961,31 @@
 										}
 									}
 									break;
-								case YAHOO.widget.Calendar.WEEKDAY:
-									
+								case CAL.WEEKDAY:
 									var weekday = rArray[1][0];
 									if (workingDate.getDay()+1 == weekday) {
 										renderer = rArray[2];
 									}
 									break;
-								case YAHOO.widget.Calendar.MONTH:
-									
+								case CAL.MONTH:
 									month = rArray[1][0];
 									if (workingDate.getMonth()+1 == month) {
 										renderer = rArray[2];
 									}
 									break;
 							}
-							
+
 							if (renderer) {
 								cellRenderers[cellRenderers.length]=renderer;
 							}
 						}
-	
+
 					}
-	
+
 					if (this._indexOfSelectedFieldArray(workingArray) > -1) {
 						cellRenderers[cellRenderers.length]=cal.renderCellStyleSelected; 
 					}
-	
+
 					if ((mindate && (workingDate.getTime() < mindate.getTime())) ||
 						(maxdate && (workingDate.getTime() > maxdate.getTime()))
 					) {
@@ -2907,25 +2994,27 @@
 						cellRenderers[cellRenderers.length]=cal.styleCellDefault;
 						cellRenderers[cellRenderers.length]=cal.renderCellDefault;	
 					}
-					
+
 					for (var x=0; x < cellRenderers.length; ++x) {
-						if (cellRenderers[x].call(cal, workingDate, cell) == YAHOO.widget.Calendar.STOP_RENDER) {
+						if (cellRenderers[x].call(cal, workingDate, cell) == CAL.STOP_RENDER) {
 							break;
 						}
 					}
-	
-					workingDate.setTime(workingDate.getTime() + YAHOO.widget.DateMath.ONE_DAY_MS);
-	
+
+					workingDate.setTime(workingDate.getTime() + DM.ONE_DAY_MS);
+					// Just in case we crossed DST/Summertime boundaries
+					workingDate = DM.clearTime(workingDate);
+
 					if (i >= 0 && i <= 6) {
-						YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_TOP);
+						D.addClass(cell, this.Style.CSS_CELL_TOP);
 					}
 					if ((i % 7) === 0) {
-						YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_LEFT);
+						D.addClass(cell, this.Style.CSS_CELL_LEFT);
 					}
 					if (((i+1) % 7) === 0) {
-						YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_RIGHT);
+						D.addClass(cell, this.Style.CSS_CELL_RIGHT);
 					}
-					
+
 					var postDays = this.postMonthDays; 
 					if (hideBlankWeeks && postDays >= 7) {
 						var blankWeeks = Math.floor(postDays/7);
@@ -2935,7 +3024,7 @@
 					}
 					
 					if (i >= ((this.preMonthDays+postDays+this.monthDays)-7)) {
-						YAHOO.util.Dom.addClass(cell, this.Style.CSS_CELL_BOTTOM);
+						D.addClass(cell, this.Style.CSS_CELL_BOTTOM);
 					}
 	
 					html[html.length] = tempDiv.innerHTML;
@@ -4076,13 +4165,13 @@
 	* Adds a weekday to the render stack. The function reference passed to this method will be executed
 	* when a date cell matches the weekday passed to this method.
 	* @method addWeekdayRenderer
-	* @param	{Number}	weekday		The weekday (0-6) to associate with this renderer
+	* @param	{Number}	weekday		The weekday (Sunday = 1, Monday = 2 ... Saturday = 7) to associate with this renderer
 	* @param	{Function}	fnRender	The function executed to render cells that match the render rules for this renderer.
 	*/
 	addWeekdayRenderer : function(weekday, fnRender) {
 		this._addRenderer(YAHOO.widget.Calendar.WEEKDAY,[weekday],fnRender);
 	},
-	
+
 	// END RENDERER METHODS
 	
 	// BEGIN CSS METHODS
@@ -6292,16 +6381,16 @@
 	 * @method applyKeyListeners
 	 */
 	applyKeyListeners : function() {
-		var E = YAHOO.util.Event;
+		var E = YAHOO.util.Event,
+			ua = YAHOO.env.ua;
 
-		// IE doesn't fire keypress for arrow/pg keys (non-char keys)
-		var ua = YAHOO.env.ua;
-		var arrowEvt = (ua.ie) ? "keydown" : "keypress";
+		// IE/Safari 3.1 doesn't fire keypress for arrow/pg keys (non-char keys)
+		var arrowEvt = (ua.ie || ua.webkit) ? "keydown" : "keypress";
 
-		// - IE doesn't fire keypress for non-char keys
+		// - IE/Safari 3.1 doesn't fire keypress for non-char keys
 		// - Opera doesn't allow us to cancel keydown or keypress for tab, but 
 		//   changes focus successfully on keydown (keypress is too late to change focus - opera's already moved on).
-		var tabEvt = (ua.ie || ua.opera) ? "keydown" : "keypress";
+		var tabEvt = (ua.ie || ua.opera || ua.webkit) ? "keydown" : "keypress";
 
 		// Everyone likes keypress for Enter (char keys) - whoo hoo!
 		E.on(this.yearEl, "keypress", this._handleEnterKey, this, true);
@@ -6317,10 +6406,11 @@
 	 * @method purgeKeyListeners
 	 */
 	purgeKeyListeners : function() {
-		var E = YAHOO.util.Event;
+		var E = YAHOO.util.Event,
+			ua = YAHOO.env.ua;
 
-		var arrowEvt = (YAHOO.env.ua.ie) ? "keydown" : "keypress";
-		var tabEvt = (YAHOO.env.ua.ie || YAHOO.env.ua.opera) ? "keydown" : "keypress";
+		var arrowEvt = (ua.ie || ua.webkit) ? "keydown" : "keypress";
+		var tabEvt = (ua.ie || ua.opera || ua.webkit) ? "keydown" : "keypress";
 
 		E.removeListener(this.yearEl, "keypress", this._handleEnterKey);
 		E.removeListener(this.yearEl, arrowEvt, this._handleDirectionKeys);
@@ -6628,6 +6718,7 @@
 		var KEYS = YAHOO.util.KeyListener.KEY;
 
 		if (YAHOO.util.Event.getCharCode(e) == KEYS.ENTER) {
+			YAHOO.util.Event.preventDefault(e);
 			this.submit();
 		}
 	},
@@ -6756,4 +6847,4 @@
 
 };
 
-YAHOO.register("calendar", YAHOO.widget.Calendar, {version: "2.4.1", build: "742"});
+YAHOO.register("calendar", YAHOO.widget.Calendar, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/charts/README
===================================================================
--- trunk/root/static/yui/charts/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/charts/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,6 +1,17 @@
 YUI Library - Charts - Release Notes
-2.4.1
-  * No change
 
+2.5.1
+  * No changes
+
+2.5.0
+  * Added lineSize style to series styles
+  * Added showLabels substyle to xAxis and yAxis styles
+  * Added more descriptive local content warning for ExternalInterface failure
+  * Improved minor unit calculation
+  * Fixed animation and marker positioning bugs
+  * Fixed bug that caused series definition update to fail
+  * Fixed bug that caused setting hex color values with # symbol to fail
+  * Added initialization flag to ensure DataSource doesn't receive multiple requests during initialization.
+
 2.4.0
-  * Experimental release
+  * Experimental release
\ No newline at end of file

Modified: trunk/root/static/yui/charts/assets/charts.swf
===================================================================
(Binary files differ)

Modified: trunk/root/static/yui/charts/charts-experimental-debug.js
===================================================================
--- trunk/root/static/yui/charts/charts-experimental-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/charts/charts-experimental-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,37 +1,50 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-/**
+/*!
  * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
  *
  * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
  * http://www.opensource.org/licenses/mit-license.php
- *
  */
-if(typeof deconcept == "undefined") var deconcept = new Object();
-if(typeof deconcept.util == "undefined") deconcept.util = new Object();
-if(typeof deconcept.SWFObjectUtil == "undefined") deconcept.SWFObjectUtil = new Object();
-deconcept.SWFObject = function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey) {
-	if (!document.getElementById) { return; }
+var deconcept = deconcept || {};
+
+if(typeof deconcept.util == "undefined" || !deconcept.util)
+{
+	deconcept.util = {};
+}
+
+if(typeof deconcept.SWFObjectUtil == "undefined" || !deconcept.SWFObjectUtil)
+{
+	deconcept.SWFObjectUtil = {};
+}
+
+deconcept.SWFObject = function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey)
+{
+	if(!document.getElementById) { return; }
 	this.DETECT_KEY = detectKey ? detectKey : 'detectflash';
 	this.skipDetect = deconcept.util.getRequestParameter(this.DETECT_KEY);
-	this.params = new Object();
-	this.variables = new Object();
-	this.attributes = new Array();
+	this.params = {};
+	this.variables = {};
+	this.attributes = [];
 	if(swf) { this.setAttribute('swf', swf); }
 	if(id) { this.setAttribute('id', id); }
 	if(w) { this.setAttribute('width', w); }
 	if(h) { this.setAttribute('height', h); }
 	if(ver) { this.setAttribute('version', new deconcept.PlayerVersion(ver.toString().split("."))); }
 	this.installedVer = deconcept.SWFObjectUtil.getPlayerVersion();
-	if (!window.opera && document.all && this.installedVer.major > 7) {
+	if (!window.opera && document.all && this.installedVer.major > 7)
+	{
 		// only add the onunload cleanup if the Flash Player version supports External Interface and we are in IE
 		deconcept.SWFObject.doPrepUnload = true;
 	}
-	if(c) { this.addParam('bgcolor', c); }
+	if(c)
+	{
+		this.addParam('bgcolor', c);
+	}
 	var q = quality ? quality : 'high';
 	this.addParam('quality', q);
 	this.setAttribute('useExpressInstall', false);
@@ -39,10 +52,16 @@
 	var xir = (xiRedirectUrl) ? xiRedirectUrl : window.location;
 	this.setAttribute('xiRedirectUrl', xir);
 	this.setAttribute('redirectUrl', '');
-	if(redirectUrl) { this.setAttribute('redirectUrl', redirectUrl); }
-}
-deconcept.SWFObject.prototype = {
-	useExpressInstall: function(path) {
+	if(redirectUrl)
+	{
+		this.setAttribute('redirectUrl', redirectUrl);
+	}
+};
+
+deconcept.SWFObject.prototype =
+{
+	useExpressInstall: function(path)
+	{
 		this.xiSWFPath = !path ? "expressinstall.swf" : path;
 		this.setAttribute('useExpressInstall', true);
 	},
@@ -68,7 +87,7 @@
 		return this.variables;
 	},
 	getVariablePairs: function(){
-		var variablePairs = new Array();
+		var variablePairs = [];
 		var key;
 		var variables = this.getVariables();
 		for(key in variables){
@@ -78,6 +97,9 @@
 	},
 	getSWFHTML: function() {
 		var swfNode = "";
+		var params = {};
+		var key = "";
+		var pairs = "";
 		if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { // netscape plugin architecture
 			if (this.getAttribute("doExpressInstall")) {
 				this.addVariable("MMplayerType", "PlugIn");
@@ -85,10 +107,10 @@
 			}
 			swfNode = '<embed type="application/x-shockwave-flash" src="'+ this.getAttribute('swf') +'" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'"';
 			swfNode += ' id="'+ this.getAttribute('id') +'" name="'+ this.getAttribute('id') +'" ';
-			var params = this.getParams();
-			 for(var key in params){ swfNode += [key] +'="'+ params[key] +'" '; }
-			var pairs = this.getVariablePairs().join("&");
-			 if (pairs.length > 0){ swfNode += 'flashvars="'+ pairs +'"'; }
+			params = this.getParams();
+			for(key in params){ swfNode += [key] +'="'+ params[key] +'" '; }
+			pairs = this.getVariablePairs().join("&");
+			if (pairs.length > 0){ swfNode += 'flashvars="'+ pairs +'"'; }
 			swfNode += '/>';
 		} else { // PC IE
 			if (this.getAttribute("doExpressInstall")) {
@@ -97,17 +119,18 @@
 			}
 			swfNode = '<object id="'+ this.getAttribute('id') +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'">';
 			swfNode += '<param name="movie" value="'+ this.getAttribute('swf') +'" />';
-			var params = this.getParams();
-			for(var key in params) {
+			params = this.getParams();
+			for(key in params) {
 			 swfNode += '<param name="'+ key +'" value="'+ params[key] +'" />';
 			}
-			var pairs = this.getVariablePairs().join("&");
+			pairs = this.getVariablePairs().join("&");
 			if(pairs.length > 0) {swfNode += '<param name="flashvars" value="'+ pairs +'" />';}
 			swfNode += "</object>";
 		}
 		return swfNode;
 	},
-	write: function(elementId){
+	write: function(elementId)
+	{
 		if(this.getAttribute('useExpressInstall')) {
 			// check to see if we need to do an express install
 			var expressInstallReqVer = new deconcept.PlayerVersion([6,0,65]);
@@ -118,120 +141,184 @@
 				this.addVariable("MMdoctitle", document.title);
 			}
 		}
-		if(this.skipDetect || this.getAttribute('doExpressInstall') || this.installedVer.versionIsValid(this.getAttribute('version'))){
+		if(this.skipDetect || this.getAttribute('doExpressInstall') || this.installedVer.versionIsValid(this.getAttribute('version')))
+		{
 			var n = (typeof elementId == 'string') ? document.getElementById(elementId) : elementId;
 			n.innerHTML = this.getSWFHTML();
 			return true;
-		}else{
-			if(this.getAttribute('redirectUrl') != "") {
+		}
+		else
+		{
+			if(this.getAttribute('redirectUrl') !== "")
+			{
 				document.location.replace(this.getAttribute('redirectUrl'));
 			}
 		}
 		return false;
 	}
-}
+};
 
 /* ---- detection functions ---- */
-deconcept.SWFObjectUtil.getPlayerVersion = function(){
+deconcept.SWFObjectUtil.getPlayerVersion = function()
+{
+	var axo = null;
 	var PlayerVersion = new deconcept.PlayerVersion([0,0,0]);
-	if(navigator.plugins && navigator.mimeTypes.length){
+	if(navigator.plugins && navigator.mimeTypes.length)
+	{
 		var x = navigator.plugins["Shockwave Flash"];
-		if(x && x.description) {
+		if(x && x.description)
+		{
 			PlayerVersion = new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split("."));
 		}
-	}else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ // if Windows CE
-		var axo = 1;
+	}
+	else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0)
+	{ // if Windows CE
 		var counter = 3;
-		while(axo) {
-			try {
+		while(axo)
+		{
+			try
+			{
 				counter++;
 				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ counter);
 //				document.write("player v: "+ counter);
 				PlayerVersion = new deconcept.PlayerVersion([counter,0,0]);
-			} catch (e) {
+			}
+			catch(e)
+			{
 				axo = null;
 			}
 		}
-	} else { // Win IE (non mobile)
+	}
+	else
+	{ // Win IE (non mobile)
 		// do minor version lookup in IE, but avoid fp6 crashing issues
 		// see http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/
-		try{
-			var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
-		}catch(e){
-			try {
-				var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
+		try
+		{
+			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
+		}
+		catch(e)
+		{
+			try
+			{
+				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
 				PlayerVersion = new deconcept.PlayerVersion([6,0,21]);
 				axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code)
-			} catch(e) {
-				if (PlayerVersion.major == 6) {
+			}
+			catch(e)
+			{
+				if(PlayerVersion.major == 6)
+				{
 					return PlayerVersion;
 				}
 			}
-			try {
+			try
+			{
 				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
-			} catch(e) {}
+			}
+			catch(e) {}
 		}
-		if (axo != null) {
+		
+		if(axo !== null)
+		{
 			PlayerVersion = new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));
 		}
 	}
 	return PlayerVersion;
-}
-deconcept.PlayerVersion = function(arrVersion){
-	this.major = arrVersion[0] != null ? parseInt(arrVersion[0]) : 0;
-	this.minor = arrVersion[1] != null ? parseInt(arrVersion[1]) : 0;
-	this.rev = arrVersion[2] != null ? parseInt(arrVersion[2]) : 0;
-}
-deconcept.PlayerVersion.prototype.versionIsValid = function(fv){
-	if(this.major < fv.major) return false;
-	if(this.major > fv.major) return true;
-	if(this.minor < fv.minor) return false;
-	if(this.minor > fv.minor) return true;
-	if(this.rev < fv.rev) return false;
+};
+
+deconcept.PlayerVersion = function(arrVersion)
+{
+	this.major = arrVersion[0] !== null ? parseInt(arrVersion[0], 0) : 0;
+	this.minor = arrVersion[1] !== null ? parseInt(arrVersion[1], 0) : 0;
+	this.rev = arrVersion[2] !== null ? parseInt(arrVersion[2], 0) : 0;
+};
+
+deconcept.PlayerVersion.prototype.versionIsValid = function(fv)
+{
+	if(this.major < fv.major)
+	{
+		return false;
+	}
+	if(this.major > fv.major)
+	{
+		return true;
+	}
+	if(this.minor < fv.minor)
+	{
+		return false;
+	}
+	if(this.minor > fv.minor)
+	{
+		return true;
+	}
+	if(this.rev < fv.rev)
+	{
+		return false;
+	}
 	return true;
-}
+};
+
 /* ---- get value of query string param ---- */
-deconcept.util = {
-	getRequestParameter: function(param) {
+deconcept.util =
+{
+	getRequestParameter: function(param)
+	{
 		var q = document.location.search || document.location.hash;
-		if (param == null) { return q; }
-		if(q) {
+		if(param === null) { return q; }
+		if(q)
+		{
 			var pairs = q.substring(1).split("&");
-			for (var i=0; i < pairs.length; i++) {
-				if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
-					return pairs[i].substring((pairs[i].indexOf("=")+1));
+			for(var i=0; i < pairs.length; i++)
+			{
+				if (pairs[i].substring(0, pairs[i].indexOf("=")) == param)
+				{
+					return pairs[i].substring((pairs[i].indexOf("=") + 1));
 				}
 			}
 		}
 		return "";
 	}
-}
+};
+
 /* fix for video streaming bug */
-deconcept.SWFObjectUtil.cleanupSWFs = function() {
+deconcept.SWFObjectUtil.cleanupSWFs = function()
+{
 	var objects = document.getElementsByTagName("OBJECT");
-	for (var i = objects.length - 1; i >= 0; i--) {
+	for(var i = objects.length - 1; i >= 0; i--)
+	{
 		objects[i].style.display = 'none';
-		for (var x in objects[i]) {
-			if (typeof objects[i][x] == 'function') {
+		for(var x in objects[i])
+		{
+			if(typeof objects[i][x] == 'function')
+			{
 				objects[i][x] = function(){};
 			}
 		}
 	}
-}
+};
+
 // fixes bug in some fp9 versions see http://blog.deconcept.com/2006/07/28/swfobject-143-released/
-if (deconcept.SWFObject.doPrepUnload) {
-	if (!deconcept.unloadSet) {
-		deconcept.SWFObjectUtil.prepUnload = function() {
+if(deconcept.SWFObject.doPrepUnload)
+{
+	if(!deconcept.unloadSet)
+	{
+		deconcept.SWFObjectUtil.prepUnload = function()
+		{
 			__flash_unloadHandler = function(){};
 			__flash_savedUnloadHandler = function(){};
 			window.attachEvent("onunload", deconcept.SWFObjectUtil.cleanupSWFs);
-		}
+		};
 		window.attachEvent("onbeforeunload", deconcept.SWFObjectUtil.prepUnload);
 		deconcept.unloadSet = true;
 	}
 }
+
 /* add document.getElementById if needed (mobile IE < 5) */
-if (!document.getElementById && document.all) { document.getElementById = function(id) { return document.all[id]; }}
+if(!document.getElementById && document.all)
+{
+	document.getElementById = function(id) { return document.all[id]; };
+}
 
 /* add some aliases for ease of use/backwards compatibility */
 var getQueryParamValue = deconcept.util.getRequestParameter;
@@ -267,7 +354,8 @@
 	this._swfURL = swfURL;
 	
 	//embed the SWF file in the page
-	this._embedSWF(this._swfURL, containerID, attributes.id, attributes.version, attributes.backgroundColor, attributes.expressInstall);
+	this._embedSWF(this._swfURL, containerID, attributes.id, attributes.version,
+		attributes.backgroundColor, attributes.expressInstall, attributes.wmode);
 	
 	/**
 	 * Fires when the SWF is initialized and communication is possible.
@@ -326,11 +414,11 @@
 	 * @method _embedSWF
 	 * @private
 	 */
-	_embedSWF: function(swfURL, containerID, swfID, version, backgroundColor, expressInstall)
+	_embedSWF: function(swfURL, containerID, swfID, version, backgroundColor, expressInstall, wmode)
 	{
 		//standard SWFObject embed
-		var swfObj = new deconcept.SWFObject(swfURL, swfID, "100%", "100%", version, backgroundColor, expressInstall);
-		
+		var swfObj = new deconcept.SWFObject(swfURL, swfID, "100%", "100%", version, backgroundColor);
+
 		if(expressInstall)
 		{
 			swfObj.useExpressInstall(expressInstall);
@@ -338,6 +426,12 @@
 
 		//make sure we can communicate with ExternalInterface
 		swfObj.addParam("allowScriptAccess", "always");
+		
+		if(wmode !== null)
+		{
+			swfObj.addParam("wmode", wmode);
+		}
+		
 		//again, a useful ExternalInterface trick
 		swfObj.addVariable("allowedDomain", document.location.hostname);
 
@@ -356,7 +450,10 @@
 			//this will allow the event handler to communicate with a YAHOO.widget.FlashAdapter
 			this._swf.owner = this;
 		}
-		else YAHOO.log("Unable to load SWF " + swfURL);
+		else
+		{
+			YAHOO.log("Unable to load SWF " + swfURL);
+		}
 	},
 
 	/**
@@ -371,15 +468,11 @@
 		switch(type)
 		{
 			case "swfReady":
-			{
    				this._loadHandler();
 				return;
-			}
 			case "log":
-			{
 				YAHOO.log(event.message, event.category, this.toString());
 				return;
-			}
 		}
 		
 		//be sure to return after your case or the event will automatically fire!
@@ -450,7 +543,10 @@
 		//fix for ie: if owner doesn't exist yet, try again in a moment
 		setTimeout(function() { YAHOO.widget.FlashAdapter.eventHandler( elementID, event ); }, 0);
 	}
-	else loadedSWF.owner._eventHandler(event);
+	else
+	{
+		loadedSWF.owner._eventHandler(event);
+	}
 };
 
 /**
@@ -599,6 +695,15 @@
 	 * @private
 	 */
 	_pollingInterval: null,
+	
+	/**
+	 * Indicates whether all attributes have been set and
+	 * the dataSource may be passed to the SWF.
+	 * @property _initialized
+	 * @type Boolean
+	 * @private
+	 */
+	_initialized: false,
 
 	/**
 	 * Public accessor to the unique name of the Chart instance.
@@ -781,6 +886,8 @@
 		
 		YAHOO.widget.Chart.superclass._loadHandler.call(this);
 		
+		this._initialized = true;
+		
 		if(this._dataSource)
 		{
 			this.set("dataSource", this._dataSource);
@@ -795,9 +902,14 @@
 	 */
 	_refreshData: function()
 	{
-		if(this._dataSource != null)
+		if(!this._initialized)
 		{
-			if(this._pollingID != null)
+			return;
+		}
+		
+		if(this._dataSource !== null)
+		{
+			if(this._pollingID !== null)
 			{
 				this._dataSource.clearInterval(this._pollingID);
 				this._pollingID = null;
@@ -835,17 +947,18 @@
 			//editing them directly.
 			var dataProvider = [];	
 			var seriesCount = 0;
-			if(this._seriesDefs)
+			var currentSeries = null;
+			var i = 0;
+			if(this._seriesDefs !== null)
 			{
 				seriesCount = this._seriesDefs.length;
-				for(var i = 0; i < seriesCount; i++)
+				for(i = 0; i < seriesCount; i++)
 				{
-					var currentSeries = this._seriesDefs[i];
+					currentSeries = this._seriesDefs[i];
 					var clonedSeries = {};
 					for(var prop in currentSeries)
 					{
-						
-						if(prop == "style" && currentSeries.style != null)
+						if(prop == "style" && currentSeries.style !== null)
 						{
 							clonedSeries.style = YAHOO.lang.JSON.stringify(currentSeries.style);
 							styleChanged = true;
@@ -854,7 +967,10 @@
 							//so null out the style property.
 							currentSeries.style = null;
 						}
-						else clonedSeries[prop] = currentSeries[prop];
+						else
+						{
+							clonedSeries[prop] = currentSeries[prop];
+						}
 					}
 					dataProvider.push(clonedSeries);
 				}
@@ -971,6 +1087,7 @@
 	_setSeriesDefs: function(value)
 	{
 		this._seriesDefs = value;
+		this._refreshData();
 	},
 
 	/**
@@ -1616,7 +1733,20 @@
 
 YAHOO.widget.Series.prototype = 
 {
+	/**
+	 * The type of series.
+	 *
+	 * @property type
+	 * @type String
+	 */
 	type: null,
+	
+	/**
+	 * The human-readable name of the series.
+	 *
+	 * @property displayName
+	 * @type String
+	 */
 	displayName: null
 };
 
@@ -1634,7 +1764,20 @@
 
 YAHOO.lang.extend(YAHOO.widget.CartesianSeries, YAHOO.widget.Series,
 {
+	/**
+	 * The field used to access the x-axis value from the items from the data source.
+	 *
+	 * @property xField
+	 * @type String
+	 */
 	xField: null,
+	
+	/**
+	 * The field used to access the y-axis value from the items from the data source.
+	 *
+	 * @property yField
+	 * @type String
+	 */
 	yField: null
 });
 
@@ -1710,4 +1853,4 @@
 	categoryField: null
 });
 
-YAHOO.register("charts", YAHOO.widget.Chart, {version: "2.4.1", build: "742"});
+YAHOO.register("charts", YAHOO.widget.Chart, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/charts/charts-experimental-min.js
===================================================================
--- trunk/root/static/yui/charts/charts-experimental-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/charts/charts-experimental-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +1,15 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-if(typeof deconcept=="undefined"){var deconcept=new Object();}if(typeof deconcept.util=="undefined"){deconcept.util=new Object();}if(typeof deconcept.SWFObjectUtil=="undefined"){deconcept.SWFObjectUtil=new Object();}deconcept.SWFObject=function(E,C,K,F,H,J,L,G,A,D){if(!document.getElementById){return ;}this.DETECT_KEY=D?D:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params=new Object();this.variables=new Object();this.attributes=new Array();if(E){this.setAttribute("swf",E);}if(C){this.setAttribute("id",C);}if(K){this.setAttribute("width",K);}if(F){this.setAttribute("height",F);}if(H){this.setAttribute("version",new deconcept.PlayerVersion(H.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}if(J){this.addParam("bgcolor",J);}var B=L?L:"high";this.addParam("quality",B);this.setAttribute("useExpressInstal!
 l",false);this.setAttribute("doExpressInstall",false);var I=(G)?G:window.location;this.setAttribute("xiRedirectUrl",I);this.setAttribute("redirectUrl","");if(A){this.setAttribute("redirectUrl",A);}};deconcept.SWFObject.prototype={useExpressInstall:function(A){this.xiSWFPath=!A?"expressinstall.swf":A;this.setAttribute("useExpressInstall",true);},setAttribute:function(A,B){this.attributes[A]=B;},getAttribute:function(A){return this.attributes[A];},addParam:function(A,B){this.params[A]=B;},getParams:function(){return this.params;},addVariable:function(A,B){this.variables[A]=B;},getVariable:function(A){return this.variables[A];},getVariables:function(){return this.variables;},getVariablePairs:function(){var A=new Array();var B;var C=this.getVariables();for(B in C){A[A.length]=B+"="+C[B];}return A;},getSWFHTML:function(){var D="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugI!
 n");this.setAttribute("swf",this.xiSWFPath);}D="<embed type=\"!
 applicat
ion/x-shockwave-flash\" src=\""+this.getAttribute("swf")+"\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\"";D+=" id=\""+this.getAttribute("id")+"\" name=\""+this.getAttribute("id")+"\" ";var C=this.getParams();for(var A in C){D+=[A]+"=\""+C[A]+"\" ";}var B=this.getVariablePairs().join("&");if(B.length>0){D+="flashvars=\""+B+"\"";}D+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}D="<object id=\""+this.getAttribute("id")+"\" classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\">";D+="<param name=\"movie\" value=\""+this.getAttribute("swf")+"\" />";var C=this.getParams();for(var A in C){D+="<param name=\""+A+"\" value=\""+C[A]+"\" />";}var B=this.getVariablePairs().join("&");if(B.length>!
 0){D+="<param name=\"flashvars\" value=\""+B+"\" />";}D+="</object>";}return D;},write:function(A){if(this.getAttribute("useExpressInstall")){var B=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(B)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var C=(typeof A=="string")?document.getElementById(A):A;C.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var C=new deconcept.PlayerVersion([0,0,0]);if(navigator.pl!
 ugins&&navigator.mimeTypes.length){var A=navigator.plugins["Sh!
 ockwave 
Flash"];if(A&&A.description){C=new deconcept.PlayerVersion(A.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var D=1;var B=3;while(D){try{B++;D=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+B);C=new deconcept.PlayerVersion([B,0,0]);}catch(E){D=null;}}}else{try{var D=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(E){try{var D=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");C=new deconcept.PlayerVersion([6,0,21]);D.AllowScriptAccess="always";}catch(E){if(C.major==6){return C;}}try{D=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(E){}}if(D!=null){C=new deconcept.PlayerVersion(D.GetVariable("$version").split(" ")[1].split(","));}}}return C;};deconcept.PlayerVersion=function(A){this.major=A[0]!=null?parseInt(A[0]):0;this.minor=A[1]!=null?parseInt(A[1]):0;this.rev=A[2]!=null?parseInt(A[2]):0;};deconcept.PlayerVersion.prototype.version!
 IsValid=function(A){if(this.major<A.major){return false;}if(this.major>A.major){return true;}if(this.minor<A.minor){return false;}if(this.minor>A.minor){return true;}if(this.rev<A.rev){return false;}return true;};deconcept.util={getRequestParameter:function(D){var C=document.location.search||document.location.hash;if(D==null){return C;}if(C){var B=C.substring(1).split("&");for(var A=0;A<B.length;A++){if(B[A].substring(0,B[A].indexOf("="))==D){return B[A].substring((B[A].indexOf("=")+1));}}}return"";}};deconcept.SWFObjectUtil.cleanupSWFs=function(){var C=document.getElementsByTagName("OBJECT");for(var B=C.length-1;B>=0;B--){C[B].style.display="none";for(var A in C[B]){if(typeof C[B][A]=="function"){C[B][A]=function(){};}}}};if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);
-};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(!document.getElementById&&document.all){document.getElementById=function(A){return document.all[A];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;YAHOO.widget.FlashAdapter=function(C,A,B){this._queue=this._queue||[];this._events=this._events||{};this._configs=this._configs||{};B=B||{};this._id=B.id=B.id||YAHOO.util.Dom.generateId(null,"yuigen");B.version=B.version||"9.0.45";B.backgroundColor=B.backgroundColor||"#ffffff";this._attributes=B;this._swfURL=C;this._embedSWF(this._swfURL,A,B.id,B.version,B.backgroundColor,B.expressInstall);this.createEvent("contentReady");};YAHOO.extend(YAHOO.widget.FlashAdapter,YAHOO.util.AttributeProvider,{_swfURL:null,_swf:null,_id:null,_attributes:null,toString:function(){return"FlashAdapter "+this._id;},_embedSWF:function(H,G,C,B,E,F){var D=new deconcept.SWF!
 Object(H,C,"100%","100%",B,E,F);if(F){D.useExpressInstall(F);}D.addParam("allowScriptAccess","always");D.addVariable("allowedDomain",document.location.hostname);D.addVariable("elementID",C);D.addVariable("eventHandler","YAHOO.widget.FlashAdapter.eventHandler");var A=YAHOO.util.Dom.get(G);var I=D.write(A);if(I){this._swf=YAHOO.util.Dom.get(C);this._swf.owner=this;}},_eventHandler:function(B){var A=B.type;switch(A){case"swfReady":this._loadHandler();return ;case"log":return ;}this.fireEvent(A,B);},_loadHandler:function(){this._initAttributes(this._attributes);this.setAttributes(this._attributes,true);this._attributes=null;this.fireEvent("contentReady");},_initAttributes:function(A){this.getAttributeConfig("swfURL",{method:this._getSWFURL});},_getSWFURL:function(){return this._swfURL;}});YAHOO.widget.FlashAdapter.eventHandler=function(A,C){var B=YAHOO.util.Dom.get(A);if(!B.owner){setTimeout(function(){YAHOO.widget.FlashAdapter.eventHandler(A,C);},0);}else{B.owner._eventHandler!
 (C);}};YAHOO.widget.Chart=function(C,A,D,B){YAHOO.widget.Chart!
 .supercl
ass.constructor.call(this,YAHOO.widget.Chart.SWFURL,A,B);this._type=C;this._dataSource=D;this.createEvent("itemMouseOverEvent");this.createEvent("itemMouseOutEvent");this.createEvent("itemClickEvent");this.createEvent("itemDoubleClickEvent");this.createEvent("itemDragStartEvent");this.createEvent("itemDragEvent");this.createEvent("itemDragEndEvent");};YAHOO.extend(YAHOO.widget.Chart,YAHOO.widget.FlashAdapter,{_type:null,_pollingID:null,_pollingInterval:null,toString:function(){return"Chart "+this._id;},setStyle:function(A,B){B=YAHOO.lang.JSON.stringify(B);this._swf.setStyle(A,B);},setStyles:function(A){A=YAHOO.lang.JSON.stringify(A);this._swf.setStyles(A);},setSeriesStyles:function(B){for(var A=0;A<B.length;A++){B[A]=YAHOO.lang.JSON.stringify(B[A]);}this._swf.setSeriesStyles(B);},_initAttributes:function(A){YAHOO.widget.Chart.superclass._initAttributes.call(this,A);this.getAttributeConfig("request",{method:this._getRequest});this.setAttributeConfig("request",{method:this._se!
 tRequest});this.getAttributeConfig("dataSource",{method:this._getDataSource});this.setAttributeConfig("dataSource",{method:this._setDataSource});this.getAttributeConfig("series",{method:this._getSeriesDefs});this.setAttributeConfig("series",{method:this._setSeriesDefs});this.getAttributeConfig("categoryNames",{method:this._getCategoryNames});this.setAttributeConfig("categoryNames",{validator:YAHOO.lang.isArray,method:this._setCategoryNames});this.getAttributeConfig("dataTipFunction",{method:this._getDataTipFunction});this.setAttributeConfig("dataTipFunction",{method:this._setDataTipFunction});this.getAttributeConfig("polling",{method:this._getPolling});this.setAttributeConfig("polling",{method:this._setPolling});},_loadHandler:function(){this._swf.setType(this._type);if(this._attributes.style){var A=this._attributes.style;this.setStyles(A);}YAHOO.widget.Chart.superclass._loadHandler.call(this);if(this._dataSource){this.set("dataSource",this._dataSource);}},_refreshData:func!
 tion(){if(this._dataSource!=null){if(this._pollingID!=null){th!
 is._data
Source.clearInterval(this._pollingID);this._pollingID=null;}if(this._pollingInterval>0){this._pollingID=this._dataSource.setInterval(this._pollingInterval,this._request,this._loadDataHandler,this);}else{this._dataSource.sendRequest(this._request,this._loadDataHandler,this);}}},_loadDataHandler:function(D,C,J){if(J){}else{var I=false;var F=[];var E=0;if(this._seriesDefs){E=this._seriesDefs.length;for(var H=0;H<E;H++){var K=this._seriesDefs[H];var B={};for(var A in K){if(A=="style"&&K.style!=null){B.style=YAHOO.lang.JSON.stringify(K.style);I=true;K.style=null;}else{B[A]=K[A];}}F.push(B);}}if(E>0){for(H=0;H<E;H++){K=F[H];if(!K.type){K.type=this._type;}K.dataProvider=C.results;}}else{var G={type:this._type,dataProvider:C.results};F.push(G);}this._swf.setDataProvider(F,I);}},_request:"",_getRequest:function(){return this._request;},_setRequest:function(A){this._request=A;this._refreshData();},_dataSource:null,_getDataSource:function(){return this._dataSource;},_setDataSource:func!
 tion(A){this._dataSource=A;this._refreshData();},_seriesDefs:null,_getSeriesDefs:function(){return this._seriesDefs;},_setSeriesDefs:function(A){this._seriesDefs=A;},_getCategoryNames:function(){return this._swf.getCategoryNames();},_setCategoryNames:function(A){this._swf.setCategoryNames(A);},_dataTipFunction:null,_getDataTipFunction:function(){return this._dataTipFunction;},_setDataTipFunction:function(A){this._dataTipFunction=A;this._swf.setDataTipFunction(A);},_getPolling:function(){return this._pollingInterval;},_setPolling:function(A){this._pollingInterval=A;this._refreshData();}});YAHOO.widget.Chart.SWFURL="assets/charts.swf";YAHOO.widget.PieChart=function(A,C,B){YAHOO.widget.PieChart.superclass.constructor.call(this,"pie",A,C,B);};YAHOO.lang.extend(YAHOO.widget.PieChart,YAHOO.widget.Chart,{_initAttributes:function(A){YAHOO.widget.PieChart.superclass._initAttributes.call(this,A);this.getAttributeConfig("dataField",{method:this._getDataField});
-this.setAttributeConfig("dataField",{validator:YAHOO.lang.isString,method:this._setDataField});this.getAttributeConfig("categoryField",{method:this._getCategoryField});this.setAttributeConfig("categoryField",{validator:YAHOO.lang.isString,method:this._setCategoryField});},_getDataField:function(){return this._swf.getDataField();},_setDataField:function(A){this._swf.setDataField(A);},_getCategoryField:function(){return this._swf.getCategoryField();},_setCategoryField:function(A){this._swf.setCategoryField(A);}});YAHOO.widget.CartesianChart=function(C,A,D,B){YAHOO.widget.CartesianChart.superclass.constructor.call(this,C,A,D,B);};YAHOO.lang.extend(YAHOO.widget.CartesianChart,YAHOO.widget.Chart,{_initAttributes:function(A){YAHOO.widget.CartesianChart.superclass._initAttributes.call(this,A);this.getAttributeConfig("xField",{method:this._getXField});this.setAttributeConfig("xField",{validator:YAHOO.lang.isString,method:this._setXField});this.getAttributeConfig("yField",{method:th!
 is._getYField});this.setAttributeConfig("yField",{validator:YAHOO.lang.isString,method:this._setYField});this.setAttributeConfig("xAxis",{method:this._setXAxis});this.setAttributeConfig("yAxis",{method:this._setYAxis});},_getXField:function(){return this._swf.getHorizontalField();},_setXField:function(A){this._swf.setHorizontalField(A);},_getYField:function(){return this._swf.getVerticalField();},_setYField:function(A){this._swf.setVerticalField(A);},_setXAxis:function(A){this._swf.setHorizontalAxis(A);},_setYAxis:function(A){this._swf.setVerticalAxis(A);}});YAHOO.widget.LineChart=function(A,C,B){YAHOO.widget.LineChart.superclass.constructor.call(this,"line",A,C,B);};YAHOO.lang.extend(YAHOO.widget.LineChart,YAHOO.widget.CartesianChart);YAHOO.widget.ColumnChart=function(A,C,B){YAHOO.widget.ColumnChart.superclass.constructor.call(this,"column",A,C,B);};YAHOO.lang.extend(YAHOO.widget.ColumnChart,YAHOO.widget.CartesianChart);YAHOO.widget.BarChart=function(A,C,B){YAHOO.widget.Ba!
 rChart.superclass.constructor.call(this,"bar",A,C,B);};YAHOO.l!
 ang.exte
nd(YAHOO.widget.BarChart,YAHOO.widget.CartesianChart);YAHOO.widget.Axis=function(){};YAHOO.widget.Axis.prototype={type:null,orientation:"horizontal",reverse:false,labelFunction:null,hideOverlappingLabels:true};YAHOO.widget.NumericAxis=function(){YAHOO.widget.NumericAxis.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.NumericAxis,YAHOO.widget.Axis,{type:"numeric",minimum:NaN,maximum:NaN,majorUnit:NaN,minorUnit:NaN,snapToUnits:true,alwaysShowZero:true,scale:"linear"});YAHOO.widget.TimeAxis=function(){YAHOO.widget.TimeAxis.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.TimeAxis,YAHOO.widget.Axis,{type:"time",minimum:null,maximum:null,majorUnit:NaN,majorTimeUnit:null,minorUnit:NaN,minorTimeUnit:null,snapToUnits:true});YAHOO.widget.CategoryAxis=function(){YAHOO.widget.CategoryAxis.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.CategoryAxis,YAHOO.widget.Axis,{type:"category",categoryNames:null});YAHOO.widget.Series=functio!
 n(){};YAHOO.widget.Series.prototype={type:null,displayName:null};YAHOO.widget.CartesianSeries=function(){YAHOO.widget.CartesianSeries.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.CartesianSeries,YAHOO.widget.Series,{xField:null,yField:null});YAHOO.widget.ColumnSeries=function(){YAHOO.widget.ColumnSeries.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.ColumnSeries,YAHOO.widget.CartesianSeries,{type:"column"});YAHOO.widget.LineSeries=function(){YAHOO.widget.LineSeries.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.LineSeries,YAHOO.widget.CartesianSeries,{type:"line"});YAHOO.widget.BarSeries=function(){YAHOO.widget.BarSeries.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.BarSeries,YAHOO.widget.CartesianSeries,{type:"bar"});YAHOO.widget.PieSeries=function(){YAHOO.widget.PieSeries.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.PieSeries,YAHOO.widget.Series,{type:"pie",dataField:n!
 ull,categoryField:null});YAHOO.register("charts",YAHOO.widget.!
 Chart,{v
ersion:"2.4.1",build:"742"});
\ No newline at end of file
+/*
+ * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
+ *
+ * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ */
+var deconcept=deconcept||{};if(typeof deconcept.util=="undefined"||!deconcept.util){deconcept.util={};}if(typeof deconcept.SWFObjectUtil=="undefined"||!deconcept.SWFObjectUtil){deconcept.SWFObjectUtil={};}deconcept.SWFObject=function(E,C,K,F,H,J,L,G,A,D){if(!document.getElementById){return ;}this.DETECT_KEY=D?D:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params={};this.variables={};this.attributes=[];if(E){this.setAttribute("swf",E);}if(C){this.setAttribute("id",C);}if(K){this.setAttribute("width",K);}if(F){this.setAttribute("height",F);}if(H){this.setAttribute("version",new deconcept.PlayerVersion(H.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}if(J){this.addParam("bgcolor",J);}var B=L?L:"high";this.addParam("quality",B);this.setAttribute("useExpressInstall",false);this.setAttribute("doExpressIn!
 stall",false);var I=(G)?G:window.location;this.setAttribute("xiRedirectUrl",I);this.setAttribute("redirectUrl","");if(A){this.setAttribute("redirectUrl",A);}};deconcept.SWFObject.prototype={useExpressInstall:function(A){this.xiSWFPath=!A?"expressinstall.swf":A;this.setAttribute("useExpressInstall",true);},setAttribute:function(A,B){this.attributes[A]=B;},getAttribute:function(A){return this.attributes[A];},addParam:function(A,B){this.params[A]=B;},getParams:function(){return this.params;},addVariable:function(A,B){this.variables[A]=B;},getVariable:function(A){return this.variables[A];},getVariables:function(){return this.variables;},getVariablePairs:function(){var A=[];var B;var C=this.getVariables();for(B in C){A[A.length]=B+"="+C[B];}return A;},getSWFHTML:function(){var D="";var C={};var A="";var B="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugIn");this.setAttribute(!
 "swf",this.xiSWFPath);}D='<embed type="application/x-shockwave!
 -flash" 
src="'+this.getAttribute("swf")+'" width="'+this.getAttribute("width")+'" height="'+this.getAttribute("height")+'" style="'+this.getAttribute("style")+'"';D+=' id="'+this.getAttribute("id")+'" name="'+this.getAttribute("id")+'" ';C=this.getParams();for(A in C){D+=[A]+'="'+C[A]+'" ';}B=this.getVariablePairs().join("&");if(B.length>0){D+='flashvars="'+B+'"';}D+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}D='<object id="'+this.getAttribute("id")+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+this.getAttribute("width")+'" height="'+this.getAttribute("height")+'" style="'+this.getAttribute("style")+'">';D+='<param name="movie" value="'+this.getAttribute("swf")+'" />';C=this.getParams();for(A in C){D+='<param name="'+A+'" value="'+C[A]+'" />';}B=this.getVariablePairs().join("&");if(B.length>0){D+='<param name="flashvars" value="'+B+'" />';}D+="</object>";}return D;},write!
 :function(A){if(this.getAttribute("useExpressInstall")){var B=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(B)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var C=(typeof A=="string")?document.getElementById(A):A;C.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute("redirectUrl")!==""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var D=null;var C=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var A=navigator.plugins["Shockwave Flas!
 h"];if(A&&A.description){C=new deconcept.PlayerVersion(A.descr!
 iption.r
eplace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var B=3;while(D){try{B++;D=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+B);C=new deconcept.PlayerVersion([B,0,0]);}catch(E){D=null;}}}else{try{D=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(E){try{D=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");C=new deconcept.PlayerVersion([6,0,21]);D.AllowScriptAccess="always";}catch(E){if(C.major==6){return C;}}try{D=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(E){}}if(D!==null){C=new deconcept.PlayerVersion(D.GetVariable("$version").split(" ")[1].split(","));}}}return C;};deconcept.PlayerVersion=function(A){this.major=A[0]!==null?parseInt(A[0],0):0;this.minor=A[1]!==null?parseInt(A[1],0):0;this.rev=A[2]!==null?parseInt(A[2],0):0;};deconcept.PlayerVersion.prototype.versionIsValid=function(A){if(this.major<A.major){return false;}if(this.major>A.major){!
 return true;}if(this.minor<A.minor){return false;}if(this.minor>A.minor){return true;}if(this.rev<A.rev){return false;}return true;};deconcept.util={getRequestParameter:function(D){var C=document.location.search||document.location.hash;if(D===null){return C;}if(C){var B=C.substring(1).split("&");for(var A=0;A<B.length;A++){if(B[A].substring(0,B[A].indexOf("="))==D){return B[A].substring((B[A].indexOf("=")+1));}}}return"";}};deconcept.SWFObjectUtil.cleanupSWFs=function(){var C=document.getElementsByTagName("OBJECT");for(var B=C.length-1;B>=0;B--){C[B].style.display="none";for(var A in C[B]){if(typeof C[B][A]=="function"){C[B][A]=function(){};}}}};if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};
+__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(!document.getElementById&&document.all){document.getElementById=function(A){return document.all[A];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;YAHOO.widget.FlashAdapter=function(C,A,B){this._queue=this._queue||[];this._events=this._events||{};this._configs=this._configs||{};B=B||{};this._id=B.id=B.id||YAHOO.util.Dom.generateId(null,"yuigen");B.version=B.version||"9.0.45";B.backgroundColor=B.backgroundColor||"#ffffff";this._attributes=B;this._swfURL=C;this._embedSWF(this._swfURL,A,B.id,B.version,B.backgroundColor,B.expressInstall,B.wmode);this.createEvent("contentReady");};YAHOO.extend(YAHOO.widget.FlashAdapter,YAHOO.util.AttributeProvider,{_swfURL:null,_swf:null,_id:null,_attribute!
 s:null,toString:function(){return"FlashAdapter "+this._id;},_embedSWF:function(I,H,D,C,F,G,B){var E=new deconcept.SWFObject(I,D,"100%","100%",C,F);if(G){E.useExpressInstall(G);}E.addParam("allowScriptAccess","always");if(B!==null){E.addParam("wmode",B);}E.addVariable("allowedDomain",document.location.hostname);E.addVariable("elementID",D);E.addVariable("eventHandler","YAHOO.widget.FlashAdapter.eventHandler");var A=YAHOO.util.Dom.get(H);var J=E.write(A);if(J){this._swf=YAHOO.util.Dom.get(D);this._swf.owner=this;}else{}},_eventHandler:function(B){var A=B.type;switch(A){case"swfReady":this._loadHandler();return ;case"log":return ;}this.fireEvent(A,B);},_loadHandler:function(){this._initAttributes(this._attributes);this.setAttributes(this._attributes,true);this._attributes=null;this.fireEvent("contentReady");},_initAttributes:function(A){this.getAttributeConfig("swfURL",{method:this._getSWFURL});},_getSWFURL:function(){return this._swfURL;}});YAHOO.widget.FlashAdapter.eventHand!
 ler=function(A,C){var B=YAHOO.util.Dom.get(A);if(!B.owner){set!
 Timeout(
function(){YAHOO.widget.FlashAdapter.eventHandler(A,C);},0);}else{B.owner._eventHandler(C);}};YAHOO.widget.Chart=function(C,A,D,B){YAHOO.widget.Chart.superclass.constructor.call(this,YAHOO.widget.Chart.SWFURL,A,B);this._type=C;this._dataSource=D;this.createEvent("itemMouseOverEvent");this.createEvent("itemMouseOutEvent");this.createEvent("itemClickEvent");this.createEvent("itemDoubleClickEvent");this.createEvent("itemDragStartEvent");this.createEvent("itemDragEvent");this.createEvent("itemDragEndEvent");};YAHOO.extend(YAHOO.widget.Chart,YAHOO.widget.FlashAdapter,{_type:null,_pollingID:null,_pollingInterval:null,_initialized:false,toString:function(){return"Chart "+this._id;},setStyle:function(A,B){B=YAHOO.lang.JSON.stringify(B);this._swf.setStyle(A,B);},setStyles:function(A){A=YAHOO.lang.JSON.stringify(A);this._swf.setStyles(A);},setSeriesStyles:function(B){for(var A=0;A<B.length;A++){B[A]=YAHOO.lang.JSON.stringify(B[A]);}this._swf.setSeriesStyles(B);},_initAttributes:functi!
 on(A){YAHOO.widget.Chart.superclass._initAttributes.call(this,A);this.getAttributeConfig("request",{method:this._getRequest});this.setAttributeConfig("request",{method:this._setRequest});this.getAttributeConfig("dataSource",{method:this._getDataSource});this.setAttributeConfig("dataSource",{method:this._setDataSource});this.getAttributeConfig("series",{method:this._getSeriesDefs});this.setAttributeConfig("series",{method:this._setSeriesDefs});this.getAttributeConfig("categoryNames",{method:this._getCategoryNames});this.setAttributeConfig("categoryNames",{validator:YAHOO.lang.isArray,method:this._setCategoryNames});this.getAttributeConfig("dataTipFunction",{method:this._getDataTipFunction});this.setAttributeConfig("dataTipFunction",{method:this._setDataTipFunction});this.getAttributeConfig("polling",{method:this._getPolling});this.setAttributeConfig("polling",{method:this._setPolling});},_loadHandler:function(){this._swf.setType(this._type);if(this._attributes.style){var A=t!
 his._attributes.style;this.setStyles(A);}YAHOO.widget.Chart.su!
 perclass
._loadHandler.call(this);this._initialized=true;if(this._dataSource){this.set("dataSource",this._dataSource);}},_refreshData:function(){if(!this._initialized){return ;}if(this._dataSource!==null){if(this._pollingID!==null){this._dataSource.clearInterval(this._pollingID);this._pollingID=null;}if(this._pollingInterval>0){this._pollingID=this._dataSource.setInterval(this._pollingInterval,this._request,this._loadDataHandler,this);}else{this._dataSource.sendRequest(this._request,this._loadDataHandler,this);}}},_loadDataHandler:function(D,C,J){if(J){}else{var I=false;var F=[];var E=0;var K=null;var H=0;if(this._seriesDefs!==null){E=this._seriesDefs.length;for(H=0;H<E;H++){K=this._seriesDefs[H];var B={};for(var A in K){if(A=="style"&&K.style!==null){B.style=YAHOO.lang.JSON.stringify(K.style);I=true;K.style=null;}else{B[A]=K[A];}}F.push(B);}}if(E>0){for(H=0;H<E;H++){K=F[H];if(!K.type){K.type=this._type;}K.dataProvider=C.results;}}else{var G={type:this._type,dataProvider:C.results};F!
 .push(G);}this._swf.setDataProvider(F,I);}},_request:"",_getRequest:function(){return this._request;},_setRequest:function(A){this._request=A;this._refreshData();},_dataSource:null,_getDataSource:function(){return this._dataSource;},_setDataSource:function(A){this._dataSource=A;this._refreshData();},_seriesDefs:null,_getSeriesDefs:function(){return this._seriesDefs;},_setSeriesDefs:function(A){this._seriesDefs=A;this._refreshData();},_getCategoryNames:function(){return this._swf.getCategoryNames();},_setCategoryNames:function(A){this._swf.setCategoryNames(A);},_dataTipFunction:null,_getDataTipFunction:function(){return this._dataTipFunction;},_setDataTipFunction:function(A){this._dataTipFunction=A;this._swf.setDataTipFunction(A);},_getPolling:function(){return this._pollingInterval;},_setPolling:function(A){this._pollingInterval=A;this._refreshData();}});YAHOO.widget.Chart.SWFURL="assets/charts.swf";YAHOO.widget.PieChart=function(A,C,B){YAHOO.widget.PieChart.superclass.cons!
 tructor.call(this,"pie",A,C,B);
+};YAHOO.lang.extend(YAHOO.widget.PieChart,YAHOO.widget.Chart,{_initAttributes:function(A){YAHOO.widget.PieChart.superclass._initAttributes.call(this,A);this.getAttributeConfig("dataField",{method:this._getDataField});this.setAttributeConfig("dataField",{validator:YAHOO.lang.isString,method:this._setDataField});this.getAttributeConfig("categoryField",{method:this._getCategoryField});this.setAttributeConfig("categoryField",{validator:YAHOO.lang.isString,method:this._setCategoryField});},_getDataField:function(){return this._swf.getDataField();},_setDataField:function(A){this._swf.setDataField(A);},_getCategoryField:function(){return this._swf.getCategoryField();},_setCategoryField:function(A){this._swf.setCategoryField(A);}});YAHOO.widget.CartesianChart=function(C,A,D,B){YAHOO.widget.CartesianChart.superclass.constructor.call(this,C,A,D,B);};YAHOO.lang.extend(YAHOO.widget.CartesianChart,YAHOO.widget.Chart,{_initAttributes:function(A){YAHOO.widget.CartesianChart.superclass._in!
 itAttributes.call(this,A);this.getAttributeConfig("xField",{method:this._getXField});this.setAttributeConfig("xField",{validator:YAHOO.lang.isString,method:this._setXField});this.getAttributeConfig("yField",{method:this._getYField});this.setAttributeConfig("yField",{validator:YAHOO.lang.isString,method:this._setYField});this.setAttributeConfig("xAxis",{method:this._setXAxis});this.setAttributeConfig("yAxis",{method:this._setYAxis});},_getXField:function(){return this._swf.getHorizontalField();},_setXField:function(A){this._swf.setHorizontalField(A);},_getYField:function(){return this._swf.getVerticalField();},_setYField:function(A){this._swf.setVerticalField(A);},_setXAxis:function(A){this._swf.setHorizontalAxis(A);},_setYAxis:function(A){this._swf.setVerticalAxis(A);}});YAHOO.widget.LineChart=function(A,C,B){YAHOO.widget.LineChart.superclass.constructor.call(this,"line",A,C,B);};YAHOO.lang.extend(YAHOO.widget.LineChart,YAHOO.widget.CartesianChart);YAHOO.widget.ColumnChart=!
 function(A,C,B){YAHOO.widget.ColumnChart.superclass.constructo!
 r.call(t
his,"column",A,C,B);};YAHOO.lang.extend(YAHOO.widget.ColumnChart,YAHOO.widget.CartesianChart);YAHOO.widget.BarChart=function(A,C,B){YAHOO.widget.BarChart.superclass.constructor.call(this,"bar",A,C,B);};YAHOO.lang.extend(YAHOO.widget.BarChart,YAHOO.widget.CartesianChart);YAHOO.widget.Axis=function(){};YAHOO.widget.Axis.prototype={type:null,orientation:"horizontal",reverse:false,labelFunction:null,hideOverlappingLabels:true};YAHOO.widget.NumericAxis=function(){YAHOO.widget.NumericAxis.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.NumericAxis,YAHOO.widget.Axis,{type:"numeric",minimum:NaN,maximum:NaN,majorUnit:NaN,minorUnit:NaN,snapToUnits:true,alwaysShowZero:true,scale:"linear"});YAHOO.widget.TimeAxis=function(){YAHOO.widget.TimeAxis.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.TimeAxis,YAHOO.widget.Axis,{type:"time",minimum:null,maximum:null,majorUnit:NaN,majorTimeUnit:null,minorUnit:NaN,minorTimeUnit:null,snapToUnits:true});YAHOO.wid!
 get.CategoryAxis=function(){YAHOO.widget.CategoryAxis.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.CategoryAxis,YAHOO.widget.Axis,{type:"category",categoryNames:null});YAHOO.widget.Series=function(){};YAHOO.widget.Series.prototype={type:null,displayName:null};YAHOO.widget.CartesianSeries=function(){YAHOO.widget.CartesianSeries.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.CartesianSeries,YAHOO.widget.Series,{xField:null,yField:null});YAHOO.widget.ColumnSeries=function(){YAHOO.widget.ColumnSeries.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.ColumnSeries,YAHOO.widget.CartesianSeries,{type:"column"});YAHOO.widget.LineSeries=function(){YAHOO.widget.LineSeries.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.LineSeries,YAHOO.widget.CartesianSeries,{type:"line"});YAHOO.widget.BarSeries=function(){YAHOO.widget.BarSeries.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.BarSeries,YAH!
 OO.widget.CartesianSeries,{type:"bar"});YAHOO.widget.PieSeries!
 =functio
n(){YAHOO.widget.PieSeries.superclass.constructor.call(this);};YAHOO.lang.extend(YAHOO.widget.PieSeries,YAHOO.widget.Series,{type:"pie",dataField:null,categoryField:null});YAHOO.register("charts",YAHOO.widget.Chart,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/charts/charts-experimental.js
===================================================================
--- trunk/root/static/yui/charts/charts-experimental.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/charts/charts-experimental.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,37 +1,50 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-/**
+/*!
  * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
  *
  * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
  * http://www.opensource.org/licenses/mit-license.php
- *
  */
-if(typeof deconcept == "undefined") var deconcept = new Object();
-if(typeof deconcept.util == "undefined") deconcept.util = new Object();
-if(typeof deconcept.SWFObjectUtil == "undefined") deconcept.SWFObjectUtil = new Object();
-deconcept.SWFObject = function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey) {
-	if (!document.getElementById) { return; }
+var deconcept = deconcept || {};
+
+if(typeof deconcept.util == "undefined" || !deconcept.util)
+{
+	deconcept.util = {};
+}
+
+if(typeof deconcept.SWFObjectUtil == "undefined" || !deconcept.SWFObjectUtil)
+{
+	deconcept.SWFObjectUtil = {};
+}
+
+deconcept.SWFObject = function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey)
+{
+	if(!document.getElementById) { return; }
 	this.DETECT_KEY = detectKey ? detectKey : 'detectflash';
 	this.skipDetect = deconcept.util.getRequestParameter(this.DETECT_KEY);
-	this.params = new Object();
-	this.variables = new Object();
-	this.attributes = new Array();
+	this.params = {};
+	this.variables = {};
+	this.attributes = [];
 	if(swf) { this.setAttribute('swf', swf); }
 	if(id) { this.setAttribute('id', id); }
 	if(w) { this.setAttribute('width', w); }
 	if(h) { this.setAttribute('height', h); }
 	if(ver) { this.setAttribute('version', new deconcept.PlayerVersion(ver.toString().split("."))); }
 	this.installedVer = deconcept.SWFObjectUtil.getPlayerVersion();
-	if (!window.opera && document.all && this.installedVer.major > 7) {
+	if (!window.opera && document.all && this.installedVer.major > 7)
+	{
 		// only add the onunload cleanup if the Flash Player version supports External Interface and we are in IE
 		deconcept.SWFObject.doPrepUnload = true;
 	}
-	if(c) { this.addParam('bgcolor', c); }
+	if(c)
+	{
+		this.addParam('bgcolor', c);
+	}
 	var q = quality ? quality : 'high';
 	this.addParam('quality', q);
 	this.setAttribute('useExpressInstall', false);
@@ -39,10 +52,16 @@
 	var xir = (xiRedirectUrl) ? xiRedirectUrl : window.location;
 	this.setAttribute('xiRedirectUrl', xir);
 	this.setAttribute('redirectUrl', '');
-	if(redirectUrl) { this.setAttribute('redirectUrl', redirectUrl); }
-}
-deconcept.SWFObject.prototype = {
-	useExpressInstall: function(path) {
+	if(redirectUrl)
+	{
+		this.setAttribute('redirectUrl', redirectUrl);
+	}
+};
+
+deconcept.SWFObject.prototype =
+{
+	useExpressInstall: function(path)
+	{
 		this.xiSWFPath = !path ? "expressinstall.swf" : path;
 		this.setAttribute('useExpressInstall', true);
 	},
@@ -68,7 +87,7 @@
 		return this.variables;
 	},
 	getVariablePairs: function(){
-		var variablePairs = new Array();
+		var variablePairs = [];
 		var key;
 		var variables = this.getVariables();
 		for(key in variables){
@@ -78,6 +97,9 @@
 	},
 	getSWFHTML: function() {
 		var swfNode = "";
+		var params = {};
+		var key = "";
+		var pairs = "";
 		if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { // netscape plugin architecture
 			if (this.getAttribute("doExpressInstall")) {
 				this.addVariable("MMplayerType", "PlugIn");
@@ -85,10 +107,10 @@
 			}
 			swfNode = '<embed type="application/x-shockwave-flash" src="'+ this.getAttribute('swf') +'" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'"';
 			swfNode += ' id="'+ this.getAttribute('id') +'" name="'+ this.getAttribute('id') +'" ';
-			var params = this.getParams();
-			 for(var key in params){ swfNode += [key] +'="'+ params[key] +'" '; }
-			var pairs = this.getVariablePairs().join("&");
-			 if (pairs.length > 0){ swfNode += 'flashvars="'+ pairs +'"'; }
+			params = this.getParams();
+			for(key in params){ swfNode += [key] +'="'+ params[key] +'" '; }
+			pairs = this.getVariablePairs().join("&");
+			if (pairs.length > 0){ swfNode += 'flashvars="'+ pairs +'"'; }
 			swfNode += '/>';
 		} else { // PC IE
 			if (this.getAttribute("doExpressInstall")) {
@@ -97,17 +119,18 @@
 			}
 			swfNode = '<object id="'+ this.getAttribute('id') +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'">';
 			swfNode += '<param name="movie" value="'+ this.getAttribute('swf') +'" />';
-			var params = this.getParams();
-			for(var key in params) {
+			params = this.getParams();
+			for(key in params) {
 			 swfNode += '<param name="'+ key +'" value="'+ params[key] +'" />';
 			}
-			var pairs = this.getVariablePairs().join("&");
+			pairs = this.getVariablePairs().join("&");
 			if(pairs.length > 0) {swfNode += '<param name="flashvars" value="'+ pairs +'" />';}
 			swfNode += "</object>";
 		}
 		return swfNode;
 	},
-	write: function(elementId){
+	write: function(elementId)
+	{
 		if(this.getAttribute('useExpressInstall')) {
 			// check to see if we need to do an express install
 			var expressInstallReqVer = new deconcept.PlayerVersion([6,0,65]);
@@ -118,120 +141,184 @@
 				this.addVariable("MMdoctitle", document.title);
 			}
 		}
-		if(this.skipDetect || this.getAttribute('doExpressInstall') || this.installedVer.versionIsValid(this.getAttribute('version'))){
+		if(this.skipDetect || this.getAttribute('doExpressInstall') || this.installedVer.versionIsValid(this.getAttribute('version')))
+		{
 			var n = (typeof elementId == 'string') ? document.getElementById(elementId) : elementId;
 			n.innerHTML = this.getSWFHTML();
 			return true;
-		}else{
-			if(this.getAttribute('redirectUrl') != "") {
+		}
+		else
+		{
+			if(this.getAttribute('redirectUrl') !== "")
+			{
 				document.location.replace(this.getAttribute('redirectUrl'));
 			}
 		}
 		return false;
 	}
-}
+};
 
 /* ---- detection functions ---- */
-deconcept.SWFObjectUtil.getPlayerVersion = function(){
+deconcept.SWFObjectUtil.getPlayerVersion = function()
+{
+	var axo = null;
 	var PlayerVersion = new deconcept.PlayerVersion([0,0,0]);
-	if(navigator.plugins && navigator.mimeTypes.length){
+	if(navigator.plugins && navigator.mimeTypes.length)
+	{
 		var x = navigator.plugins["Shockwave Flash"];
-		if(x && x.description) {
+		if(x && x.description)
+		{
 			PlayerVersion = new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split("."));
 		}
-	}else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ // if Windows CE
-		var axo = 1;
+	}
+	else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0)
+	{ // if Windows CE
 		var counter = 3;
-		while(axo) {
-			try {
+		while(axo)
+		{
+			try
+			{
 				counter++;
 				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ counter);
 //				document.write("player v: "+ counter);
 				PlayerVersion = new deconcept.PlayerVersion([counter,0,0]);
-			} catch (e) {
+			}
+			catch(e)
+			{
 				axo = null;
 			}
 		}
-	} else { // Win IE (non mobile)
+	}
+	else
+	{ // Win IE (non mobile)
 		// do minor version lookup in IE, but avoid fp6 crashing issues
 		// see http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/
-		try{
-			var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
-		}catch(e){
-			try {
-				var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
+		try
+		{
+			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
+		}
+		catch(e)
+		{
+			try
+			{
+				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
 				PlayerVersion = new deconcept.PlayerVersion([6,0,21]);
 				axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code)
-			} catch(e) {
-				if (PlayerVersion.major == 6) {
+			}
+			catch(e)
+			{
+				if(PlayerVersion.major == 6)
+				{
 					return PlayerVersion;
 				}
 			}
-			try {
+			try
+			{
 				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
-			} catch(e) {}
+			}
+			catch(e) {}
 		}
-		if (axo != null) {
+		
+		if(axo !== null)
+		{
 			PlayerVersion = new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));
 		}
 	}
 	return PlayerVersion;
-}
-deconcept.PlayerVersion = function(arrVersion){
-	this.major = arrVersion[0] != null ? parseInt(arrVersion[0]) : 0;
-	this.minor = arrVersion[1] != null ? parseInt(arrVersion[1]) : 0;
-	this.rev = arrVersion[2] != null ? parseInt(arrVersion[2]) : 0;
-}
-deconcept.PlayerVersion.prototype.versionIsValid = function(fv){
-	if(this.major < fv.major) return false;
-	if(this.major > fv.major) return true;
-	if(this.minor < fv.minor) return false;
-	if(this.minor > fv.minor) return true;
-	if(this.rev < fv.rev) return false;
+};
+
+deconcept.PlayerVersion = function(arrVersion)
+{
+	this.major = arrVersion[0] !== null ? parseInt(arrVersion[0], 0) : 0;
+	this.minor = arrVersion[1] !== null ? parseInt(arrVersion[1], 0) : 0;
+	this.rev = arrVersion[2] !== null ? parseInt(arrVersion[2], 0) : 0;
+};
+
+deconcept.PlayerVersion.prototype.versionIsValid = function(fv)
+{
+	if(this.major < fv.major)
+	{
+		return false;
+	}
+	if(this.major > fv.major)
+	{
+		return true;
+	}
+	if(this.minor < fv.minor)
+	{
+		return false;
+	}
+	if(this.minor > fv.minor)
+	{
+		return true;
+	}
+	if(this.rev < fv.rev)
+	{
+		return false;
+	}
 	return true;
-}
+};
+
 /* ---- get value of query string param ---- */
-deconcept.util = {
-	getRequestParameter: function(param) {
+deconcept.util =
+{
+	getRequestParameter: function(param)
+	{
 		var q = document.location.search || document.location.hash;
-		if (param == null) { return q; }
-		if(q) {
+		if(param === null) { return q; }
+		if(q)
+		{
 			var pairs = q.substring(1).split("&");
-			for (var i=0; i < pairs.length; i++) {
-				if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
-					return pairs[i].substring((pairs[i].indexOf("=")+1));
+			for(var i=0; i < pairs.length; i++)
+			{
+				if (pairs[i].substring(0, pairs[i].indexOf("=")) == param)
+				{
+					return pairs[i].substring((pairs[i].indexOf("=") + 1));
 				}
 			}
 		}
 		return "";
 	}
-}
+};
+
 /* fix for video streaming bug */
-deconcept.SWFObjectUtil.cleanupSWFs = function() {
+deconcept.SWFObjectUtil.cleanupSWFs = function()
+{
 	var objects = document.getElementsByTagName("OBJECT");
-	for (var i = objects.length - 1; i >= 0; i--) {
+	for(var i = objects.length - 1; i >= 0; i--)
+	{
 		objects[i].style.display = 'none';
-		for (var x in objects[i]) {
-			if (typeof objects[i][x] == 'function') {
+		for(var x in objects[i])
+		{
+			if(typeof objects[i][x] == 'function')
+			{
 				objects[i][x] = function(){};
 			}
 		}
 	}
-}
+};
+
 // fixes bug in some fp9 versions see http://blog.deconcept.com/2006/07/28/swfobject-143-released/
-if (deconcept.SWFObject.doPrepUnload) {
-	if (!deconcept.unloadSet) {
-		deconcept.SWFObjectUtil.prepUnload = function() {
+if(deconcept.SWFObject.doPrepUnload)
+{
+	if(!deconcept.unloadSet)
+	{
+		deconcept.SWFObjectUtil.prepUnload = function()
+		{
 			__flash_unloadHandler = function(){};
 			__flash_savedUnloadHandler = function(){};
 			window.attachEvent("onunload", deconcept.SWFObjectUtil.cleanupSWFs);
-		}
+		};
 		window.attachEvent("onbeforeunload", deconcept.SWFObjectUtil.prepUnload);
 		deconcept.unloadSet = true;
 	}
 }
+
 /* add document.getElementById if needed (mobile IE < 5) */
-if (!document.getElementById && document.all) { document.getElementById = function(id) { return document.all[id]; }}
+if(!document.getElementById && document.all)
+{
+	document.getElementById = function(id) { return document.all[id]; };
+}
 
 /* add some aliases for ease of use/backwards compatibility */
 var getQueryParamValue = deconcept.util.getRequestParameter;
@@ -267,7 +354,8 @@
 	this._swfURL = swfURL;
 	
 	//embed the SWF file in the page
-	this._embedSWF(this._swfURL, containerID, attributes.id, attributes.version, attributes.backgroundColor, attributes.expressInstall);
+	this._embedSWF(this._swfURL, containerID, attributes.id, attributes.version,
+		attributes.backgroundColor, attributes.expressInstall, attributes.wmode);
 	
 	/**
 	 * Fires when the SWF is initialized and communication is possible.
@@ -326,11 +414,11 @@
 	 * @method _embedSWF
 	 * @private
 	 */
-	_embedSWF: function(swfURL, containerID, swfID, version, backgroundColor, expressInstall)
+	_embedSWF: function(swfURL, containerID, swfID, version, backgroundColor, expressInstall, wmode)
 	{
 		//standard SWFObject embed
-		var swfObj = new deconcept.SWFObject(swfURL, swfID, "100%", "100%", version, backgroundColor, expressInstall);
-		
+		var swfObj = new deconcept.SWFObject(swfURL, swfID, "100%", "100%", version, backgroundColor);
+
 		if(expressInstall)
 		{
 			swfObj.useExpressInstall(expressInstall);
@@ -338,6 +426,12 @@
 
 		//make sure we can communicate with ExternalInterface
 		swfObj.addParam("allowScriptAccess", "always");
+		
+		if(wmode !== null)
+		{
+			swfObj.addParam("wmode", wmode);
+		}
+		
 		//again, a useful ExternalInterface trick
 		swfObj.addVariable("allowedDomain", document.location.hostname);
 
@@ -356,6 +450,9 @@
 			//this will allow the event handler to communicate with a YAHOO.widget.FlashAdapter
 			this._swf.owner = this;
 		}
+		else
+		{
+		}
 	},
 
 	/**
@@ -370,14 +467,10 @@
 		switch(type)
 		{
 			case "swfReady":
-			{
    				this._loadHandler();
 				return;
-			}
 			case "log":
-			{
 				return;
-			}
 		}
 		
 		//be sure to return after your case or the event will automatically fire!
@@ -448,7 +541,10 @@
 		//fix for ie: if owner doesn't exist yet, try again in a moment
 		setTimeout(function() { YAHOO.widget.FlashAdapter.eventHandler( elementID, event ); }, 0);
 	}
-	else loadedSWF.owner._eventHandler(event);
+	else
+	{
+		loadedSWF.owner._eventHandler(event);
+	}
 };
 
 /**
@@ -597,6 +693,15 @@
 	 * @private
 	 */
 	_pollingInterval: null,
+	
+	/**
+	 * Indicates whether all attributes have been set and
+	 * the dataSource may be passed to the SWF.
+	 * @property _initialized
+	 * @type Boolean
+	 * @private
+	 */
+	_initialized: false,
 
 	/**
 	 * Public accessor to the unique name of the Chart instance.
@@ -779,6 +884,8 @@
 		
 		YAHOO.widget.Chart.superclass._loadHandler.call(this);
 		
+		this._initialized = true;
+		
 		if(this._dataSource)
 		{
 			this.set("dataSource", this._dataSource);
@@ -793,9 +900,14 @@
 	 */
 	_refreshData: function()
 	{
-		if(this._dataSource != null)
+		if(!this._initialized)
 		{
-			if(this._pollingID != null)
+			return;
+		}
+		
+		if(this._dataSource !== null)
+		{
+			if(this._pollingID !== null)
 			{
 				this._dataSource.clearInterval(this._pollingID);
 				this._pollingID = null;
@@ -832,17 +944,18 @@
 			//editing them directly.
 			var dataProvider = [];	
 			var seriesCount = 0;
-			if(this._seriesDefs)
+			var currentSeries = null;
+			var i = 0;
+			if(this._seriesDefs !== null)
 			{
 				seriesCount = this._seriesDefs.length;
-				for(var i = 0; i < seriesCount; i++)
+				for(i = 0; i < seriesCount; i++)
 				{
-					var currentSeries = this._seriesDefs[i];
+					currentSeries = this._seriesDefs[i];
 					var clonedSeries = {};
 					for(var prop in currentSeries)
 					{
-						
-						if(prop == "style" && currentSeries.style != null)
+						if(prop == "style" && currentSeries.style !== null)
 						{
 							clonedSeries.style = YAHOO.lang.JSON.stringify(currentSeries.style);
 							styleChanged = true;
@@ -851,7 +964,10 @@
 							//so null out the style property.
 							currentSeries.style = null;
 						}
-						else clonedSeries[prop] = currentSeries[prop];
+						else
+						{
+							clonedSeries[prop] = currentSeries[prop];
+						}
 					}
 					dataProvider.push(clonedSeries);
 				}
@@ -968,6 +1084,7 @@
 	_setSeriesDefs: function(value)
 	{
 		this._seriesDefs = value;
+		this._refreshData();
 	},
 
 	/**
@@ -1613,7 +1730,20 @@
 
 YAHOO.widget.Series.prototype = 
 {
+	/**
+	 * The type of series.
+	 *
+	 * @property type
+	 * @type String
+	 */
 	type: null,
+	
+	/**
+	 * The human-readable name of the series.
+	 *
+	 * @property displayName
+	 * @type String
+	 */
 	displayName: null
 };
 
@@ -1631,7 +1761,20 @@
 
 YAHOO.lang.extend(YAHOO.widget.CartesianSeries, YAHOO.widget.Series,
 {
+	/**
+	 * The field used to access the x-axis value from the items from the data source.
+	 *
+	 * @property xField
+	 * @type String
+	 */
 	xField: null,
+	
+	/**
+	 * The field used to access the y-axis value from the items from the data source.
+	 *
+	 * @property yField
+	 * @type String
+	 */
 	yField: null
 });
 
@@ -1707,4 +1850,4 @@
 	categoryField: null
 });
 
-YAHOO.register("charts", YAHOO.widget.Chart, {version: "2.4.1", build: "742"});
+YAHOO.register("charts", YAHOO.widget.Chart, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/colorpicker/README
===================================================================
--- trunk/root/static/yui/colorpicker/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/colorpicker/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,11 @@
 ColorPicker - Release Notes
 
-2.4.1
+2.5.1
    * No change
 
+2.5.0
+   * No change
+
 2.4.0
    * Initialization values assigned to showcontrols, showrgbcontrols,
      showwebsafe, showhexsummary, animate, red, green, and blue in the

Modified: trunk/root/static/yui/colorpicker/assets/colorpicker_core.css
===================================================================
--- trunk/root/static/yui/colorpicker/assets/colorpicker_core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/colorpicker/assets/colorpicker_core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,6 +1,6 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */

Modified: trunk/root/static/yui/colorpicker/assets/skins/sam/colorpicker-skin.css
===================================================================
--- trunk/root/static/yui/colorpicker/assets/skins/sam/colorpicker-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/colorpicker/assets/skins/sam/colorpicker-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 
 .yui-picker-panel {

Modified: trunk/root/static/yui/colorpicker/assets/skins/sam/colorpicker.css
===================================================================
--- trunk/root/static/yui/colorpicker/assets/skins/sam/colorpicker.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/colorpicker/assets/skins/sam/colorpicker.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-picker-panel{background:#e3e3e3;border-color:#888;}.yui-picker-panel .hd{background-color:#ccc;font-size:100%;line-height:100%;border:1px solid #e3e3e3;font-weight:bold;overflow:hidden;padding:6px;color:#000;}.yui-picker-panel .bd{background:#e8e8e8;margin:1px;height:200px;}.yui-picker-panel .ft{background:#e8e8e8;margin:1px;padding:1px;}.yui-picker{position:relative;}.yui-picker-hue-thumb{cursor:default;width:18px;height:18px;top:-8px;left:-2px;z-index:9;position:absolute;}.yui-picker-hue-bg{-moz-outline:none;outline:0px none;position:absolute;left:200px;height:183px;width:14px;background:url(hue_bg.png) no-repeat;top:4px;}.yui-picker-bg{-moz-outline:none;outline:0px none;position:absolute;top:4px;left:4px;height:182px;width:182px;background-color:#F00;background-image:url(picker_mask.png);}*html .yui-picker-bg{background-image:none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../../build/colorpicker/assets/picker_mask.png',sizingMethod='scale');}.yu!
 i-picker-mask{position:absolute;z-index:1;top:0px;left:0px;}.yui-picker-thumb{cursor:default;width:11px;height:11px;z-index:9;position:absolute;top:-4px;left:-4px;}.yui-picker-swatch{position:absolute;left:240px;top:4px;height:60px;width:55px;border:1px solid #888;}.yui-picker-websafe-swatch{position:absolute;left:304px;top:4px;height:24px;width:24px;border:1px solid #888;}.yui-picker-controls{position:absolute;top:72px;left:226px;font:1em monospace;}.yui-picker-controls .hd{background:transparent;border-width:0px !important;}.yui-picker-controls .bd{height:100px;border-width:0px !important;}.yui-picker-controls ul{float:left;padding:0 2px 0 0;margin:0}.yui-picker-controls li{padding:2px;list-style:none;margin:0}.yui-picker-controls input{font-size:0.85em;width:2.4em;}.yui-picker-hex-controls{clear:both;padding:2px;}.yui-picker-hex-controls input{width:4.6em;}.yui-picker-controls a{font:1em arial,helvetica,clean,sans-serif;display:block;*display:inline-block;padding:0;color!
 :#000;}

Deleted: trunk/root/static/yui/colorpicker/colorpicker-beta-debug.js
===================================================================
--- trunk/root/static/yui/colorpicker/colorpicker-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/colorpicker/colorpicker-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,1755 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-/**
- * Provides color conversion and validation utils
- * @class YAHOO.util.Color
- * @namespace YAHOO.util
- */
-YAHOO.util.Color = function() {
-
-    var HCHARS="0123456789ABCDEF", lang=YAHOO.lang;
-
-    return {
-
-        /**
-         * Converts 0-1 to 0-255
-         * @method real2dec
-         * @param n {float} the number to convert
-         * @return {int} a number 0-255
-         */
-        real2dec: function(n) {
-            return Math.min(255, Math.round(n*256));
-        },
-
-        /**
-         * Converts HSV (h[0-360], s[0-1]), v[0-1] to RGB [255,255,255]
-         * @method hsv2rgb
-         * @param h {int|[int, float, float]} the hue, or an
-         *        array containing all three parameters
-         * @param s {float} the saturation
-         * @param v {float} the value/brightness
-         * @return {[int, int, int]} the red, green, blue values in
-         *          decimal.
-         */
-        hsv2rgb: function(h, s, v) { 
-
-            if (lang.isArray(h)) {
-                return this.hsv2rgb.call(this, h[0], h[1], h[2]);
-            }
-
-            var r, g, b, i, f, p, q, t;
-            i = Math.floor((h/60)%6);
-            f = (h/60)-i;
-            p = v*(1-s);
-            q = v*(1-f*s);
-            t = v*(1-(1-f)*s);
-            switch(i) {
-                case 0: r=v; g=t; b=p; break;
-                case 1: r=q; g=v; b=p; break;
-                case 2: r=p; g=v; b=t; break;
-                case 3: r=p; g=q; b=v; break;
-                case 4: r=t; g=p; b=v; break;
-                case 5: r=v; g=p; b=q; break;
-            }
-
-            var fn=this.real2dec;
-
-            return [fn(r), fn(g), fn(b)];
-        },
-
-        /**
-         * Converts to RGB [255,255,255] to HSV (h[0-360], s[0-1]), v[0-1]
-         * @method rgb2hsv
-         * @param r {int|[int, int, int]} the red value, or an
-         *        array containing all three parameters
-         * @param g {int} the green value
-         * @param b {int} the blue value
-         * @return {[int, float, float]} the value converted to hsv
-         */
-        rgb2hsv: function(r, g, b) {
-
-            if (lang.isArray(r)) {
-                return this.rgb2hsv.call(this, r[0], r[1], r[2]);
-            }
-
-            r=r/255;
-            g=g/255;
-            b=b/255;
-
-            var min,max,delta,h,s,v;
-            min = Math.min(Math.min(r,g),b);
-            max = Math.max(Math.max(r,g),b);
-            delta = max-min;
-
-            switch (max) {
-                case min: h=0; break;
-                case r:   h=60*(g-b)/delta; 
-                          if (g<b) {
-                              h+=360;
-                          }
-                          break;
-                case g:   h=(60*(b-r)/delta)+120; break;
-                case b:   h=(60*(r-g)/delta)+240; break;
-            }
-            
-            s = (max === 0) ? 0 : 1-(min/max);
-
-            var hsv = [Math.round(h), s, max];
-
-            return hsv;
-
-        },
-
-        /**
-         * Converts decimal rgb values into a hex string
-         * 255,255,255 -> FFFFFF
-         * @method rgb2hex
-         * @param r {int|[int, int, int]} the red value, or an
-         *        array containing all three parameters
-         * @param g {int} the green value
-         * @param b {int} the blue value
-         * @return {string} the hex string
-         */
-        rgb2hex: function(r, g, b) {
-            if (lang.isArray(r)) {
-                return this.rgb2hex.call(this, r[0], r[1], r[2]);
-            }
-
-            var f=this.dec2hex;
-            return f(r) + f(g) + f(b);
-        },
-     
-        /**
-         * Converts an int 0...255 to hex pair 00...FF
-         * @method dec2hex
-         * @param n {int} the number to convert
-         * @return {string} the hex equivalent
-         */
-        dec2hex: function(n) {
-            n = parseInt(n, 10);
-            n = (lang.isNumber(n)) ? n : 0;
-            n = (n > 255 || n < 0) ? 0 : n;
-
-            return HCHARS.charAt((n - n % 16) / 16) + HCHARS.charAt(n % 16);
-        },
-
-        /**
-         * Converts a hex pair 00...FF to an int 0...255 
-         * @method hex2dec
-         * @param str {string} the hex pair to convert
-         * @return {int} the decimal
-         */
-        hex2dec: function(str) {
-            var f = function(c) {
-                return HCHARS.indexOf(c.toUpperCase());
-            };
-
-            var s=str.split('');
-            
-            return ((f(s[0]) * 16) + f(s[1]));
-        },
-
-        /**
-         * Converts a hex string to rgb
-         * @method hex2rgb
-         * @param str {string} the hex string
-         * @return {[int, int, int]} an array containing the rgb values
-         */
-        hex2rgb: function(s) { 
-            var f = this.hex2dec;
-            return [f(s.substr(0, 2)), f(s.substr(2, 2)), f(s.substr(4, 2))];
-        },
-
-        /**
-         * Returns the closest websafe color to the supplied rgb value.
-         * @method websafe
-         * @param r {int|[int, int, int]} the red value, or an
-         *        array containing all three parameters
-         * @param g {int} the green value
-         * @param b {int} the blue value
-         * @return {[int, int, int]} an array containing the closes
-         *                           websafe rgb colors.
-         */
-        websafe: function(r, g, b) {
-
-            if (lang.isArray(r)) {
-                return this.websafe.call(this, r[0], r[1], r[2]);
-            }
-
-            // returns the closest match [0, 51, 102, 153, 204, 255]
-            var f = function(v) {
-                if (lang.isNumber(v)) {
-                    v = Math.min(Math.max(0, v), 255);
-                    var i, next;
-                    for (i=0; i<256; i=i+51) {
-                        next = i+51;
-                        if (v >= i && v <= next) {
-                            return (v-i > 25) ? next : i;
-                        }
-                    }
- YAHOO.log("Error calculating the websafe value for " + v, "warn");
-                }
-
-                return v;
-            };
-
-            return [f(r), f(g), f(b)];
-        }
-    };
-}();
-
-
-(function() {
-
-    var _pickercount = 0;
-
-    /**
-     * The colorpicker module provides a widget for selecting colors
-     * @module colorpicker
-     * @requires yahoo, dom, event, element, slider
-     */
-
-
-    /**
-     * Creates the host element if it doesn't exist
-     * @method _createHostElement
-     * @private
-     */
-    var _createHostElement = function() {
-        var el = document.createElement('div');
-
-        if (this.CSS.BASE) {
-            el.className = this.CSS.BASE;
-        }
-        
-        return el;
-    };
-
-    /**
-     * A widget to select colors
-     * @namespace YAHOO.widget
-     * @class YAHOO.widget.ColorPicker
-     * @extends YAHOO.util.Element
-     * @constructor
-     * @param {HTMLElement | String | Object} el(optional) The html 
-     * element that represents the colorpicker, or the attribute object to use. 
-     * An element will be created if none provided.
-     * @param {Object} attr (optional) A key map of the colorpicker's 
-     * initial attributes.  Ignored if first arg is attributes object.
-     */
-    YAHOO.widget.ColorPicker = function(el, attr) {
-        _pickercount = _pickercount + 1;
-        this.logger = new YAHOO.widget.LogWriter("ColorPicker");
-        attr = attr || {};
-        if (arguments.length === 1 && !YAHOO.lang.isString(el) && !el.nodeName) {
-            attr = el; // treat first arg as attr object
-            el = attr.element || null;
-        }
-        
-        if (!el && !attr.element) { // create if we dont have one
-            this.logger.log("creating host element");
-            el = _createHostElement.call(this, attr);
-        }
-
-    	YAHOO.widget.ColorPicker.superclass.constructor.call(this, el, attr); 
-    };
-
-    YAHOO.extend(YAHOO.widget.ColorPicker, YAHOO.util.Element);
-    
-    var proto = YAHOO.widget.ColorPicker.prototype,
-        Slider=YAHOO.widget.Slider,
-        Color=YAHOO.util.Color,
-        Dom = YAHOO.util.Dom,
-        Event = YAHOO.util.Event,
-        lang = YAHOO.lang,
-        sub = lang.substitute;
-    
-
-    var b = "yui-picker";
-
-    /**
-     * The element ids used by this control
-     * @property ID
-     * @final
-     */
-    proto.ID = {
-
-        /**
-         * The id for the "red" form field
-         * @property ID.R
-         * @type String
-         * @final
-         * @default yui-picker-r
-         */
-        R: b + "-r",
-
-        /**
-         * The id for the "red" hex pair output
-         * @property ID.R_HEX
-         * @type String
-         * @final
-         * @default yui-picker-rhex
-         */
-        R_HEX: b + "-rhex",
-
-        /**
-         * The id for the "green" form field
-         * @property ID.G
-         * @type String
-         * @final
-         * @default yui-picker-g
-         */
-        G: b + "-g",
-
-        /**
-         * The id for the "green" hex pair output
-         * @property ID.G_HEX
-         * @type String
-         * @final
-         * @default yui-picker-ghex
-         */
-        G_HEX: b + "-ghex",
-
-
-        /**
-         * The id for the "blue" form field
-         * @property ID.B
-         * @type String
-         * @final
-         * @default yui-picker-b
-         */
-        B: b + "-b",
-
-        /**
-         * The id for the "blue" hex pair output
-         * @property ID.B_HEX
-         * @type String
-         * @final
-         * @default yui-picker-bhex
-         */
-        B_HEX: b + "-bhex",
-
-        /**
-         * The id for the "hue" form field
-         * @property ID.H
-         * @type String
-         * @final
-         * @default yui-picker-h
-         */
-        H: b + "-h",
-
-        /**
-         * The id for the "saturation" form field
-         * @property ID.S
-         * @type String
-         * @final
-         * @default yui-picker-s
-         */
-        S: b + "-s",
-
-        /**
-         * The id for the "value" form field
-         * @property ID.V
-         * @type String
-         * @final
-         * @default yui-picker-v
-         */
-        V: b + "-v",
-
-        /**
-         * The id for the picker region slider
-         * @property ID.PICKER_BG
-         * @type String
-         * @final
-         * @default yui-picker-bg
-         */
-        PICKER_BG:      b + "-bg",
-
-        /**
-         * The id for the picker region thumb
-         * @property ID.PICKER_THUMB
-         * @type String
-         * @final
-         * @default yui-picker-thumb
-         */
-        PICKER_THUMB:   b + "-thumb",
-
-        /**
-         * The id for the hue slider
-         * @property ID.HUE_BG
-         * @type String
-         * @final
-         * @default yui-picker-hue-bg
-         */
-        HUE_BG:         b + "-hue-bg",
-
-        /**
-         * The id for the hue thumb
-         * @property ID.HUE_THUMB
-         * @type String
-         * @final
-         * @default yui-picker-hue-thumb
-         */
-        HUE_THUMB:      b + "-hue-thumb",
-
-        /**
-         * The id for the hex value form field
-         * @property ID.HEX
-         * @type String
-         * @final
-         * @default yui-picker-hex
-         */
-        HEX:            b + "-hex",
-
-        /**
-         * The id for the color swatch
-         * @property ID.SWATCH
-         * @type String
-         * @final
-         * @default yui-picker-swatch
-         */
-        SWATCH:         b + "-swatch",
-
-        /**
-         * The id for the websafe color swatch
-         * @property ID.WEBSAFE_SWATCH
-         * @type String
-         * @final
-         * @default yui-picker-websafe-swatch
-         */
-        WEBSAFE_SWATCH: b + "-websafe-swatch",
-
-        /**
-         * The id for the control details
-         * @property ID.CONTROLS
-         * @final
-         * @default yui-picker-controls
-         */
-        CONTROLS: b + "-controls",
-
-        /**
-         * The id for the rgb controls
-         * @property ID.RGB_CONTROLS
-         * @final
-         * @default yui-picker-rgb-controls
-         */
-        RGB_CONTROLS: b + "-rgb-controls",
-
-        /**
-         * The id for the hsv controls
-         * @property ID.HSV_CONTROLS
-         * @final
-         * @default yui-picker-hsv-controls
-         */
-        HSV_CONTROLS: b + "-hsv-controls",
-        
-        /**
-         * The id for the hsv controls
-         * @property ID.HEX_CONTROLS
-         * @final
-         * @default yui-picker-hex-controls
-         */
-        HEX_CONTROLS: b + "-hex-controls",
-
-        /**
-         * The id for the hex summary
-         * @property ID.HEX_SUMMARY
-         * @final
-         * @default yui-picker-hex-summary
-         */
-        HEX_SUMMARY: b + "-hex-summary",
-
-        /**
-         * The id for the controls section header
-         * @property ID.CONTROLS_LABEL
-         * @final
-         * @default yui-picker-controls-label
-         */
-        CONTROLS_LABEL: b + "-controls-label"
-    };
-
-    /**
-     * Constants for any script-generated messages.  The values here
-     * are the default messages.  They can be updated by providing
-     * the complete list to the constructor for the "txt" attribute.
-     * @property TXT
-     * @final
-     */
-    proto.TXT = {
-        ILLEGAL_HEX: "Illegal hex value entered",
-        SHOW_CONTROLS: "Show color details",
-        HIDE_CONTROLS: "Hide color details",
-        CURRENT_COLOR: "Currently selected color: {rgb}",
-        CLOSEST_WEBSAFE: "Closest websafe color: {rgb}. Click to select.",
-        R: "R",
-        G: "G",
-        B: "B",
-        H: "H",
-        S: "S",
-        V: "V",
-        HEX: "#",
-        DEG: "\u00B0",
-        PERCENT: "%"
-    };
-
-    /**
-     * Constants for the default image locations for img tags that are
-     * generated by the control.  They can be modified by passing the
-     * complete list to the contructor for the "images" attribute
-     * @property IMAGE
-     * @final
-     */
-    proto.IMAGE = {
-        PICKER_THUMB: "../../build/colorpicker/assets/picker_thumb.png",
-        HUE_THUMB: "../../build/colorpicker/assets/hue_thumb.png"
-    };
-
-    /*
-     * Constants for the control's custom event names.  subscribe
-     * to the rgbChange event instead.
-     * @property EVENT
-     * @final
-     */
-    //proto.EVENT = {
-        //CHANGE: "change"
-    //};
-
-    //proto.CSS = { };
-
-    /**
-     * Constants for the control's default default values
-     * @property DEFAULT
-     * @final
-     */
-    proto.DEFAULT = {
-        PICKER_SIZE: 180
-    };
-
-    /**
-     * Constants for the control's configuration attributes
-     * @property OPT
-     * @final
-     */
-    proto.OPT = {
-        HUE: "hue",
-        SATURATION: "saturation",
-        VALUE: "value",
-        RED: "red",
-        GREEN: "green",
-        BLUE: "blue",
-        HSV: "hsv",
-        RGB: "rgb",
-        WEBSAFE: "websafe",
-        HEX: "hex",
-        PICKER_SIZE: "pickersize",
-        SHOW_CONTROLS: "showcontrols",
-        SHOW_RGB_CONTROLS: "showrgbcontrols",
-        SHOW_HSV_CONTROLS: "showhsvcontrols",
-        SHOW_HEX_CONTROLS: "showhexcontrols",
-        SHOW_HEX_SUMMARY: "showhexsummary",
-        SHOW_WEBSAFE: "showwebsafe",
-        //SHOW_SUBMIT: "showsubmit",
-        CONTAINER: "container",
-        IDS: "ids",
-        ELEMENTS: "elements",
-        TXT: "txt",
-        IMAGES: "images",
-        ANIMATE: "animate"
-    };
-
-    /**
-     * Moves the hue slider into the position dictated by the current state
-     * of the control
-     * @method _updateHueSlider
-     * @private
-     */
-    var _updateHueSlider = function() {
-        var size = this.get(this.OPT.PICKER_SIZE),
-            h = this.get(this.OPT.HUE);
-
-        h = size - Math.round(h / 360 * size);
-        
-        // 0 is at the top and bottom of the hue slider.  Always go to
-        // the top so we don't end up sending the thumb to the bottom
-        // when the value didn't actually change (e.g., a conversion
-        // produced 360 instead of 0 and the value was already 0).
-        if (h === size) {
-            h = 0;
-        }
-        this.logger.log("Hue slider is being set to " + h);
-
-        this.hueSlider.setValue(h);
-    };
-
-    /**
-     * Moves the picker slider into the position dictated by the current state
-     * of the control
-     * @method _updatePickerSlider
-     * @private
-     */
-    var _updatePickerSlider = function() {
-        var size = this.get(this.OPT.PICKER_SIZE),
-            s = this.get(this.OPT.SATURATION),
-            v = this.get(this.OPT.VALUE);
-
-        s = Math.round(s * size / 100);
-        v = Math.round(size - (v * size / 100));
-
-        this.logger.log("Setting picker slider to " + [s, v]);
-
-        this.pickerSlider.setRegionValue(s, v);
-    };
-
-    /**
-     * Moves the sliders into the position dictated by the current state
-     * of the control
-     * @method _updateSliders
-     * @private
-     */
-    var _updateSliders = function() {
-        _updateHueSlider.call(this);
-        _updatePickerSlider.call(this);
-    };
-
-    /**
-     * Sets the control to the specified rgb value and
-     * moves the sliders to the proper positions
-     * @method setValue
-     * @param rgb {[int, int, int]} the rgb value
-     * @param silent {boolean} whether or not to fire the change event
-     */
-    proto.setValue = function(rgb, silent) {
-        silent = (silent) || false;
-        this.set(this.OPT.RGB, rgb, silent);
-        _updateSliders.call(this);
-    };
-
-    /**
-     * The hue slider
-     * @property hueSlider
-     * @type YAHOO.widget.Slider
-     */
-    proto.hueSlider = null; 
-    
-    /**
-     * The picker region
-     * @property pickerSlider
-     * @type YAHOO.widget.Slider
-     */
-    proto.pickerSlider = null;
-
-    /**
-     * Translates the slider value into hue, int[0,359]
-     * @method _getH
-     * @private
-     * @return {int} the hue from 0 to 359
-     */
-    var _getH = function() {
-        var size = this.get(this.OPT.PICKER_SIZE),
-            h = (size - this.hueSlider.getValue()) / size;
-        h = Math.round(h*360);
-        return (h === 360) ? 0 : h;
-    };
-
-    /**
-     * Translates the slider value into saturation, int[0,1], left to right
-     * @method _getS
-     * @private
-     * @return {int} the saturation from 0 to 1
-     */
-    var _getS = function() {
-        return this.pickerSlider.getXValue() / this.get(this.OPT.PICKER_SIZE);
-    };
-
-    /**
-     * Translates the slider value into value/brightness, int[0,1], top
-     * to bottom
-     * @method _getV
-     * @private
-     * @return {int} the value from 0 to 1
-     */
-    var _getV = function() {
-        var size = this.get(this.OPT.PICKER_SIZE);
-        return (size - this.pickerSlider.getYValue()) / size;
-    };
-
-    /**
-     * Updates the background of the swatch with the current rbg value.
-     * Also updates the websafe swatch to the closest websafe color
-     * @method _updateSwatch
-     * @private
-     */
-    var _updateSwatch = function() {
-        var rgb = this.get(this.OPT.RGB),
-            websafe = this.get(this.OPT.WEBSAFE),
-            el = this.getElement(this.ID.SWATCH),
-            color = rgb.join(","),
-            txt = this.get(this.OPT.TXT);
-
-        Dom.setStyle(el, "background-color", "rgb(" + color  + ")");
-        el.title = lang.substitute(txt.CURRENT_COLOR, {
-                "rgb": "#" + this.get(this.OPT.HEX)
-            });
-
-
-        el = this.getElement(this.ID.WEBSAFE_SWATCH);
-        color = websafe.join(",");
-
-        Dom.setStyle(el, "background-color", "rgb(" + color + ")");
-        el.title = lang.substitute(txt.CLOSEST_WEBSAFE, {
-                "rgb": "#" + Color.rgb2hex(websafe)
-            });
-
-    };
-
-    /**
-     * Reads the sliders and converts the values to RGB, updating the
-     * internal state for all the individual form fields
-     * @method _getValuesFromSliders
-     * @private
-     */
-    var _getValuesFromSliders = function() {
-        var h=_getH.call(this), s=_getS.call(this), v=_getV.call(this);
-        YAHOO.log("hsv " + [h, s, v]);
-
-        var rgb = Color.hsv2rgb(h, s, v);
-        //var websafe = Color.websafe(rgb);
-        //var hex = Color.rgb2hex(rgb[0], rgb[1], rgb[2]);
-
-        this.set(this.OPT.RGB, rgb);
-    };
-
-    /**
-     * Updates the form field controls with the state data contained
-     * in the control.
-     * @method _updateFormFields
-     * @private
-     */
-    var _updateFormFields = function() {
-        this.getElement(this.ID.H).value = this.get(this.OPT.HUE);
-        this.getElement(this.ID.S).value = this.get(this.OPT.SATURATION);
-        this.getElement(this.ID.V).value = this.get(this.OPT.VALUE);
-        this.getElement(this.ID.R).value = this.get(this.OPT.RED);
-        this.getElement(this.ID.R_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.RED));
-        this.getElement(this.ID.G).value = this.get(this.OPT.GREEN);
-        this.getElement(this.ID.G_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.GREEN));
-        this.getElement(this.ID.B).value = this.get(this.OPT.BLUE);
-        this.getElement(this.ID.B_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.BLUE));
-        this.getElement(this.ID.HEX).value = this.get(this.OPT.HEX);
-    };
-
-    /**
-     * Event handler for the hue slider.
-     * @method _onHueSliderChange
-     * @param newOffset {int} pixels from the start position
-     * @private
-     */
-    var _onHueSliderChange = function(newOffset) {
-        this.logger.log("hue update: " + newOffset , "warn");
-
-        var h = _getH.call(this);
-        this.set(this.OPT.HUE, h, true);
-
-        // set picker background to the hue
-        var rgb = Color.hsv2rgb(h, 1, 1);
-        var styleDef = "rgb(" + rgb.join(",") + ")";
-
-        Dom.setStyle(this.getElement(this.ID.PICKER_BG), "background-color", styleDef);
-
-        if (this.hueSlider.valueChangeSource === this.hueSlider.SOURCE_UI_EVENT) {
-            _getValuesFromSliders.call(this);
-        }
-
-        _updateFormFields.call(this);
-        _updateSwatch.call(this);
-    };
-
-    /**
-     * Event handler for the picker slider, which controls the
-     * saturation and value/brightness.
-     * @method _onPickerSliderChange
-     * @param newOffset {{x: int, y: int}} x/y pixels from the start position
-     * @private
-     */
-    var _onPickerSliderChange = function(newOffset) {
-        this.logger.log(sub("picker update [{x}, {y}]", newOffset));
-
-        var s=_getS.call(this), v=_getV.call(this);
-        this.set(this.OPT.SATURATION, Math.round(s*100), true);
-        this.set(this.OPT.VALUE, Math.round(v*100), true);
-
-        if (this.pickerSlider.valueChangeSource === this.pickerSlider.SOURCE_UI_EVENT) {
-            _getValuesFromSliders.call(this);
-        }
-
-        _updateFormFields.call(this);
-        _updateSwatch.call(this);
-    };
-
-
-    /**
-     * Key map to well-known commands for txt field input
-     * @method _getCommand
-     * @param e {Event} the keypress or keydown event
-     * @return {int} a command code
-     * <ul>
-     * <li>0 = not a number, letter in range, or special key</li>
-     * <li>1 = number</li>
-     * <li>2 = a-fA-F</li>
-     * <li>3 = increment (up arrow)</li>
-     * <li>4 = decrement (down arrow)</li>
-     * <li>5 = special key (tab, delete, return, escape, left, right)</li> 
-     * <li>6 = return</li>
-     * </ul>
-     * @private
-     */
-    var _getCommand = function(e) {
-        var c = Event.getCharCode(e);
-
-        //alert(Event.getCharCode(e) + ", " + e.keyCode + ", " + e.charCode);
-
-        // special keys
-        if (c === 38) { // up arrow
-            return 3;
-        } else if (c === 13) { // return
-            return 6;
-        } else if (c === 40) { // down array
-            return 4;
-        } else if (c >= 48 && c<=57) { // 0-9
-            return 1;
-        } else if (c >= 97 && c<=102) { // a-f
-            return 2;
-        } else if (c >= 65 && c<=70) { // A-F
-            return 2;
-        //} else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1 || 
-        //              (c >= 112 && c <=123)) { // including F-keys
-        // tab, delete, return, escape, left, right
-        } else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1) { // special chars
-            return 5;
-        } else { // something we probably don't want
-            return 0;
-        }
-    };
-
-    /**
-     * Use the value of the text field to update the control
-     * @method _hexFieldKeypress
-     * @param e {Event} an event
-     * @param el {HTMLElement} the field
-     * @param prop {string} the key to the linked property
-     * @private
-     */
-    var _useFieldValue = function(e, el, prop) {
-        var val = el.value;
-
-        if (prop !== this.OPT.HEX) {
-            val = parseInt(val, 10);
-        }
-
-        if (val !== this.get(prop)) {
-            this.set(prop, val);
-        }
-    };
-
-    /**
-     * Handle keypress on one of the rgb or hsv fields.
-     * @method _rgbFieldKeypress
-     * @param e {Event} the keypress event
-     * @param el {HTMLElement} the field
-     * @param prop {string} the key to the linked property
-     * @private
-     */
-    var _rgbFieldKeypress = function(e, el, prop) {
-        var command = _getCommand(e);
-        var inc = (e.shiftKey) ? 10 : 1;
-        switch (command) {
-            case 6: // return, update the value
-                _useFieldValue.apply(this, arguments);
-                break;
-                        
-            case 3: // up arrow, increment
-                this.set(prop, Math.min(this.get(prop)+inc, 255));
-                _updateFormFields.call(this);
-                //Event.stopEvent(e);
-                break;
-            case 4: // down arrow, decrement
-                this.set(prop, Math.max(this.get(prop)-inc, 0));
-                _updateFormFields.call(this);
-                //Event.stopEvent(e);
-                break;
-
-            default:
-        }
-
-    };
-
-    /**
-     * Handle keydown on the hex field
-     * @method _hexFieldKeypress
-     * @param e {Event} the keypress event
-     * @param el {HTMLElement} the field
-     * @param prop {string} the key to the linked property
-     * @private
-     */
-    var _hexFieldKeypress = function(e, el, prop) {
-        var command = _getCommand(e);
-        if (command === 6) { // return, update the value
-            _useFieldValue.apply(this, arguments);
-        }
-    };
-
-    /** 
-     * Allows numbers and special chars, and by default allows a-f.  
-     * Used for the hex field keypress handler.
-     * @method _hexOnly
-     * @param e {Event} the event
-     * @param numbersOnly omits a-f if set to true
-     * @private
-     * @return {boolean} false if we are canceling the event
-     */
-    var _hexOnly = function(e, numbersOnly) {
-        var command = _getCommand(e);
-        switch (command) {
-            case 6: // return
-            case 5: // special char
-            case 1: // number
-                break;
-            case 2: // hex char (a-f)
-                if (numbersOnly !== true) {
-                    break;
-                }
-
-                // fallthrough is intentional
-
-            default: // prevent alpha and punctuation
-                Event.stopEvent(e);
-                return false;
-        }
-    };
-
-    /** 
-     * Allows numbers and special chars only.  Used for the
-     * rgb and hsv fields keypress handler.
-     * @method _numbersOnly
-     * @param e {Event} the event
-     * @private
-     * @return {boolean} false if we are canceling the event
-     */
-    var _numbersOnly = function(e) {
-        return _hexOnly(e, true);
-    };
-
-    /**
-     * Returns the element reference that is saved.  The id can be either
-     * the element id, or the key for this id in the "id" config attribute.
-     * For instance, the host element id can be obtained by passing its
-     * id (default: "yui_picker") or by its key "YUI_PICKER".
-     * @param id {string} the element id, or key 
-     * @return {HTMLElement} a reference to the element
-     */
-    proto.getElement = function(id) { 
-        return this.get(this.OPT.ELEMENTS)[this.get(this.OPT.IDS)[id]]; 
-    };
-
-    var _createElements = function() {
-        this.logger.log("Building markup");
-        var el, child, img, fld, i, 
-            ids = this.get(this.OPT.IDS),
-            txt = this.get(this.OPT.TXT),
-            images = this.get(this.OPT.IMAGES),
-            Elem = function(type, o) {
-                var n = document.createElement(type);
-                if (o) {
-                    lang.augmentObject(n, o, true);
-                }
-                return n;
-            },
-            RGBElem = function(type, obj) {
-                var o = lang.merge({
-                        //type: "txt",
-                        autocomplete: "off",
-                        value: "0",
-                        size: 3,
-                        maxlength: 3
-                    }, obj);
-
-                o.name = o.id;
-                return new Elem(type, o);
-            };
-
-        var p = this.get("element");
-
-        // Picker slider (S and V) ---------------------------------------------
-
-        el = new Elem("div", {
-            id: ids[this.ID.PICKER_BG],
-            className: "yui-picker-bg",
-            tabIndex: -1,
-            hideFocus: true
-        });
-
-        child = new Elem("div", {
-            id: ids[this.ID.PICKER_THUMB],
-            className: "yui-picker-thumb"
-        });
-
-        img = new Elem("img", {
-            src: images.PICKER_THUMB
-        });
-
-        child.appendChild(img);
-        el.appendChild(child);
-        p.appendChild(el);
-        
-        // Hue slider ---------------------------------------------
-        el = new Elem("div", {
-            id: ids[this.ID.HUE_BG],
-            className: "yui-picker-hue-bg",
-            tabIndex: -1,
-            hideFocus: true
-        });
-
-        child = new Elem("div", {
-            id: ids[this.ID.HUE_THUMB],
-            className: "yui-picker-hue-thumb"
-        });
-
-        img = new Elem("img", {
-            src: images.HUE_THUMB
-        });
-
-        child.appendChild(img);
-        el.appendChild(child);
-        p.appendChild(el);
-
-
-        // controls ---------------------------------------------
-
-        el = new Elem("div", {
-            id: ids[this.ID.CONTROLS],
-            className: "yui-picker-controls"
-        });
-
-        p.appendChild(el);
-        p = el;
-
-            // controls header
-            el = new Elem("div", {
-                className: "hd"
-            });
-
-            child = new Elem("a", {
-                id: ids[this.ID.CONTROLS_LABEL],
-                //className: "yui-picker-controls-label",
-                href: "#"
-            });
-            el.appendChild(child);
-            p.appendChild(el);
-
-            // bd
-            el = new Elem("div", {
-                className: "bd"
-            });
-
-            p.appendChild(el);
-            p = el;
-
-                // rgb
-                el = new Elem("ul", {
-                    id: ids[this.ID.RGB_CONTROLS],
-                    className: "yui-picker-rgb-controls"
-                });
-
-                child = new Elem("li");
-                child.appendChild(document.createTextNode(txt.R + " "));
-
-                fld = new RGBElem("input", {
-                    id: ids[this.ID.R],
-                    className: "yui-picker-r"
-                });
-
-                child.appendChild(fld);
-                el.appendChild(child);
-
-                child = new Elem("li");
-                child.appendChild(document.createTextNode(txt.G + " "));
-
-                fld = new RGBElem("input", {
-                    id: ids[this.ID.G],
-                    className: "yui-picker-g"
-                });
-
-                child.appendChild(fld);
-                el.appendChild(child);
-
-                child = new Elem("li");
-                child.appendChild(document.createTextNode(txt.B + " "));
-
-                fld = new RGBElem("input", {
-                    id: ids[this.ID.B],
-                    className: "yui-picker-b"
-                });
-
-                child.appendChild(fld);
-                el.appendChild(child);
-
-                p.appendChild(el);
-
-                // hsv
-                el = new Elem("ul", {
-                    id: ids[this.ID.HSV_CONTROLS],
-                    className: "yui-picker-hsv-controls"
-                });
-
-                child = new Elem("li");
-                child.appendChild(document.createTextNode(txt.H + " "));
-
-                fld = new RGBElem("input", {
-                    id: ids[this.ID.H],
-                    className: "yui-picker-h"
-                });
-
-                child.appendChild(fld);
-                child.appendChild(document.createTextNode(" " + txt.DEG));
-
-                el.appendChild(child);
-
-                child = new Elem("li");
-                child.appendChild(document.createTextNode(txt.S + " "));
-
-                fld = new RGBElem("input", {
-                    id: ids[this.ID.S],
-                    className: "yui-picker-s"
-                });
-
-                child.appendChild(fld);
-                child.appendChild(document.createTextNode(" " + txt.PERCENT));
-
-                el.appendChild(child);
-
-                child = new Elem("li");
-                child.appendChild(document.createTextNode(txt.V + " "));
-
-                fld = new RGBElem("input", {
-                    id: ids[this.ID.V],
-                    className: "yui-picker-v"
-                });
-
-                child.appendChild(fld);
-                child.appendChild(document.createTextNode(" " + txt.PERCENT));
-
-                el.appendChild(child);
-                p.appendChild(el);
-
-
-                // hex summary
-
-                el = new Elem("ul", {
-                    id: ids[this.ID.HEX_SUMMARY],
-                    className: "yui-picker-hex_summary"
-                });
-
-                child = new Elem("li", {
-                    id: ids[this.ID.R_HEX]
-                });
-                el.appendChild(child);
-
-                child = new Elem("li", {
-                    id: ids[this.ID.G_HEX]
-                });
-                el.appendChild(child);
-
-                child = new Elem("li", {
-                    id: ids[this.ID.B_HEX]
-                });
-                el.appendChild(child);
-                p.appendChild(el);
-
-                // hex field
-                el = new Elem("div", {
-                    id: ids[this.ID.HEX_CONTROLS],
-                    className: "yui-picker-hex-controls"
-                });
-                el.appendChild(document.createTextNode(txt.HEX + " "));
-
-                child = new RGBElem("input", {
-                    id: ids[this.ID.HEX],
-                    className: "yui-picker-hex",
-                    size: 6,
-                    maxlength: 6
-                });
-
-                el.appendChild(child);
-                p.appendChild(el);
-
-                p = this.get("element");
-
-                // swatch
-                el = new Elem("div", {
-                    id: ids[this.ID.SWATCH],
-                    className: "yui-picker-swatch"
-                });
-
-                p.appendChild(el);
-
-                // websafe swatch
-                el = new Elem("div", {
-                    id: ids[this.ID.WEBSAFE_SWATCH],
-                    className: "yui-picker-websafe-swatch"
-                });
-
-                p.appendChild(el);
-
-    };
-
-    var _attachRGBHSV = function(id, config) {
-        Event.on(this.getElement(id), "keydown", function(e, me) {
-                _rgbFieldKeypress.call(me, e, this, config);
-            }, this);
-        Event.on(this.getElement(id), "keypress", _numbersOnly, this);
-        Event.on(this.getElement(id), "blur", function(e, me) {
-                _useFieldValue.call(me, e, this, config);
-            }, this);
-    };
-
-
-    /**
-     * Updates the rgb attribute with the current state of the r,g,b
-     * fields.  This is invoked from change listeners on these
-     * attributes to facilitate updating these values from the
-     * individual form fields
-     * @method _updateRGB
-     * @private
-     */
-    var _updateRGB = function() {
-        var rgb = [this.get(this.OPT.RED), 
-                   this.get(this.OPT.GREEN),
-                   this.get(this.OPT.BLUE)];
-
-        this.logger.log("RGB value set to " + rgb);
-        this.set(this.OPT.RGB, rgb);
-
-        _updateSliders.call(this);
-    };
-
-    /**
-     * Sets the initial state of the sliders
-     * @method initPicker
-     */
-    proto.initPicker = function () {
-
-        // bind all of our elements
-        var o=this.OPT, 
-            ids = this.get(o.IDS), 
-            els = this.get(o.ELEMENTS), 
-                  i, el, id;
-
-        // Add the default value as a key for each element for easier lookup
-        for (i in this.ID) {
-            if (lang.hasOwnProperty(this.ID, i)) {
-                ids[this.ID[i]] = ids[i];
-            }
-        }
-
-        // Check for picker element, if not there, create all of them
-        el = Dom.get(ids[this.ID.PICKER_BG]);
-        if (!el) {
-            _createElements.call(this);
-        } else {
-            this.logger.log("Using pre-existing markup");
-        }
-
-        for (i in ids) {
-            if (lang.hasOwnProperty(ids, i)) {
-                // look for element
-                el = Dom.get(ids[i]);
-
-                // generate an id if the implementer passed in an element reference,
-                // and the element did not have an id already
-                id = Dom.generateId(el);
-
-                // update the id in case we generated the id
-                ids[i] = id; // key is WEBSAFE_SWATCH
-                ids[ids[i]] = id; // key is websafe_swatch
-
-                // store the dom ref
-                els[id] = el;
-            }
-        }
-
-        // set the initial visibility state of our controls
-            els = [o.SHOW_CONTROLS, 
-                   o.SHOW_RGB_CONTROLS,
-                   o.SHOW_HSV_CONTROLS,
-                   o.SHOW_HEX_CONTROLS,
-                   o.SHOW_HEX_SUMMARY,
-                   o.SHOW_WEBSAFE
-                   ];
-
-        for (i=0; i<els.length; i=i+1) {
-            this.set(els[i], this.get(els[i]));
-        }
-
-        var s = this.get(o.PICKER_SIZE);
-        this.logger.log("picker size" + s);
-
-        this.hueSlider = Slider.getVertSlider(this.getElement(this.ID.HUE_BG), 
-                                              this.getElement(this.ID.HUE_THUMB), 0, s);
-        this.hueSlider.subscribe("change", _onHueSliderChange, this, true);
-
-        this.pickerSlider = Slider.getSliderRegion(this.getElement(this.ID.PICKER_BG), 
-                                                   this.getElement(this.ID.PICKER_THUMB), 0, s, 0, s);
-        this.pickerSlider.subscribe("change", _onPickerSliderChange, this, true);
-
-        // Set the animate state
-        this.set(o.ANIMATE,this.get(o.ANIMATE));
-
-        //_onHueSliderChange.call(this, 0);
-
-        Event.on(this.getElement(this.ID.WEBSAFE_SWATCH), "click", function(e) {
-               this.setValue(this.get(o.WEBSAFE));
-               //_updateSliders
-           }, this, true);
-
-        Event.on(this.getElement(this.ID.CONTROLS_LABEL), "click", function(e) {
-               this.set(o.SHOW_CONTROLS, !this.get(o.SHOW_CONTROLS));
-               Event.preventDefault(e);
-           }, this, true);
-
-        _attachRGBHSV.call(this, this.ID.R, this.OPT.RED); 
-        _attachRGBHSV.call(this, this.ID.G, this.OPT.GREEN); 
-        _attachRGBHSV.call(this, this.ID.B, this.OPT.BLUE); 
-        _attachRGBHSV.call(this, this.ID.H, this.OPT.HUE); 
-        _attachRGBHSV.call(this, this.ID.S, this.OPT.SATURATION); 
-        _attachRGBHSV.call(this, this.ID.V, this.OPT.VALUE); 
-
-        Event.on(this.getElement(this.ID.HEX), "keydown", function(e, me) {
-                _hexFieldKeypress.call(me, e, this, me.OPT.HEX);
-            }, this);
-
-        Event.on(this.getElement(this.ID.HEX), "keypress", _hexOnly, this);
-        Event.on(this.getElement(this.ID.HEX), "blur", function(e, me) {
-                _useFieldValue.call(me, e, this, me.OPT.HEX);
-            }, this);
-
-        _updateRGB.call(this);
-    };
-
-
-    /**
-     * Updates the RGB values from the current state of the HSV
-     * values.  Executed when the one of the HSV form fields are
-     * updated
-     * _updateRGBFromHSV
-     * @private
-     */
-    var _updateRGBFromHSV = function() {
-        var hsv = [this.get(this.OPT.HUE), 
-                   this.get(this.OPT.SATURATION)/100,
-                   this.get(this.OPT.VALUE)/100];
-
-        var rgb = Color.hsv2rgb(hsv);
-
-        this.logger.log("HSV converted to RGB " + hsv + " : " + rgb);
-        this.set(this.OPT.RGB, rgb);
-
-        _updateSliders.call(this);
-    };
-
-    /**
-     * Parses the hex string to normalize shorthand values, converts
-     * the hex value to rgb and updates the rgb attribute (which
-     * updates the state for all of the other values)
-     * method _updateHex
-     * @private
-     */
-    var _updateHex = function() {
-       
-        var hex = this.get(this.OPT.HEX), l=hex.length;
-
-        // support #369 -> #336699 shorthand
-        if (l === 3) {
-            var c = hex.split(""), i;
-            for (i=0; i<l; i=i+1) {
-                c[i] = c[i] + c[i];
-            }
-
-            hex = c.join("");
-        }
-
-        if (hex.length !== 6) {
-            this.logger.log(this.get(this.TXT.ILLEGAL_HEX), "error");
-            return false;
-        }
-
-        var rgb = Color.hex2rgb(hex);
-
-        this.logger.log(sub("Hex value set to {hex} ({rgb})", {
-                hex: hex, rgb: rgb
-            }));
-
-        this.setValue(rgb);
-
-        //_updateSliders.call(this);
-
-    };
-
-
-
-    /**
-     * Sets up the config attributes and the change listeners for this
-     * properties
-     * @method initAttributes
-     * @param attr An object containing default attribute values
-     */
-    proto.initAttributes = function(attr) {
-
-        attr = attr || {};
-        YAHOO.widget.ColorPicker.superclass.initAttributes.call(this, attr);
-        
-        /**
-         * The size of the picker. Trying to change this is not recommended.
-         * @attribute pickersize
-         * @default 180
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.PICKER_SIZE, {
-                value: attr.size || this.DEFAULT.PICKER_SIZE
-            });
-
-        /**
-         * The current hue value 0-360
-         * @attribute hue
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.HUE, {
-                value: attr.hue || 0,
-                validator: lang.isNumber
-            });
-
-        /**
-         * The current saturation value 0-100
-         * @attribute saturation
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.SATURATION, {
-                value: attr.saturation || 0,
-                validator: lang.isNumber
-            });
-
-        /**
-         * The current value/brightness value 0-100
-         * @attribute value
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.VALUE, {
-                value: lang.isNumber(attr.value) ? attr.value : 100,
-                validator: lang.isNumber
-            });
-
-        /**
-         * The current red value 0-255
-         * @attribute red
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.RED, {
-                value: lang.isNumber(attr.red) ? attr.red : 255,
-                validator: lang.isNumber
-            });
-
-        /**
-         * The current green value 0-255
-         * @attribute green 
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.GREEN, {
-                value: lang.isNumber(attr.green) ? attr.green : 255,
-                validator: lang.isNumber
-            });
-
-        /**
-         * The current blue value 0-255
-         * @attribute blue
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.BLUE, {
-                value: lang.isNumber(attr.blue) ? attr.blue : 255,
-                validator: lang.isNumber
-            });
-
-        /**
-         * The current hex value #000000-#FFFFFF, without the #
-         * @attribute hex
-         * @type string
-         */
-        this.setAttributeConfig(this.OPT.HEX, {
-                value: attr.hex || "FFFFFF",
-                validator: lang.isString
-            });
-
-        /**
-         * The current rgb value.  Updates the state of all of the
-         * other value fields.  Read-only: use setValue to set the
-         * controls rgb value.
-         * @attribute hex
-         * @type [int, int, int]
-         * @readonly
-         */
-        this.setAttributeConfig(this.OPT.RGB, {
-                value: attr.rgb || [255,255,255],
-                method: function(rgb) {
-
-                    this.set(this.OPT.RED, rgb[0], true);
-                    this.set(this.OPT.GREEN, rgb[1], true);
-                    this.set(this.OPT.BLUE, rgb[2], true);
-
-                    var websafe = Color.websafe(rgb);
-                    this.set(this.OPT.WEBSAFE, websafe, true);
-
-                    var hex = Color.rgb2hex(rgb);
-                    this.set(this.OPT.HEX, hex, true);
-
-                    var hsv = Color.rgb2hsv(rgb);
-
-                    this.logger.log(sub("RGB value set to {rgb} (hsv: {hsv})", {
-                            "hsv": hsv, "rgb": rgb
-                        }));
-
-                    this.set(this.OPT.HUE, hsv[0], true);
-                    this.set(this.OPT.SATURATION, Math.round(hsv[1]*100), true);
-                    this.set(this.OPT.VALUE, Math.round(hsv[2]*100), true);
-                },
-                readonly: true
-            });
-
-        /**
-         * If the color picker will live inside of a container object,
-         * set, provide a reference to it so the control can use the
-         * container's events.
-         * @attribute container
-         * @type YAHOO.widget.Panel
-         */
-        this.setAttributeConfig(this.OPT.CONTAINER, {
-                    value: null,
-                    method: function(container) {
-                        if (container) {
-                            // Position can get out of sync when the
-                            // control is manipulated while display is
-                            // none.  Resetting the slider constraints
-                            // when it is visible gets the state back in
-                            // order.
-                            container.showEvent.subscribe(function() {
-                                // this.pickerSlider.thumb.resetConstraints();
-                                // this.hueSlider.thumb.resetConstraints();
-                                this.pickerSlider.focus();
-                            }, this, true);
-                        }
-                    }
-                });
-        /**
-         * The closest current websafe value
-         * @attribute websafe
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.WEBSAFE, {
-                value: attr.websafe || [255,255,255]
-            });
-
-
-        var ids = attr.ids || lang.merge({}, this.ID);
-
-        if (!attr.ids && _pickercount > 1) {
-            for (var i in ids) {
-                if (lang.hasOwnProperty(ids, i)) {
-                    ids[i] = ids[i] + _pickercount;
-                }
-            }
-        }
-
-
-        /**
-         * A list of element ids and/or element references used by the 
-         * control.  The default is the this.ID list, and can be customized
-         * by passing a list in the contructor
-         * @attribute ids
-         * @type {referenceid: realid}
-         * @writeonce
-         */
-        this.setAttributeConfig(this.OPT.IDS, {
-                value: ids,
-                writeonce: true
-            });
-
-        /**
-         * A list of txt strings for internationalization.  Default
-         * is this.TXT
-         * @attribute txt
-         * @type {key: txt}
-         * @writeonce
-         */
-        this.setAttributeConfig(this.OPT.TXT, {
-                value: attr.txt || this.TXT,
-                writeonce: true
-            });
-
-        /**
-         * The img src default list
-         * is this.IMAGES
-         * @attribute images
-         * @type {key: image}
-         * @writeonce
-         */
-        this.setAttributeConfig(this.OPT.IMAGES, {
-                value: attr.images || this.IMAGE,
-                writeonce: true
-            });
-        /**
-         * The element refs used by this control.  Set at initialization
-         * @attribute elements
-         * @type {id: HTMLElement}
-         * @readonly
-         */
-        this.setAttributeConfig(this.OPT.ELEMENTS, {
-                value: {},
-                readonly: true
-            });
-
-        /**
-         * Returns the cached element reference.  If the id is not a string, it
-         * is assumed that it is an element and this is returned.
-         * @param id {string|HTMLElement} the element key, id, or ref
-         * @param on {boolean} hide or show.  If true, show
-         * @private */
-        var _hideShowEl = function(id, on) {
-            var el = (lang.isString(id) ? this.getElement(id) : id);
-            //Dom.setStyle(id, "visibility", (on) ? "" : "hidden");
-            Dom.setStyle(el, "display", (on) ? "" : "none");
-        };
-
-        /**
-         * Hide/show the entire set of controls
-         * @attribute showcontrols
-         * @type boolean
-         * @default true
-         */
-        this.setAttributeConfig(this.OPT.SHOW_CONTROLS, {
-                value: lang.isBoolean(attr.showcontrols) ? attr.showcontrols : true,
-                method: function(on) {
-
-                    var el = Dom.getElementsByClassName("bd", "div", 
-                            this.getElement(this.ID.CONTROLS))[0];
-
-                    _hideShowEl.call(this, el, on);
-
-                    this.getElement(this.ID.CONTROLS_LABEL).innerHTML = 
-                        (on) ? this.get(this.OPT.TXT).HIDE_CONTROLS :
-                               this.get(this.OPT.TXT).SHOW_CONTROLS;
-
-                }
-            });
-
-        /**
-         * Hide/show the rgb controls
-         * @attribute showrgbcontrols
-         * @type boolean
-         * @default true
-         */
-        this.setAttributeConfig(this.OPT.SHOW_RGB_CONTROLS, {
-                value: lang.isBoolean(attr.showrgbcontrols) ? attr.showrgbcontrols : true,
-                method: function(on) {
-                    //Dom.setStyle(this.getElement(this.ID.RBG_CONTROLS), "visibility", (on) ? "" : "hidden");
-                    _hideShowEl.call(this, this.ID.RGB_CONTROLS, on);
-                }
-            });
-
-        /**
-         * Hide/show the hsv controls
-         * @attribute showhsvcontrols
-         * @type boolean
-         * @default false
-         */
-        this.setAttributeConfig(this.OPT.SHOW_HSV_CONTROLS, {
-                value: lang.isBoolean(attr.showhsvcontrols) ?
-                                      attr.showhsvcontrols : false,
-                method: function(on) {
-                    //Dom.setStyle(this.getElement(this.ID.HSV_CONTROLS), "visibility", (on) ? "" : "hidden");
-                    _hideShowEl.call(this, this.ID.HSV_CONTROLS, on);
-
-                    // can't show both the hsv controls and the rbg hex summary
-                    if (on && this.get(this.OPT.SHOW_HEX_SUMMARY)) {
-                        this.set(this.OPT.SHOW_HEX_SUMMARY, false);
-                    }
-                }
-            });
-
-        /**
-         * Hide/show the hex controls
-         * @attribute showhexcontrols
-         * @type boolean
-         * @default true
-         */
-        this.setAttributeConfig(this.OPT.SHOW_HEX_CONTROLS, {
-                value: lang.isBoolean(attr.showhexcontrols) ?
-                                      attr.showhexcontrols : false,
-                method: function(on) {
-                    _hideShowEl.call(this, this.ID.HEX_CONTROLS, on);
-                }
-            });
-
-        /**
-         * Hide/show the websafe swatch
-         * @attribute showwebsafe
-         * @type boolean
-         * @default true
-         */
-        this.setAttributeConfig(this.OPT.SHOW_WEBSAFE, {
-                value: lang.isBoolean(attr.showwebsafe) ? attr.showwebsafe : true,
-                method: function(on) {
-                    _hideShowEl.call(this, this.ID.WEBSAFE_SWATCH, on);
-                }
-            });
-
-        /**
-         * Hide/show the hex summary
-         * @attribute showhexsummary
-         * @type boolean
-         * @default true
-         */
-        this.setAttributeConfig(this.OPT.SHOW_HEX_SUMMARY, {
-                value: lang.isBoolean(attr.showhexsummary) ? attr.showhexsummary : true,
-                method: function(on) {
-                    _hideShowEl.call(this, this.ID.HEX_SUMMARY, on);
-
-                    // can't show both the hsv controls and the rbg hex summary
-                    if (on && this.get(this.OPT.SHOW_HSV_CONTROLS)) {
-                        this.set(this.OPT.SHOW_HSV_CONTROLS, false);
-                    }
-                }
-            });
-        this.setAttributeConfig(this.OPT.ANIMATE, {
-                value: lang.isBoolean(attr.animate) ? attr.animate : true,
-                method: function(on) {
-                    this.pickerSlider.animate = on;
-                    this.hueSlider.animate = on;
-                }
-            });
-
-        this.on(this.OPT.HUE + "Change", _updateRGBFromHSV, this, true);
-        this.on(this.OPT.SATURATION + "Change", _updateRGBFromHSV, this, true);
-        this.on(this.OPT.VALUE + "Change", _updatePickerSlider, this, true);
-
-        this.on(this.OPT.RED + "Change", _updateRGB, this, true);
-        this.on(this.OPT.GREEN + "Change", _updateRGB, this, true);
-        this.on(this.OPT.BLUE + "Change", _updateRGB, this, true);
-
-        this.on(this.OPT.HEX + "Change", _updateHex, this, true);
-
-        this.initPicker();
-    };
-
-})();
-YAHOO.register("colorpicker", YAHOO.widget.ColorPicker, {version: "2.4.1", build: "742"});

Deleted: trunk/root/static/yui/colorpicker/colorpicker-beta-min.js
===================================================================
--- trunk/root/static/yui/colorpicker/colorpicker-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/colorpicker/colorpicker-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-YAHOO.util.Color=function(){var A="0123456789ABCDEF",B=YAHOO.lang;return{real2dec:function(C){return Math.min(255,Math.round(C*256));},hsv2rgb:function(G,N,L){if(B.isArray(G)){return this.hsv2rgb.call(this,G[0],G[1],G[2]);}var C,H,K,F,I,E,D,M;F=Math.floor((G/60)%6);I=(G/60)-F;E=L*(1-N);D=L*(1-I*N);M=L*(1-(1-I)*N);switch(F){case 0:C=L;H=M;K=E;break;case 1:C=D;H=L;K=E;break;case 2:C=E;H=L;K=M;break;case 3:C=E;H=D;K=L;break;case 4:C=M;H=E;K=L;break;case 5:C=L;H=E;K=D;break;}var J=this.real2dec;return[J(C),J(H),J(K)];},rgb2hsv:function(C,G,H){if(B.isArray(C)){return this.rgb2hsv.call(this,C[0],C[1],C[2]);}C=C/255;G=G/255;H=H/255;var D,I,K,F,L,J;D=Math.min(Math.min(C,G),H);I=Math.max(Math.max(C,G),H);K=I-D;switch(I){case D:F=0;break;case C:F=60*(G-H)/K;if(G<H){F+=360;}break;case G:F=(60*(H-C)/K)+120;break;case H:F=(60*(C-G)/K)+240;break;}L=(I===0)?0:1-(D/I);var E=[Math.round(F),L,I];return E;},rgb2hex:function(E,D,C){if(B.isArray(E)){return this.rgb2hex.call(this,E[0],E[1],E[2])!
 ;}var F=this.dec2hex;return F(E)+F(D)+F(C);},dec2hex:function(C){C=parseInt(C,10);C=(B.isNumber(C))?C:0;C=(C>255||C<0)?0:C;return A.charAt((C-C%16)/16)+A.charAt(C%16);},hex2dec:function(E){var D=function(F){return A.indexOf(F.toUpperCase());};var C=E.split("");return((D(C[0])*16)+D(C[1]));},hex2rgb:function(C){var D=this.hex2dec;return[D(C.substr(0,2)),D(C.substr(2,2)),D(C.substr(4,2))];},websafe:function(E,D,C){if(B.isArray(E)){return this.websafe.call(this,E[0],E[1],E[2]);}var F=function(G){if(B.isNumber(G)){G=Math.min(Math.max(0,G),255);var H,I;for(H=0;H<256;H=H+51){I=H+51;if(G>=H&&G<=I){return(G-H>25)?I:H;}}}return G;};return[F(E),F(D),F(C)];}};}();(function(){var E=0;var R=function(){var b=document.createElement("div");if(this.CSS.BASE){b.className=this.CSS.BASE;}return b;};YAHOO.widget.ColorPicker=function(h,b){E=E+1;b=b||{};if(arguments.length===1&&!YAHOO.lang.isString(h)&&!h.nodeName){b=h;h=b.element||null;}if(!h&&!b.element){h=R.call(this,b);}YAHOO.widget.ColorPick!
 er.superclass.constructor.call(this,h,b);};YAHOO.extend(YAHOO.!
 widget.C
olorPicker,YAHOO.util.Element);var Q=YAHOO.widget.ColorPicker.prototype,P=YAHOO.widget.Slider,e=YAHOO.util.Color,C=YAHOO.util.Dom,f=YAHOO.util.Event,g=YAHOO.lang,J=g.substitute;var a="yui-picker";Q.ID={R:a+"-r",R_HEX:a+"-rhex",G:a+"-g",G_HEX:a+"-ghex",B:a+"-b",B_HEX:a+"-bhex",H:a+"-h",S:a+"-s",V:a+"-v",PICKER_BG:a+"-bg",PICKER_THUMB:a+"-thumb",HUE_BG:a+"-hue-bg",HUE_THUMB:a+"-hue-thumb",HEX:a+"-hex",SWATCH:a+"-swatch",WEBSAFE_SWATCH:a+"-websafe-swatch",CONTROLS:a+"-controls",RGB_CONTROLS:a+"-rgb-controls",HSV_CONTROLS:a+"-hsv-controls",HEX_CONTROLS:a+"-hex-controls",HEX_SUMMARY:a+"-hex-summary",CONTROLS_LABEL:a+"-controls-label"};Q.TXT={ILLEGAL_HEX:"Illegal hex value entered",SHOW_CONTROLS:"Show color details",HIDE_CONTROLS:"Hide color details",CURRENT_COLOR:"Currently selected color: {rgb}",CLOSEST_WEBSAFE:"Closest websafe color: {rgb}. Click to select.",R:"R",G:"G",B:"B",H:"H",S:"S",V:"V",HEX:"#",DEG:"¡",PERCENT:"%"};Q.IMAGE={PICKER_THUMB:"../../build/colorpicker/assets/pi!
 cker_thumb.png",HUE_THUMB:"../../build/colorpicker/assets/hue_thumb.png"};Q.DEFAULT={PICKER_SIZE:180};Q.OPT={HUE:"hue",SATURATION:"saturation",VALUE:"value",RED:"red",GREEN:"green",BLUE:"blue",HSV:"hsv",RGB:"rgb",WEBSAFE:"websafe",HEX:"hex",PICKER_SIZE:"pickersize",SHOW_CONTROLS:"showcontrols",SHOW_RGB_CONTROLS:"showrgbcontrols",SHOW_HSV_CONTROLS:"showhsvcontrols",SHOW_HEX_CONTROLS:"showhexcontrols",SHOW_HEX_SUMMARY:"showhexsummary",SHOW_WEBSAFE:"showwebsafe",CONTAINER:"container",IDS:"ids",ELEMENTS:"elements",TXT:"txt",IMAGES:"images",ANIMATE:"animate"};var S=function(){var b=this.get(this.OPT.PICKER_SIZE),i=this.get(this.OPT.HUE);i=b-Math.round(i/360*b);if(i===b){i=0;}this.hueSlider.setValue(i);};var d=function(){var h=this.get(this.OPT.PICKER_SIZE),i=this.get(this.OPT.SATURATION),b=this.get(this.OPT.VALUE);i=Math.round(i*h/100);b=Math.round(h-(b*h/100));this.pickerSlider.setRegionValue(i,b);};var T=function(){S.call(this);d.call(this);};Q.setValue=function(h,b){b=(b)||fa!
 lse;this.set(this.OPT.RGB,h,b);T.call(this);};Q.hueSlider=null!
 ;Q.picke
rSlider=null;var X=function(){var b=this.get(this.OPT.PICKER_SIZE),i=(b-this.hueSlider.getValue())/b;i=Math.round(i*360);return(i===360)?0:i;};var O=function(){return this.pickerSlider.getXValue()/this.get(this.OPT.PICKER_SIZE);};var N=function(){var b=this.get(this.OPT.PICKER_SIZE);return(b-this.pickerSlider.getYValue())/b;};var M=function(){var i=this.get(this.OPT.RGB),k=this.get(this.OPT.WEBSAFE),j=this.getElement(this.ID.SWATCH),h=i.join(","),b=this.get(this.OPT.TXT);C.setStyle(j,"background-color","rgb("+h+")");j.title=g.substitute(b.CURRENT_COLOR,{"rgb":"#"+this.get(this.OPT.HEX)});j=this.getElement(this.ID.WEBSAFE_SWATCH);h=k.join(",");C.setStyle(j,"background-color","rgb("+h+")");j.title=g.substitute(b.CLOSEST_WEBSAFE,{"rgb":"#"+e.rgb2hex(k)});};var Z=function(){var k=X.call(this),j=O.call(this),b=N.call(this);var i=e.hsv2rgb(k,j,b);this.set(this.OPT.RGB,i);};var B=function(){this.getElement(this.ID.H).value=this.get(this.OPT.HUE);this.getElement(this.ID.S).value=thi!
 s.get(this.OPT.SATURATION);this.getElement(this.ID.V).value=this.get(this.OPT.VALUE);this.getElement(this.ID.R).value=this.get(this.OPT.RED);this.getElement(this.ID.R_HEX).innerHTML=e.dec2hex(this.get(this.OPT.RED));this.getElement(this.ID.G).value=this.get(this.OPT.GREEN);this.getElement(this.ID.G_HEX).innerHTML=e.dec2hex(this.get(this.OPT.GREEN));this.getElement(this.ID.B).value=this.get(this.OPT.BLUE);this.getElement(this.ID.B_HEX).innerHTML=e.dec2hex(this.get(this.OPT.BLUE));this.getElement(this.ID.HEX).value=this.get(this.OPT.HEX);};var Y=function(k){var i=X.call(this);this.set(this.OPT.HUE,i,true);var b=e.hsv2rgb(i,1,1);var j="rgb("+b.join(",")+")";C.setStyle(this.getElement(this.ID.PICKER_BG),"background-color",j);if(this.hueSlider.valueChangeSource===this.hueSlider.SOURCE_UI_EVENT){Z.call(this);}B.call(this);M.call(this);};var H=function(i){var h=O.call(this),b=N.call(this);this.set(this.OPT.SATURATION,Math.round(h*100),true);
-this.set(this.OPT.VALUE,Math.round(b*100),true);if(this.pickerSlider.valueChangeSource===this.pickerSlider.SOURCE_UI_EVENT){Z.call(this);}B.call(this);M.call(this);};var W=function(b){var h=f.getCharCode(b);if(h===38){return 3;}else{if(h===13){return 6;}else{if(h===40){return 4;}else{if(h>=48&&h<=57){return 1;}else{if(h>=97&&h<=102){return 2;}else{if(h>=65&&h<=70){return 2;}else{if("8, 9, 13, 27, 37, 39".indexOf(h)>-1){return 5;}else{return 0;}}}}}}}};var I=function(h,b,j){var i=b.value;if(j!==this.OPT.HEX){i=parseInt(i,10);}if(i!==this.get(j)){this.set(j,i);}};var G=function(i,b,k){var j=W(i);var h=(i.shiftKey)?10:1;switch(j){case 6:I.apply(this,arguments);break;case 3:this.set(k,Math.min(this.get(k)+h,255));B.call(this);break;case 4:this.set(k,Math.max(this.get(k)-h,0));B.call(this);break;default:}};var A=function(h,b,j){var i=W(h);if(i===6){I.apply(this,arguments);}};var L=function(h,b){var i=W(h);switch(i){case 6:case 5:case 1:break;case 2:if(b!==true){break;}default:f.!
 stopEvent(h);return false;}};var K=function(b){return L(b,true);};Q.getElement=function(b){return this.get(this.OPT.ELEMENTS)[this.get(this.OPT.IDS)[b]];};var D=function(){var k,j,n,l,m,b=this.get(this.OPT.IDS),o=this.get(this.OPT.TXT),r=this.get(this.OPT.IMAGES),q=function(i,p){var t=document.createElement(i);if(p){g.augmentObject(t,p,true);}return t;},s=function(i,p){var t=g.merge({autocomplete:"off",value:"0",size:3,maxlength:3},p);t.name=t.id;return new q(i,t);};var h=this.get("element");k=new q("div",{id:b[this.ID.PICKER_BG],className:"yui-picker-bg",tabIndex:-1,hideFocus:true});j=new q("div",{id:b[this.ID.PICKER_THUMB],className:"yui-picker-thumb"});n=new q("img",{src:r.PICKER_THUMB});j.appendChild(n);k.appendChild(j);h.appendChild(k);k=new q("div",{id:b[this.ID.HUE_BG],className:"yui-picker-hue-bg",tabIndex:-1,hideFocus:true});j=new q("div",{id:b[this.ID.HUE_THUMB],className:"yui-picker-hue-thumb"});n=new q("img",{src:r.HUE_THUMB});j.appendChild(n);k.appendChild(j);h!
 .appendChild(k);k=new q("div",{id:b[this.ID.CONTROLS],classNam!
 e:"yui-p
icker-controls"});h.appendChild(k);h=k;k=new q("div",{className:"hd"});j=new q("a",{id:b[this.ID.CONTROLS_LABEL],href:"#"});k.appendChild(j);h.appendChild(k);k=new q("div",{className:"bd"});h.appendChild(k);h=k;k=new q("ul",{id:b[this.ID.RGB_CONTROLS],className:"yui-picker-rgb-controls"});j=new q("li");j.appendChild(document.createTextNode(o.R+" "));l=new s("input",{id:b[this.ID.R],className:"yui-picker-r"});j.appendChild(l);k.appendChild(j);j=new q("li");j.appendChild(document.createTextNode(o.G+" "));l=new s("input",{id:b[this.ID.G],className:"yui-picker-g"});j.appendChild(l);k.appendChild(j);j=new q("li");j.appendChild(document.createTextNode(o.B+" "));l=new s("input",{id:b[this.ID.B],className:"yui-picker-b"});j.appendChild(l);k.appendChild(j);h.appendChild(k);k=new q("ul",{id:b[this.ID.HSV_CONTROLS],className:"yui-picker-hsv-controls"});j=new q("li");j.appendChild(document.createTextNode(o.H+" "));l=new s("input",{id:b[this.ID.H],className:"yui-picker-h"});j.appendChild!
 (l);j.appendChild(document.createTextNode(" "+o.DEG));k.appendChild(j);j=new q("li");j.appendChild(document.createTextNode(o.S+" "));l=new s("input",{id:b[this.ID.S],className:"yui-picker-s"});j.appendChild(l);j.appendChild(document.createTextNode(" "+o.PERCENT));k.appendChild(j);j=new q("li");j.appendChild(document.createTextNode(o.V+" "));l=new s("input",{id:b[this.ID.V],className:"yui-picker-v"});j.appendChild(l);j.appendChild(document.createTextNode(" "+o.PERCENT));k.appendChild(j);h.appendChild(k);k=new q("ul",{id:b[this.ID.HEX_SUMMARY],className:"yui-picker-hex_summary"});j=new q("li",{id:b[this.ID.R_HEX]});k.appendChild(j);j=new q("li",{id:b[this.ID.G_HEX]});k.appendChild(j);j=new q("li",{id:b[this.ID.B_HEX]});k.appendChild(j);h.appendChild(k);k=new q("div",{id:b[this.ID.HEX_CONTROLS],className:"yui-picker-hex-controls"});k.appendChild(document.createTextNode(o.HEX+" "));j=new s("input",{id:b[this.ID.HEX],className:"yui-picker-hex",size:6,maxlength:6});k.appendChild(!
 j);h.appendChild(k);h=this.get("element");k=new q("div",{id:b[!
 this.ID.
SWATCH],className:"yui-picker-swatch"});h.appendChild(k);k=new q("div",{id:b[this.ID.WEBSAFE_SWATCH],className:"yui-picker-websafe-swatch"});h.appendChild(k);};var c=function(h,b){f.on(this.getElement(h),"keydown",function(j,i){G.call(i,j,this,b);},this);f.on(this.getElement(h),"keypress",K,this);f.on(this.getElement(h),"blur",function(j,i){I.call(i,j,this,b);},this);};var F=function(){var b=[this.get(this.OPT.RED),this.get(this.OPT.GREEN),this.get(this.OPT.BLUE)];this.set(this.OPT.RGB,b);T.call(this);};Q.initPicker=function(){var m=this.OPT,l=this.get(m.IDS),h=this.get(m.ELEMENTS),b,k,n;for(b in this.ID){if(g.hasOwnProperty(this.ID,b)){l[this.ID[b]]=l[b];}}k=C.get(l[this.ID.PICKER_BG]);if(!k){D.call(this);}else{}for(b in l){if(g.hasOwnProperty(l,b)){k=C.get(l[b]);n=C.generateId(k);l[b]=n;l[l[b]]=n;h[n]=k;}}h=[m.SHOW_CONTROLS,m.SHOW_RGB_CONTROLS,m.SHOW_HSV_CONTROLS,m.SHOW_HEX_CONTROLS,m.SHOW_HEX_SUMMARY,m.SHOW_WEBSAFE];for(b=0;b<h.length;b=b+1){this.set(h[b],this.get(h[b]));!
 }var j=this.get(m.PICKER_SIZE);this.hueSlider=P.getVertSlider(this.getElement(this.ID.HUE_BG),this.getElement(this.ID.HUE_THUMB),0,j);this.hueSlider.subscribe("change",Y,this,true);this.pickerSlider=P.getSliderRegion(this.getElement(this.ID.PICKER_BG),this.getElement(this.ID.PICKER_THUMB),0,j,0,j);this.pickerSlider.subscribe("change",H,this,true);this.set(m.ANIMATE,this.get(m.ANIMATE));f.on(this.getElement(this.ID.WEBSAFE_SWATCH),"click",function(i){this.setValue(this.get(m.WEBSAFE));},this,true);f.on(this.getElement(this.ID.CONTROLS_LABEL),"click",function(i){this.set(m.SHOW_CONTROLS,!this.get(m.SHOW_CONTROLS));f.preventDefault(i);},this,true);c.call(this,this.ID.R,this.OPT.RED);c.call(this,this.ID.G,this.OPT.GREEN);c.call(this,this.ID.B,this.OPT.BLUE);c.call(this,this.ID.H,this.OPT.HUE);c.call(this,this.ID.S,this.OPT.SATURATION);c.call(this,this.ID.V,this.OPT.VALUE);f.on(this.getElement(this.ID.HEX),"keydown",function(o,i){A.call(i,o,this,i.OPT.HEX);
-},this);f.on(this.getElement(this.ID.HEX),"keypress",L,this);f.on(this.getElement(this.ID.HEX),"blur",function(o,i){I.call(i,o,this,i.OPT.HEX);},this);F.call(this);};var U=function(){var h=[this.get(this.OPT.HUE),this.get(this.OPT.SATURATION)/100,this.get(this.OPT.VALUE)/100];var b=e.hsv2rgb(h);this.set(this.OPT.RGB,b);T.call(this);};var V=function(){var k=this.get(this.OPT.HEX),b=k.length;if(b===3){var m=k.split(""),j;for(j=0;j<b;j=j+1){m[j]=m[j]+m[j];}k=m.join("");}if(k.length!==6){return false;}var h=e.hex2rgb(k);this.setValue(h);};Q.initAttributes=function(b){b=b||{};YAHOO.widget.ColorPicker.superclass.initAttributes.call(this,b);this.setAttributeConfig(this.OPT.PICKER_SIZE,{value:b.size||this.DEFAULT.PICKER_SIZE});this.setAttributeConfig(this.OPT.HUE,{value:b.hue||0,validator:g.isNumber});this.setAttributeConfig(this.OPT.SATURATION,{value:b.saturation||0,validator:g.isNumber});this.setAttributeConfig(this.OPT.VALUE,{value:g.isNumber(b.value)?b.value:100,validator:g.isN!
 umber});this.setAttributeConfig(this.OPT.RED,{value:g.isNumber(b.red)?b.red:255,validator:g.isNumber});this.setAttributeConfig(this.OPT.GREEN,{value:g.isNumber(b.green)?b.green:255,validator:g.isNumber});this.setAttributeConfig(this.OPT.BLUE,{value:g.isNumber(b.blue)?b.blue:255,validator:g.isNumber});this.setAttributeConfig(this.OPT.HEX,{value:b.hex||"FFFFFF",validator:g.isString});this.setAttributeConfig(this.OPT.RGB,{value:b.rgb||[255,255,255],method:function(l){this.set(this.OPT.RED,l[0],true);this.set(this.OPT.GREEN,l[1],true);this.set(this.OPT.BLUE,l[2],true);var n=e.websafe(l);this.set(this.OPT.WEBSAFE,n,true);var m=e.rgb2hex(l);this.set(this.OPT.HEX,m,true);var i=e.rgb2hsv(l);this.set(this.OPT.HUE,i[0],true);this.set(this.OPT.SATURATION,Math.round(i[1]*100),true);this.set(this.OPT.VALUE,Math.round(i[2]*100),true);},readonly:true});this.setAttributeConfig(this.OPT.CONTAINER,{value:null,method:function(i){if(i){i.showEvent.subscribe(function(){this.pickerSlider.focus()!
 ;},this,true);}}});this.setAttributeConfig(this.OPT.WEBSAFE,{v!
 alue:b.w
ebsafe||[255,255,255]});var j=b.ids||g.merge({},this.ID);if(!b.ids&&E>1){for(var h in j){if(g.hasOwnProperty(j,h)){j[h]=j[h]+E;}}}this.setAttributeConfig(this.OPT.IDS,{value:j,writeonce:true});this.setAttributeConfig(this.OPT.TXT,{value:b.txt||this.TXT,writeonce:true});this.setAttributeConfig(this.OPT.IMAGES,{value:b.images||this.IMAGE,writeonce:true});this.setAttributeConfig(this.OPT.ELEMENTS,{value:{},readonly:true});var k=function(m,i){var l=(g.isString(m)?this.getElement(m):m);C.setStyle(l,"display",(i)?"":"none");};this.setAttributeConfig(this.OPT.SHOW_CONTROLS,{value:g.isBoolean(b.showcontrols)?b.showcontrols:true,method:function(i){var l=C.getElementsByClassName("bd","div",this.getElement(this.ID.CONTROLS))[0];k.call(this,l,i);this.getElement(this.ID.CONTROLS_LABEL).innerHTML=(i)?this.get(this.OPT.TXT).HIDE_CONTROLS:this.get(this.OPT.TXT).SHOW_CONTROLS;}});this.setAttributeConfig(this.OPT.SHOW_RGB_CONTROLS,{value:g.isBoolean(b.showrgbcontrols)?b.showrgbcontrols:true,m!
 ethod:function(i){k.call(this,this.ID.RGB_CONTROLS,i);}});this.setAttributeConfig(this.OPT.SHOW_HSV_CONTROLS,{value:g.isBoolean(b.showhsvcontrols)?b.showhsvcontrols:false,method:function(i){k.call(this,this.ID.HSV_CONTROLS,i);if(i&&this.get(this.OPT.SHOW_HEX_SUMMARY)){this.set(this.OPT.SHOW_HEX_SUMMARY,false);}}});this.setAttributeConfig(this.OPT.SHOW_HEX_CONTROLS,{value:g.isBoolean(b.showhexcontrols)?b.showhexcontrols:false,method:function(i){k.call(this,this.ID.HEX_CONTROLS,i);}});this.setAttributeConfig(this.OPT.SHOW_WEBSAFE,{value:g.isBoolean(b.showwebsafe)?b.showwebsafe:true,method:function(i){k.call(this,this.ID.WEBSAFE_SWATCH,i);}});this.setAttributeConfig(this.OPT.SHOW_HEX_SUMMARY,{value:g.isBoolean(b.showhexsummary)?b.showhexsummary:true,method:function(i){k.call(this,this.ID.HEX_SUMMARY,i);if(i&&this.get(this.OPT.SHOW_HSV_CONTROLS)){this.set(this.OPT.SHOW_HSV_CONTROLS,false);}}});this.setAttributeConfig(this.OPT.ANIMATE,{value:g.isBoolean(b.animate)?b.animate:true!
 ,method:function(i){this.pickerSlider.animate=i;this.hueSlider!
 .animate
=i;}});this.on(this.OPT.HUE+"Change",U,this,true);this.on(this.OPT.SATURATION+"Change",U,this,true);this.on(this.OPT.VALUE+"Change",d,this,true);this.on(this.OPT.RED+"Change",F,this,true);this.on(this.OPT.GREEN+"Change",F,this,true);this.on(this.OPT.BLUE+"Change",F,this,true);this.on(this.OPT.HEX+"Change",V,this,true);this.initPicker();};})();YAHOO.register("colorpicker",YAHOO.widget.ColorPicker,{version:"2.4.1",build:"742"});
\ No newline at end of file

Deleted: trunk/root/static/yui/colorpicker/colorpicker-beta.js
===================================================================
--- trunk/root/static/yui/colorpicker/colorpicker-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/colorpicker/colorpicker-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,1735 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-/**
- * Provides color conversion and validation utils
- * @class YAHOO.util.Color
- * @namespace YAHOO.util
- */
-YAHOO.util.Color = function() {
-
-    var HCHARS="0123456789ABCDEF", lang=YAHOO.lang;
-
-    return {
-
-        /**
-         * Converts 0-1 to 0-255
-         * @method real2dec
-         * @param n {float} the number to convert
-         * @return {int} a number 0-255
-         */
-        real2dec: function(n) {
-            return Math.min(255, Math.round(n*256));
-        },
-
-        /**
-         * Converts HSV (h[0-360], s[0-1]), v[0-1] to RGB [255,255,255]
-         * @method hsv2rgb
-         * @param h {int|[int, float, float]} the hue, or an
-         *        array containing all three parameters
-         * @param s {float} the saturation
-         * @param v {float} the value/brightness
-         * @return {[int, int, int]} the red, green, blue values in
-         *          decimal.
-         */
-        hsv2rgb: function(h, s, v) { 
-
-            if (lang.isArray(h)) {
-                return this.hsv2rgb.call(this, h[0], h[1], h[2]);
-            }
-
-            var r, g, b, i, f, p, q, t;
-            i = Math.floor((h/60)%6);
-            f = (h/60)-i;
-            p = v*(1-s);
-            q = v*(1-f*s);
-            t = v*(1-(1-f)*s);
-            switch(i) {
-                case 0: r=v; g=t; b=p; break;
-                case 1: r=q; g=v; b=p; break;
-                case 2: r=p; g=v; b=t; break;
-                case 3: r=p; g=q; b=v; break;
-                case 4: r=t; g=p; b=v; break;
-                case 5: r=v; g=p; b=q; break;
-            }
-
-            var fn=this.real2dec;
-
-            return [fn(r), fn(g), fn(b)];
-        },
-
-        /**
-         * Converts to RGB [255,255,255] to HSV (h[0-360], s[0-1]), v[0-1]
-         * @method rgb2hsv
-         * @param r {int|[int, int, int]} the red value, or an
-         *        array containing all three parameters
-         * @param g {int} the green value
-         * @param b {int} the blue value
-         * @return {[int, float, float]} the value converted to hsv
-         */
-        rgb2hsv: function(r, g, b) {
-
-            if (lang.isArray(r)) {
-                return this.rgb2hsv.call(this, r[0], r[1], r[2]);
-            }
-
-            r=r/255;
-            g=g/255;
-            b=b/255;
-
-            var min,max,delta,h,s,v;
-            min = Math.min(Math.min(r,g),b);
-            max = Math.max(Math.max(r,g),b);
-            delta = max-min;
-
-            switch (max) {
-                case min: h=0; break;
-                case r:   h=60*(g-b)/delta; 
-                          if (g<b) {
-                              h+=360;
-                          }
-                          break;
-                case g:   h=(60*(b-r)/delta)+120; break;
-                case b:   h=(60*(r-g)/delta)+240; break;
-            }
-            
-            s = (max === 0) ? 0 : 1-(min/max);
-
-            var hsv = [Math.round(h), s, max];
-
-            return hsv;
-
-        },
-
-        /**
-         * Converts decimal rgb values into a hex string
-         * 255,255,255 -> FFFFFF
-         * @method rgb2hex
-         * @param r {int|[int, int, int]} the red value, or an
-         *        array containing all three parameters
-         * @param g {int} the green value
-         * @param b {int} the blue value
-         * @return {string} the hex string
-         */
-        rgb2hex: function(r, g, b) {
-            if (lang.isArray(r)) {
-                return this.rgb2hex.call(this, r[0], r[1], r[2]);
-            }
-
-            var f=this.dec2hex;
-            return f(r) + f(g) + f(b);
-        },
-     
-        /**
-         * Converts an int 0...255 to hex pair 00...FF
-         * @method dec2hex
-         * @param n {int} the number to convert
-         * @return {string} the hex equivalent
-         */
-        dec2hex: function(n) {
-            n = parseInt(n, 10);
-            n = (lang.isNumber(n)) ? n : 0;
-            n = (n > 255 || n < 0) ? 0 : n;
-
-            return HCHARS.charAt((n - n % 16) / 16) + HCHARS.charAt(n % 16);
-        },
-
-        /**
-         * Converts a hex pair 00...FF to an int 0...255 
-         * @method hex2dec
-         * @param str {string} the hex pair to convert
-         * @return {int} the decimal
-         */
-        hex2dec: function(str) {
-            var f = function(c) {
-                return HCHARS.indexOf(c.toUpperCase());
-            };
-
-            var s=str.split('');
-            
-            return ((f(s[0]) * 16) + f(s[1]));
-        },
-
-        /**
-         * Converts a hex string to rgb
-         * @method hex2rgb
-         * @param str {string} the hex string
-         * @return {[int, int, int]} an array containing the rgb values
-         */
-        hex2rgb: function(s) { 
-            var f = this.hex2dec;
-            return [f(s.substr(0, 2)), f(s.substr(2, 2)), f(s.substr(4, 2))];
-        },
-
-        /**
-         * Returns the closest websafe color to the supplied rgb value.
-         * @method websafe
-         * @param r {int|[int, int, int]} the red value, or an
-         *        array containing all three parameters
-         * @param g {int} the green value
-         * @param b {int} the blue value
-         * @return {[int, int, int]} an array containing the closes
-         *                           websafe rgb colors.
-         */
-        websafe: function(r, g, b) {
-
-            if (lang.isArray(r)) {
-                return this.websafe.call(this, r[0], r[1], r[2]);
-            }
-
-            // returns the closest match [0, 51, 102, 153, 204, 255]
-            var f = function(v) {
-                if (lang.isNumber(v)) {
-                    v = Math.min(Math.max(0, v), 255);
-                    var i, next;
-                    for (i=0; i<256; i=i+51) {
-                        next = i+51;
-                        if (v >= i && v <= next) {
-                            return (v-i > 25) ? next : i;
-                        }
-                    }
-                }
-
-                return v;
-            };
-
-            return [f(r), f(g), f(b)];
-        }
-    };
-}();
-
-
-(function() {
-
-    var _pickercount = 0;
-
-    /**
-     * The colorpicker module provides a widget for selecting colors
-     * @module colorpicker
-     * @requires yahoo, dom, event, element, slider
-     */
-
-
-    /**
-     * Creates the host element if it doesn't exist
-     * @method _createHostElement
-     * @private
-     */
-    var _createHostElement = function() {
-        var el = document.createElement('div');
-
-        if (this.CSS.BASE) {
-            el.className = this.CSS.BASE;
-        }
-        
-        return el;
-    };
-
-    /**
-     * A widget to select colors
-     * @namespace YAHOO.widget
-     * @class YAHOO.widget.ColorPicker
-     * @extends YAHOO.util.Element
-     * @constructor
-     * @param {HTMLElement | String | Object} el(optional) The html 
-     * element that represents the colorpicker, or the attribute object to use. 
-     * An element will be created if none provided.
-     * @param {Object} attr (optional) A key map of the colorpicker's 
-     * initial attributes.  Ignored if first arg is attributes object.
-     */
-    YAHOO.widget.ColorPicker = function(el, attr) {
-        _pickercount = _pickercount + 1;
-        attr = attr || {};
-        if (arguments.length === 1 && !YAHOO.lang.isString(el) && !el.nodeName) {
-            attr = el; // treat first arg as attr object
-            el = attr.element || null;
-        }
-        
-        if (!el && !attr.element) { // create if we dont have one
-            el = _createHostElement.call(this, attr);
-        }
-
-    	YAHOO.widget.ColorPicker.superclass.constructor.call(this, el, attr); 
-    };
-
-    YAHOO.extend(YAHOO.widget.ColorPicker, YAHOO.util.Element);
-    
-    var proto = YAHOO.widget.ColorPicker.prototype,
-        Slider=YAHOO.widget.Slider,
-        Color=YAHOO.util.Color,
-        Dom = YAHOO.util.Dom,
-        Event = YAHOO.util.Event,
-        lang = YAHOO.lang,
-        sub = lang.substitute;
-    
-
-    var b = "yui-picker";
-
-    /**
-     * The element ids used by this control
-     * @property ID
-     * @final
-     */
-    proto.ID = {
-
-        /**
-         * The id for the "red" form field
-         * @property ID.R
-         * @type String
-         * @final
-         * @default yui-picker-r
-         */
-        R: b + "-r",
-
-        /**
-         * The id for the "red" hex pair output
-         * @property ID.R_HEX
-         * @type String
-         * @final
-         * @default yui-picker-rhex
-         */
-        R_HEX: b + "-rhex",
-
-        /**
-         * The id for the "green" form field
-         * @property ID.G
-         * @type String
-         * @final
-         * @default yui-picker-g
-         */
-        G: b + "-g",
-
-        /**
-         * The id for the "green" hex pair output
-         * @property ID.G_HEX
-         * @type String
-         * @final
-         * @default yui-picker-ghex
-         */
-        G_HEX: b + "-ghex",
-
-
-        /**
-         * The id for the "blue" form field
-         * @property ID.B
-         * @type String
-         * @final
-         * @default yui-picker-b
-         */
-        B: b + "-b",
-
-        /**
-         * The id for the "blue" hex pair output
-         * @property ID.B_HEX
-         * @type String
-         * @final
-         * @default yui-picker-bhex
-         */
-        B_HEX: b + "-bhex",
-
-        /**
-         * The id for the "hue" form field
-         * @property ID.H
-         * @type String
-         * @final
-         * @default yui-picker-h
-         */
-        H: b + "-h",
-
-        /**
-         * The id for the "saturation" form field
-         * @property ID.S
-         * @type String
-         * @final
-         * @default yui-picker-s
-         */
-        S: b + "-s",
-
-        /**
-         * The id for the "value" form field
-         * @property ID.V
-         * @type String
-         * @final
-         * @default yui-picker-v
-         */
-        V: b + "-v",
-
-        /**
-         * The id for the picker region slider
-         * @property ID.PICKER_BG
-         * @type String
-         * @final
-         * @default yui-picker-bg
-         */
-        PICKER_BG:      b + "-bg",
-
-        /**
-         * The id for the picker region thumb
-         * @property ID.PICKER_THUMB
-         * @type String
-         * @final
-         * @default yui-picker-thumb
-         */
-        PICKER_THUMB:   b + "-thumb",
-
-        /**
-         * The id for the hue slider
-         * @property ID.HUE_BG
-         * @type String
-         * @final
-         * @default yui-picker-hue-bg
-         */
-        HUE_BG:         b + "-hue-bg",
-
-        /**
-         * The id for the hue thumb
-         * @property ID.HUE_THUMB
-         * @type String
-         * @final
-         * @default yui-picker-hue-thumb
-         */
-        HUE_THUMB:      b + "-hue-thumb",
-
-        /**
-         * The id for the hex value form field
-         * @property ID.HEX
-         * @type String
-         * @final
-         * @default yui-picker-hex
-         */
-        HEX:            b + "-hex",
-
-        /**
-         * The id for the color swatch
-         * @property ID.SWATCH
-         * @type String
-         * @final
-         * @default yui-picker-swatch
-         */
-        SWATCH:         b + "-swatch",
-
-        /**
-         * The id for the websafe color swatch
-         * @property ID.WEBSAFE_SWATCH
-         * @type String
-         * @final
-         * @default yui-picker-websafe-swatch
-         */
-        WEBSAFE_SWATCH: b + "-websafe-swatch",
-
-        /**
-         * The id for the control details
-         * @property ID.CONTROLS
-         * @final
-         * @default yui-picker-controls
-         */
-        CONTROLS: b + "-controls",
-
-        /**
-         * The id for the rgb controls
-         * @property ID.RGB_CONTROLS
-         * @final
-         * @default yui-picker-rgb-controls
-         */
-        RGB_CONTROLS: b + "-rgb-controls",
-
-        /**
-         * The id for the hsv controls
-         * @property ID.HSV_CONTROLS
-         * @final
-         * @default yui-picker-hsv-controls
-         */
-        HSV_CONTROLS: b + "-hsv-controls",
-        
-        /**
-         * The id for the hsv controls
-         * @property ID.HEX_CONTROLS
-         * @final
-         * @default yui-picker-hex-controls
-         */
-        HEX_CONTROLS: b + "-hex-controls",
-
-        /**
-         * The id for the hex summary
-         * @property ID.HEX_SUMMARY
-         * @final
-         * @default yui-picker-hex-summary
-         */
-        HEX_SUMMARY: b + "-hex-summary",
-
-        /**
-         * The id for the controls section header
-         * @property ID.CONTROLS_LABEL
-         * @final
-         * @default yui-picker-controls-label
-         */
-        CONTROLS_LABEL: b + "-controls-label"
-    };
-
-    /**
-     * Constants for any script-generated messages.  The values here
-     * are the default messages.  They can be updated by providing
-     * the complete list to the constructor for the "txt" attribute.
-     * @property TXT
-     * @final
-     */
-    proto.TXT = {
-        ILLEGAL_HEX: "Illegal hex value entered",
-        SHOW_CONTROLS: "Show color details",
-        HIDE_CONTROLS: "Hide color details",
-        CURRENT_COLOR: "Currently selected color: {rgb}",
-        CLOSEST_WEBSAFE: "Closest websafe color: {rgb}. Click to select.",
-        R: "R",
-        G: "G",
-        B: "B",
-        H: "H",
-        S: "S",
-        V: "V",
-        HEX: "#",
-        DEG: "\u00B0",
-        PERCENT: "%"
-    };
-
-    /**
-     * Constants for the default image locations for img tags that are
-     * generated by the control.  They can be modified by passing the
-     * complete list to the contructor for the "images" attribute
-     * @property IMAGE
-     * @final
-     */
-    proto.IMAGE = {
-        PICKER_THUMB: "../../build/colorpicker/assets/picker_thumb.png",
-        HUE_THUMB: "../../build/colorpicker/assets/hue_thumb.png"
-    };
-
-    /*
-     * Constants for the control's custom event names.  subscribe
-     * to the rgbChange event instead.
-     * @property EVENT
-     * @final
-     */
-    //proto.EVENT = {
-        //CHANGE: "change"
-    //};
-
-    //proto.CSS = { };
-
-    /**
-     * Constants for the control's default default values
-     * @property DEFAULT
-     * @final
-     */
-    proto.DEFAULT = {
-        PICKER_SIZE: 180
-    };
-
-    /**
-     * Constants for the control's configuration attributes
-     * @property OPT
-     * @final
-     */
-    proto.OPT = {
-        HUE: "hue",
-        SATURATION: "saturation",
-        VALUE: "value",
-        RED: "red",
-        GREEN: "green",
-        BLUE: "blue",
-        HSV: "hsv",
-        RGB: "rgb",
-        WEBSAFE: "websafe",
-        HEX: "hex",
-        PICKER_SIZE: "pickersize",
-        SHOW_CONTROLS: "showcontrols",
-        SHOW_RGB_CONTROLS: "showrgbcontrols",
-        SHOW_HSV_CONTROLS: "showhsvcontrols",
-        SHOW_HEX_CONTROLS: "showhexcontrols",
-        SHOW_HEX_SUMMARY: "showhexsummary",
-        SHOW_WEBSAFE: "showwebsafe",
-        //SHOW_SUBMIT: "showsubmit",
-        CONTAINER: "container",
-        IDS: "ids",
-        ELEMENTS: "elements",
-        TXT: "txt",
-        IMAGES: "images",
-        ANIMATE: "animate"
-    };
-
-    /**
-     * Moves the hue slider into the position dictated by the current state
-     * of the control
-     * @method _updateHueSlider
-     * @private
-     */
-    var _updateHueSlider = function() {
-        var size = this.get(this.OPT.PICKER_SIZE),
-            h = this.get(this.OPT.HUE);
-
-        h = size - Math.round(h / 360 * size);
-        
-        // 0 is at the top and bottom of the hue slider.  Always go to
-        // the top so we don't end up sending the thumb to the bottom
-        // when the value didn't actually change (e.g., a conversion
-        // produced 360 instead of 0 and the value was already 0).
-        if (h === size) {
-            h = 0;
-        }
-
-        this.hueSlider.setValue(h);
-    };
-
-    /**
-     * Moves the picker slider into the position dictated by the current state
-     * of the control
-     * @method _updatePickerSlider
-     * @private
-     */
-    var _updatePickerSlider = function() {
-        var size = this.get(this.OPT.PICKER_SIZE),
-            s = this.get(this.OPT.SATURATION),
-            v = this.get(this.OPT.VALUE);
-
-        s = Math.round(s * size / 100);
-        v = Math.round(size - (v * size / 100));
-
-
-        this.pickerSlider.setRegionValue(s, v);
-    };
-
-    /**
-     * Moves the sliders into the position dictated by the current state
-     * of the control
-     * @method _updateSliders
-     * @private
-     */
-    var _updateSliders = function() {
-        _updateHueSlider.call(this);
-        _updatePickerSlider.call(this);
-    };
-
-    /**
-     * Sets the control to the specified rgb value and
-     * moves the sliders to the proper positions
-     * @method setValue
-     * @param rgb {[int, int, int]} the rgb value
-     * @param silent {boolean} whether or not to fire the change event
-     */
-    proto.setValue = function(rgb, silent) {
-        silent = (silent) || false;
-        this.set(this.OPT.RGB, rgb, silent);
-        _updateSliders.call(this);
-    };
-
-    /**
-     * The hue slider
-     * @property hueSlider
-     * @type YAHOO.widget.Slider
-     */
-    proto.hueSlider = null; 
-    
-    /**
-     * The picker region
-     * @property pickerSlider
-     * @type YAHOO.widget.Slider
-     */
-    proto.pickerSlider = null;
-
-    /**
-     * Translates the slider value into hue, int[0,359]
-     * @method _getH
-     * @private
-     * @return {int} the hue from 0 to 359
-     */
-    var _getH = function() {
-        var size = this.get(this.OPT.PICKER_SIZE),
-            h = (size - this.hueSlider.getValue()) / size;
-        h = Math.round(h*360);
-        return (h === 360) ? 0 : h;
-    };
-
-    /**
-     * Translates the slider value into saturation, int[0,1], left to right
-     * @method _getS
-     * @private
-     * @return {int} the saturation from 0 to 1
-     */
-    var _getS = function() {
-        return this.pickerSlider.getXValue() / this.get(this.OPT.PICKER_SIZE);
-    };
-
-    /**
-     * Translates the slider value into value/brightness, int[0,1], top
-     * to bottom
-     * @method _getV
-     * @private
-     * @return {int} the value from 0 to 1
-     */
-    var _getV = function() {
-        var size = this.get(this.OPT.PICKER_SIZE);
-        return (size - this.pickerSlider.getYValue()) / size;
-    };
-
-    /**
-     * Updates the background of the swatch with the current rbg value.
-     * Also updates the websafe swatch to the closest websafe color
-     * @method _updateSwatch
-     * @private
-     */
-    var _updateSwatch = function() {
-        var rgb = this.get(this.OPT.RGB),
-            websafe = this.get(this.OPT.WEBSAFE),
-            el = this.getElement(this.ID.SWATCH),
-            color = rgb.join(","),
-            txt = this.get(this.OPT.TXT);
-
-        Dom.setStyle(el, "background-color", "rgb(" + color  + ")");
-        el.title = lang.substitute(txt.CURRENT_COLOR, {
-                "rgb": "#" + this.get(this.OPT.HEX)
-            });
-
-
-        el = this.getElement(this.ID.WEBSAFE_SWATCH);
-        color = websafe.join(",");
-
-        Dom.setStyle(el, "background-color", "rgb(" + color + ")");
-        el.title = lang.substitute(txt.CLOSEST_WEBSAFE, {
-                "rgb": "#" + Color.rgb2hex(websafe)
-            });
-
-    };
-
-    /**
-     * Reads the sliders and converts the values to RGB, updating the
-     * internal state for all the individual form fields
-     * @method _getValuesFromSliders
-     * @private
-     */
-    var _getValuesFromSliders = function() {
-        var h=_getH.call(this), s=_getS.call(this), v=_getV.call(this);
-
-        var rgb = Color.hsv2rgb(h, s, v);
-        //var websafe = Color.websafe(rgb);
-        //var hex = Color.rgb2hex(rgb[0], rgb[1], rgb[2]);
-
-        this.set(this.OPT.RGB, rgb);
-    };
-
-    /**
-     * Updates the form field controls with the state data contained
-     * in the control.
-     * @method _updateFormFields
-     * @private
-     */
-    var _updateFormFields = function() {
-        this.getElement(this.ID.H).value = this.get(this.OPT.HUE);
-        this.getElement(this.ID.S).value = this.get(this.OPT.SATURATION);
-        this.getElement(this.ID.V).value = this.get(this.OPT.VALUE);
-        this.getElement(this.ID.R).value = this.get(this.OPT.RED);
-        this.getElement(this.ID.R_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.RED));
-        this.getElement(this.ID.G).value = this.get(this.OPT.GREEN);
-        this.getElement(this.ID.G_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.GREEN));
-        this.getElement(this.ID.B).value = this.get(this.OPT.BLUE);
-        this.getElement(this.ID.B_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.BLUE));
-        this.getElement(this.ID.HEX).value = this.get(this.OPT.HEX);
-    };
-
-    /**
-     * Event handler for the hue slider.
-     * @method _onHueSliderChange
-     * @param newOffset {int} pixels from the start position
-     * @private
-     */
-    var _onHueSliderChange = function(newOffset) {
-
-        var h = _getH.call(this);
-        this.set(this.OPT.HUE, h, true);
-
-        // set picker background to the hue
-        var rgb = Color.hsv2rgb(h, 1, 1);
-        var styleDef = "rgb(" + rgb.join(",") + ")";
-
-        Dom.setStyle(this.getElement(this.ID.PICKER_BG), "background-color", styleDef);
-
-        if (this.hueSlider.valueChangeSource === this.hueSlider.SOURCE_UI_EVENT) {
-            _getValuesFromSliders.call(this);
-        }
-
-        _updateFormFields.call(this);
-        _updateSwatch.call(this);
-    };
-
-    /**
-     * Event handler for the picker slider, which controls the
-     * saturation and value/brightness.
-     * @method _onPickerSliderChange
-     * @param newOffset {{x: int, y: int}} x/y pixels from the start position
-     * @private
-     */
-    var _onPickerSliderChange = function(newOffset) {
-
-        var s=_getS.call(this), v=_getV.call(this);
-        this.set(this.OPT.SATURATION, Math.round(s*100), true);
-        this.set(this.OPT.VALUE, Math.round(v*100), true);
-
-        if (this.pickerSlider.valueChangeSource === this.pickerSlider.SOURCE_UI_EVENT) {
-            _getValuesFromSliders.call(this);
-        }
-
-        _updateFormFields.call(this);
-        _updateSwatch.call(this);
-    };
-
-
-    /**
-     * Key map to well-known commands for txt field input
-     * @method _getCommand
-     * @param e {Event} the keypress or keydown event
-     * @return {int} a command code
-     * <ul>
-     * <li>0 = not a number, letter in range, or special key</li>
-     * <li>1 = number</li>
-     * <li>2 = a-fA-F</li>
-     * <li>3 = increment (up arrow)</li>
-     * <li>4 = decrement (down arrow)</li>
-     * <li>5 = special key (tab, delete, return, escape, left, right)</li> 
-     * <li>6 = return</li>
-     * </ul>
-     * @private
-     */
-    var _getCommand = function(e) {
-        var c = Event.getCharCode(e);
-
-        //alert(Event.getCharCode(e) + ", " + e.keyCode + ", " + e.charCode);
-
-        // special keys
-        if (c === 38) { // up arrow
-            return 3;
-        } else if (c === 13) { // return
-            return 6;
-        } else if (c === 40) { // down array
-            return 4;
-        } else if (c >= 48 && c<=57) { // 0-9
-            return 1;
-        } else if (c >= 97 && c<=102) { // a-f
-            return 2;
-        } else if (c >= 65 && c<=70) { // A-F
-            return 2;
-        //} else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1 || 
-        //              (c >= 112 && c <=123)) { // including F-keys
-        // tab, delete, return, escape, left, right
-        } else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1) { // special chars
-            return 5;
-        } else { // something we probably don't want
-            return 0;
-        }
-    };
-
-    /**
-     * Use the value of the text field to update the control
-     * @method _hexFieldKeypress
-     * @param e {Event} an event
-     * @param el {HTMLElement} the field
-     * @param prop {string} the key to the linked property
-     * @private
-     */
-    var _useFieldValue = function(e, el, prop) {
-        var val = el.value;
-
-        if (prop !== this.OPT.HEX) {
-            val = parseInt(val, 10);
-        }
-
-        if (val !== this.get(prop)) {
-            this.set(prop, val);
-        }
-    };
-
-    /**
-     * Handle keypress on one of the rgb or hsv fields.
-     * @method _rgbFieldKeypress
-     * @param e {Event} the keypress event
-     * @param el {HTMLElement} the field
-     * @param prop {string} the key to the linked property
-     * @private
-     */
-    var _rgbFieldKeypress = function(e, el, prop) {
-        var command = _getCommand(e);
-        var inc = (e.shiftKey) ? 10 : 1;
-        switch (command) {
-            case 6: // return, update the value
-                _useFieldValue.apply(this, arguments);
-                break;
-                        
-            case 3: // up arrow, increment
-                this.set(prop, Math.min(this.get(prop)+inc, 255));
-                _updateFormFields.call(this);
-                //Event.stopEvent(e);
-                break;
-            case 4: // down arrow, decrement
-                this.set(prop, Math.max(this.get(prop)-inc, 0));
-                _updateFormFields.call(this);
-                //Event.stopEvent(e);
-                break;
-
-            default:
-        }
-
-    };
-
-    /**
-     * Handle keydown on the hex field
-     * @method _hexFieldKeypress
-     * @param e {Event} the keypress event
-     * @param el {HTMLElement} the field
-     * @param prop {string} the key to the linked property
-     * @private
-     */
-    var _hexFieldKeypress = function(e, el, prop) {
-        var command = _getCommand(e);
-        if (command === 6) { // return, update the value
-            _useFieldValue.apply(this, arguments);
-        }
-    };
-
-    /** 
-     * Allows numbers and special chars, and by default allows a-f.  
-     * Used for the hex field keypress handler.
-     * @method _hexOnly
-     * @param e {Event} the event
-     * @param numbersOnly omits a-f if set to true
-     * @private
-     * @return {boolean} false if we are canceling the event
-     */
-    var _hexOnly = function(e, numbersOnly) {
-        var command = _getCommand(e);
-        switch (command) {
-            case 6: // return
-            case 5: // special char
-            case 1: // number
-                break;
-            case 2: // hex char (a-f)
-                if (numbersOnly !== true) {
-                    break;
-                }
-
-                // fallthrough is intentional
-
-            default: // prevent alpha and punctuation
-                Event.stopEvent(e);
-                return false;
-        }
-    };
-
-    /** 
-     * Allows numbers and special chars only.  Used for the
-     * rgb and hsv fields keypress handler.
-     * @method _numbersOnly
-     * @param e {Event} the event
-     * @private
-     * @return {boolean} false if we are canceling the event
-     */
-    var _numbersOnly = function(e) {
-        return _hexOnly(e, true);
-    };
-
-    /**
-     * Returns the element reference that is saved.  The id can be either
-     * the element id, or the key for this id in the "id" config attribute.
-     * For instance, the host element id can be obtained by passing its
-     * id (default: "yui_picker") or by its key "YUI_PICKER".
-     * @param id {string} the element id, or key 
-     * @return {HTMLElement} a reference to the element
-     */
-    proto.getElement = function(id) { 
-        return this.get(this.OPT.ELEMENTS)[this.get(this.OPT.IDS)[id]]; 
-    };
-
-    var _createElements = function() {
-        var el, child, img, fld, i, 
-            ids = this.get(this.OPT.IDS),
-            txt = this.get(this.OPT.TXT),
-            images = this.get(this.OPT.IMAGES),
-            Elem = function(type, o) {
-                var n = document.createElement(type);
-                if (o) {
-                    lang.augmentObject(n, o, true);
-                }
-                return n;
-            },
-            RGBElem = function(type, obj) {
-                var o = lang.merge({
-                        //type: "txt",
-                        autocomplete: "off",
-                        value: "0",
-                        size: 3,
-                        maxlength: 3
-                    }, obj);
-
-                o.name = o.id;
-                return new Elem(type, o);
-            };
-
-        var p = this.get("element");
-
-        // Picker slider (S and V) ---------------------------------------------
-
-        el = new Elem("div", {
-            id: ids[this.ID.PICKER_BG],
-            className: "yui-picker-bg",
-            tabIndex: -1,
-            hideFocus: true
-        });
-
-        child = new Elem("div", {
-            id: ids[this.ID.PICKER_THUMB],
-            className: "yui-picker-thumb"
-        });
-
-        img = new Elem("img", {
-            src: images.PICKER_THUMB
-        });
-
-        child.appendChild(img);
-        el.appendChild(child);
-        p.appendChild(el);
-        
-        // Hue slider ---------------------------------------------
-        el = new Elem("div", {
-            id: ids[this.ID.HUE_BG],
-            className: "yui-picker-hue-bg",
-            tabIndex: -1,
-            hideFocus: true
-        });
-
-        child = new Elem("div", {
-            id: ids[this.ID.HUE_THUMB],
-            className: "yui-picker-hue-thumb"
-        });
-
-        img = new Elem("img", {
-            src: images.HUE_THUMB
-        });
-
-        child.appendChild(img);
-        el.appendChild(child);
-        p.appendChild(el);
-
-
-        // controls ---------------------------------------------
-
-        el = new Elem("div", {
-            id: ids[this.ID.CONTROLS],
-            className: "yui-picker-controls"
-        });
-
-        p.appendChild(el);
-        p = el;
-
-            // controls header
-            el = new Elem("div", {
-                className: "hd"
-            });
-
-            child = new Elem("a", {
-                id: ids[this.ID.CONTROLS_LABEL],
-                //className: "yui-picker-controls-label",
-                href: "#"
-            });
-            el.appendChild(child);
-            p.appendChild(el);
-
-            // bd
-            el = new Elem("div", {
-                className: "bd"
-            });
-
-            p.appendChild(el);
-            p = el;
-
-                // rgb
-                el = new Elem("ul", {
-                    id: ids[this.ID.RGB_CONTROLS],
-                    className: "yui-picker-rgb-controls"
-                });
-
-                child = new Elem("li");
-                child.appendChild(document.createTextNode(txt.R + " "));
-
-                fld = new RGBElem("input", {
-                    id: ids[this.ID.R],
-                    className: "yui-picker-r"
-                });
-
-                child.appendChild(fld);
-                el.appendChild(child);
-
-                child = new Elem("li");
-                child.appendChild(document.createTextNode(txt.G + " "));
-
-                fld = new RGBElem("input", {
-                    id: ids[this.ID.G],
-                    className: "yui-picker-g"
-                });
-
-                child.appendChild(fld);
-                el.appendChild(child);
-
-                child = new Elem("li");
-                child.appendChild(document.createTextNode(txt.B + " "));
-
-                fld = new RGBElem("input", {
-                    id: ids[this.ID.B],
-                    className: "yui-picker-b"
-                });
-
-                child.appendChild(fld);
-                el.appendChild(child);
-
-                p.appendChild(el);
-
-                // hsv
-                el = new Elem("ul", {
-                    id: ids[this.ID.HSV_CONTROLS],
-                    className: "yui-picker-hsv-controls"
-                });
-
-                child = new Elem("li");
-                child.appendChild(document.createTextNode(txt.H + " "));
-
-                fld = new RGBElem("input", {
-                    id: ids[this.ID.H],
-                    className: "yui-picker-h"
-                });
-
-                child.appendChild(fld);
-                child.appendChild(document.createTextNode(" " + txt.DEG));
-
-                el.appendChild(child);
-
-                child = new Elem("li");
-                child.appendChild(document.createTextNode(txt.S + " "));
-
-                fld = new RGBElem("input", {
-                    id: ids[this.ID.S],
-                    className: "yui-picker-s"
-                });
-
-                child.appendChild(fld);
-                child.appendChild(document.createTextNode(" " + txt.PERCENT));
-
-                el.appendChild(child);
-
-                child = new Elem("li");
-                child.appendChild(document.createTextNode(txt.V + " "));
-
-                fld = new RGBElem("input", {
-                    id: ids[this.ID.V],
-                    className: "yui-picker-v"
-                });
-
-                child.appendChild(fld);
-                child.appendChild(document.createTextNode(" " + txt.PERCENT));
-
-                el.appendChild(child);
-                p.appendChild(el);
-
-
-                // hex summary
-
-                el = new Elem("ul", {
-                    id: ids[this.ID.HEX_SUMMARY],
-                    className: "yui-picker-hex_summary"
-                });
-
-                child = new Elem("li", {
-                    id: ids[this.ID.R_HEX]
-                });
-                el.appendChild(child);
-
-                child = new Elem("li", {
-                    id: ids[this.ID.G_HEX]
-                });
-                el.appendChild(child);
-
-                child = new Elem("li", {
-                    id: ids[this.ID.B_HEX]
-                });
-                el.appendChild(child);
-                p.appendChild(el);
-
-                // hex field
-                el = new Elem("div", {
-                    id: ids[this.ID.HEX_CONTROLS],
-                    className: "yui-picker-hex-controls"
-                });
-                el.appendChild(document.createTextNode(txt.HEX + " "));
-
-                child = new RGBElem("input", {
-                    id: ids[this.ID.HEX],
-                    className: "yui-picker-hex",
-                    size: 6,
-                    maxlength: 6
-                });
-
-                el.appendChild(child);
-                p.appendChild(el);
-
-                p = this.get("element");
-
-                // swatch
-                el = new Elem("div", {
-                    id: ids[this.ID.SWATCH],
-                    className: "yui-picker-swatch"
-                });
-
-                p.appendChild(el);
-
-                // websafe swatch
-                el = new Elem("div", {
-                    id: ids[this.ID.WEBSAFE_SWATCH],
-                    className: "yui-picker-websafe-swatch"
-                });
-
-                p.appendChild(el);
-
-    };
-
-    var _attachRGBHSV = function(id, config) {
-        Event.on(this.getElement(id), "keydown", function(e, me) {
-                _rgbFieldKeypress.call(me, e, this, config);
-            }, this);
-        Event.on(this.getElement(id), "keypress", _numbersOnly, this);
-        Event.on(this.getElement(id), "blur", function(e, me) {
-                _useFieldValue.call(me, e, this, config);
-            }, this);
-    };
-
-
-    /**
-     * Updates the rgb attribute with the current state of the r,g,b
-     * fields.  This is invoked from change listeners on these
-     * attributes to facilitate updating these values from the
-     * individual form fields
-     * @method _updateRGB
-     * @private
-     */
-    var _updateRGB = function() {
-        var rgb = [this.get(this.OPT.RED), 
-                   this.get(this.OPT.GREEN),
-                   this.get(this.OPT.BLUE)];
-
-        this.set(this.OPT.RGB, rgb);
-
-        _updateSliders.call(this);
-    };
-
-    /**
-     * Sets the initial state of the sliders
-     * @method initPicker
-     */
-    proto.initPicker = function () {
-
-        // bind all of our elements
-        var o=this.OPT, 
-            ids = this.get(o.IDS), 
-            els = this.get(o.ELEMENTS), 
-                  i, el, id;
-
-        // Add the default value as a key for each element for easier lookup
-        for (i in this.ID) {
-            if (lang.hasOwnProperty(this.ID, i)) {
-                ids[this.ID[i]] = ids[i];
-            }
-        }
-
-        // Check for picker element, if not there, create all of them
-        el = Dom.get(ids[this.ID.PICKER_BG]);
-        if (!el) {
-            _createElements.call(this);
-        } else {
-        }
-
-        for (i in ids) {
-            if (lang.hasOwnProperty(ids, i)) {
-                // look for element
-                el = Dom.get(ids[i]);
-
-                // generate an id if the implementer passed in an element reference,
-                // and the element did not have an id already
-                id = Dom.generateId(el);
-
-                // update the id in case we generated the id
-                ids[i] = id; // key is WEBSAFE_SWATCH
-                ids[ids[i]] = id; // key is websafe_swatch
-
-                // store the dom ref
-                els[id] = el;
-            }
-        }
-
-        // set the initial visibility state of our controls
-            els = [o.SHOW_CONTROLS, 
-                   o.SHOW_RGB_CONTROLS,
-                   o.SHOW_HSV_CONTROLS,
-                   o.SHOW_HEX_CONTROLS,
-                   o.SHOW_HEX_SUMMARY,
-                   o.SHOW_WEBSAFE
-                   ];
-
-        for (i=0; i<els.length; i=i+1) {
-            this.set(els[i], this.get(els[i]));
-        }
-
-        var s = this.get(o.PICKER_SIZE);
-
-        this.hueSlider = Slider.getVertSlider(this.getElement(this.ID.HUE_BG), 
-                                              this.getElement(this.ID.HUE_THUMB), 0, s);
-        this.hueSlider.subscribe("change", _onHueSliderChange, this, true);
-
-        this.pickerSlider = Slider.getSliderRegion(this.getElement(this.ID.PICKER_BG), 
-                                                   this.getElement(this.ID.PICKER_THUMB), 0, s, 0, s);
-        this.pickerSlider.subscribe("change", _onPickerSliderChange, this, true);
-
-        // Set the animate state
-        this.set(o.ANIMATE,this.get(o.ANIMATE));
-
-        //_onHueSliderChange.call(this, 0);
-
-        Event.on(this.getElement(this.ID.WEBSAFE_SWATCH), "click", function(e) {
-               this.setValue(this.get(o.WEBSAFE));
-               //_updateSliders
-           }, this, true);
-
-        Event.on(this.getElement(this.ID.CONTROLS_LABEL), "click", function(e) {
-               this.set(o.SHOW_CONTROLS, !this.get(o.SHOW_CONTROLS));
-               Event.preventDefault(e);
-           }, this, true);
-
-        _attachRGBHSV.call(this, this.ID.R, this.OPT.RED); 
-        _attachRGBHSV.call(this, this.ID.G, this.OPT.GREEN); 
-        _attachRGBHSV.call(this, this.ID.B, this.OPT.BLUE); 
-        _attachRGBHSV.call(this, this.ID.H, this.OPT.HUE); 
-        _attachRGBHSV.call(this, this.ID.S, this.OPT.SATURATION); 
-        _attachRGBHSV.call(this, this.ID.V, this.OPT.VALUE); 
-
-        Event.on(this.getElement(this.ID.HEX), "keydown", function(e, me) {
-                _hexFieldKeypress.call(me, e, this, me.OPT.HEX);
-            }, this);
-
-        Event.on(this.getElement(this.ID.HEX), "keypress", _hexOnly, this);
-        Event.on(this.getElement(this.ID.HEX), "blur", function(e, me) {
-                _useFieldValue.call(me, e, this, me.OPT.HEX);
-            }, this);
-
-        _updateRGB.call(this);
-    };
-
-
-    /**
-     * Updates the RGB values from the current state of the HSV
-     * values.  Executed when the one of the HSV form fields are
-     * updated
-     * _updateRGBFromHSV
-     * @private
-     */
-    var _updateRGBFromHSV = function() {
-        var hsv = [this.get(this.OPT.HUE), 
-                   this.get(this.OPT.SATURATION)/100,
-                   this.get(this.OPT.VALUE)/100];
-
-        var rgb = Color.hsv2rgb(hsv);
-
-        this.set(this.OPT.RGB, rgb);
-
-        _updateSliders.call(this);
-    };
-
-    /**
-     * Parses the hex string to normalize shorthand values, converts
-     * the hex value to rgb and updates the rgb attribute (which
-     * updates the state for all of the other values)
-     * method _updateHex
-     * @private
-     */
-    var _updateHex = function() {
-       
-        var hex = this.get(this.OPT.HEX), l=hex.length;
-
-        // support #369 -> #336699 shorthand
-        if (l === 3) {
-            var c = hex.split(""), i;
-            for (i=0; i<l; i=i+1) {
-                c[i] = c[i] + c[i];
-            }
-
-            hex = c.join("");
-        }
-
-        if (hex.length !== 6) {
-            return false;
-        }
-
-        var rgb = Color.hex2rgb(hex);
-
-
-        this.setValue(rgb);
-
-        //_updateSliders.call(this);
-
-    };
-
-
-
-    /**
-     * Sets up the config attributes and the change listeners for this
-     * properties
-     * @method initAttributes
-     * @param attr An object containing default attribute values
-     */
-    proto.initAttributes = function(attr) {
-
-        attr = attr || {};
-        YAHOO.widget.ColorPicker.superclass.initAttributes.call(this, attr);
-        
-        /**
-         * The size of the picker. Trying to change this is not recommended.
-         * @attribute pickersize
-         * @default 180
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.PICKER_SIZE, {
-                value: attr.size || this.DEFAULT.PICKER_SIZE
-            });
-
-        /**
-         * The current hue value 0-360
-         * @attribute hue
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.HUE, {
-                value: attr.hue || 0,
-                validator: lang.isNumber
-            });
-
-        /**
-         * The current saturation value 0-100
-         * @attribute saturation
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.SATURATION, {
-                value: attr.saturation || 0,
-                validator: lang.isNumber
-            });
-
-        /**
-         * The current value/brightness value 0-100
-         * @attribute value
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.VALUE, {
-                value: lang.isNumber(attr.value) ? attr.value : 100,
-                validator: lang.isNumber
-            });
-
-        /**
-         * The current red value 0-255
-         * @attribute red
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.RED, {
-                value: lang.isNumber(attr.red) ? attr.red : 255,
-                validator: lang.isNumber
-            });
-
-        /**
-         * The current green value 0-255
-         * @attribute green 
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.GREEN, {
-                value: lang.isNumber(attr.green) ? attr.green : 255,
-                validator: lang.isNumber
-            });
-
-        /**
-         * The current blue value 0-255
-         * @attribute blue
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.BLUE, {
-                value: lang.isNumber(attr.blue) ? attr.blue : 255,
-                validator: lang.isNumber
-            });
-
-        /**
-         * The current hex value #000000-#FFFFFF, without the #
-         * @attribute hex
-         * @type string
-         */
-        this.setAttributeConfig(this.OPT.HEX, {
-                value: attr.hex || "FFFFFF",
-                validator: lang.isString
-            });
-
-        /**
-         * The current rgb value.  Updates the state of all of the
-         * other value fields.  Read-only: use setValue to set the
-         * controls rgb value.
-         * @attribute hex
-         * @type [int, int, int]
-         * @readonly
-         */
-        this.setAttributeConfig(this.OPT.RGB, {
-                value: attr.rgb || [255,255,255],
-                method: function(rgb) {
-
-                    this.set(this.OPT.RED, rgb[0], true);
-                    this.set(this.OPT.GREEN, rgb[1], true);
-                    this.set(this.OPT.BLUE, rgb[2], true);
-
-                    var websafe = Color.websafe(rgb);
-                    this.set(this.OPT.WEBSAFE, websafe, true);
-
-                    var hex = Color.rgb2hex(rgb);
-                    this.set(this.OPT.HEX, hex, true);
-
-                    var hsv = Color.rgb2hsv(rgb);
-
-
-                    this.set(this.OPT.HUE, hsv[0], true);
-                    this.set(this.OPT.SATURATION, Math.round(hsv[1]*100), true);
-                    this.set(this.OPT.VALUE, Math.round(hsv[2]*100), true);
-                },
-                readonly: true
-            });
-
-        /**
-         * If the color picker will live inside of a container object,
-         * set, provide a reference to it so the control can use the
-         * container's events.
-         * @attribute container
-         * @type YAHOO.widget.Panel
-         */
-        this.setAttributeConfig(this.OPT.CONTAINER, {
-                    value: null,
-                    method: function(container) {
-                        if (container) {
-                            // Position can get out of sync when the
-                            // control is manipulated while display is
-                            // none.  Resetting the slider constraints
-                            // when it is visible gets the state back in
-                            // order.
-                            container.showEvent.subscribe(function() {
-                                // this.pickerSlider.thumb.resetConstraints();
-                                // this.hueSlider.thumb.resetConstraints();
-                                this.pickerSlider.focus();
-                            }, this, true);
-                        }
-                    }
-                });
-        /**
-         * The closest current websafe value
-         * @attribute websafe
-         * @type int
-         */
-        this.setAttributeConfig(this.OPT.WEBSAFE, {
-                value: attr.websafe || [255,255,255]
-            });
-
-
-        var ids = attr.ids || lang.merge({}, this.ID);
-
-        if (!attr.ids && _pickercount > 1) {
-            for (var i in ids) {
-                if (lang.hasOwnProperty(ids, i)) {
-                    ids[i] = ids[i] + _pickercount;
-                }
-            }
-        }
-
-
-        /**
-         * A list of element ids and/or element references used by the 
-         * control.  The default is the this.ID list, and can be customized
-         * by passing a list in the contructor
-         * @attribute ids
-         * @type {referenceid: realid}
-         * @writeonce
-         */
-        this.setAttributeConfig(this.OPT.IDS, {
-                value: ids,
-                writeonce: true
-            });
-
-        /**
-         * A list of txt strings for internationalization.  Default
-         * is this.TXT
-         * @attribute txt
-         * @type {key: txt}
-         * @writeonce
-         */
-        this.setAttributeConfig(this.OPT.TXT, {
-                value: attr.txt || this.TXT,
-                writeonce: true
-            });
-
-        /**
-         * The img src default list
-         * is this.IMAGES
-         * @attribute images
-         * @type {key: image}
-         * @writeonce
-         */
-        this.setAttributeConfig(this.OPT.IMAGES, {
-                value: attr.images || this.IMAGE,
-                writeonce: true
-            });
-        /**
-         * The element refs used by this control.  Set at initialization
-         * @attribute elements
-         * @type {id: HTMLElement}
-         * @readonly
-         */
-        this.setAttributeConfig(this.OPT.ELEMENTS, {
-                value: {},
-                readonly: true
-            });
-
-        /**
-         * Returns the cached element reference.  If the id is not a string, it
-         * is assumed that it is an element and this is returned.
-         * @param id {string|HTMLElement} the element key, id, or ref
-         * @param on {boolean} hide or show.  If true, show
-         * @private */
-        var _hideShowEl = function(id, on) {
-            var el = (lang.isString(id) ? this.getElement(id) : id);
-            //Dom.setStyle(id, "visibility", (on) ? "" : "hidden");
-            Dom.setStyle(el, "display", (on) ? "" : "none");
-        };
-
-        /**
-         * Hide/show the entire set of controls
-         * @attribute showcontrols
-         * @type boolean
-         * @default true
-         */
-        this.setAttributeConfig(this.OPT.SHOW_CONTROLS, {
-                value: lang.isBoolean(attr.showcontrols) ? attr.showcontrols : true,
-                method: function(on) {
-
-                    var el = Dom.getElementsByClassName("bd", "div", 
-                            this.getElement(this.ID.CONTROLS))[0];
-
-                    _hideShowEl.call(this, el, on);
-
-                    this.getElement(this.ID.CONTROLS_LABEL).innerHTML = 
-                        (on) ? this.get(this.OPT.TXT).HIDE_CONTROLS :
-                               this.get(this.OPT.TXT).SHOW_CONTROLS;
-
-                }
-            });
-
-        /**
-         * Hide/show the rgb controls
-         * @attribute showrgbcontrols
-         * @type boolean
-         * @default true
-         */
-        this.setAttributeConfig(this.OPT.SHOW_RGB_CONTROLS, {
-                value: lang.isBoolean(attr.showrgbcontrols) ? attr.showrgbcontrols : true,
-                method: function(on) {
-                    //Dom.setStyle(this.getElement(this.ID.RBG_CONTROLS), "visibility", (on) ? "" : "hidden");
-                    _hideShowEl.call(this, this.ID.RGB_CONTROLS, on);
-                }
-            });
-
-        /**
-         * Hide/show the hsv controls
-         * @attribute showhsvcontrols
-         * @type boolean
-         * @default false
-         */
-        this.setAttributeConfig(this.OPT.SHOW_HSV_CONTROLS, {
-                value: lang.isBoolean(attr.showhsvcontrols) ?
-                                      attr.showhsvcontrols : false,
-                method: function(on) {
-                    //Dom.setStyle(this.getElement(this.ID.HSV_CONTROLS), "visibility", (on) ? "" : "hidden");
-                    _hideShowEl.call(this, this.ID.HSV_CONTROLS, on);
-
-                    // can't show both the hsv controls and the rbg hex summary
-                    if (on && this.get(this.OPT.SHOW_HEX_SUMMARY)) {
-                        this.set(this.OPT.SHOW_HEX_SUMMARY, false);
-                    }
-                }
-            });
-
-        /**
-         * Hide/show the hex controls
-         * @attribute showhexcontrols
-         * @type boolean
-         * @default true
-         */
-        this.setAttributeConfig(this.OPT.SHOW_HEX_CONTROLS, {
-                value: lang.isBoolean(attr.showhexcontrols) ?
-                                      attr.showhexcontrols : false,
-                method: function(on) {
-                    _hideShowEl.call(this, this.ID.HEX_CONTROLS, on);
-                }
-            });
-
-        /**
-         * Hide/show the websafe swatch
-         * @attribute showwebsafe
-         * @type boolean
-         * @default true
-         */
-        this.setAttributeConfig(this.OPT.SHOW_WEBSAFE, {
-                value: lang.isBoolean(attr.showwebsafe) ? attr.showwebsafe : true,
-                method: function(on) {
-                    _hideShowEl.call(this, this.ID.WEBSAFE_SWATCH, on);
-                }
-            });
-
-        /**
-         * Hide/show the hex summary
-         * @attribute showhexsummary
-         * @type boolean
-         * @default true
-         */
-        this.setAttributeConfig(this.OPT.SHOW_HEX_SUMMARY, {
-                value: lang.isBoolean(attr.showhexsummary) ? attr.showhexsummary : true,
-                method: function(on) {
-                    _hideShowEl.call(this, this.ID.HEX_SUMMARY, on);
-
-                    // can't show both the hsv controls and the rbg hex summary
-                    if (on && this.get(this.OPT.SHOW_HSV_CONTROLS)) {
-                        this.set(this.OPT.SHOW_HSV_CONTROLS, false);
-                    }
-                }
-            });
-        this.setAttributeConfig(this.OPT.ANIMATE, {
-                value: lang.isBoolean(attr.animate) ? attr.animate : true,
-                method: function(on) {
-                    this.pickerSlider.animate = on;
-                    this.hueSlider.animate = on;
-                }
-            });
-
-        this.on(this.OPT.HUE + "Change", _updateRGBFromHSV, this, true);
-        this.on(this.OPT.SATURATION + "Change", _updateRGBFromHSV, this, true);
-        this.on(this.OPT.VALUE + "Change", _updatePickerSlider, this, true);
-
-        this.on(this.OPT.RED + "Change", _updateRGB, this, true);
-        this.on(this.OPT.GREEN + "Change", _updateRGB, this, true);
-        this.on(this.OPT.BLUE + "Change", _updateRGB, this, true);
-
-        this.on(this.OPT.HEX + "Change", _updateHex, this, true);
-
-        this.initPicker();
-    };
-
-})();
-YAHOO.register("colorpicker", YAHOO.widget.ColorPicker, {version: "2.4.1", build: "742"});

Added: trunk/root/static/yui/colorpicker/colorpicker-debug.js
===================================================================
--- trunk/root/static/yui/colorpicker/colorpicker-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/colorpicker/colorpicker-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,1755 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * Provides color conversion and validation utils
+ * @class YAHOO.util.Color
+ * @namespace YAHOO.util
+ */
+YAHOO.util.Color = function() {
+
+    var HCHARS="0123456789ABCDEF", lang=YAHOO.lang;
+
+    return {
+
+        /**
+         * Converts 0-1 to 0-255
+         * @method real2dec
+         * @param n {float} the number to convert
+         * @return {int} a number 0-255
+         */
+        real2dec: function(n) {
+            return Math.min(255, Math.round(n*256));
+        },
+
+        /**
+         * Converts HSV (h[0-360], s[0-1]), v[0-1] to RGB [255,255,255]
+         * @method hsv2rgb
+         * @param h {int|[int, float, float]} the hue, or an
+         *        array containing all three parameters
+         * @param s {float} the saturation
+         * @param v {float} the value/brightness
+         * @return {[int, int, int]} the red, green, blue values in
+         *          decimal.
+         */
+        hsv2rgb: function(h, s, v) { 
+
+            if (lang.isArray(h)) {
+                return this.hsv2rgb.call(this, h[0], h[1], h[2]);
+            }
+
+            var r, g, b, i, f, p, q, t;
+            i = Math.floor((h/60)%6);
+            f = (h/60)-i;
+            p = v*(1-s);
+            q = v*(1-f*s);
+            t = v*(1-(1-f)*s);
+            switch(i) {
+                case 0: r=v; g=t; b=p; break;
+                case 1: r=q; g=v; b=p; break;
+                case 2: r=p; g=v; b=t; break;
+                case 3: r=p; g=q; b=v; break;
+                case 4: r=t; g=p; b=v; break;
+                case 5: r=v; g=p; b=q; break;
+            }
+
+            var fn=this.real2dec;
+
+            return [fn(r), fn(g), fn(b)];
+        },
+
+        /**
+         * Converts to RGB [255,255,255] to HSV (h[0-360], s[0-1]), v[0-1]
+         * @method rgb2hsv
+         * @param r {int|[int, int, int]} the red value, or an
+         *        array containing all three parameters
+         * @param g {int} the green value
+         * @param b {int} the blue value
+         * @return {[int, float, float]} the value converted to hsv
+         */
+        rgb2hsv: function(r, g, b) {
+
+            if (lang.isArray(r)) {
+                return this.rgb2hsv.call(this, r[0], r[1], r[2]);
+            }
+
+            r=r/255;
+            g=g/255;
+            b=b/255;
+
+            var min,max,delta,h,s,v;
+            min = Math.min(Math.min(r,g),b);
+            max = Math.max(Math.max(r,g),b);
+            delta = max-min;
+
+            switch (max) {
+                case min: h=0; break;
+                case r:   h=60*(g-b)/delta; 
+                          if (g<b) {
+                              h+=360;
+                          }
+                          break;
+                case g:   h=(60*(b-r)/delta)+120; break;
+                case b:   h=(60*(r-g)/delta)+240; break;
+            }
+            
+            s = (max === 0) ? 0 : 1-(min/max);
+
+            var hsv = [Math.round(h), s, max];
+
+            return hsv;
+
+        },
+
+        /**
+         * Converts decimal rgb values into a hex string
+         * 255,255,255 -> FFFFFF
+         * @method rgb2hex
+         * @param r {int|[int, int, int]} the red value, or an
+         *        array containing all three parameters
+         * @param g {int} the green value
+         * @param b {int} the blue value
+         * @return {string} the hex string
+         */
+        rgb2hex: function(r, g, b) {
+            if (lang.isArray(r)) {
+                return this.rgb2hex.call(this, r[0], r[1], r[2]);
+            }
+
+            var f=this.dec2hex;
+            return f(r) + f(g) + f(b);
+        },
+     
+        /**
+         * Converts an int 0...255 to hex pair 00...FF
+         * @method dec2hex
+         * @param n {int} the number to convert
+         * @return {string} the hex equivalent
+         */
+        dec2hex: function(n) {
+            n = parseInt(n, 10);
+            n = (lang.isNumber(n)) ? n : 0;
+            n = (n > 255 || n < 0) ? 0 : n;
+
+            return HCHARS.charAt((n - n % 16) / 16) + HCHARS.charAt(n % 16);
+        },
+
+        /**
+         * Converts a hex pair 00...FF to an int 0...255 
+         * @method hex2dec
+         * @param str {string} the hex pair to convert
+         * @return {int} the decimal
+         */
+        hex2dec: function(str) {
+            var f = function(c) {
+                return HCHARS.indexOf(c.toUpperCase());
+            };
+
+            var s=str.split('');
+            
+            return ((f(s[0]) * 16) + f(s[1]));
+        },
+
+        /**
+         * Converts a hex string to rgb
+         * @method hex2rgb
+         * @param str {string} the hex string
+         * @return {[int, int, int]} an array containing the rgb values
+         */
+        hex2rgb: function(s) { 
+            var f = this.hex2dec;
+            return [f(s.substr(0, 2)), f(s.substr(2, 2)), f(s.substr(4, 2))];
+        },
+
+        /**
+         * Returns the closest websafe color to the supplied rgb value.
+         * @method websafe
+         * @param r {int|[int, int, int]} the red value, or an
+         *        array containing all three parameters
+         * @param g {int} the green value
+         * @param b {int} the blue value
+         * @return {[int, int, int]} an array containing the closes
+         *                           websafe rgb colors.
+         */
+        websafe: function(r, g, b) {
+
+            if (lang.isArray(r)) {
+                return this.websafe.call(this, r[0], r[1], r[2]);
+            }
+
+            // returns the closest match [0, 51, 102, 153, 204, 255]
+            var f = function(v) {
+                if (lang.isNumber(v)) {
+                    v = Math.min(Math.max(0, v), 255);
+                    var i, next;
+                    for (i=0; i<256; i=i+51) {
+                        next = i+51;
+                        if (v >= i && v <= next) {
+                            return (v-i > 25) ? next : i;
+                        }
+                    }
+ YAHOO.log("Error calculating the websafe value for " + v, "warn");
+                }
+
+                return v;
+            };
+
+            return [f(r), f(g), f(b)];
+        }
+    };
+}();
+
+
+(function() {
+
+    var _pickercount = 0;
+
+    /**
+     * The colorpicker module provides a widget for selecting colors
+     * @module colorpicker
+     * @requires yahoo, dom, event, element, slider
+     */
+
+
+    /**
+     * Creates the host element if it doesn't exist
+     * @method _createHostElement
+     * @private
+     */
+    var _createHostElement = function() {
+        var el = document.createElement('div');
+
+        if (this.CSS.BASE) {
+            el.className = this.CSS.BASE;
+        }
+        
+        return el;
+    };
+
+    /**
+     * A widget to select colors
+     * @namespace YAHOO.widget
+     * @class YAHOO.widget.ColorPicker
+     * @extends YAHOO.util.Element
+     * @constructor
+     * @param {HTMLElement | String | Object} el(optional) The html 
+     * element that represents the colorpicker, or the attribute object to use. 
+     * An element will be created if none provided.
+     * @param {Object} attr (optional) A key map of the colorpicker's 
+     * initial attributes.  Ignored if first arg is attributes object.
+     */
+    YAHOO.widget.ColorPicker = function(el, attr) {
+        _pickercount = _pickercount + 1;
+        this.logger = new YAHOO.widget.LogWriter("ColorPicker");
+        attr = attr || {};
+        if (arguments.length === 1 && !YAHOO.lang.isString(el) && !el.nodeName) {
+            attr = el; // treat first arg as attr object
+            el = attr.element || null;
+        }
+        
+        if (!el && !attr.element) { // create if we dont have one
+            this.logger.log("creating host element");
+            el = _createHostElement.call(this, attr);
+        }
+
+    	YAHOO.widget.ColorPicker.superclass.constructor.call(this, el, attr); 
+    };
+
+    YAHOO.extend(YAHOO.widget.ColorPicker, YAHOO.util.Element);
+    
+    var proto = YAHOO.widget.ColorPicker.prototype,
+        Slider=YAHOO.widget.Slider,
+        Color=YAHOO.util.Color,
+        Dom = YAHOO.util.Dom,
+        Event = YAHOO.util.Event,
+        lang = YAHOO.lang,
+        sub = lang.substitute;
+    
+
+    var b = "yui-picker";
+
+    /**
+     * The element ids used by this control
+     * @property ID
+     * @final
+     */
+    proto.ID = {
+
+        /**
+         * The id for the "red" form field
+         * @property ID.R
+         * @type String
+         * @final
+         * @default yui-picker-r
+         */
+        R: b + "-r",
+
+        /**
+         * The id for the "red" hex pair output
+         * @property ID.R_HEX
+         * @type String
+         * @final
+         * @default yui-picker-rhex
+         */
+        R_HEX: b + "-rhex",
+
+        /**
+         * The id for the "green" form field
+         * @property ID.G
+         * @type String
+         * @final
+         * @default yui-picker-g
+         */
+        G: b + "-g",
+
+        /**
+         * The id for the "green" hex pair output
+         * @property ID.G_HEX
+         * @type String
+         * @final
+         * @default yui-picker-ghex
+         */
+        G_HEX: b + "-ghex",
+
+
+        /**
+         * The id for the "blue" form field
+         * @property ID.B
+         * @type String
+         * @final
+         * @default yui-picker-b
+         */
+        B: b + "-b",
+
+        /**
+         * The id for the "blue" hex pair output
+         * @property ID.B_HEX
+         * @type String
+         * @final
+         * @default yui-picker-bhex
+         */
+        B_HEX: b + "-bhex",
+
+        /**
+         * The id for the "hue" form field
+         * @property ID.H
+         * @type String
+         * @final
+         * @default yui-picker-h
+         */
+        H: b + "-h",
+
+        /**
+         * The id for the "saturation" form field
+         * @property ID.S
+         * @type String
+         * @final
+         * @default yui-picker-s
+         */
+        S: b + "-s",
+
+        /**
+         * The id for the "value" form field
+         * @property ID.V
+         * @type String
+         * @final
+         * @default yui-picker-v
+         */
+        V: b + "-v",
+
+        /**
+         * The id for the picker region slider
+         * @property ID.PICKER_BG
+         * @type String
+         * @final
+         * @default yui-picker-bg
+         */
+        PICKER_BG:      b + "-bg",
+
+        /**
+         * The id for the picker region thumb
+         * @property ID.PICKER_THUMB
+         * @type String
+         * @final
+         * @default yui-picker-thumb
+         */
+        PICKER_THUMB:   b + "-thumb",
+
+        /**
+         * The id for the hue slider
+         * @property ID.HUE_BG
+         * @type String
+         * @final
+         * @default yui-picker-hue-bg
+         */
+        HUE_BG:         b + "-hue-bg",
+
+        /**
+         * The id for the hue thumb
+         * @property ID.HUE_THUMB
+         * @type String
+         * @final
+         * @default yui-picker-hue-thumb
+         */
+        HUE_THUMB:      b + "-hue-thumb",
+
+        /**
+         * The id for the hex value form field
+         * @property ID.HEX
+         * @type String
+         * @final
+         * @default yui-picker-hex
+         */
+        HEX:            b + "-hex",
+
+        /**
+         * The id for the color swatch
+         * @property ID.SWATCH
+         * @type String
+         * @final
+         * @default yui-picker-swatch
+         */
+        SWATCH:         b + "-swatch",
+
+        /**
+         * The id for the websafe color swatch
+         * @property ID.WEBSAFE_SWATCH
+         * @type String
+         * @final
+         * @default yui-picker-websafe-swatch
+         */
+        WEBSAFE_SWATCH: b + "-websafe-swatch",
+
+        /**
+         * The id for the control details
+         * @property ID.CONTROLS
+         * @final
+         * @default yui-picker-controls
+         */
+        CONTROLS: b + "-controls",
+
+        /**
+         * The id for the rgb controls
+         * @property ID.RGB_CONTROLS
+         * @final
+         * @default yui-picker-rgb-controls
+         */
+        RGB_CONTROLS: b + "-rgb-controls",
+
+        /**
+         * The id for the hsv controls
+         * @property ID.HSV_CONTROLS
+         * @final
+         * @default yui-picker-hsv-controls
+         */
+        HSV_CONTROLS: b + "-hsv-controls",
+        
+        /**
+         * The id for the hsv controls
+         * @property ID.HEX_CONTROLS
+         * @final
+         * @default yui-picker-hex-controls
+         */
+        HEX_CONTROLS: b + "-hex-controls",
+
+        /**
+         * The id for the hex summary
+         * @property ID.HEX_SUMMARY
+         * @final
+         * @default yui-picker-hex-summary
+         */
+        HEX_SUMMARY: b + "-hex-summary",
+
+        /**
+         * The id for the controls section header
+         * @property ID.CONTROLS_LABEL
+         * @final
+         * @default yui-picker-controls-label
+         */
+        CONTROLS_LABEL: b + "-controls-label"
+    };
+
+    /**
+     * Constants for any script-generated messages.  The values here
+     * are the default messages.  They can be updated by providing
+     * the complete list to the constructor for the "txt" attribute.
+     * @property TXT
+     * @final
+     */
+    proto.TXT = {
+        ILLEGAL_HEX: "Illegal hex value entered",
+        SHOW_CONTROLS: "Show color details",
+        HIDE_CONTROLS: "Hide color details",
+        CURRENT_COLOR: "Currently selected color: {rgb}",
+        CLOSEST_WEBSAFE: "Closest websafe color: {rgb}. Click to select.",
+        R: "R",
+        G: "G",
+        B: "B",
+        H: "H",
+        S: "S",
+        V: "V",
+        HEX: "#",
+        DEG: "\u00B0",
+        PERCENT: "%"
+    };
+
+    /**
+     * Constants for the default image locations for img tags that are
+     * generated by the control.  They can be modified by passing the
+     * complete list to the contructor for the "images" attribute
+     * @property IMAGE
+     * @final
+     */
+    proto.IMAGE = {
+        PICKER_THUMB: "../../build/colorpicker/assets/picker_thumb.png",
+        HUE_THUMB: "../../build/colorpicker/assets/hue_thumb.png"
+    };
+
+    /*
+     * Constants for the control's custom event names.  subscribe
+     * to the rgbChange event instead.
+     * @property EVENT
+     * @final
+     */
+    //proto.EVENT = {
+        //CHANGE: "change"
+    //};
+
+    //proto.CSS = { };
+
+    /**
+     * Constants for the control's default default values
+     * @property DEFAULT
+     * @final
+     */
+    proto.DEFAULT = {
+        PICKER_SIZE: 180
+    };
+
+    /**
+     * Constants for the control's configuration attributes
+     * @property OPT
+     * @final
+     */
+    proto.OPT = {
+        HUE: "hue",
+        SATURATION: "saturation",
+        VALUE: "value",
+        RED: "red",
+        GREEN: "green",
+        BLUE: "blue",
+        HSV: "hsv",
+        RGB: "rgb",
+        WEBSAFE: "websafe",
+        HEX: "hex",
+        PICKER_SIZE: "pickersize",
+        SHOW_CONTROLS: "showcontrols",
+        SHOW_RGB_CONTROLS: "showrgbcontrols",
+        SHOW_HSV_CONTROLS: "showhsvcontrols",
+        SHOW_HEX_CONTROLS: "showhexcontrols",
+        SHOW_HEX_SUMMARY: "showhexsummary",
+        SHOW_WEBSAFE: "showwebsafe",
+        //SHOW_SUBMIT: "showsubmit",
+        CONTAINER: "container",
+        IDS: "ids",
+        ELEMENTS: "elements",
+        TXT: "txt",
+        IMAGES: "images",
+        ANIMATE: "animate"
+    };
+
+    /**
+     * Moves the hue slider into the position dictated by the current state
+     * of the control
+     * @method _updateHueSlider
+     * @private
+     */
+    var _updateHueSlider = function() {
+        var size = this.get(this.OPT.PICKER_SIZE),
+            h = this.get(this.OPT.HUE);
+
+        h = size - Math.round(h / 360 * size);
+        
+        // 0 is at the top and bottom of the hue slider.  Always go to
+        // the top so we don't end up sending the thumb to the bottom
+        // when the value didn't actually change (e.g., a conversion
+        // produced 360 instead of 0 and the value was already 0).
+        if (h === size) {
+            h = 0;
+        }
+        this.logger.log("Hue slider is being set to " + h);
+
+        this.hueSlider.setValue(h);
+    };
+
+    /**
+     * Moves the picker slider into the position dictated by the current state
+     * of the control
+     * @method _updatePickerSlider
+     * @private
+     */
+    var _updatePickerSlider = function() {
+        var size = this.get(this.OPT.PICKER_SIZE),
+            s = this.get(this.OPT.SATURATION),
+            v = this.get(this.OPT.VALUE);
+
+        s = Math.round(s * size / 100);
+        v = Math.round(size - (v * size / 100));
+
+        this.logger.log("Setting picker slider to " + [s, v]);
+
+        this.pickerSlider.setRegionValue(s, v);
+    };
+
+    /**
+     * Moves the sliders into the position dictated by the current state
+     * of the control
+     * @method _updateSliders
+     * @private
+     */
+    var _updateSliders = function() {
+        _updateHueSlider.call(this);
+        _updatePickerSlider.call(this);
+    };
+
+    /**
+     * Sets the control to the specified rgb value and
+     * moves the sliders to the proper positions
+     * @method setValue
+     * @param rgb {[int, int, int]} the rgb value
+     * @param silent {boolean} whether or not to fire the change event
+     */
+    proto.setValue = function(rgb, silent) {
+        silent = (silent) || false;
+        this.set(this.OPT.RGB, rgb, silent);
+        _updateSliders.call(this);
+    };
+
+    /**
+     * The hue slider
+     * @property hueSlider
+     * @type YAHOO.widget.Slider
+     */
+    proto.hueSlider = null; 
+    
+    /**
+     * The picker region
+     * @property pickerSlider
+     * @type YAHOO.widget.Slider
+     */
+    proto.pickerSlider = null;
+
+    /**
+     * Translates the slider value into hue, int[0,359]
+     * @method _getH
+     * @private
+     * @return {int} the hue from 0 to 359
+     */
+    var _getH = function() {
+        var size = this.get(this.OPT.PICKER_SIZE),
+            h = (size - this.hueSlider.getValue()) / size;
+        h = Math.round(h*360);
+        return (h === 360) ? 0 : h;
+    };
+
+    /**
+     * Translates the slider value into saturation, int[0,1], left to right
+     * @method _getS
+     * @private
+     * @return {int} the saturation from 0 to 1
+     */
+    var _getS = function() {
+        return this.pickerSlider.getXValue() / this.get(this.OPT.PICKER_SIZE);
+    };
+
+    /**
+     * Translates the slider value into value/brightness, int[0,1], top
+     * to bottom
+     * @method _getV
+     * @private
+     * @return {int} the value from 0 to 1
+     */
+    var _getV = function() {
+        var size = this.get(this.OPT.PICKER_SIZE);
+        return (size - this.pickerSlider.getYValue()) / size;
+    };
+
+    /**
+     * Updates the background of the swatch with the current rbg value.
+     * Also updates the websafe swatch to the closest websafe color
+     * @method _updateSwatch
+     * @private
+     */
+    var _updateSwatch = function() {
+        var rgb = this.get(this.OPT.RGB),
+            websafe = this.get(this.OPT.WEBSAFE),
+            el = this.getElement(this.ID.SWATCH),
+            color = rgb.join(","),
+            txt = this.get(this.OPT.TXT);
+
+        Dom.setStyle(el, "background-color", "rgb(" + color  + ")");
+        el.title = lang.substitute(txt.CURRENT_COLOR, {
+                "rgb": "#" + this.get(this.OPT.HEX)
+            });
+
+
+        el = this.getElement(this.ID.WEBSAFE_SWATCH);
+        color = websafe.join(",");
+
+        Dom.setStyle(el, "background-color", "rgb(" + color + ")");
+        el.title = lang.substitute(txt.CLOSEST_WEBSAFE, {
+                "rgb": "#" + Color.rgb2hex(websafe)
+            });
+
+    };
+
+    /**
+     * Reads the sliders and converts the values to RGB, updating the
+     * internal state for all the individual form fields
+     * @method _getValuesFromSliders
+     * @private
+     */
+    var _getValuesFromSliders = function() {
+        var h=_getH.call(this), s=_getS.call(this), v=_getV.call(this);
+        YAHOO.log("hsv " + [h, s, v]);
+
+        var rgb = Color.hsv2rgb(h, s, v);
+        //var websafe = Color.websafe(rgb);
+        //var hex = Color.rgb2hex(rgb[0], rgb[1], rgb[2]);
+
+        this.set(this.OPT.RGB, rgb);
+    };
+
+    /**
+     * Updates the form field controls with the state data contained
+     * in the control.
+     * @method _updateFormFields
+     * @private
+     */
+    var _updateFormFields = function() {
+        this.getElement(this.ID.H).value = this.get(this.OPT.HUE);
+        this.getElement(this.ID.S).value = this.get(this.OPT.SATURATION);
+        this.getElement(this.ID.V).value = this.get(this.OPT.VALUE);
+        this.getElement(this.ID.R).value = this.get(this.OPT.RED);
+        this.getElement(this.ID.R_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.RED));
+        this.getElement(this.ID.G).value = this.get(this.OPT.GREEN);
+        this.getElement(this.ID.G_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.GREEN));
+        this.getElement(this.ID.B).value = this.get(this.OPT.BLUE);
+        this.getElement(this.ID.B_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.BLUE));
+        this.getElement(this.ID.HEX).value = this.get(this.OPT.HEX);
+    };
+
+    /**
+     * Event handler for the hue slider.
+     * @method _onHueSliderChange
+     * @param newOffset {int} pixels from the start position
+     * @private
+     */
+    var _onHueSliderChange = function(newOffset) {
+        this.logger.log("hue update: " + newOffset , "warn");
+
+        var h = _getH.call(this);
+        this.set(this.OPT.HUE, h, true);
+
+        // set picker background to the hue
+        var rgb = Color.hsv2rgb(h, 1, 1);
+        var styleDef = "rgb(" + rgb.join(",") + ")";
+
+        Dom.setStyle(this.getElement(this.ID.PICKER_BG), "background-color", styleDef);
+
+        if (this.hueSlider.valueChangeSource === this.hueSlider.SOURCE_UI_EVENT) {
+            _getValuesFromSliders.call(this);
+        }
+
+        _updateFormFields.call(this);
+        _updateSwatch.call(this);
+    };
+
+    /**
+     * Event handler for the picker slider, which controls the
+     * saturation and value/brightness.
+     * @method _onPickerSliderChange
+     * @param newOffset {{x: int, y: int}} x/y pixels from the start position
+     * @private
+     */
+    var _onPickerSliderChange = function(newOffset) {
+        this.logger.log(sub("picker update [{x}, {y}]", newOffset));
+
+        var s=_getS.call(this), v=_getV.call(this);
+        this.set(this.OPT.SATURATION, Math.round(s*100), true);
+        this.set(this.OPT.VALUE, Math.round(v*100), true);
+
+        if (this.pickerSlider.valueChangeSource === this.pickerSlider.SOURCE_UI_EVENT) {
+            _getValuesFromSliders.call(this);
+        }
+
+        _updateFormFields.call(this);
+        _updateSwatch.call(this);
+    };
+
+
+    /**
+     * Key map to well-known commands for txt field input
+     * @method _getCommand
+     * @param e {Event} the keypress or keydown event
+     * @return {int} a command code
+     * <ul>
+     * <li>0 = not a number, letter in range, or special key</li>
+     * <li>1 = number</li>
+     * <li>2 = a-fA-F</li>
+     * <li>3 = increment (up arrow)</li>
+     * <li>4 = decrement (down arrow)</li>
+     * <li>5 = special key (tab, delete, return, escape, left, right)</li> 
+     * <li>6 = return</li>
+     * </ul>
+     * @private
+     */
+    var _getCommand = function(e) {
+        var c = Event.getCharCode(e);
+
+        //alert(Event.getCharCode(e) + ", " + e.keyCode + ", " + e.charCode);
+
+        // special keys
+        if (c === 38) { // up arrow
+            return 3;
+        } else if (c === 13) { // return
+            return 6;
+        } else if (c === 40) { // down array
+            return 4;
+        } else if (c >= 48 && c<=57) { // 0-9
+            return 1;
+        } else if (c >= 97 && c<=102) { // a-f
+            return 2;
+        } else if (c >= 65 && c<=70) { // A-F
+            return 2;
+        //} else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1 || 
+        //              (c >= 112 && c <=123)) { // including F-keys
+        // tab, delete, return, escape, left, right
+        } else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1) { // special chars
+            return 5;
+        } else { // something we probably don't want
+            return 0;
+        }
+    };
+
+    /**
+     * Use the value of the text field to update the control
+     * @method _hexFieldKeypress
+     * @param e {Event} an event
+     * @param el {HTMLElement} the field
+     * @param prop {string} the key to the linked property
+     * @private
+     */
+    var _useFieldValue = function(e, el, prop) {
+        var val = el.value;
+
+        if (prop !== this.OPT.HEX) {
+            val = parseInt(val, 10);
+        }
+
+        if (val !== this.get(prop)) {
+            this.set(prop, val);
+        }
+    };
+
+    /**
+     * Handle keypress on one of the rgb or hsv fields.
+     * @method _rgbFieldKeypress
+     * @param e {Event} the keypress event
+     * @param el {HTMLElement} the field
+     * @param prop {string} the key to the linked property
+     * @private
+     */
+    var _rgbFieldKeypress = function(e, el, prop) {
+        var command = _getCommand(e);
+        var inc = (e.shiftKey) ? 10 : 1;
+        switch (command) {
+            case 6: // return, update the value
+                _useFieldValue.apply(this, arguments);
+                break;
+                        
+            case 3: // up arrow, increment
+                this.set(prop, Math.min(this.get(prop)+inc, 255));
+                _updateFormFields.call(this);
+                //Event.stopEvent(e);
+                break;
+            case 4: // down arrow, decrement
+                this.set(prop, Math.max(this.get(prop)-inc, 0));
+                _updateFormFields.call(this);
+                //Event.stopEvent(e);
+                break;
+
+            default:
+        }
+
+    };
+
+    /**
+     * Handle keydown on the hex field
+     * @method _hexFieldKeypress
+     * @param e {Event} the keypress event
+     * @param el {HTMLElement} the field
+     * @param prop {string} the key to the linked property
+     * @private
+     */
+    var _hexFieldKeypress = function(e, el, prop) {
+        var command = _getCommand(e);
+        if (command === 6) { // return, update the value
+            _useFieldValue.apply(this, arguments);
+        }
+    };
+
+    /** 
+     * Allows numbers and special chars, and by default allows a-f.  
+     * Used for the hex field keypress handler.
+     * @method _hexOnly
+     * @param e {Event} the event
+     * @param numbersOnly omits a-f if set to true
+     * @private
+     * @return {boolean} false if we are canceling the event
+     */
+    var _hexOnly = function(e, numbersOnly) {
+        var command = _getCommand(e);
+        switch (command) {
+            case 6: // return
+            case 5: // special char
+            case 1: // number
+                break;
+            case 2: // hex char (a-f)
+                if (numbersOnly !== true) {
+                    break;
+                }
+
+                // fallthrough is intentional
+
+            default: // prevent alpha and punctuation
+                Event.stopEvent(e);
+                return false;
+        }
+    };
+
+    /** 
+     * Allows numbers and special chars only.  Used for the
+     * rgb and hsv fields keypress handler.
+     * @method _numbersOnly
+     * @param e {Event} the event
+     * @private
+     * @return {boolean} false if we are canceling the event
+     */
+    var _numbersOnly = function(e) {
+        return _hexOnly(e, true);
+    };
+
+    /**
+     * Returns the element reference that is saved.  The id can be either
+     * the element id, or the key for this id in the "id" config attribute.
+     * For instance, the host element id can be obtained by passing its
+     * id (default: "yui_picker") or by its key "YUI_PICKER".
+     * @param id {string} the element id, or key 
+     * @return {HTMLElement} a reference to the element
+     */
+    proto.getElement = function(id) { 
+        return this.get(this.OPT.ELEMENTS)[this.get(this.OPT.IDS)[id]]; 
+    };
+
+    var _createElements = function() {
+        this.logger.log("Building markup");
+        var el, child, img, fld, i, 
+            ids = this.get(this.OPT.IDS),
+            txt = this.get(this.OPT.TXT),
+            images = this.get(this.OPT.IMAGES),
+            Elem = function(type, o) {
+                var n = document.createElement(type);
+                if (o) {
+                    lang.augmentObject(n, o, true);
+                }
+                return n;
+            },
+            RGBElem = function(type, obj) {
+                var o = lang.merge({
+                        //type: "txt",
+                        autocomplete: "off",
+                        value: "0",
+                        size: 3,
+                        maxlength: 3
+                    }, obj);
+
+                o.name = o.id;
+                return new Elem(type, o);
+            };
+
+        var p = this.get("element");
+
+        // Picker slider (S and V) ---------------------------------------------
+
+        el = new Elem("div", {
+            id: ids[this.ID.PICKER_BG],
+            className: "yui-picker-bg",
+            tabIndex: -1,
+            hideFocus: true
+        });
+
+        child = new Elem("div", {
+            id: ids[this.ID.PICKER_THUMB],
+            className: "yui-picker-thumb"
+        });
+
+        img = new Elem("img", {
+            src: images.PICKER_THUMB
+        });
+
+        child.appendChild(img);
+        el.appendChild(child);
+        p.appendChild(el);
+        
+        // Hue slider ---------------------------------------------
+        el = new Elem("div", {
+            id: ids[this.ID.HUE_BG],
+            className: "yui-picker-hue-bg",
+            tabIndex: -1,
+            hideFocus: true
+        });
+
+        child = new Elem("div", {
+            id: ids[this.ID.HUE_THUMB],
+            className: "yui-picker-hue-thumb"
+        });
+
+        img = new Elem("img", {
+            src: images.HUE_THUMB
+        });
+
+        child.appendChild(img);
+        el.appendChild(child);
+        p.appendChild(el);
+
+
+        // controls ---------------------------------------------
+
+        el = new Elem("div", {
+            id: ids[this.ID.CONTROLS],
+            className: "yui-picker-controls"
+        });
+
+        p.appendChild(el);
+        p = el;
+
+            // controls header
+            el = new Elem("div", {
+                className: "hd"
+            });
+
+            child = new Elem("a", {
+                id: ids[this.ID.CONTROLS_LABEL],
+                //className: "yui-picker-controls-label",
+                href: "#"
+            });
+            el.appendChild(child);
+            p.appendChild(el);
+
+            // bd
+            el = new Elem("div", {
+                className: "bd"
+            });
+
+            p.appendChild(el);
+            p = el;
+
+                // rgb
+                el = new Elem("ul", {
+                    id: ids[this.ID.RGB_CONTROLS],
+                    className: "yui-picker-rgb-controls"
+                });
+
+                child = new Elem("li");
+                child.appendChild(document.createTextNode(txt.R + " "));
+
+                fld = new RGBElem("input", {
+                    id: ids[this.ID.R],
+                    className: "yui-picker-r"
+                });
+
+                child.appendChild(fld);
+                el.appendChild(child);
+
+                child = new Elem("li");
+                child.appendChild(document.createTextNode(txt.G + " "));
+
+                fld = new RGBElem("input", {
+                    id: ids[this.ID.G],
+                    className: "yui-picker-g"
+                });
+
+                child.appendChild(fld);
+                el.appendChild(child);
+
+                child = new Elem("li");
+                child.appendChild(document.createTextNode(txt.B + " "));
+
+                fld = new RGBElem("input", {
+                    id: ids[this.ID.B],
+                    className: "yui-picker-b"
+                });
+
+                child.appendChild(fld);
+                el.appendChild(child);
+
+                p.appendChild(el);
+
+                // hsv
+                el = new Elem("ul", {
+                    id: ids[this.ID.HSV_CONTROLS],
+                    className: "yui-picker-hsv-controls"
+                });
+
+                child = new Elem("li");
+                child.appendChild(document.createTextNode(txt.H + " "));
+
+                fld = new RGBElem("input", {
+                    id: ids[this.ID.H],
+                    className: "yui-picker-h"
+                });
+
+                child.appendChild(fld);
+                child.appendChild(document.createTextNode(" " + txt.DEG));
+
+                el.appendChild(child);
+
+                child = new Elem("li");
+                child.appendChild(document.createTextNode(txt.S + " "));
+
+                fld = new RGBElem("input", {
+                    id: ids[this.ID.S],
+                    className: "yui-picker-s"
+                });
+
+                child.appendChild(fld);
+                child.appendChild(document.createTextNode(" " + txt.PERCENT));
+
+                el.appendChild(child);
+
+                child = new Elem("li");
+                child.appendChild(document.createTextNode(txt.V + " "));
+
+                fld = new RGBElem("input", {
+                    id: ids[this.ID.V],
+                    className: "yui-picker-v"
+                });
+
+                child.appendChild(fld);
+                child.appendChild(document.createTextNode(" " + txt.PERCENT));
+
+                el.appendChild(child);
+                p.appendChild(el);
+
+
+                // hex summary
+
+                el = new Elem("ul", {
+                    id: ids[this.ID.HEX_SUMMARY],
+                    className: "yui-picker-hex_summary"
+                });
+
+                child = new Elem("li", {
+                    id: ids[this.ID.R_HEX]
+                });
+                el.appendChild(child);
+
+                child = new Elem("li", {
+                    id: ids[this.ID.G_HEX]
+                });
+                el.appendChild(child);
+
+                child = new Elem("li", {
+                    id: ids[this.ID.B_HEX]
+                });
+                el.appendChild(child);
+                p.appendChild(el);
+
+                // hex field
+                el = new Elem("div", {
+                    id: ids[this.ID.HEX_CONTROLS],
+                    className: "yui-picker-hex-controls"
+                });
+                el.appendChild(document.createTextNode(txt.HEX + " "));
+
+                child = new RGBElem("input", {
+                    id: ids[this.ID.HEX],
+                    className: "yui-picker-hex",
+                    size: 6,
+                    maxlength: 6
+                });
+
+                el.appendChild(child);
+                p.appendChild(el);
+
+                p = this.get("element");
+
+                // swatch
+                el = new Elem("div", {
+                    id: ids[this.ID.SWATCH],
+                    className: "yui-picker-swatch"
+                });
+
+                p.appendChild(el);
+
+                // websafe swatch
+                el = new Elem("div", {
+                    id: ids[this.ID.WEBSAFE_SWATCH],
+                    className: "yui-picker-websafe-swatch"
+                });
+
+                p.appendChild(el);
+
+    };
+
+    var _attachRGBHSV = function(id, config) {
+        Event.on(this.getElement(id), "keydown", function(e, me) {
+                _rgbFieldKeypress.call(me, e, this, config);
+            }, this);
+        Event.on(this.getElement(id), "keypress", _numbersOnly, this);
+        Event.on(this.getElement(id), "blur", function(e, me) {
+                _useFieldValue.call(me, e, this, config);
+            }, this);
+    };
+
+
+    /**
+     * Updates the rgb attribute with the current state of the r,g,b
+     * fields.  This is invoked from change listeners on these
+     * attributes to facilitate updating these values from the
+     * individual form fields
+     * @method _updateRGB
+     * @private
+     */
+    var _updateRGB = function() {
+        var rgb = [this.get(this.OPT.RED), 
+                   this.get(this.OPT.GREEN),
+                   this.get(this.OPT.BLUE)];
+
+        this.logger.log("RGB value set to " + rgb);
+        this.set(this.OPT.RGB, rgb);
+
+        _updateSliders.call(this);
+    };
+
+    /**
+     * Sets the initial state of the sliders
+     * @method initPicker
+     */
+    proto.initPicker = function () {
+
+        // bind all of our elements
+        var o=this.OPT, 
+            ids = this.get(o.IDS), 
+            els = this.get(o.ELEMENTS), 
+                  i, el, id;
+
+        // Add the default value as a key for each element for easier lookup
+        for (i in this.ID) {
+            if (lang.hasOwnProperty(this.ID, i)) {
+                ids[this.ID[i]] = ids[i];
+            }
+        }
+
+        // Check for picker element, if not there, create all of them
+        el = Dom.get(ids[this.ID.PICKER_BG]);
+        if (!el) {
+            _createElements.call(this);
+        } else {
+            this.logger.log("Using pre-existing markup");
+        }
+
+        for (i in ids) {
+            if (lang.hasOwnProperty(ids, i)) {
+                // look for element
+                el = Dom.get(ids[i]);
+
+                // generate an id if the implementer passed in an element reference,
+                // and the element did not have an id already
+                id = Dom.generateId(el);
+
+                // update the id in case we generated the id
+                ids[i] = id; // key is WEBSAFE_SWATCH
+                ids[ids[i]] = id; // key is websafe_swatch
+
+                // store the dom ref
+                els[id] = el;
+            }
+        }
+
+        // set the initial visibility state of our controls
+            els = [o.SHOW_CONTROLS, 
+                   o.SHOW_RGB_CONTROLS,
+                   o.SHOW_HSV_CONTROLS,
+                   o.SHOW_HEX_CONTROLS,
+                   o.SHOW_HEX_SUMMARY,
+                   o.SHOW_WEBSAFE
+                   ];
+
+        for (i=0; i<els.length; i=i+1) {
+            this.set(els[i], this.get(els[i]));
+        }
+
+        var s = this.get(o.PICKER_SIZE);
+        this.logger.log("picker size" + s);
+
+        this.hueSlider = Slider.getVertSlider(this.getElement(this.ID.HUE_BG), 
+                                              this.getElement(this.ID.HUE_THUMB), 0, s);
+        this.hueSlider.subscribe("change", _onHueSliderChange, this, true);
+
+        this.pickerSlider = Slider.getSliderRegion(this.getElement(this.ID.PICKER_BG), 
+                                                   this.getElement(this.ID.PICKER_THUMB), 0, s, 0, s);
+        this.pickerSlider.subscribe("change", _onPickerSliderChange, this, true);
+
+        // Set the animate state
+        this.set(o.ANIMATE,this.get(o.ANIMATE));
+
+        //_onHueSliderChange.call(this, 0);
+
+        Event.on(this.getElement(this.ID.WEBSAFE_SWATCH), "click", function(e) {
+               this.setValue(this.get(o.WEBSAFE));
+               //_updateSliders
+           }, this, true);
+
+        Event.on(this.getElement(this.ID.CONTROLS_LABEL), "click", function(e) {
+               this.set(o.SHOW_CONTROLS, !this.get(o.SHOW_CONTROLS));
+               Event.preventDefault(e);
+           }, this, true);
+
+        _attachRGBHSV.call(this, this.ID.R, this.OPT.RED); 
+        _attachRGBHSV.call(this, this.ID.G, this.OPT.GREEN); 
+        _attachRGBHSV.call(this, this.ID.B, this.OPT.BLUE); 
+        _attachRGBHSV.call(this, this.ID.H, this.OPT.HUE); 
+        _attachRGBHSV.call(this, this.ID.S, this.OPT.SATURATION); 
+        _attachRGBHSV.call(this, this.ID.V, this.OPT.VALUE); 
+
+        Event.on(this.getElement(this.ID.HEX), "keydown", function(e, me) {
+                _hexFieldKeypress.call(me, e, this, me.OPT.HEX);
+            }, this);
+
+        Event.on(this.getElement(this.ID.HEX), "keypress", _hexOnly, this);
+        Event.on(this.getElement(this.ID.HEX), "blur", function(e, me) {
+                _useFieldValue.call(me, e, this, me.OPT.HEX);
+            }, this);
+
+        _updateRGB.call(this);
+    };
+
+
+    /**
+     * Updates the RGB values from the current state of the HSV
+     * values.  Executed when the one of the HSV form fields are
+     * updated
+     * _updateRGBFromHSV
+     * @private
+     */
+    var _updateRGBFromHSV = function() {
+        var hsv = [this.get(this.OPT.HUE), 
+                   this.get(this.OPT.SATURATION)/100,
+                   this.get(this.OPT.VALUE)/100];
+
+        var rgb = Color.hsv2rgb(hsv);
+
+        this.logger.log("HSV converted to RGB " + hsv + " : " + rgb);
+        this.set(this.OPT.RGB, rgb);
+
+        _updateSliders.call(this);
+    };
+
+    /**
+     * Parses the hex string to normalize shorthand values, converts
+     * the hex value to rgb and updates the rgb attribute (which
+     * updates the state for all of the other values)
+     * method _updateHex
+     * @private
+     */
+    var _updateHex = function() {
+       
+        var hex = this.get(this.OPT.HEX), l=hex.length;
+
+        // support #369 -> #336699 shorthand
+        if (l === 3) {
+            var c = hex.split(""), i;
+            for (i=0; i<l; i=i+1) {
+                c[i] = c[i] + c[i];
+            }
+
+            hex = c.join("");
+        }
+
+        if (hex.length !== 6) {
+            this.logger.log(this.get(this.TXT.ILLEGAL_HEX), "error");
+            return false;
+        }
+
+        var rgb = Color.hex2rgb(hex);
+
+        this.logger.log(sub("Hex value set to {hex} ({rgb})", {
+                hex: hex, rgb: rgb
+            }));
+
+        this.setValue(rgb);
+
+        //_updateSliders.call(this);
+
+    };
+
+
+
+    /**
+     * Sets up the config attributes and the change listeners for this
+     * properties
+     * @method initAttributes
+     * @param attr An object containing default attribute values
+     */
+    proto.initAttributes = function(attr) {
+
+        attr = attr || {};
+        YAHOO.widget.ColorPicker.superclass.initAttributes.call(this, attr);
+        
+        /**
+         * The size of the picker. Trying to change this is not recommended.
+         * @attribute pickersize
+         * @default 180
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.PICKER_SIZE, {
+                value: attr.size || this.DEFAULT.PICKER_SIZE
+            });
+
+        /**
+         * The current hue value 0-360
+         * @attribute hue
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.HUE, {
+                value: attr.hue || 0,
+                validator: lang.isNumber
+            });
+
+        /**
+         * The current saturation value 0-100
+         * @attribute saturation
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.SATURATION, {
+                value: attr.saturation || 0,
+                validator: lang.isNumber
+            });
+
+        /**
+         * The current value/brightness value 0-100
+         * @attribute value
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.VALUE, {
+                value: lang.isNumber(attr.value) ? attr.value : 100,
+                validator: lang.isNumber
+            });
+
+        /**
+         * The current red value 0-255
+         * @attribute red
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.RED, {
+                value: lang.isNumber(attr.red) ? attr.red : 255,
+                validator: lang.isNumber
+            });
+
+        /**
+         * The current green value 0-255
+         * @attribute green 
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.GREEN, {
+                value: lang.isNumber(attr.green) ? attr.green : 255,
+                validator: lang.isNumber
+            });
+
+        /**
+         * The current blue value 0-255
+         * @attribute blue
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.BLUE, {
+                value: lang.isNumber(attr.blue) ? attr.blue : 255,
+                validator: lang.isNumber
+            });
+
+        /**
+         * The current hex value #000000-#FFFFFF, without the #
+         * @attribute hex
+         * @type string
+         */
+        this.setAttributeConfig(this.OPT.HEX, {
+                value: attr.hex || "FFFFFF",
+                validator: lang.isString
+            });
+
+        /**
+         * The current rgb value.  Updates the state of all of the
+         * other value fields.  Read-only: use setValue to set the
+         * controls rgb value.
+         * @attribute hex
+         * @type [int, int, int]
+         * @readonly
+         */
+        this.setAttributeConfig(this.OPT.RGB, {
+                value: attr.rgb || [255,255,255],
+                method: function(rgb) {
+
+                    this.set(this.OPT.RED, rgb[0], true);
+                    this.set(this.OPT.GREEN, rgb[1], true);
+                    this.set(this.OPT.BLUE, rgb[2], true);
+
+                    var websafe = Color.websafe(rgb);
+                    this.set(this.OPT.WEBSAFE, websafe, true);
+
+                    var hex = Color.rgb2hex(rgb);
+                    this.set(this.OPT.HEX, hex, true);
+
+                    var hsv = Color.rgb2hsv(rgb);
+
+                    this.logger.log(sub("RGB value set to {rgb} (hsv: {hsv})", {
+                            "hsv": hsv, "rgb": rgb
+                        }));
+
+                    this.set(this.OPT.HUE, hsv[0], true);
+                    this.set(this.OPT.SATURATION, Math.round(hsv[1]*100), true);
+                    this.set(this.OPT.VALUE, Math.round(hsv[2]*100), true);
+                },
+                readonly: true
+            });
+
+        /**
+         * If the color picker will live inside of a container object,
+         * set, provide a reference to it so the control can use the
+         * container's events.
+         * @attribute container
+         * @type YAHOO.widget.Panel
+         */
+        this.setAttributeConfig(this.OPT.CONTAINER, {
+                    value: null,
+                    method: function(container) {
+                        if (container) {
+                            // Position can get out of sync when the
+                            // control is manipulated while display is
+                            // none.  Resetting the slider constraints
+                            // when it is visible gets the state back in
+                            // order.
+                            container.showEvent.subscribe(function() {
+                                // this.pickerSlider.thumb.resetConstraints();
+                                // this.hueSlider.thumb.resetConstraints();
+                                this.pickerSlider.focus();
+                            }, this, true);
+                        }
+                    }
+                });
+        /**
+         * The closest current websafe value
+         * @attribute websafe
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.WEBSAFE, {
+                value: attr.websafe || [255,255,255]
+            });
+
+
+        var ids = attr.ids || lang.merge({}, this.ID);
+
+        if (!attr.ids && _pickercount > 1) {
+            for (var i in ids) {
+                if (lang.hasOwnProperty(ids, i)) {
+                    ids[i] = ids[i] + _pickercount;
+                }
+            }
+        }
+
+
+        /**
+         * A list of element ids and/or element references used by the 
+         * control.  The default is the this.ID list, and can be customized
+         * by passing a list in the contructor
+         * @attribute ids
+         * @type {referenceid: realid}
+         * @writeonce
+         */
+        this.setAttributeConfig(this.OPT.IDS, {
+                value: ids,
+                writeonce: true
+            });
+
+        /**
+         * A list of txt strings for internationalization.  Default
+         * is this.TXT
+         * @attribute txt
+         * @type {key: txt}
+         * @writeonce
+         */
+        this.setAttributeConfig(this.OPT.TXT, {
+                value: attr.txt || this.TXT,
+                writeonce: true
+            });
+
+        /**
+         * The img src default list
+         * is this.IMAGES
+         * @attribute images
+         * @type {key: image}
+         * @writeonce
+         */
+        this.setAttributeConfig(this.OPT.IMAGES, {
+                value: attr.images || this.IMAGE,
+                writeonce: true
+            });
+        /**
+         * The element refs used by this control.  Set at initialization
+         * @attribute elements
+         * @type {id: HTMLElement}
+         * @readonly
+         */
+        this.setAttributeConfig(this.OPT.ELEMENTS, {
+                value: {},
+                readonly: true
+            });
+
+        /**
+         * Returns the cached element reference.  If the id is not a string, it
+         * is assumed that it is an element and this is returned.
+         * @param id {string|HTMLElement} the element key, id, or ref
+         * @param on {boolean} hide or show.  If true, show
+         * @private */
+        var _hideShowEl = function(id, on) {
+            var el = (lang.isString(id) ? this.getElement(id) : id);
+            //Dom.setStyle(id, "visibility", (on) ? "" : "hidden");
+            Dom.setStyle(el, "display", (on) ? "" : "none");
+        };
+
+        /**
+         * Hide/show the entire set of controls
+         * @attribute showcontrols
+         * @type boolean
+         * @default true
+         */
+        this.setAttributeConfig(this.OPT.SHOW_CONTROLS, {
+                value: lang.isBoolean(attr.showcontrols) ? attr.showcontrols : true,
+                method: function(on) {
+
+                    var el = Dom.getElementsByClassName("bd", "div", 
+                            this.getElement(this.ID.CONTROLS))[0];
+
+                    _hideShowEl.call(this, el, on);
+
+                    this.getElement(this.ID.CONTROLS_LABEL).innerHTML = 
+                        (on) ? this.get(this.OPT.TXT).HIDE_CONTROLS :
+                               this.get(this.OPT.TXT).SHOW_CONTROLS;
+
+                }
+            });
+
+        /**
+         * Hide/show the rgb controls
+         * @attribute showrgbcontrols
+         * @type boolean
+         * @default true
+         */
+        this.setAttributeConfig(this.OPT.SHOW_RGB_CONTROLS, {
+                value: lang.isBoolean(attr.showrgbcontrols) ? attr.showrgbcontrols : true,
+                method: function(on) {
+                    //Dom.setStyle(this.getElement(this.ID.RBG_CONTROLS), "visibility", (on) ? "" : "hidden");
+                    _hideShowEl.call(this, this.ID.RGB_CONTROLS, on);
+                }
+            });
+
+        /**
+         * Hide/show the hsv controls
+         * @attribute showhsvcontrols
+         * @type boolean
+         * @default false
+         */
+        this.setAttributeConfig(this.OPT.SHOW_HSV_CONTROLS, {
+                value: lang.isBoolean(attr.showhsvcontrols) ?
+                                      attr.showhsvcontrols : false,
+                method: function(on) {
+                    //Dom.setStyle(this.getElement(this.ID.HSV_CONTROLS), "visibility", (on) ? "" : "hidden");
+                    _hideShowEl.call(this, this.ID.HSV_CONTROLS, on);
+
+                    // can't show both the hsv controls and the rbg hex summary
+                    if (on && this.get(this.OPT.SHOW_HEX_SUMMARY)) {
+                        this.set(this.OPT.SHOW_HEX_SUMMARY, false);
+                    }
+                }
+            });
+
+        /**
+         * Hide/show the hex controls
+         * @attribute showhexcontrols
+         * @type boolean
+         * @default true
+         */
+        this.setAttributeConfig(this.OPT.SHOW_HEX_CONTROLS, {
+                value: lang.isBoolean(attr.showhexcontrols) ?
+                                      attr.showhexcontrols : false,
+                method: function(on) {
+                    _hideShowEl.call(this, this.ID.HEX_CONTROLS, on);
+                }
+            });
+
+        /**
+         * Hide/show the websafe swatch
+         * @attribute showwebsafe
+         * @type boolean
+         * @default true
+         */
+        this.setAttributeConfig(this.OPT.SHOW_WEBSAFE, {
+                value: lang.isBoolean(attr.showwebsafe) ? attr.showwebsafe : true,
+                method: function(on) {
+                    _hideShowEl.call(this, this.ID.WEBSAFE_SWATCH, on);
+                }
+            });
+
+        /**
+         * Hide/show the hex summary
+         * @attribute showhexsummary
+         * @type boolean
+         * @default true
+         */
+        this.setAttributeConfig(this.OPT.SHOW_HEX_SUMMARY, {
+                value: lang.isBoolean(attr.showhexsummary) ? attr.showhexsummary : true,
+                method: function(on) {
+                    _hideShowEl.call(this, this.ID.HEX_SUMMARY, on);
+
+                    // can't show both the hsv controls and the rbg hex summary
+                    if (on && this.get(this.OPT.SHOW_HSV_CONTROLS)) {
+                        this.set(this.OPT.SHOW_HSV_CONTROLS, false);
+                    }
+                }
+            });
+        this.setAttributeConfig(this.OPT.ANIMATE, {
+                value: lang.isBoolean(attr.animate) ? attr.animate : true,
+                method: function(on) {
+                    this.pickerSlider.animate = on;
+                    this.hueSlider.animate = on;
+                }
+            });
+
+        this.on(this.OPT.HUE + "Change", _updateRGBFromHSV, this, true);
+        this.on(this.OPT.SATURATION + "Change", _updateRGBFromHSV, this, true);
+        this.on(this.OPT.VALUE + "Change", _updatePickerSlider, this, true);
+
+        this.on(this.OPT.RED + "Change", _updateRGB, this, true);
+        this.on(this.OPT.GREEN + "Change", _updateRGB, this, true);
+        this.on(this.OPT.BLUE + "Change", _updateRGB, this, true);
+
+        this.on(this.OPT.HEX + "Change", _updateHex, this, true);
+
+        this.initPicker();
+    };
+
+})();
+YAHOO.register("colorpicker", YAHOO.widget.ColorPicker, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/colorpicker/colorpicker-min.js
===================================================================
--- trunk/root/static/yui/colorpicker/colorpicker-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/colorpicker/colorpicker-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,9 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+YAHOO.util.Color=function(){var A="0123456789ABCDEF",B=YAHOO.lang;return{real2dec:function(C){return Math.min(255,Math.round(C*256));},hsv2rgb:function(G,N,L){if(B.isArray(G)){return this.hsv2rgb.call(this,G[0],G[1],G[2]);}var C,H,K,F,I,E,D,M;F=Math.floor((G/60)%6);I=(G/60)-F;E=L*(1-N);D=L*(1-I*N);M=L*(1-(1-I)*N);switch(F){case 0:C=L;H=M;K=E;break;case 1:C=D;H=L;K=E;break;case 2:C=E;H=L;K=M;break;case 3:C=E;H=D;K=L;break;case 4:C=M;H=E;K=L;break;case 5:C=L;H=E;K=D;break;}var J=this.real2dec;return[J(C),J(H),J(K)];},rgb2hsv:function(C,G,H){if(B.isArray(C)){return this.rgb2hsv.call(this,C[0],C[1],C[2]);}C=C/255;G=G/255;H=H/255;var D,I,K,F,L,J;D=Math.min(Math.min(C,G),H);I=Math.max(Math.max(C,G),H);K=I-D;switch(I){case D:F=0;break;case C:F=60*(G-H)/K;if(G<H){F+=360;}break;case G:F=(60*(H-C)/K)+120;break;case H:F=(60*(C-G)/K)+240;break;}L=(I===0)?0:1-(D/I);var E=[Math.round(F),L,I];return E;},rgb2hex:function(E,D,C){if(B.isArray(E)){return this.rgb2hex.call(this,E[0],E[1],E[2])!
 ;}var F=this.dec2hex;return F(E)+F(D)+F(C);},dec2hex:function(C){C=parseInt(C,10);C=(B.isNumber(C))?C:0;C=(C>255||C<0)?0:C;return A.charAt((C-C%16)/16)+A.charAt(C%16);},hex2dec:function(E){var D=function(F){return A.indexOf(F.toUpperCase());};var C=E.split("");return((D(C[0])*16)+D(C[1]));},hex2rgb:function(C){var D=this.hex2dec;return[D(C.substr(0,2)),D(C.substr(2,2)),D(C.substr(4,2))];},websafe:function(E,D,C){if(B.isArray(E)){return this.websafe.call(this,E[0],E[1],E[2]);}var F=function(G){if(B.isNumber(G)){G=Math.min(Math.max(0,G),255);var H,I;for(H=0;H<256;H=H+51){I=H+51;if(G>=H&&G<=I){return(G-H>25)?I:H;}}}return G;};return[F(E),F(D),F(C)];}};}();(function(){var E=0;var R=function(){var b=document.createElement("div");if(this.CSS.BASE){b.className=this.CSS.BASE;}return b;};YAHOO.widget.ColorPicker=function(h,b){E=E+1;b=b||{};if(arguments.length===1&&!YAHOO.lang.isString(h)&&!h.nodeName){b=h;h=b.element||null;}if(!h&&!b.element){h=R.call(this,b);}YAHOO.widget.ColorPick!
 er.superclass.constructor.call(this,h,b);};YAHOO.extend(YAHOO.!
 widget.C
olorPicker,YAHOO.util.Element);var Q=YAHOO.widget.ColorPicker.prototype,P=YAHOO.widget.Slider,e=YAHOO.util.Color,C=YAHOO.util.Dom,f=YAHOO.util.Event,g=YAHOO.lang,J=g.substitute;var a="yui-picker";Q.ID={R:a+"-r",R_HEX:a+"-rhex",G:a+"-g",G_HEX:a+"-ghex",B:a+"-b",B_HEX:a+"-bhex",H:a+"-h",S:a+"-s",V:a+"-v",PICKER_BG:a+"-bg",PICKER_THUMB:a+"-thumb",HUE_BG:a+"-hue-bg",HUE_THUMB:a+"-hue-thumb",HEX:a+"-hex",SWATCH:a+"-swatch",WEBSAFE_SWATCH:a+"-websafe-swatch",CONTROLS:a+"-controls",RGB_CONTROLS:a+"-rgb-controls",HSV_CONTROLS:a+"-hsv-controls",HEX_CONTROLS:a+"-hex-controls",HEX_SUMMARY:a+"-hex-summary",CONTROLS_LABEL:a+"-controls-label"};Q.TXT={ILLEGAL_HEX:"Illegal hex value entered",SHOW_CONTROLS:"Show color details",HIDE_CONTROLS:"Hide color details",CURRENT_COLOR:"Currently selected color: {rgb}",CLOSEST_WEBSAFE:"Closest websafe color: {rgb}. Click to select.",R:"R",G:"G",B:"B",H:"H",S:"S",V:"V",HEX:"#",DEG:"\u00B0",PERCENT:"%"};Q.IMAGE={PICKER_THUMB:"../../build/colorpicker/asse!
 ts/picker_thumb.png",HUE_THUMB:"../../build/colorpicker/assets/hue_thumb.png"};Q.DEFAULT={PICKER_SIZE:180};Q.OPT={HUE:"hue",SATURATION:"saturation",VALUE:"value",RED:"red",GREEN:"green",BLUE:"blue",HSV:"hsv",RGB:"rgb",WEBSAFE:"websafe",HEX:"hex",PICKER_SIZE:"pickersize",SHOW_CONTROLS:"showcontrols",SHOW_RGB_CONTROLS:"showrgbcontrols",SHOW_HSV_CONTROLS:"showhsvcontrols",SHOW_HEX_CONTROLS:"showhexcontrols",SHOW_HEX_SUMMARY:"showhexsummary",SHOW_WEBSAFE:"showwebsafe",CONTAINER:"container",IDS:"ids",ELEMENTS:"elements",TXT:"txt",IMAGES:"images",ANIMATE:"animate"};var S=function(){var b=this.get(this.OPT.PICKER_SIZE),i=this.get(this.OPT.HUE);i=b-Math.round(i/360*b);if(i===b){i=0;}this.hueSlider.setValue(i);};var d=function(){var h=this.get(this.OPT.PICKER_SIZE),i=this.get(this.OPT.SATURATION),b=this.get(this.OPT.VALUE);i=Math.round(i*h/100);b=Math.round(h-(b*h/100));this.pickerSlider.setRegionValue(i,b);};var T=function(){S.call(this);d.call(this);};Q.setValue=function(h,b){b=(b!
 )||false;this.set(this.OPT.RGB,h,b);T.call(this);};Q.hueSlider!
 =null;Q.
pickerSlider=null;var X=function(){var b=this.get(this.OPT.PICKER_SIZE),i=(b-this.hueSlider.getValue())/b;i=Math.round(i*360);return(i===360)?0:i;};var O=function(){return this.pickerSlider.getXValue()/this.get(this.OPT.PICKER_SIZE);};var N=function(){var b=this.get(this.OPT.PICKER_SIZE);return(b-this.pickerSlider.getYValue())/b;};var M=function(){var i=this.get(this.OPT.RGB),k=this.get(this.OPT.WEBSAFE),j=this.getElement(this.ID.SWATCH),h=i.join(","),b=this.get(this.OPT.TXT);C.setStyle(j,"background-color","rgb("+h+")");j.title=g.substitute(b.CURRENT_COLOR,{"rgb":"#"+this.get(this.OPT.HEX)});j=this.getElement(this.ID.WEBSAFE_SWATCH);h=k.join(",");C.setStyle(j,"background-color","rgb("+h+")");j.title=g.substitute(b.CLOSEST_WEBSAFE,{"rgb":"#"+e.rgb2hex(k)});};var Z=function(){var k=X.call(this),j=O.call(this),b=N.call(this);var i=e.hsv2rgb(k,j,b);this.set(this.OPT.RGB,i);};var B=function(){this.getElement(this.ID.H).value=this.get(this.OPT.HUE);this.getElement(this.ID.S).valu!
 e=this.get(this.OPT.SATURATION);this.getElement(this.ID.V).value=this.get(this.OPT.VALUE);this.getElement(this.ID.R).value=this.get(this.OPT.RED);this.getElement(this.ID.R_HEX).innerHTML=e.dec2hex(this.get(this.OPT.RED));this.getElement(this.ID.G).value=this.get(this.OPT.GREEN);this.getElement(this.ID.G_HEX).innerHTML=e.dec2hex(this.get(this.OPT.GREEN));this.getElement(this.ID.B).value=this.get(this.OPT.BLUE);this.getElement(this.ID.B_HEX).innerHTML=e.dec2hex(this.get(this.OPT.BLUE));this.getElement(this.ID.HEX).value=this.get(this.OPT.HEX);};var Y=function(k){var i=X.call(this);this.set(this.OPT.HUE,i,true);var b=e.hsv2rgb(i,1,1);var j="rgb("+b.join(",")+")";C.setStyle(this.getElement(this.ID.PICKER_BG),"background-color",j);if(this.hueSlider.valueChangeSource===this.hueSlider.SOURCE_UI_EVENT){Z.call(this);}B.call(this);M.call(this);};var H=function(i){var h=O.call(this),b=N.call(this);this.set(this.OPT.SATURATION,Math.round(h*100),true);
+this.set(this.OPT.VALUE,Math.round(b*100),true);if(this.pickerSlider.valueChangeSource===this.pickerSlider.SOURCE_UI_EVENT){Z.call(this);}B.call(this);M.call(this);};var W=function(b){var h=f.getCharCode(b);if(h===38){return 3;}else{if(h===13){return 6;}else{if(h===40){return 4;}else{if(h>=48&&h<=57){return 1;}else{if(h>=97&&h<=102){return 2;}else{if(h>=65&&h<=70){return 2;}else{if("8, 9, 13, 27, 37, 39".indexOf(h)>-1){return 5;}else{return 0;}}}}}}}};var I=function(h,b,j){var i=b.value;if(j!==this.OPT.HEX){i=parseInt(i,10);}if(i!==this.get(j)){this.set(j,i);}};var G=function(i,b,k){var j=W(i);var h=(i.shiftKey)?10:1;switch(j){case 6:I.apply(this,arguments);break;case 3:this.set(k,Math.min(this.get(k)+h,255));B.call(this);break;case 4:this.set(k,Math.max(this.get(k)-h,0));B.call(this);break;default:}};var A=function(h,b,j){var i=W(h);if(i===6){I.apply(this,arguments);}};var L=function(h,b){var i=W(h);switch(i){case 6:case 5:case 1:break;case 2:if(b!==true){break;}default:f.!
 stopEvent(h);return false;}};var K=function(b){return L(b,true);};Q.getElement=function(b){return this.get(this.OPT.ELEMENTS)[this.get(this.OPT.IDS)[b]];};var D=function(){var k,j,n,l,m,b=this.get(this.OPT.IDS),o=this.get(this.OPT.TXT),r=this.get(this.OPT.IMAGES),q=function(i,p){var t=document.createElement(i);if(p){g.augmentObject(t,p,true);}return t;},s=function(i,p){var t=g.merge({autocomplete:"off",value:"0",size:3,maxlength:3},p);t.name=t.id;return new q(i,t);};var h=this.get("element");k=new q("div",{id:b[this.ID.PICKER_BG],className:"yui-picker-bg",tabIndex:-1,hideFocus:true});j=new q("div",{id:b[this.ID.PICKER_THUMB],className:"yui-picker-thumb"});n=new q("img",{src:r.PICKER_THUMB});j.appendChild(n);k.appendChild(j);h.appendChild(k);k=new q("div",{id:b[this.ID.HUE_BG],className:"yui-picker-hue-bg",tabIndex:-1,hideFocus:true});j=new q("div",{id:b[this.ID.HUE_THUMB],className:"yui-picker-hue-thumb"});n=new q("img",{src:r.HUE_THUMB});j.appendChild(n);k.appendChild(j);h!
 .appendChild(k);k=new q("div",{id:b[this.ID.CONTROLS],classNam!
 e:"yui-p
icker-controls"});h.appendChild(k);h=k;k=new q("div",{className:"hd"});j=new q("a",{id:b[this.ID.CONTROLS_LABEL],href:"#"});k.appendChild(j);h.appendChild(k);k=new q("div",{className:"bd"});h.appendChild(k);h=k;k=new q("ul",{id:b[this.ID.RGB_CONTROLS],className:"yui-picker-rgb-controls"});j=new q("li");j.appendChild(document.createTextNode(o.R+" "));l=new s("input",{id:b[this.ID.R],className:"yui-picker-r"});j.appendChild(l);k.appendChild(j);j=new q("li");j.appendChild(document.createTextNode(o.G+" "));l=new s("input",{id:b[this.ID.G],className:"yui-picker-g"});j.appendChild(l);k.appendChild(j);j=new q("li");j.appendChild(document.createTextNode(o.B+" "));l=new s("input",{id:b[this.ID.B],className:"yui-picker-b"});j.appendChild(l);k.appendChild(j);h.appendChild(k);k=new q("ul",{id:b[this.ID.HSV_CONTROLS],className:"yui-picker-hsv-controls"});j=new q("li");j.appendChild(document.createTextNode(o.H+" "));l=new s("input",{id:b[this.ID.H],className:"yui-picker-h"});j.appendChild!
 (l);j.appendChild(document.createTextNode(" "+o.DEG));k.appendChild(j);j=new q("li");j.appendChild(document.createTextNode(o.S+" "));l=new s("input",{id:b[this.ID.S],className:"yui-picker-s"});j.appendChild(l);j.appendChild(document.createTextNode(" "+o.PERCENT));k.appendChild(j);j=new q("li");j.appendChild(document.createTextNode(o.V+" "));l=new s("input",{id:b[this.ID.V],className:"yui-picker-v"});j.appendChild(l);j.appendChild(document.createTextNode(" "+o.PERCENT));k.appendChild(j);h.appendChild(k);k=new q("ul",{id:b[this.ID.HEX_SUMMARY],className:"yui-picker-hex_summary"});j=new q("li",{id:b[this.ID.R_HEX]});k.appendChild(j);j=new q("li",{id:b[this.ID.G_HEX]});k.appendChild(j);j=new q("li",{id:b[this.ID.B_HEX]});k.appendChild(j);h.appendChild(k);k=new q("div",{id:b[this.ID.HEX_CONTROLS],className:"yui-picker-hex-controls"});k.appendChild(document.createTextNode(o.HEX+" "));j=new s("input",{id:b[this.ID.HEX],className:"yui-picker-hex",size:6,maxlength:6});k.appendChild(!
 j);h.appendChild(k);h=this.get("element");k=new q("div",{id:b[!
 this.ID.
SWATCH],className:"yui-picker-swatch"});h.appendChild(k);k=new q("div",{id:b[this.ID.WEBSAFE_SWATCH],className:"yui-picker-websafe-swatch"});h.appendChild(k);};var c=function(h,b){f.on(this.getElement(h),"keydown",function(j,i){G.call(i,j,this,b);},this);f.on(this.getElement(h),"keypress",K,this);f.on(this.getElement(h),"blur",function(j,i){I.call(i,j,this,b);},this);};var F=function(){var b=[this.get(this.OPT.RED),this.get(this.OPT.GREEN),this.get(this.OPT.BLUE)];this.set(this.OPT.RGB,b);T.call(this);};Q.initPicker=function(){var m=this.OPT,l=this.get(m.IDS),h=this.get(m.ELEMENTS),b,k,n;for(b in this.ID){if(g.hasOwnProperty(this.ID,b)){l[this.ID[b]]=l[b];}}k=C.get(l[this.ID.PICKER_BG]);if(!k){D.call(this);}else{}for(b in l){if(g.hasOwnProperty(l,b)){k=C.get(l[b]);n=C.generateId(k);l[b]=n;l[l[b]]=n;h[n]=k;}}h=[m.SHOW_CONTROLS,m.SHOW_RGB_CONTROLS,m.SHOW_HSV_CONTROLS,m.SHOW_HEX_CONTROLS,m.SHOW_HEX_SUMMARY,m.SHOW_WEBSAFE];for(b=0;b<h.length;b=b+1){this.set(h[b],this.get(h[b]));!
 }var j=this.get(m.PICKER_SIZE);this.hueSlider=P.getVertSlider(this.getElement(this.ID.HUE_BG),this.getElement(this.ID.HUE_THUMB),0,j);this.hueSlider.subscribe("change",Y,this,true);this.pickerSlider=P.getSliderRegion(this.getElement(this.ID.PICKER_BG),this.getElement(this.ID.PICKER_THUMB),0,j,0,j);this.pickerSlider.subscribe("change",H,this,true);this.set(m.ANIMATE,this.get(m.ANIMATE));f.on(this.getElement(this.ID.WEBSAFE_SWATCH),"click",function(i){this.setValue(this.get(m.WEBSAFE));},this,true);f.on(this.getElement(this.ID.CONTROLS_LABEL),"click",function(i){this.set(m.SHOW_CONTROLS,!this.get(m.SHOW_CONTROLS));f.preventDefault(i);},this,true);c.call(this,this.ID.R,this.OPT.RED);c.call(this,this.ID.G,this.OPT.GREEN);c.call(this,this.ID.B,this.OPT.BLUE);c.call(this,this.ID.H,this.OPT.HUE);c.call(this,this.ID.S,this.OPT.SATURATION);c.call(this,this.ID.V,this.OPT.VALUE);f.on(this.getElement(this.ID.HEX),"keydown",function(o,i){A.call(i,o,this,i.OPT.HEX);
+},this);f.on(this.getElement(this.ID.HEX),"keypress",L,this);f.on(this.getElement(this.ID.HEX),"blur",function(o,i){I.call(i,o,this,i.OPT.HEX);},this);F.call(this);};var U=function(){var h=[this.get(this.OPT.HUE),this.get(this.OPT.SATURATION)/100,this.get(this.OPT.VALUE)/100];var b=e.hsv2rgb(h);this.set(this.OPT.RGB,b);T.call(this);};var V=function(){var k=this.get(this.OPT.HEX),b=k.length;if(b===3){var m=k.split(""),j;for(j=0;j<b;j=j+1){m[j]=m[j]+m[j];}k=m.join("");}if(k.length!==6){return false;}var h=e.hex2rgb(k);this.setValue(h);};Q.initAttributes=function(b){b=b||{};YAHOO.widget.ColorPicker.superclass.initAttributes.call(this,b);this.setAttributeConfig(this.OPT.PICKER_SIZE,{value:b.size||this.DEFAULT.PICKER_SIZE});this.setAttributeConfig(this.OPT.HUE,{value:b.hue||0,validator:g.isNumber});this.setAttributeConfig(this.OPT.SATURATION,{value:b.saturation||0,validator:g.isNumber});this.setAttributeConfig(this.OPT.VALUE,{value:g.isNumber(b.value)?b.value:100,validator:g.isN!
 umber});this.setAttributeConfig(this.OPT.RED,{value:g.isNumber(b.red)?b.red:255,validator:g.isNumber});this.setAttributeConfig(this.OPT.GREEN,{value:g.isNumber(b.green)?b.green:255,validator:g.isNumber});this.setAttributeConfig(this.OPT.BLUE,{value:g.isNumber(b.blue)?b.blue:255,validator:g.isNumber});this.setAttributeConfig(this.OPT.HEX,{value:b.hex||"FFFFFF",validator:g.isString});this.setAttributeConfig(this.OPT.RGB,{value:b.rgb||[255,255,255],method:function(l){this.set(this.OPT.RED,l[0],true);this.set(this.OPT.GREEN,l[1],true);this.set(this.OPT.BLUE,l[2],true);var n=e.websafe(l);this.set(this.OPT.WEBSAFE,n,true);var m=e.rgb2hex(l);this.set(this.OPT.HEX,m,true);var i=e.rgb2hsv(l);this.set(this.OPT.HUE,i[0],true);this.set(this.OPT.SATURATION,Math.round(i[1]*100),true);this.set(this.OPT.VALUE,Math.round(i[2]*100),true);},readonly:true});this.setAttributeConfig(this.OPT.CONTAINER,{value:null,method:function(i){if(i){i.showEvent.subscribe(function(){this.pickerSlider.focus()!
 ;},this,true);}}});this.setAttributeConfig(this.OPT.WEBSAFE,{v!
 alue:b.w
ebsafe||[255,255,255]});var j=b.ids||g.merge({},this.ID);if(!b.ids&&E>1){for(var h in j){if(g.hasOwnProperty(j,h)){j[h]=j[h]+E;}}}this.setAttributeConfig(this.OPT.IDS,{value:j,writeonce:true});this.setAttributeConfig(this.OPT.TXT,{value:b.txt||this.TXT,writeonce:true});this.setAttributeConfig(this.OPT.IMAGES,{value:b.images||this.IMAGE,writeonce:true});this.setAttributeConfig(this.OPT.ELEMENTS,{value:{},readonly:true});var k=function(m,i){var l=(g.isString(m)?this.getElement(m):m);C.setStyle(l,"display",(i)?"":"none");};this.setAttributeConfig(this.OPT.SHOW_CONTROLS,{value:g.isBoolean(b.showcontrols)?b.showcontrols:true,method:function(i){var l=C.getElementsByClassName("bd","div",this.getElement(this.ID.CONTROLS))[0];k.call(this,l,i);this.getElement(this.ID.CONTROLS_LABEL).innerHTML=(i)?this.get(this.OPT.TXT).HIDE_CONTROLS:this.get(this.OPT.TXT).SHOW_CONTROLS;}});this.setAttributeConfig(this.OPT.SHOW_RGB_CONTROLS,{value:g.isBoolean(b.showrgbcontrols)?b.showrgbcontrols:true,m!
 ethod:function(i){k.call(this,this.ID.RGB_CONTROLS,i);}});this.setAttributeConfig(this.OPT.SHOW_HSV_CONTROLS,{value:g.isBoolean(b.showhsvcontrols)?b.showhsvcontrols:false,method:function(i){k.call(this,this.ID.HSV_CONTROLS,i);if(i&&this.get(this.OPT.SHOW_HEX_SUMMARY)){this.set(this.OPT.SHOW_HEX_SUMMARY,false);}}});this.setAttributeConfig(this.OPT.SHOW_HEX_CONTROLS,{value:g.isBoolean(b.showhexcontrols)?b.showhexcontrols:false,method:function(i){k.call(this,this.ID.HEX_CONTROLS,i);}});this.setAttributeConfig(this.OPT.SHOW_WEBSAFE,{value:g.isBoolean(b.showwebsafe)?b.showwebsafe:true,method:function(i){k.call(this,this.ID.WEBSAFE_SWATCH,i);}});this.setAttributeConfig(this.OPT.SHOW_HEX_SUMMARY,{value:g.isBoolean(b.showhexsummary)?b.showhexsummary:true,method:function(i){k.call(this,this.ID.HEX_SUMMARY,i);if(i&&this.get(this.OPT.SHOW_HSV_CONTROLS)){this.set(this.OPT.SHOW_HSV_CONTROLS,false);}}});this.setAttributeConfig(this.OPT.ANIMATE,{value:g.isBoolean(b.animate)?b.animate:true!
 ,method:function(i){this.pickerSlider.animate=i;this.hueSlider!
 .animate
=i;}});this.on(this.OPT.HUE+"Change",U,this,true);this.on(this.OPT.SATURATION+"Change",U,this,true);this.on(this.OPT.VALUE+"Change",d,this,true);this.on(this.OPT.RED+"Change",F,this,true);this.on(this.OPT.GREEN+"Change",F,this,true);this.on(this.OPT.BLUE+"Change",F,this,true);this.on(this.OPT.HEX+"Change",V,this,true);this.initPicker();};})();YAHOO.register("colorpicker",YAHOO.widget.ColorPicker,{version:"2.5.1",build:"984"});
\ No newline at end of file

Added: trunk/root/static/yui/colorpicker/colorpicker.js
===================================================================
--- trunk/root/static/yui/colorpicker/colorpicker.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/colorpicker/colorpicker.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,1735 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * Provides color conversion and validation utils
+ * @class YAHOO.util.Color
+ * @namespace YAHOO.util
+ */
+YAHOO.util.Color = function() {
+
+    var HCHARS="0123456789ABCDEF", lang=YAHOO.lang;
+
+    return {
+
+        /**
+         * Converts 0-1 to 0-255
+         * @method real2dec
+         * @param n {float} the number to convert
+         * @return {int} a number 0-255
+         */
+        real2dec: function(n) {
+            return Math.min(255, Math.round(n*256));
+        },
+
+        /**
+         * Converts HSV (h[0-360], s[0-1]), v[0-1] to RGB [255,255,255]
+         * @method hsv2rgb
+         * @param h {int|[int, float, float]} the hue, or an
+         *        array containing all three parameters
+         * @param s {float} the saturation
+         * @param v {float} the value/brightness
+         * @return {[int, int, int]} the red, green, blue values in
+         *          decimal.
+         */
+        hsv2rgb: function(h, s, v) { 
+
+            if (lang.isArray(h)) {
+                return this.hsv2rgb.call(this, h[0], h[1], h[2]);
+            }
+
+            var r, g, b, i, f, p, q, t;
+            i = Math.floor((h/60)%6);
+            f = (h/60)-i;
+            p = v*(1-s);
+            q = v*(1-f*s);
+            t = v*(1-(1-f)*s);
+            switch(i) {
+                case 0: r=v; g=t; b=p; break;
+                case 1: r=q; g=v; b=p; break;
+                case 2: r=p; g=v; b=t; break;
+                case 3: r=p; g=q; b=v; break;
+                case 4: r=t; g=p; b=v; break;
+                case 5: r=v; g=p; b=q; break;
+            }
+
+            var fn=this.real2dec;
+
+            return [fn(r), fn(g), fn(b)];
+        },
+
+        /**
+         * Converts to RGB [255,255,255] to HSV (h[0-360], s[0-1]), v[0-1]
+         * @method rgb2hsv
+         * @param r {int|[int, int, int]} the red value, or an
+         *        array containing all three parameters
+         * @param g {int} the green value
+         * @param b {int} the blue value
+         * @return {[int, float, float]} the value converted to hsv
+         */
+        rgb2hsv: function(r, g, b) {
+
+            if (lang.isArray(r)) {
+                return this.rgb2hsv.call(this, r[0], r[1], r[2]);
+            }
+
+            r=r/255;
+            g=g/255;
+            b=b/255;
+
+            var min,max,delta,h,s,v;
+            min = Math.min(Math.min(r,g),b);
+            max = Math.max(Math.max(r,g),b);
+            delta = max-min;
+
+            switch (max) {
+                case min: h=0; break;
+                case r:   h=60*(g-b)/delta; 
+                          if (g<b) {
+                              h+=360;
+                          }
+                          break;
+                case g:   h=(60*(b-r)/delta)+120; break;
+                case b:   h=(60*(r-g)/delta)+240; break;
+            }
+            
+            s = (max === 0) ? 0 : 1-(min/max);
+
+            var hsv = [Math.round(h), s, max];
+
+            return hsv;
+
+        },
+
+        /**
+         * Converts decimal rgb values into a hex string
+         * 255,255,255 -> FFFFFF
+         * @method rgb2hex
+         * @param r {int|[int, int, int]} the red value, or an
+         *        array containing all three parameters
+         * @param g {int} the green value
+         * @param b {int} the blue value
+         * @return {string} the hex string
+         */
+        rgb2hex: function(r, g, b) {
+            if (lang.isArray(r)) {
+                return this.rgb2hex.call(this, r[0], r[1], r[2]);
+            }
+
+            var f=this.dec2hex;
+            return f(r) + f(g) + f(b);
+        },
+     
+        /**
+         * Converts an int 0...255 to hex pair 00...FF
+         * @method dec2hex
+         * @param n {int} the number to convert
+         * @return {string} the hex equivalent
+         */
+        dec2hex: function(n) {
+            n = parseInt(n, 10);
+            n = (lang.isNumber(n)) ? n : 0;
+            n = (n > 255 || n < 0) ? 0 : n;
+
+            return HCHARS.charAt((n - n % 16) / 16) + HCHARS.charAt(n % 16);
+        },
+
+        /**
+         * Converts a hex pair 00...FF to an int 0...255 
+         * @method hex2dec
+         * @param str {string} the hex pair to convert
+         * @return {int} the decimal
+         */
+        hex2dec: function(str) {
+            var f = function(c) {
+                return HCHARS.indexOf(c.toUpperCase());
+            };
+
+            var s=str.split('');
+            
+            return ((f(s[0]) * 16) + f(s[1]));
+        },
+
+        /**
+         * Converts a hex string to rgb
+         * @method hex2rgb
+         * @param str {string} the hex string
+         * @return {[int, int, int]} an array containing the rgb values
+         */
+        hex2rgb: function(s) { 
+            var f = this.hex2dec;
+            return [f(s.substr(0, 2)), f(s.substr(2, 2)), f(s.substr(4, 2))];
+        },
+
+        /**
+         * Returns the closest websafe color to the supplied rgb value.
+         * @method websafe
+         * @param r {int|[int, int, int]} the red value, or an
+         *        array containing all three parameters
+         * @param g {int} the green value
+         * @param b {int} the blue value
+         * @return {[int, int, int]} an array containing the closes
+         *                           websafe rgb colors.
+         */
+        websafe: function(r, g, b) {
+
+            if (lang.isArray(r)) {
+                return this.websafe.call(this, r[0], r[1], r[2]);
+            }
+
+            // returns the closest match [0, 51, 102, 153, 204, 255]
+            var f = function(v) {
+                if (lang.isNumber(v)) {
+                    v = Math.min(Math.max(0, v), 255);
+                    var i, next;
+                    for (i=0; i<256; i=i+51) {
+                        next = i+51;
+                        if (v >= i && v <= next) {
+                            return (v-i > 25) ? next : i;
+                        }
+                    }
+                }
+
+                return v;
+            };
+
+            return [f(r), f(g), f(b)];
+        }
+    };
+}();
+
+
+(function() {
+
+    var _pickercount = 0;
+
+    /**
+     * The colorpicker module provides a widget for selecting colors
+     * @module colorpicker
+     * @requires yahoo, dom, event, element, slider
+     */
+
+
+    /**
+     * Creates the host element if it doesn't exist
+     * @method _createHostElement
+     * @private
+     */
+    var _createHostElement = function() {
+        var el = document.createElement('div');
+
+        if (this.CSS.BASE) {
+            el.className = this.CSS.BASE;
+        }
+        
+        return el;
+    };
+
+    /**
+     * A widget to select colors
+     * @namespace YAHOO.widget
+     * @class YAHOO.widget.ColorPicker
+     * @extends YAHOO.util.Element
+     * @constructor
+     * @param {HTMLElement | String | Object} el(optional) The html 
+     * element that represents the colorpicker, or the attribute object to use. 
+     * An element will be created if none provided.
+     * @param {Object} attr (optional) A key map of the colorpicker's 
+     * initial attributes.  Ignored if first arg is attributes object.
+     */
+    YAHOO.widget.ColorPicker = function(el, attr) {
+        _pickercount = _pickercount + 1;
+        attr = attr || {};
+        if (arguments.length === 1 && !YAHOO.lang.isString(el) && !el.nodeName) {
+            attr = el; // treat first arg as attr object
+            el = attr.element || null;
+        }
+        
+        if (!el && !attr.element) { // create if we dont have one
+            el = _createHostElement.call(this, attr);
+        }
+
+    	YAHOO.widget.ColorPicker.superclass.constructor.call(this, el, attr); 
+    };
+
+    YAHOO.extend(YAHOO.widget.ColorPicker, YAHOO.util.Element);
+    
+    var proto = YAHOO.widget.ColorPicker.prototype,
+        Slider=YAHOO.widget.Slider,
+        Color=YAHOO.util.Color,
+        Dom = YAHOO.util.Dom,
+        Event = YAHOO.util.Event,
+        lang = YAHOO.lang,
+        sub = lang.substitute;
+    
+
+    var b = "yui-picker";
+
+    /**
+     * The element ids used by this control
+     * @property ID
+     * @final
+     */
+    proto.ID = {
+
+        /**
+         * The id for the "red" form field
+         * @property ID.R
+         * @type String
+         * @final
+         * @default yui-picker-r
+         */
+        R: b + "-r",
+
+        /**
+         * The id for the "red" hex pair output
+         * @property ID.R_HEX
+         * @type String
+         * @final
+         * @default yui-picker-rhex
+         */
+        R_HEX: b + "-rhex",
+
+        /**
+         * The id for the "green" form field
+         * @property ID.G
+         * @type String
+         * @final
+         * @default yui-picker-g
+         */
+        G: b + "-g",
+
+        /**
+         * The id for the "green" hex pair output
+         * @property ID.G_HEX
+         * @type String
+         * @final
+         * @default yui-picker-ghex
+         */
+        G_HEX: b + "-ghex",
+
+
+        /**
+         * The id for the "blue" form field
+         * @property ID.B
+         * @type String
+         * @final
+         * @default yui-picker-b
+         */
+        B: b + "-b",
+
+        /**
+         * The id for the "blue" hex pair output
+         * @property ID.B_HEX
+         * @type String
+         * @final
+         * @default yui-picker-bhex
+         */
+        B_HEX: b + "-bhex",
+
+        /**
+         * The id for the "hue" form field
+         * @property ID.H
+         * @type String
+         * @final
+         * @default yui-picker-h
+         */
+        H: b + "-h",
+
+        /**
+         * The id for the "saturation" form field
+         * @property ID.S
+         * @type String
+         * @final
+         * @default yui-picker-s
+         */
+        S: b + "-s",
+
+        /**
+         * The id for the "value" form field
+         * @property ID.V
+         * @type String
+         * @final
+         * @default yui-picker-v
+         */
+        V: b + "-v",
+
+        /**
+         * The id for the picker region slider
+         * @property ID.PICKER_BG
+         * @type String
+         * @final
+         * @default yui-picker-bg
+         */
+        PICKER_BG:      b + "-bg",
+
+        /**
+         * The id for the picker region thumb
+         * @property ID.PICKER_THUMB
+         * @type String
+         * @final
+         * @default yui-picker-thumb
+         */
+        PICKER_THUMB:   b + "-thumb",
+
+        /**
+         * The id for the hue slider
+         * @property ID.HUE_BG
+         * @type String
+         * @final
+         * @default yui-picker-hue-bg
+         */
+        HUE_BG:         b + "-hue-bg",
+
+        /**
+         * The id for the hue thumb
+         * @property ID.HUE_THUMB
+         * @type String
+         * @final
+         * @default yui-picker-hue-thumb
+         */
+        HUE_THUMB:      b + "-hue-thumb",
+
+        /**
+         * The id for the hex value form field
+         * @property ID.HEX
+         * @type String
+         * @final
+         * @default yui-picker-hex
+         */
+        HEX:            b + "-hex",
+
+        /**
+         * The id for the color swatch
+         * @property ID.SWATCH
+         * @type String
+         * @final
+         * @default yui-picker-swatch
+         */
+        SWATCH:         b + "-swatch",
+
+        /**
+         * The id for the websafe color swatch
+         * @property ID.WEBSAFE_SWATCH
+         * @type String
+         * @final
+         * @default yui-picker-websafe-swatch
+         */
+        WEBSAFE_SWATCH: b + "-websafe-swatch",
+
+        /**
+         * The id for the control details
+         * @property ID.CONTROLS
+         * @final
+         * @default yui-picker-controls
+         */
+        CONTROLS: b + "-controls",
+
+        /**
+         * The id for the rgb controls
+         * @property ID.RGB_CONTROLS
+         * @final
+         * @default yui-picker-rgb-controls
+         */
+        RGB_CONTROLS: b + "-rgb-controls",
+
+        /**
+         * The id for the hsv controls
+         * @property ID.HSV_CONTROLS
+         * @final
+         * @default yui-picker-hsv-controls
+         */
+        HSV_CONTROLS: b + "-hsv-controls",
+        
+        /**
+         * The id for the hsv controls
+         * @property ID.HEX_CONTROLS
+         * @final
+         * @default yui-picker-hex-controls
+         */
+        HEX_CONTROLS: b + "-hex-controls",
+
+        /**
+         * The id for the hex summary
+         * @property ID.HEX_SUMMARY
+         * @final
+         * @default yui-picker-hex-summary
+         */
+        HEX_SUMMARY: b + "-hex-summary",
+
+        /**
+         * The id for the controls section header
+         * @property ID.CONTROLS_LABEL
+         * @final
+         * @default yui-picker-controls-label
+         */
+        CONTROLS_LABEL: b + "-controls-label"
+    };
+
+    /**
+     * Constants for any script-generated messages.  The values here
+     * are the default messages.  They can be updated by providing
+     * the complete list to the constructor for the "txt" attribute.
+     * @property TXT
+     * @final
+     */
+    proto.TXT = {
+        ILLEGAL_HEX: "Illegal hex value entered",
+        SHOW_CONTROLS: "Show color details",
+        HIDE_CONTROLS: "Hide color details",
+        CURRENT_COLOR: "Currently selected color: {rgb}",
+        CLOSEST_WEBSAFE: "Closest websafe color: {rgb}. Click to select.",
+        R: "R",
+        G: "G",
+        B: "B",
+        H: "H",
+        S: "S",
+        V: "V",
+        HEX: "#",
+        DEG: "\u00B0",
+        PERCENT: "%"
+    };
+
+    /**
+     * Constants for the default image locations for img tags that are
+     * generated by the control.  They can be modified by passing the
+     * complete list to the contructor for the "images" attribute
+     * @property IMAGE
+     * @final
+     */
+    proto.IMAGE = {
+        PICKER_THUMB: "../../build/colorpicker/assets/picker_thumb.png",
+        HUE_THUMB: "../../build/colorpicker/assets/hue_thumb.png"
+    };
+
+    /*
+     * Constants for the control's custom event names.  subscribe
+     * to the rgbChange event instead.
+     * @property EVENT
+     * @final
+     */
+    //proto.EVENT = {
+        //CHANGE: "change"
+    //};
+
+    //proto.CSS = { };
+
+    /**
+     * Constants for the control's default default values
+     * @property DEFAULT
+     * @final
+     */
+    proto.DEFAULT = {
+        PICKER_SIZE: 180
+    };
+
+    /**
+     * Constants for the control's configuration attributes
+     * @property OPT
+     * @final
+     */
+    proto.OPT = {
+        HUE: "hue",
+        SATURATION: "saturation",
+        VALUE: "value",
+        RED: "red",
+        GREEN: "green",
+        BLUE: "blue",
+        HSV: "hsv",
+        RGB: "rgb",
+        WEBSAFE: "websafe",
+        HEX: "hex",
+        PICKER_SIZE: "pickersize",
+        SHOW_CONTROLS: "showcontrols",
+        SHOW_RGB_CONTROLS: "showrgbcontrols",
+        SHOW_HSV_CONTROLS: "showhsvcontrols",
+        SHOW_HEX_CONTROLS: "showhexcontrols",
+        SHOW_HEX_SUMMARY: "showhexsummary",
+        SHOW_WEBSAFE: "showwebsafe",
+        //SHOW_SUBMIT: "showsubmit",
+        CONTAINER: "container",
+        IDS: "ids",
+        ELEMENTS: "elements",
+        TXT: "txt",
+        IMAGES: "images",
+        ANIMATE: "animate"
+    };
+
+    /**
+     * Moves the hue slider into the position dictated by the current state
+     * of the control
+     * @method _updateHueSlider
+     * @private
+     */
+    var _updateHueSlider = function() {
+        var size = this.get(this.OPT.PICKER_SIZE),
+            h = this.get(this.OPT.HUE);
+
+        h = size - Math.round(h / 360 * size);
+        
+        // 0 is at the top and bottom of the hue slider.  Always go to
+        // the top so we don't end up sending the thumb to the bottom
+        // when the value didn't actually change (e.g., a conversion
+        // produced 360 instead of 0 and the value was already 0).
+        if (h === size) {
+            h = 0;
+        }
+
+        this.hueSlider.setValue(h);
+    };
+
+    /**
+     * Moves the picker slider into the position dictated by the current state
+     * of the control
+     * @method _updatePickerSlider
+     * @private
+     */
+    var _updatePickerSlider = function() {
+        var size = this.get(this.OPT.PICKER_SIZE),
+            s = this.get(this.OPT.SATURATION),
+            v = this.get(this.OPT.VALUE);
+
+        s = Math.round(s * size / 100);
+        v = Math.round(size - (v * size / 100));
+
+
+        this.pickerSlider.setRegionValue(s, v);
+    };
+
+    /**
+     * Moves the sliders into the position dictated by the current state
+     * of the control
+     * @method _updateSliders
+     * @private
+     */
+    var _updateSliders = function() {
+        _updateHueSlider.call(this);
+        _updatePickerSlider.call(this);
+    };
+
+    /**
+     * Sets the control to the specified rgb value and
+     * moves the sliders to the proper positions
+     * @method setValue
+     * @param rgb {[int, int, int]} the rgb value
+     * @param silent {boolean} whether or not to fire the change event
+     */
+    proto.setValue = function(rgb, silent) {
+        silent = (silent) || false;
+        this.set(this.OPT.RGB, rgb, silent);
+        _updateSliders.call(this);
+    };
+
+    /**
+     * The hue slider
+     * @property hueSlider
+     * @type YAHOO.widget.Slider
+     */
+    proto.hueSlider = null; 
+    
+    /**
+     * The picker region
+     * @property pickerSlider
+     * @type YAHOO.widget.Slider
+     */
+    proto.pickerSlider = null;
+
+    /**
+     * Translates the slider value into hue, int[0,359]
+     * @method _getH
+     * @private
+     * @return {int} the hue from 0 to 359
+     */
+    var _getH = function() {
+        var size = this.get(this.OPT.PICKER_SIZE),
+            h = (size - this.hueSlider.getValue()) / size;
+        h = Math.round(h*360);
+        return (h === 360) ? 0 : h;
+    };
+
+    /**
+     * Translates the slider value into saturation, int[0,1], left to right
+     * @method _getS
+     * @private
+     * @return {int} the saturation from 0 to 1
+     */
+    var _getS = function() {
+        return this.pickerSlider.getXValue() / this.get(this.OPT.PICKER_SIZE);
+    };
+
+    /**
+     * Translates the slider value into value/brightness, int[0,1], top
+     * to bottom
+     * @method _getV
+     * @private
+     * @return {int} the value from 0 to 1
+     */
+    var _getV = function() {
+        var size = this.get(this.OPT.PICKER_SIZE);
+        return (size - this.pickerSlider.getYValue()) / size;
+    };
+
+    /**
+     * Updates the background of the swatch with the current rbg value.
+     * Also updates the websafe swatch to the closest websafe color
+     * @method _updateSwatch
+     * @private
+     */
+    var _updateSwatch = function() {
+        var rgb = this.get(this.OPT.RGB),
+            websafe = this.get(this.OPT.WEBSAFE),
+            el = this.getElement(this.ID.SWATCH),
+            color = rgb.join(","),
+            txt = this.get(this.OPT.TXT);
+
+        Dom.setStyle(el, "background-color", "rgb(" + color  + ")");
+        el.title = lang.substitute(txt.CURRENT_COLOR, {
+                "rgb": "#" + this.get(this.OPT.HEX)
+            });
+
+
+        el = this.getElement(this.ID.WEBSAFE_SWATCH);
+        color = websafe.join(",");
+
+        Dom.setStyle(el, "background-color", "rgb(" + color + ")");
+        el.title = lang.substitute(txt.CLOSEST_WEBSAFE, {
+                "rgb": "#" + Color.rgb2hex(websafe)
+            });
+
+    };
+
+    /**
+     * Reads the sliders and converts the values to RGB, updating the
+     * internal state for all the individual form fields
+     * @method _getValuesFromSliders
+     * @private
+     */
+    var _getValuesFromSliders = function() {
+        var h=_getH.call(this), s=_getS.call(this), v=_getV.call(this);
+
+        var rgb = Color.hsv2rgb(h, s, v);
+        //var websafe = Color.websafe(rgb);
+        //var hex = Color.rgb2hex(rgb[0], rgb[1], rgb[2]);
+
+        this.set(this.OPT.RGB, rgb);
+    };
+
+    /**
+     * Updates the form field controls with the state data contained
+     * in the control.
+     * @method _updateFormFields
+     * @private
+     */
+    var _updateFormFields = function() {
+        this.getElement(this.ID.H).value = this.get(this.OPT.HUE);
+        this.getElement(this.ID.S).value = this.get(this.OPT.SATURATION);
+        this.getElement(this.ID.V).value = this.get(this.OPT.VALUE);
+        this.getElement(this.ID.R).value = this.get(this.OPT.RED);
+        this.getElement(this.ID.R_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.RED));
+        this.getElement(this.ID.G).value = this.get(this.OPT.GREEN);
+        this.getElement(this.ID.G_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.GREEN));
+        this.getElement(this.ID.B).value = this.get(this.OPT.BLUE);
+        this.getElement(this.ID.B_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.BLUE));
+        this.getElement(this.ID.HEX).value = this.get(this.OPT.HEX);
+    };
+
+    /**
+     * Event handler for the hue slider.
+     * @method _onHueSliderChange
+     * @param newOffset {int} pixels from the start position
+     * @private
+     */
+    var _onHueSliderChange = function(newOffset) {
+
+        var h = _getH.call(this);
+        this.set(this.OPT.HUE, h, true);
+
+        // set picker background to the hue
+        var rgb = Color.hsv2rgb(h, 1, 1);
+        var styleDef = "rgb(" + rgb.join(",") + ")";
+
+        Dom.setStyle(this.getElement(this.ID.PICKER_BG), "background-color", styleDef);
+
+        if (this.hueSlider.valueChangeSource === this.hueSlider.SOURCE_UI_EVENT) {
+            _getValuesFromSliders.call(this);
+        }
+
+        _updateFormFields.call(this);
+        _updateSwatch.call(this);
+    };
+
+    /**
+     * Event handler for the picker slider, which controls the
+     * saturation and value/brightness.
+     * @method _onPickerSliderChange
+     * @param newOffset {{x: int, y: int}} x/y pixels from the start position
+     * @private
+     */
+    var _onPickerSliderChange = function(newOffset) {
+
+        var s=_getS.call(this), v=_getV.call(this);
+        this.set(this.OPT.SATURATION, Math.round(s*100), true);
+        this.set(this.OPT.VALUE, Math.round(v*100), true);
+
+        if (this.pickerSlider.valueChangeSource === this.pickerSlider.SOURCE_UI_EVENT) {
+            _getValuesFromSliders.call(this);
+        }
+
+        _updateFormFields.call(this);
+        _updateSwatch.call(this);
+    };
+
+
+    /**
+     * Key map to well-known commands for txt field input
+     * @method _getCommand
+     * @param e {Event} the keypress or keydown event
+     * @return {int} a command code
+     * <ul>
+     * <li>0 = not a number, letter in range, or special key</li>
+     * <li>1 = number</li>
+     * <li>2 = a-fA-F</li>
+     * <li>3 = increment (up arrow)</li>
+     * <li>4 = decrement (down arrow)</li>
+     * <li>5 = special key (tab, delete, return, escape, left, right)</li> 
+     * <li>6 = return</li>
+     * </ul>
+     * @private
+     */
+    var _getCommand = function(e) {
+        var c = Event.getCharCode(e);
+
+        //alert(Event.getCharCode(e) + ", " + e.keyCode + ", " + e.charCode);
+
+        // special keys
+        if (c === 38) { // up arrow
+            return 3;
+        } else if (c === 13) { // return
+            return 6;
+        } else if (c === 40) { // down array
+            return 4;
+        } else if (c >= 48 && c<=57) { // 0-9
+            return 1;
+        } else if (c >= 97 && c<=102) { // a-f
+            return 2;
+        } else if (c >= 65 && c<=70) { // A-F
+            return 2;
+        //} else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1 || 
+        //              (c >= 112 && c <=123)) { // including F-keys
+        // tab, delete, return, escape, left, right
+        } else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1) { // special chars
+            return 5;
+        } else { // something we probably don't want
+            return 0;
+        }
+    };
+
+    /**
+     * Use the value of the text field to update the control
+     * @method _hexFieldKeypress
+     * @param e {Event} an event
+     * @param el {HTMLElement} the field
+     * @param prop {string} the key to the linked property
+     * @private
+     */
+    var _useFieldValue = function(e, el, prop) {
+        var val = el.value;
+
+        if (prop !== this.OPT.HEX) {
+            val = parseInt(val, 10);
+        }
+
+        if (val !== this.get(prop)) {
+            this.set(prop, val);
+        }
+    };
+
+    /**
+     * Handle keypress on one of the rgb or hsv fields.
+     * @method _rgbFieldKeypress
+     * @param e {Event} the keypress event
+     * @param el {HTMLElement} the field
+     * @param prop {string} the key to the linked property
+     * @private
+     */
+    var _rgbFieldKeypress = function(e, el, prop) {
+        var command = _getCommand(e);
+        var inc = (e.shiftKey) ? 10 : 1;
+        switch (command) {
+            case 6: // return, update the value
+                _useFieldValue.apply(this, arguments);
+                break;
+                        
+            case 3: // up arrow, increment
+                this.set(prop, Math.min(this.get(prop)+inc, 255));
+                _updateFormFields.call(this);
+                //Event.stopEvent(e);
+                break;
+            case 4: // down arrow, decrement
+                this.set(prop, Math.max(this.get(prop)-inc, 0));
+                _updateFormFields.call(this);
+                //Event.stopEvent(e);
+                break;
+
+            default:
+        }
+
+    };
+
+    /**
+     * Handle keydown on the hex field
+     * @method _hexFieldKeypress
+     * @param e {Event} the keypress event
+     * @param el {HTMLElement} the field
+     * @param prop {string} the key to the linked property
+     * @private
+     */
+    var _hexFieldKeypress = function(e, el, prop) {
+        var command = _getCommand(e);
+        if (command === 6) { // return, update the value
+            _useFieldValue.apply(this, arguments);
+        }
+    };
+
+    /** 
+     * Allows numbers and special chars, and by default allows a-f.  
+     * Used for the hex field keypress handler.
+     * @method _hexOnly
+     * @param e {Event} the event
+     * @param numbersOnly omits a-f if set to true
+     * @private
+     * @return {boolean} false if we are canceling the event
+     */
+    var _hexOnly = function(e, numbersOnly) {
+        var command = _getCommand(e);
+        switch (command) {
+            case 6: // return
+            case 5: // special char
+            case 1: // number
+                break;
+            case 2: // hex char (a-f)
+                if (numbersOnly !== true) {
+                    break;
+                }
+
+                // fallthrough is intentional
+
+            default: // prevent alpha and punctuation
+                Event.stopEvent(e);
+                return false;
+        }
+    };
+
+    /** 
+     * Allows numbers and special chars only.  Used for the
+     * rgb and hsv fields keypress handler.
+     * @method _numbersOnly
+     * @param e {Event} the event
+     * @private
+     * @return {boolean} false if we are canceling the event
+     */
+    var _numbersOnly = function(e) {
+        return _hexOnly(e, true);
+    };
+
+    /**
+     * Returns the element reference that is saved.  The id can be either
+     * the element id, or the key for this id in the "id" config attribute.
+     * For instance, the host element id can be obtained by passing its
+     * id (default: "yui_picker") or by its key "YUI_PICKER".
+     * @param id {string} the element id, or key 
+     * @return {HTMLElement} a reference to the element
+     */
+    proto.getElement = function(id) { 
+        return this.get(this.OPT.ELEMENTS)[this.get(this.OPT.IDS)[id]]; 
+    };
+
+    var _createElements = function() {
+        var el, child, img, fld, i, 
+            ids = this.get(this.OPT.IDS),
+            txt = this.get(this.OPT.TXT),
+            images = this.get(this.OPT.IMAGES),
+            Elem = function(type, o) {
+                var n = document.createElement(type);
+                if (o) {
+                    lang.augmentObject(n, o, true);
+                }
+                return n;
+            },
+            RGBElem = function(type, obj) {
+                var o = lang.merge({
+                        //type: "txt",
+                        autocomplete: "off",
+                        value: "0",
+                        size: 3,
+                        maxlength: 3
+                    }, obj);
+
+                o.name = o.id;
+                return new Elem(type, o);
+            };
+
+        var p = this.get("element");
+
+        // Picker slider (S and V) ---------------------------------------------
+
+        el = new Elem("div", {
+            id: ids[this.ID.PICKER_BG],
+            className: "yui-picker-bg",
+            tabIndex: -1,
+            hideFocus: true
+        });
+
+        child = new Elem("div", {
+            id: ids[this.ID.PICKER_THUMB],
+            className: "yui-picker-thumb"
+        });
+
+        img = new Elem("img", {
+            src: images.PICKER_THUMB
+        });
+
+        child.appendChild(img);
+        el.appendChild(child);
+        p.appendChild(el);
+        
+        // Hue slider ---------------------------------------------
+        el = new Elem("div", {
+            id: ids[this.ID.HUE_BG],
+            className: "yui-picker-hue-bg",
+            tabIndex: -1,
+            hideFocus: true
+        });
+
+        child = new Elem("div", {
+            id: ids[this.ID.HUE_THUMB],
+            className: "yui-picker-hue-thumb"
+        });
+
+        img = new Elem("img", {
+            src: images.HUE_THUMB
+        });
+
+        child.appendChild(img);
+        el.appendChild(child);
+        p.appendChild(el);
+
+
+        // controls ---------------------------------------------
+
+        el = new Elem("div", {
+            id: ids[this.ID.CONTROLS],
+            className: "yui-picker-controls"
+        });
+
+        p.appendChild(el);
+        p = el;
+
+            // controls header
+            el = new Elem("div", {
+                className: "hd"
+            });
+
+            child = new Elem("a", {
+                id: ids[this.ID.CONTROLS_LABEL],
+                //className: "yui-picker-controls-label",
+                href: "#"
+            });
+            el.appendChild(child);
+            p.appendChild(el);
+
+            // bd
+            el = new Elem("div", {
+                className: "bd"
+            });
+
+            p.appendChild(el);
+            p = el;
+
+                // rgb
+                el = new Elem("ul", {
+                    id: ids[this.ID.RGB_CONTROLS],
+                    className: "yui-picker-rgb-controls"
+                });
+
+                child = new Elem("li");
+                child.appendChild(document.createTextNode(txt.R + " "));
+
+                fld = new RGBElem("input", {
+                    id: ids[this.ID.R],
+                    className: "yui-picker-r"
+                });
+
+                child.appendChild(fld);
+                el.appendChild(child);
+
+                child = new Elem("li");
+                child.appendChild(document.createTextNode(txt.G + " "));
+
+                fld = new RGBElem("input", {
+                    id: ids[this.ID.G],
+                    className: "yui-picker-g"
+                });
+
+                child.appendChild(fld);
+                el.appendChild(child);
+
+                child = new Elem("li");
+                child.appendChild(document.createTextNode(txt.B + " "));
+
+                fld = new RGBElem("input", {
+                    id: ids[this.ID.B],
+                    className: "yui-picker-b"
+                });
+
+                child.appendChild(fld);
+                el.appendChild(child);
+
+                p.appendChild(el);
+
+                // hsv
+                el = new Elem("ul", {
+                    id: ids[this.ID.HSV_CONTROLS],
+                    className: "yui-picker-hsv-controls"
+                });
+
+                child = new Elem("li");
+                child.appendChild(document.createTextNode(txt.H + " "));
+
+                fld = new RGBElem("input", {
+                    id: ids[this.ID.H],
+                    className: "yui-picker-h"
+                });
+
+                child.appendChild(fld);
+                child.appendChild(document.createTextNode(" " + txt.DEG));
+
+                el.appendChild(child);
+
+                child = new Elem("li");
+                child.appendChild(document.createTextNode(txt.S + " "));
+
+                fld = new RGBElem("input", {
+                    id: ids[this.ID.S],
+                    className: "yui-picker-s"
+                });
+
+                child.appendChild(fld);
+                child.appendChild(document.createTextNode(" " + txt.PERCENT));
+
+                el.appendChild(child);
+
+                child = new Elem("li");
+                child.appendChild(document.createTextNode(txt.V + " "));
+
+                fld = new RGBElem("input", {
+                    id: ids[this.ID.V],
+                    className: "yui-picker-v"
+                });
+
+                child.appendChild(fld);
+                child.appendChild(document.createTextNode(" " + txt.PERCENT));
+
+                el.appendChild(child);
+                p.appendChild(el);
+
+
+                // hex summary
+
+                el = new Elem("ul", {
+                    id: ids[this.ID.HEX_SUMMARY],
+                    className: "yui-picker-hex_summary"
+                });
+
+                child = new Elem("li", {
+                    id: ids[this.ID.R_HEX]
+                });
+                el.appendChild(child);
+
+                child = new Elem("li", {
+                    id: ids[this.ID.G_HEX]
+                });
+                el.appendChild(child);
+
+                child = new Elem("li", {
+                    id: ids[this.ID.B_HEX]
+                });
+                el.appendChild(child);
+                p.appendChild(el);
+
+                // hex field
+                el = new Elem("div", {
+                    id: ids[this.ID.HEX_CONTROLS],
+                    className: "yui-picker-hex-controls"
+                });
+                el.appendChild(document.createTextNode(txt.HEX + " "));
+
+                child = new RGBElem("input", {
+                    id: ids[this.ID.HEX],
+                    className: "yui-picker-hex",
+                    size: 6,
+                    maxlength: 6
+                });
+
+                el.appendChild(child);
+                p.appendChild(el);
+
+                p = this.get("element");
+
+                // swatch
+                el = new Elem("div", {
+                    id: ids[this.ID.SWATCH],
+                    className: "yui-picker-swatch"
+                });
+
+                p.appendChild(el);
+
+                // websafe swatch
+                el = new Elem("div", {
+                    id: ids[this.ID.WEBSAFE_SWATCH],
+                    className: "yui-picker-websafe-swatch"
+                });
+
+                p.appendChild(el);
+
+    };
+
+    var _attachRGBHSV = function(id, config) {
+        Event.on(this.getElement(id), "keydown", function(e, me) {
+                _rgbFieldKeypress.call(me, e, this, config);
+            }, this);
+        Event.on(this.getElement(id), "keypress", _numbersOnly, this);
+        Event.on(this.getElement(id), "blur", function(e, me) {
+                _useFieldValue.call(me, e, this, config);
+            }, this);
+    };
+
+
+    /**
+     * Updates the rgb attribute with the current state of the r,g,b
+     * fields.  This is invoked from change listeners on these
+     * attributes to facilitate updating these values from the
+     * individual form fields
+     * @method _updateRGB
+     * @private
+     */
+    var _updateRGB = function() {
+        var rgb = [this.get(this.OPT.RED), 
+                   this.get(this.OPT.GREEN),
+                   this.get(this.OPT.BLUE)];
+
+        this.set(this.OPT.RGB, rgb);
+
+        _updateSliders.call(this);
+    };
+
+    /**
+     * Sets the initial state of the sliders
+     * @method initPicker
+     */
+    proto.initPicker = function () {
+
+        // bind all of our elements
+        var o=this.OPT, 
+            ids = this.get(o.IDS), 
+            els = this.get(o.ELEMENTS), 
+                  i, el, id;
+
+        // Add the default value as a key for each element for easier lookup
+        for (i in this.ID) {
+            if (lang.hasOwnProperty(this.ID, i)) {
+                ids[this.ID[i]] = ids[i];
+            }
+        }
+
+        // Check for picker element, if not there, create all of them
+        el = Dom.get(ids[this.ID.PICKER_BG]);
+        if (!el) {
+            _createElements.call(this);
+        } else {
+        }
+
+        for (i in ids) {
+            if (lang.hasOwnProperty(ids, i)) {
+                // look for element
+                el = Dom.get(ids[i]);
+
+                // generate an id if the implementer passed in an element reference,
+                // and the element did not have an id already
+                id = Dom.generateId(el);
+
+                // update the id in case we generated the id
+                ids[i] = id; // key is WEBSAFE_SWATCH
+                ids[ids[i]] = id; // key is websafe_swatch
+
+                // store the dom ref
+                els[id] = el;
+            }
+        }
+
+        // set the initial visibility state of our controls
+            els = [o.SHOW_CONTROLS, 
+                   o.SHOW_RGB_CONTROLS,
+                   o.SHOW_HSV_CONTROLS,
+                   o.SHOW_HEX_CONTROLS,
+                   o.SHOW_HEX_SUMMARY,
+                   o.SHOW_WEBSAFE
+                   ];
+
+        for (i=0; i<els.length; i=i+1) {
+            this.set(els[i], this.get(els[i]));
+        }
+
+        var s = this.get(o.PICKER_SIZE);
+
+        this.hueSlider = Slider.getVertSlider(this.getElement(this.ID.HUE_BG), 
+                                              this.getElement(this.ID.HUE_THUMB), 0, s);
+        this.hueSlider.subscribe("change", _onHueSliderChange, this, true);
+
+        this.pickerSlider = Slider.getSliderRegion(this.getElement(this.ID.PICKER_BG), 
+                                                   this.getElement(this.ID.PICKER_THUMB), 0, s, 0, s);
+        this.pickerSlider.subscribe("change", _onPickerSliderChange, this, true);
+
+        // Set the animate state
+        this.set(o.ANIMATE,this.get(o.ANIMATE));
+
+        //_onHueSliderChange.call(this, 0);
+
+        Event.on(this.getElement(this.ID.WEBSAFE_SWATCH), "click", function(e) {
+               this.setValue(this.get(o.WEBSAFE));
+               //_updateSliders
+           }, this, true);
+
+        Event.on(this.getElement(this.ID.CONTROLS_LABEL), "click", function(e) {
+               this.set(o.SHOW_CONTROLS, !this.get(o.SHOW_CONTROLS));
+               Event.preventDefault(e);
+           }, this, true);
+
+        _attachRGBHSV.call(this, this.ID.R, this.OPT.RED); 
+        _attachRGBHSV.call(this, this.ID.G, this.OPT.GREEN); 
+        _attachRGBHSV.call(this, this.ID.B, this.OPT.BLUE); 
+        _attachRGBHSV.call(this, this.ID.H, this.OPT.HUE); 
+        _attachRGBHSV.call(this, this.ID.S, this.OPT.SATURATION); 
+        _attachRGBHSV.call(this, this.ID.V, this.OPT.VALUE); 
+
+        Event.on(this.getElement(this.ID.HEX), "keydown", function(e, me) {
+                _hexFieldKeypress.call(me, e, this, me.OPT.HEX);
+            }, this);
+
+        Event.on(this.getElement(this.ID.HEX), "keypress", _hexOnly, this);
+        Event.on(this.getElement(this.ID.HEX), "blur", function(e, me) {
+                _useFieldValue.call(me, e, this, me.OPT.HEX);
+            }, this);
+
+        _updateRGB.call(this);
+    };
+
+
+    /**
+     * Updates the RGB values from the current state of the HSV
+     * values.  Executed when the one of the HSV form fields are
+     * updated
+     * _updateRGBFromHSV
+     * @private
+     */
+    var _updateRGBFromHSV = function() {
+        var hsv = [this.get(this.OPT.HUE), 
+                   this.get(this.OPT.SATURATION)/100,
+                   this.get(this.OPT.VALUE)/100];
+
+        var rgb = Color.hsv2rgb(hsv);
+
+        this.set(this.OPT.RGB, rgb);
+
+        _updateSliders.call(this);
+    };
+
+    /**
+     * Parses the hex string to normalize shorthand values, converts
+     * the hex value to rgb and updates the rgb attribute (which
+     * updates the state for all of the other values)
+     * method _updateHex
+     * @private
+     */
+    var _updateHex = function() {
+       
+        var hex = this.get(this.OPT.HEX), l=hex.length;
+
+        // support #369 -> #336699 shorthand
+        if (l === 3) {
+            var c = hex.split(""), i;
+            for (i=0; i<l; i=i+1) {
+                c[i] = c[i] + c[i];
+            }
+
+            hex = c.join("");
+        }
+
+        if (hex.length !== 6) {
+            return false;
+        }
+
+        var rgb = Color.hex2rgb(hex);
+
+
+        this.setValue(rgb);
+
+        //_updateSliders.call(this);
+
+    };
+
+
+
+    /**
+     * Sets up the config attributes and the change listeners for this
+     * properties
+     * @method initAttributes
+     * @param attr An object containing default attribute values
+     */
+    proto.initAttributes = function(attr) {
+
+        attr = attr || {};
+        YAHOO.widget.ColorPicker.superclass.initAttributes.call(this, attr);
+        
+        /**
+         * The size of the picker. Trying to change this is not recommended.
+         * @attribute pickersize
+         * @default 180
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.PICKER_SIZE, {
+                value: attr.size || this.DEFAULT.PICKER_SIZE
+            });
+
+        /**
+         * The current hue value 0-360
+         * @attribute hue
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.HUE, {
+                value: attr.hue || 0,
+                validator: lang.isNumber
+            });
+
+        /**
+         * The current saturation value 0-100
+         * @attribute saturation
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.SATURATION, {
+                value: attr.saturation || 0,
+                validator: lang.isNumber
+            });
+
+        /**
+         * The current value/brightness value 0-100
+         * @attribute value
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.VALUE, {
+                value: lang.isNumber(attr.value) ? attr.value : 100,
+                validator: lang.isNumber
+            });
+
+        /**
+         * The current red value 0-255
+         * @attribute red
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.RED, {
+                value: lang.isNumber(attr.red) ? attr.red : 255,
+                validator: lang.isNumber
+            });
+
+        /**
+         * The current green value 0-255
+         * @attribute green 
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.GREEN, {
+                value: lang.isNumber(attr.green) ? attr.green : 255,
+                validator: lang.isNumber
+            });
+
+        /**
+         * The current blue value 0-255
+         * @attribute blue
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.BLUE, {
+                value: lang.isNumber(attr.blue) ? attr.blue : 255,
+                validator: lang.isNumber
+            });
+
+        /**
+         * The current hex value #000000-#FFFFFF, without the #
+         * @attribute hex
+         * @type string
+         */
+        this.setAttributeConfig(this.OPT.HEX, {
+                value: attr.hex || "FFFFFF",
+                validator: lang.isString
+            });
+
+        /**
+         * The current rgb value.  Updates the state of all of the
+         * other value fields.  Read-only: use setValue to set the
+         * controls rgb value.
+         * @attribute hex
+         * @type [int, int, int]
+         * @readonly
+         */
+        this.setAttributeConfig(this.OPT.RGB, {
+                value: attr.rgb || [255,255,255],
+                method: function(rgb) {
+
+                    this.set(this.OPT.RED, rgb[0], true);
+                    this.set(this.OPT.GREEN, rgb[1], true);
+                    this.set(this.OPT.BLUE, rgb[2], true);
+
+                    var websafe = Color.websafe(rgb);
+                    this.set(this.OPT.WEBSAFE, websafe, true);
+
+                    var hex = Color.rgb2hex(rgb);
+                    this.set(this.OPT.HEX, hex, true);
+
+                    var hsv = Color.rgb2hsv(rgb);
+
+
+                    this.set(this.OPT.HUE, hsv[0], true);
+                    this.set(this.OPT.SATURATION, Math.round(hsv[1]*100), true);
+                    this.set(this.OPT.VALUE, Math.round(hsv[2]*100), true);
+                },
+                readonly: true
+            });
+
+        /**
+         * If the color picker will live inside of a container object,
+         * set, provide a reference to it so the control can use the
+         * container's events.
+         * @attribute container
+         * @type YAHOO.widget.Panel
+         */
+        this.setAttributeConfig(this.OPT.CONTAINER, {
+                    value: null,
+                    method: function(container) {
+                        if (container) {
+                            // Position can get out of sync when the
+                            // control is manipulated while display is
+                            // none.  Resetting the slider constraints
+                            // when it is visible gets the state back in
+                            // order.
+                            container.showEvent.subscribe(function() {
+                                // this.pickerSlider.thumb.resetConstraints();
+                                // this.hueSlider.thumb.resetConstraints();
+                                this.pickerSlider.focus();
+                            }, this, true);
+                        }
+                    }
+                });
+        /**
+         * The closest current websafe value
+         * @attribute websafe
+         * @type int
+         */
+        this.setAttributeConfig(this.OPT.WEBSAFE, {
+                value: attr.websafe || [255,255,255]
+            });
+
+
+        var ids = attr.ids || lang.merge({}, this.ID);
+
+        if (!attr.ids && _pickercount > 1) {
+            for (var i in ids) {
+                if (lang.hasOwnProperty(ids, i)) {
+                    ids[i] = ids[i] + _pickercount;
+                }
+            }
+        }
+
+
+        /**
+         * A list of element ids and/or element references used by the 
+         * control.  The default is the this.ID list, and can be customized
+         * by passing a list in the contructor
+         * @attribute ids
+         * @type {referenceid: realid}
+         * @writeonce
+         */
+        this.setAttributeConfig(this.OPT.IDS, {
+                value: ids,
+                writeonce: true
+            });
+
+        /**
+         * A list of txt strings for internationalization.  Default
+         * is this.TXT
+         * @attribute txt
+         * @type {key: txt}
+         * @writeonce
+         */
+        this.setAttributeConfig(this.OPT.TXT, {
+                value: attr.txt || this.TXT,
+                writeonce: true
+            });
+
+        /**
+         * The img src default list
+         * is this.IMAGES
+         * @attribute images
+         * @type {key: image}
+         * @writeonce
+         */
+        this.setAttributeConfig(this.OPT.IMAGES, {
+                value: attr.images || this.IMAGE,
+                writeonce: true
+            });
+        /**
+         * The element refs used by this control.  Set at initialization
+         * @attribute elements
+         * @type {id: HTMLElement}
+         * @readonly
+         */
+        this.setAttributeConfig(this.OPT.ELEMENTS, {
+                value: {},
+                readonly: true
+            });
+
+        /**
+         * Returns the cached element reference.  If the id is not a string, it
+         * is assumed that it is an element and this is returned.
+         * @param id {string|HTMLElement} the element key, id, or ref
+         * @param on {boolean} hide or show.  If true, show
+         * @private */
+        var _hideShowEl = function(id, on) {
+            var el = (lang.isString(id) ? this.getElement(id) : id);
+            //Dom.setStyle(id, "visibility", (on) ? "" : "hidden");
+            Dom.setStyle(el, "display", (on) ? "" : "none");
+        };
+
+        /**
+         * Hide/show the entire set of controls
+         * @attribute showcontrols
+         * @type boolean
+         * @default true
+         */
+        this.setAttributeConfig(this.OPT.SHOW_CONTROLS, {
+                value: lang.isBoolean(attr.showcontrols) ? attr.showcontrols : true,
+                method: function(on) {
+
+                    var el = Dom.getElementsByClassName("bd", "div", 
+                            this.getElement(this.ID.CONTROLS))[0];
+
+                    _hideShowEl.call(this, el, on);
+
+                    this.getElement(this.ID.CONTROLS_LABEL).innerHTML = 
+                        (on) ? this.get(this.OPT.TXT).HIDE_CONTROLS :
+                               this.get(this.OPT.TXT).SHOW_CONTROLS;
+
+                }
+            });
+
+        /**
+         * Hide/show the rgb controls
+         * @attribute showrgbcontrols
+         * @type boolean
+         * @default true
+         */
+        this.setAttributeConfig(this.OPT.SHOW_RGB_CONTROLS, {
+                value: lang.isBoolean(attr.showrgbcontrols) ? attr.showrgbcontrols : true,
+                method: function(on) {
+                    //Dom.setStyle(this.getElement(this.ID.RBG_CONTROLS), "visibility", (on) ? "" : "hidden");
+                    _hideShowEl.call(this, this.ID.RGB_CONTROLS, on);
+                }
+            });
+
+        /**
+         * Hide/show the hsv controls
+         * @attribute showhsvcontrols
+         * @type boolean
+         * @default false
+         */
+        this.setAttributeConfig(this.OPT.SHOW_HSV_CONTROLS, {
+                value: lang.isBoolean(attr.showhsvcontrols) ?
+                                      attr.showhsvcontrols : false,
+                method: function(on) {
+                    //Dom.setStyle(this.getElement(this.ID.HSV_CONTROLS), "visibility", (on) ? "" : "hidden");
+                    _hideShowEl.call(this, this.ID.HSV_CONTROLS, on);
+
+                    // can't show both the hsv controls and the rbg hex summary
+                    if (on && this.get(this.OPT.SHOW_HEX_SUMMARY)) {
+                        this.set(this.OPT.SHOW_HEX_SUMMARY, false);
+                    }
+                }
+            });
+
+        /**
+         * Hide/show the hex controls
+         * @attribute showhexcontrols
+         * @type boolean
+         * @default true
+         */
+        this.setAttributeConfig(this.OPT.SHOW_HEX_CONTROLS, {
+                value: lang.isBoolean(attr.showhexcontrols) ?
+                                      attr.showhexcontrols : false,
+                method: function(on) {
+                    _hideShowEl.call(this, this.ID.HEX_CONTROLS, on);
+                }
+            });
+
+        /**
+         * Hide/show the websafe swatch
+         * @attribute showwebsafe
+         * @type boolean
+         * @default true
+         */
+        this.setAttributeConfig(this.OPT.SHOW_WEBSAFE, {
+                value: lang.isBoolean(attr.showwebsafe) ? attr.showwebsafe : true,
+                method: function(on) {
+                    _hideShowEl.call(this, this.ID.WEBSAFE_SWATCH, on);
+                }
+            });
+
+        /**
+         * Hide/show the hex summary
+         * @attribute showhexsummary
+         * @type boolean
+         * @default true
+         */
+        this.setAttributeConfig(this.OPT.SHOW_HEX_SUMMARY, {
+                value: lang.isBoolean(attr.showhexsummary) ? attr.showhexsummary : true,
+                method: function(on) {
+                    _hideShowEl.call(this, this.ID.HEX_SUMMARY, on);
+
+                    // can't show both the hsv controls and the rbg hex summary
+                    if (on && this.get(this.OPT.SHOW_HSV_CONTROLS)) {
+                        this.set(this.OPT.SHOW_HSV_CONTROLS, false);
+                    }
+                }
+            });
+        this.setAttributeConfig(this.OPT.ANIMATE, {
+                value: lang.isBoolean(attr.animate) ? attr.animate : true,
+                method: function(on) {
+                    this.pickerSlider.animate = on;
+                    this.hueSlider.animate = on;
+                }
+            });
+
+        this.on(this.OPT.HUE + "Change", _updateRGBFromHSV, this, true);
+        this.on(this.OPT.SATURATION + "Change", _updateRGBFromHSV, this, true);
+        this.on(this.OPT.VALUE + "Change", _updatePickerSlider, this, true);
+
+        this.on(this.OPT.RED + "Change", _updateRGB, this, true);
+        this.on(this.OPT.GREEN + "Change", _updateRGB, this, true);
+        this.on(this.OPT.BLUE + "Change", _updateRGB, this, true);
+
+        this.on(this.OPT.HEX + "Change", _updateHex, this, true);
+
+        this.initPicker();
+    };
+
+})();
+YAHOO.register("colorpicker", YAHOO.widget.ColorPicker, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/connection/README
===================================================================
--- trunk/root/static/yui/connection/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/connection/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +1,19 @@
 Connection Manager Release Notes
 
-*** version 2.4.1 ***
+*** version 2.5.1 ***
 
-No change
+* no changes.
 
+*** version 2.5.0 ***
+
+* setForm() can now detects HTTPS in the URI for file upload transactions.  The
+third, boolean argument for HTTPS when using IE is no longer necessary.
+
+* [FIXED] SF1882101.  POST transactions without a message will now have a
+Content-Length value set to 0 for FF 2.x.  This is accomplished by passing a
+value of empty string instead of null to XHR's send().  All other A-Grade
+browsers remain unaffected and perform correctly.
+
 *** version 2.4.0 ***
 
 * [FIXED] SF1804153.  Transactions initialized with setForm() now properly clear
@@ -257,3 +267,5 @@
 
 * Initial release
 
+
+

Modified: trunk/root/static/yui/connection/connection-debug.js
===================================================================
--- trunk/root/static/yui/connection/connection-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/connection/connection-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The Connection Manager provides a simplified interface to the XMLHttpRequest
@@ -235,7 +235,7 @@
 				'click',
 				function(e){
 					var obj = YAHOO.util.Event.getTarget(e);
-					if(obj.type && obj.type.toLowerCase() == 'submit'){
+					if(obj.nodeName.toLowerCase() == 'input' && (obj.type && obj.type.toLowerCase() == 'submit')){
 						YAHOO.util.Connect._submitElementValue = encodeURIComponent(obj.name) + "=" + encodeURIComponent(obj.value);
 					}
 				});
@@ -547,7 +547,7 @@
 			}
 
 			this.handleReadyState(o, callback);
-			o.conn.send(postData || null);
+			o.conn.send(postData || '');
 			YAHOO.log('Transaction ' + o.tId + ' sent.', 'info', 'Connection');
 
 
@@ -956,7 +956,7 @@
 		if(isUpload){
 
 			// Create iframe in preparation for file upload.
-			var io = this.createFrame(secureUri?secureUri:null);
+			var io = this.createFrame((window.location.href.toLowerCase().indexOf("https") === 0 || secureUri)?true:false);
 			// Set form reference and file upload properties to true.
 			this._isFormSubmit = true;
 			this._isFileUpload = true;
@@ -1079,10 +1079,6 @@
 			if(typeof secureUri == 'boolean'){
 				io.src = 'javascript:false';
 			}
-			else if(typeof secureURI == 'string'){
-				// Deprecated
-				io.src = secureUri;
-			}
 		}
 		else{
 			io = document.createElement('iframe');
@@ -1396,4 +1392,4 @@
 	}
 };
 
-YAHOO.register("connection", YAHOO.util.Connect, {version: "2.4.1", build: "742"});
+YAHOO.register("connection", YAHOO.util.Connect, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/connection/connection-min.js
===================================================================
--- trunk/root/static/yui/connection/connection-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/connection/connection-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-YAHOO.util.Connect={_msxml_progid:["Microsoft.XMLHTTP","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP"],_http_headers:{},_has_http_headers:false,_use_default_post_header:true,_default_post_header:"application/x-www-form-urlencoded; charset=UTF-8",_default_form_header:"application/x-www-form-urlencoded",_use_default_xhr_header:true,_default_xhr_header:"XMLHttpRequest",_has_default_headers:true,_default_headers:{},_isFormSubmit:false,_isFileUpload:false,_formNode:null,_sFormData:null,_poll:{},_timeOut:{},_polling_interval:50,_transaction_id:0,_submitElementValue:null,_hasSubmitListener:(function(){if(YAHOO.util.Event){YAHOO.util.Event.addListener(document,"click",function(B){var A=YAHOO.util.Event.getTarget(B);if(A.type&&A.type.toLowerCase()=="submit"){YAHOO.util.Connect._submitElementValue=encodeURIComponent(A.name)+"="+encodeURIComponent(A.value);}});return true;}return false;})(),startEvent:new YAHOO.util.CustomEvent("start"),completeEvent:new YAHOO.util.CustomEvent("complete"),succ!
 essEvent:new YAHOO.util.CustomEvent("success"),failureEvent:new YAHOO.util.CustomEvent("failure"),uploadEvent:new YAHOO.util.CustomEvent("upload"),abortEvent:new YAHOO.util.CustomEvent("abort"),_customEvents:{onStart:["startEvent","start"],onComplete:["completeEvent","complete"],onSuccess:["successEvent","success"],onFailure:["failureEvent","failure"],onUpload:["uploadEvent","upload"],onAbort:["abortEvent","abort"]},setProgId:function(A){this._msxml_progid.unshift(A);},setDefaultPostHeader:function(A){if(typeof A=="string"){this._default_post_header=A;}else{if(typeof A=="boolean"){this._use_default_post_header=A;}}},setDefaultXhrHeader:function(A){if(typeof A=="string"){this._default_xhr_header=A;}else{this._use_default_xhr_header=A;}},setPollingInterval:function(A){if(typeof A=="number"&&isFinite(A)){this._polling_interval=A;}},createXhrObject:function(E){var D,A;try{A=new XMLHttpRequest();D={conn:A,tId:E};}catch(C){for(var B=0;B<this._msxml_progid.length;++B){try{A=new Ac!
 tiveXObject(this._msxml_progid[B]);D={conn:A,tId:E};break;}cat!
 ch(C){}}
}finally{return D;}},getConnectionObject:function(A){var C;var D=this._transaction_id;try{if(!A){C=this.createXhrObject(D);}else{C={};C.tId=D;C.isUpload=true;}if(C){this._transaction_id++;}}catch(B){}finally{return C;}},asyncRequest:function(F,C,E,A){var D=(this._isFileUpload)?this.getConnectionObject(true):this.getConnectionObject();var B=(E&&E.argument)?E.argument:null;if(!D){return null;}else{if(E&&E.customevents){this.initCustomEvents(D,E);}if(this._isFormSubmit){if(this._isFileUpload){this.uploadFile(D,E,C,A);return D;}if(F.toUpperCase()=="GET"){if(this._sFormData.length!==0){C+=((C.indexOf("?")==-1)?"?":"&")+this._sFormData;}}else{if(F.toUpperCase()=="POST"){A=A?this._sFormData+"&"+A:this._sFormData;}}}if(F.toUpperCase()=="GET"&&(E&&E.cache===false)){C+=((C.indexOf("?")==-1)?"?":"&")+"rnd="+new Date().valueOf().toString();}D.conn.open(F,C,true);if(this._use_default_xhr_header){if(!this._default_headers["X-Requested-With"]){this.initHeader("X-Requested-With",this._defau!
 lt_xhr_header,true);}}if((F.toUpperCase()=="POST"&&this._use_default_post_header)&&this._isFormSubmit===false){this.initHeader("Content-Type",this._default_post_header);}if(this._has_default_headers||this._has_http_headers){this.setHeader(D);}this.handleReadyState(D,E);D.conn.send(A||null);if(this._isFormSubmit===true){this.resetFormState();}this.startEvent.fire(D,B);if(D.startEvent){D.startEvent.fire(D,B);}return D;}},initCustomEvents:function(A,C){for(var B in C.customevents){if(this._customEvents[B][0]){A[this._customEvents[B][0]]=new YAHOO.util.CustomEvent(this._customEvents[B][1],(C.scope)?C.scope:null);A[this._customEvents[B][0]].subscribe(C.customevents[B]);}}},handleReadyState:function(C,D){var B=this;var A=(D&&D.argument)?D.argument:null;if(D&&D.timeout){this._timeOut[C.tId]=window.setTimeout(function(){B.abort(C,D,true);},D.timeout);}this._poll[C.tId]=window.setInterval(function(){if(C.conn&&C.conn.readyState===4){window.clearInterval(B._poll[C.tId]);delete B._pol!
 l[C.tId];if(D&&D.timeout){window.clearTimeout(B._timeOut[C.tId!
 ]);delet
e B._timeOut[C.tId];}B.completeEvent.fire(C,A);if(C.completeEvent){C.completeEvent.fire(C,A);}B.handleTransactionResponse(C,D);}},this._polling_interval);},handleTransactionResponse:function(F,G,A){var D,C;var B=(G&&G.argument)?G.argument:null;try{if(F.conn.status!==undefined&&F.conn.status!==0){D=F.conn.status;}else{D=13030;}}catch(E){D=13030;}if(D>=200&&D<300||D===1223){C=this.createResponseObject(F,B);if(G&&G.success){if(!G.scope){G.success(C);}else{G.success.apply(G.scope,[C]);}}this.successEvent.fire(C);if(F.successEvent){F.successEvent.fire(C);}}else{switch(D){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:C=this.createExceptionObject(F.tId,B,(A?A:false));if(G&&G.failure){if(!G.scope){G.failure(C);}else{G.failure.apply(G.scope,[C]);}}break;default:C=this.createResponseObject(F,B);if(G&&G.failure){if(!G.scope){G.failure(C);}else{G.failure.apply(G.scope,[C]);}}}this.failureEvent.fire(C);if(F.failureEvent){F.failureEvent.fire(C);}}this.releaseObject(F);!
 C=null;},createResponseObject:function(A,G){var D={};var I={};try{var C=A.conn.getAllResponseHeaders();var F=C.split("\n");for(var E=0;E<F.length;E++){var B=F[E].indexOf(":");if(B!=-1){I[F[E].substring(0,B)]=F[E].substring(B+2);}}}catch(H){}D.tId=A.tId;D.status=(A.conn.status==1223)?204:A.conn.status;D.statusText=(A.conn.status==1223)?"No Content":A.conn.statusText;D.getResponseHeader=I;D.getAllResponseHeaders=C;D.responseText=A.conn.responseText;D.responseXML=A.conn.responseXML;if(G){D.argument=G;}return D;},createExceptionObject:function(H,D,A){var F=0;var G="communication failure";var C=-1;var B="transaction aborted";var E={};E.tId=H;if(A){E.status=C;E.statusText=B;}else{E.status=F;E.statusText=G;}if(D){E.argument=D;}return E;},initHeader:function(A,D,C){var B=(C)?this._default_headers:this._http_headers;B[A]=D;if(C){this._has_default_headers=true;}else{this._has_http_headers=true;}},setHeader:function(A){if(this._has_default_headers){for(var B in this._default_headers){!
 if(YAHOO.lang.hasOwnProperty(this._default_headers,B)){A.conn.!
 setReque
stHeader(B,this._default_headers[B]);
-}}}if(this._has_http_headers){for(var B in this._http_headers){if(YAHOO.lang.hasOwnProperty(this._http_headers,B)){A.conn.setRequestHeader(B,this._http_headers[B]);}}delete this._http_headers;this._http_headers={};this._has_http_headers=false;}},resetDefaultHeaders:function(){delete this._default_headers;this._default_headers={};this._has_default_headers=false;},setForm:function(K,E,B){this.resetFormState();var J;if(typeof K=="string"){J=(document.getElementById(K)||document.forms[K]);}else{if(typeof K=="object"){J=K;}else{return ;}}if(E){var F=this.createFrame(B?B:null);this._isFormSubmit=true;this._isFileUpload=true;this._formNode=J;return ;}var A,I,G,L;var H=false;for(var D=0;D<J.elements.length;D++){A=J.elements[D];L=A.disabled;I=A.name;G=A.value;if(!L&&I){switch(A.type){case"select-one":case"select-multiple":for(var C=0;C<A.options.length;C++){if(A.options[C].selected){if(window.ActiveXObject){this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(A.options[C].a!
 ttributes["value"].specified?A.options[C].value:A.options[C].text)+"&";}else{this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(A.options[C].hasAttribute("value")?A.options[C].value:A.options[C].text)+"&";}}}break;case"radio":case"checkbox":if(A.checked){this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(G)+"&";}break;case"file":case undefined:case"reset":case"button":break;case"submit":if(H===false){if(this._hasSubmitListener&&this._submitElementValue){this._sFormData+=this._submitElementValue+"&";}else{this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(G)+"&";}H=true;}break;default:this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(G)+"&";}}}this._isFormSubmit=true;this._sFormData=this._sFormData.substr(0,this._sFormData.length-1);this.initHeader("Content-Type",this._default_form_header);return this._sFormData;},resetFormState:function(){this._isFormSubmit=false;this._isFileUpload=false;this._formNode=null;this._sFormData="";},c!
 reateFrame:function(A){var B="yuiIO"+this._transaction_id;var !
 C;if(win
dow.ActiveXObject){C=document.createElement("<iframe id=\""+B+"\" name=\""+B+"\" />");if(typeof A=="boolean"){C.src="javascript:false";}else{if(typeof secureURI=="string"){C.src=A;}}}else{C=document.createElement("iframe");C.id=B;C.name=B;}C.style.position="absolute";C.style.top="-1000px";C.style.left="-1000px";document.body.appendChild(C);},appendPostData:function(A){var D=[];var B=A.split("&");for(var C=0;C<B.length;C++){var E=B[C].indexOf("=");if(E!=-1){D[C]=document.createElement("input");D[C].type="hidden";D[C].name=B[C].substring(0,E);D[C].value=B[C].substring(E+1);this._formNode.appendChild(D[C]);}}return D;},uploadFile:function(D,M,E,C){var N=this;var H="yuiIO"+D.tId;var I="multipart/form-data";var K=document.getElementById(H);var J=(M&&M.argument)?M.argument:null;var B={action:this._formNode.getAttribute("action"),method:this._formNode.getAttribute("method"),target:this._formNode.getAttribute("target")};this._formNode.setAttribute("action",E);this._formNode.setAttri!
 bute("method","POST");this._formNode.setAttribute("target",H);if(this._formNode.encoding){this._formNode.setAttribute("encoding",I);}else{this._formNode.setAttribute("enctype",I);}if(C){var L=this.appendPostData(C);}this._formNode.submit();this.startEvent.fire(D,J);if(D.startEvent){D.startEvent.fire(D,J);}if(M&&M.timeout){this._timeOut[D.tId]=window.setTimeout(function(){N.abort(D,M,true);},M.timeout);}if(L&&L.length>0){for(var G=0;G<L.length;G++){this._formNode.removeChild(L[G]);}}for(var A in B){if(YAHOO.lang.hasOwnProperty(B,A)){if(B[A]){this._formNode.setAttribute(A,B[A]);}else{this._formNode.removeAttribute(A);}}}this.resetFormState();var F=function(){if(M&&M.timeout){window.clearTimeout(N._timeOut[D.tId]);delete N._timeOut[D.tId];}N.completeEvent.fire(D,J);if(D.completeEvent){D.completeEvent.fire(D,J);}var P={};P.tId=D.tId;P.argument=M.argument;try{P.responseText=K.contentWindow.document.body?K.contentWindow.document.body.innerHTML:K.contentWindow.document.documentEle!
 ment.textContent;P.responseXML=K.contentWindow.document.XMLDoc!
 ument?K.
contentWindow.document.XMLDocument:K.contentWindow.document;}catch(O){}if(M&&M.upload){if(!M.scope){M.upload(P);}else{M.upload.apply(M.scope,[P]);}}N.uploadEvent.fire(P);if(D.uploadEvent){D.uploadEvent.fire(P);}YAHOO.util.Event.removeListener(K,"load",F);setTimeout(function(){document.body.removeChild(K);N.releaseObject(D);},100);};YAHOO.util.Event.addListener(K,"load",F);},abort:function(E,G,A){var D;var B=(G&&G.argument)?G.argument:null;if(E&&E.conn){if(this.isCallInProgress(E)){E.conn.abort();window.clearInterval(this._poll[E.tId]);delete this._poll[E.tId];if(A){window.clearTimeout(this._timeOut[E.tId]);delete this._timeOut[E.tId];}D=true;}}else{if(E&&E.isUpload===true){var C="yuiIO"+E.tId;var F=document.getElementById(C);if(F){YAHOO.util.Event.removeListener(F,"load");document.body.removeChild(F);if(A){window.clearTimeout(this._timeOut[E.tId]);delete this._timeOut[E.tId];}D=true;}}else{D=false;}}if(D===true){this.abortEvent.fire(E,B);if(E.abortEvent){E.abortEvent.fire(E,!
 B);}this.handleTransactionResponse(E,G,true);}return D;},isCallInProgress:function(B){if(B&&B.conn){return B.conn.readyState!==4&&B.conn.readyState!==0;}else{if(B&&B.isUpload===true){var A="yuiIO"+B.tId;return document.getElementById(A)?true:false;}else{return false;}}},releaseObject:function(A){if(A&&A.conn){A.conn=null;A=null;}}};YAHOO.register("connection",YAHOO.util.Connect,{version:"2.4.1",build:"742"});
\ No newline at end of file
+YAHOO.util.Connect={_msxml_progid:["Microsoft.XMLHTTP","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP"],_http_headers:{},_has_http_headers:false,_use_default_post_header:true,_default_post_header:"application/x-www-form-urlencoded; charset=UTF-8",_default_form_header:"application/x-www-form-urlencoded",_use_default_xhr_header:true,_default_xhr_header:"XMLHttpRequest",_has_default_headers:true,_default_headers:{},_isFormSubmit:false,_isFileUpload:false,_formNode:null,_sFormData:null,_poll:{},_timeOut:{},_polling_interval:50,_transaction_id:0,_submitElementValue:null,_hasSubmitListener:(function(){if(YAHOO.util.Event){YAHOO.util.Event.addListener(document,"click",function(B){var A=YAHOO.util.Event.getTarget(B);if(A.nodeName.toLowerCase()=="input"&&(A.type&&A.type.toLowerCase()=="submit")){YAHOO.util.Connect._submitElementValue=encodeURIComponent(A.name)+"="+encodeURIComponent(A.value);}});return true;}return false;})(),startEvent:new YAHOO.util.CustomEvent("start"),completeEvent:new YA!
 HOO.util.CustomEvent("complete"),successEvent:new YAHOO.util.CustomEvent("success"),failureEvent:new YAHOO.util.CustomEvent("failure"),uploadEvent:new YAHOO.util.CustomEvent("upload"),abortEvent:new YAHOO.util.CustomEvent("abort"),_customEvents:{onStart:["startEvent","start"],onComplete:["completeEvent","complete"],onSuccess:["successEvent","success"],onFailure:["failureEvent","failure"],onUpload:["uploadEvent","upload"],onAbort:["abortEvent","abort"]},setProgId:function(A){this._msxml_progid.unshift(A);},setDefaultPostHeader:function(A){if(typeof A=="string"){this._default_post_header=A;}else{if(typeof A=="boolean"){this._use_default_post_header=A;}}},setDefaultXhrHeader:function(A){if(typeof A=="string"){this._default_xhr_header=A;}else{this._use_default_xhr_header=A;}},setPollingInterval:function(A){if(typeof A=="number"&&isFinite(A)){this._polling_interval=A;}},createXhrObject:function(E){var D,A;try{A=new XMLHttpRequest();D={conn:A,tId:E};}catch(C){for(var B=0;B<this._!
 msxml_progid.length;++B){try{A=new ActiveXObject(this._msxml_p!
 rogid[B]
);D={conn:A,tId:E};break;}catch(C){}}}finally{return D;}},getConnectionObject:function(A){var C;var D=this._transaction_id;try{if(!A){C=this.createXhrObject(D);}else{C={};C.tId=D;C.isUpload=true;}if(C){this._transaction_id++;}}catch(B){}finally{return C;}},asyncRequest:function(F,C,E,A){var D=(this._isFileUpload)?this.getConnectionObject(true):this.getConnectionObject();var B=(E&&E.argument)?E.argument:null;if(!D){return null;}else{if(E&&E.customevents){this.initCustomEvents(D,E);}if(this._isFormSubmit){if(this._isFileUpload){this.uploadFile(D,E,C,A);return D;}if(F.toUpperCase()=="GET"){if(this._sFormData.length!==0){C+=((C.indexOf("?")==-1)?"?":"&")+this._sFormData;}}else{if(F.toUpperCase()=="POST"){A=A?this._sFormData+"&"+A:this._sFormData;}}}if(F.toUpperCase()=="GET"&&(E&&E.cache===false)){C+=((C.indexOf("?")==-1)?"?":"&")+"rnd="+new Date().valueOf().toString();}D.conn.open(F,C,true);if(this._use_default_xhr_header){if(!this._default_headers["X-Requested-With"]){this.init!
 Header("X-Requested-With",this._default_xhr_header,true);}}if((F.toUpperCase()=="POST"&&this._use_default_post_header)&&this._isFormSubmit===false){this.initHeader("Content-Type",this._default_post_header);}if(this._has_default_headers||this._has_http_headers){this.setHeader(D);}this.handleReadyState(D,E);D.conn.send(A||"");if(this._isFormSubmit===true){this.resetFormState();}this.startEvent.fire(D,B);if(D.startEvent){D.startEvent.fire(D,B);}return D;}},initCustomEvents:function(A,C){for(var B in C.customevents){if(this._customEvents[B][0]){A[this._customEvents[B][0]]=new YAHOO.util.CustomEvent(this._customEvents[B][1],(C.scope)?C.scope:null);A[this._customEvents[B][0]].subscribe(C.customevents[B]);}}},handleReadyState:function(C,D){var B=this;var A=(D&&D.argument)?D.argument:null;if(D&&D.timeout){this._timeOut[C.tId]=window.setTimeout(function(){B.abort(C,D,true);},D.timeout);}this._poll[C.tId]=window.setInterval(function(){if(C.conn&&C.conn.readyState===4){window.clearInt!
 erval(B._poll[C.tId]);delete B._poll[C.tId];if(D&&D.timeout){w!
 indow.cl
earTimeout(B._timeOut[C.tId]);delete B._timeOut[C.tId];}B.completeEvent.fire(C,A);if(C.completeEvent){C.completeEvent.fire(C,A);}B.handleTransactionResponse(C,D);}},this._polling_interval);},handleTransactionResponse:function(F,G,A){var D,C;var B=(G&&G.argument)?G.argument:null;try{if(F.conn.status!==undefined&&F.conn.status!==0){D=F.conn.status;}else{D=13030;}}catch(E){D=13030;}if(D>=200&&D<300||D===1223){C=this.createResponseObject(F,B);if(G&&G.success){if(!G.scope){G.success(C);}else{G.success.apply(G.scope,[C]);}}this.successEvent.fire(C);if(F.successEvent){F.successEvent.fire(C);}}else{switch(D){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:C=this.createExceptionObject(F.tId,B,(A?A:false));if(G&&G.failure){if(!G.scope){G.failure(C);}else{G.failure.apply(G.scope,[C]);}}break;default:C=this.createResponseObject(F,B);if(G&&G.failure){if(!G.scope){G.failure(C);}else{G.failure.apply(G.scope,[C]);}}}this.failureEvent.fire(C);if(F.failureEvent){F.failureEve!
 nt.fire(C);}}this.releaseObject(F);C=null;},createResponseObject:function(A,G){var D={};var I={};try{var C=A.conn.getAllResponseHeaders();var F=C.split("\n");for(var E=0;E<F.length;E++){var B=F[E].indexOf(":");if(B!=-1){I[F[E].substring(0,B)]=F[E].substring(B+2);}}}catch(H){}D.tId=A.tId;D.status=(A.conn.status==1223)?204:A.conn.status;D.statusText=(A.conn.status==1223)?"No Content":A.conn.statusText;D.getResponseHeader=I;D.getAllResponseHeaders=C;D.responseText=A.conn.responseText;D.responseXML=A.conn.responseXML;if(G){D.argument=G;}return D;},createExceptionObject:function(H,D,A){var F=0;var G="communication failure";var C=-1;var B="transaction aborted";var E={};E.tId=H;if(A){E.status=C;E.statusText=B;}else{E.status=F;E.statusText=G;}if(D){E.argument=D;}return E;},initHeader:function(A,D,C){var B=(C)?this._default_headers:this._http_headers;B[A]=D;if(C){this._has_default_headers=true;}else{this._has_http_headers=true;
+}},setHeader:function(A){if(this._has_default_headers){for(var B in this._default_headers){if(YAHOO.lang.hasOwnProperty(this._default_headers,B)){A.conn.setRequestHeader(B,this._default_headers[B]);}}}if(this._has_http_headers){for(var B in this._http_headers){if(YAHOO.lang.hasOwnProperty(this._http_headers,B)){A.conn.setRequestHeader(B,this._http_headers[B]);}}delete this._http_headers;this._http_headers={};this._has_http_headers=false;}},resetDefaultHeaders:function(){delete this._default_headers;this._default_headers={};this._has_default_headers=false;},setForm:function(K,E,B){this.resetFormState();var J;if(typeof K=="string"){J=(document.getElementById(K)||document.forms[K]);}else{if(typeof K=="object"){J=K;}else{return ;}}if(E){var F=this.createFrame((window.location.href.toLowerCase().indexOf("https")===0||B)?true:false);this._isFormSubmit=true;this._isFileUpload=true;this._formNode=J;return ;}var A,I,G,L;var H=false;for(var D=0;D<J.elements.length;D++){A=J.elements[D!
 ];L=A.disabled;I=A.name;G=A.value;if(!L&&I){switch(A.type){case"select-one":case"select-multiple":for(var C=0;C<A.options.length;C++){if(A.options[C].selected){if(window.ActiveXObject){this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(A.options[C].attributes["value"].specified?A.options[C].value:A.options[C].text)+"&";}else{this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(A.options[C].hasAttribute("value")?A.options[C].value:A.options[C].text)+"&";}}}break;case"radio":case"checkbox":if(A.checked){this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(G)+"&";}break;case"file":case undefined:case"reset":case"button":break;case"submit":if(H===false){if(this._hasSubmitListener&&this._submitElementValue){this._sFormData+=this._submitElementValue+"&";}else{this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(G)+"&";}H=true;}break;default:this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(G)+"&";}}}this._isFormSubmit=true;this._s!
 FormData=this._sFormData.substr(0,this._sFormData.length-1);th!
 is.initH
eader("Content-Type",this._default_form_header);return this._sFormData;},resetFormState:function(){this._isFormSubmit=false;this._isFileUpload=false;this._formNode=null;this._sFormData="";},createFrame:function(A){var B="yuiIO"+this._transaction_id;var C;if(window.ActiveXObject){C=document.createElement("<iframe id=\""+B+"\" name=\""+B+"\" />");if(typeof A=="boolean"){C.src="javascript:false";}}else{C=document.createElement("iframe");C.id=B;C.name=B;}C.style.position="absolute";C.style.top="-1000px";C.style.left="-1000px";document.body.appendChild(C);},appendPostData:function(A){var D=[];var B=A.split("&");for(var C=0;C<B.length;C++){var E=B[C].indexOf("=");if(E!=-1){D[C]=document.createElement("input");D[C].type="hidden";D[C].name=B[C].substring(0,E);D[C].value=B[C].substring(E+1);this._formNode.appendChild(D[C]);}}return D;},uploadFile:function(D,M,E,C){var N=this;var H="yuiIO"+D.tId;var I="multipart/form-data";var K=document.getElementById(H);var J=(M&&M.argument)?M.argum!
 ent:null;var B={action:this._formNode.getAttribute("action"),method:this._formNode.getAttribute("method"),target:this._formNode.getAttribute("target")};this._formNode.setAttribute("action",E);this._formNode.setAttribute("method","POST");this._formNode.setAttribute("target",H);if(this._formNode.encoding){this._formNode.setAttribute("encoding",I);}else{this._formNode.setAttribute("enctype",I);}if(C){var L=this.appendPostData(C);}this._formNode.submit();this.startEvent.fire(D,J);if(D.startEvent){D.startEvent.fire(D,J);}if(M&&M.timeout){this._timeOut[D.tId]=window.setTimeout(function(){N.abort(D,M,true);},M.timeout);}if(L&&L.length>0){for(var G=0;G<L.length;G++){this._formNode.removeChild(L[G]);}}for(var A in B){if(YAHOO.lang.hasOwnProperty(B,A)){if(B[A]){this._formNode.setAttribute(A,B[A]);}else{this._formNode.removeAttribute(A);}}}this.resetFormState();var F=function(){if(M&&M.timeout){window.clearTimeout(N._timeOut[D.tId]);delete N._timeOut[D.tId];}N.completeEvent.fire(D,J);!
 if(D.completeEvent){D.completeEvent.fire(D,J);}var P={};P.tId=!
 D.tId;P.
argument=M.argument;try{P.responseText=K.contentWindow.document.body?K.contentWindow.document.body.innerHTML:K.contentWindow.document.documentElement.textContent;P.responseXML=K.contentWindow.document.XMLDocument?K.contentWindow.document.XMLDocument:K.contentWindow.document;}catch(O){}if(M&&M.upload){if(!M.scope){M.upload(P);}else{M.upload.apply(M.scope,[P]);}}N.uploadEvent.fire(P);if(D.uploadEvent){D.uploadEvent.fire(P);}YAHOO.util.Event.removeListener(K,"load",F);setTimeout(function(){document.body.removeChild(K);N.releaseObject(D);},100);};YAHOO.util.Event.addListener(K,"load",F);},abort:function(E,G,A){var D;var B=(G&&G.argument)?G.argument:null;if(E&&E.conn){if(this.isCallInProgress(E)){E.conn.abort();window.clearInterval(this._poll[E.tId]);delete this._poll[E.tId];if(A){window.clearTimeout(this._timeOut[E.tId]);delete this._timeOut[E.tId];}D=true;}}else{if(E&&E.isUpload===true){var C="yuiIO"+E.tId;var F=document.getElementById(C);if(F){YAHOO.util.Event.removeListener(F!
 ,"load");document.body.removeChild(F);if(A){window.clearTimeout(this._timeOut[E.tId]);delete this._timeOut[E.tId];}D=true;}}else{D=false;}}if(D===true){this.abortEvent.fire(E,B);if(E.abortEvent){E.abortEvent.fire(E,B);}this.handleTransactionResponse(E,G,true);}return D;},isCallInProgress:function(B){if(B&&B.conn){return B.conn.readyState!==4&&B.conn.readyState!==0;}else{if(B&&B.isUpload===true){var A="yuiIO"+B.tId;return document.getElementById(A)?true:false;}else{return false;}}},releaseObject:function(A){if(A&&A.conn){A.conn=null;A=null;}}};YAHOO.register("connection",YAHOO.util.Connect,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/connection/connection.js
===================================================================
--- trunk/root/static/yui/connection/connection.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/connection/connection.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The Connection Manager provides a simplified interface to the XMLHttpRequest
@@ -235,7 +235,7 @@
 				'click',
 				function(e){
 					var obj = YAHOO.util.Event.getTarget(e);
-					if(obj.type && obj.type.toLowerCase() == 'submit'){
+					if(obj.nodeName.toLowerCase() == 'input' && (obj.type && obj.type.toLowerCase() == 'submit')){
 						YAHOO.util.Connect._submitElementValue = encodeURIComponent(obj.name) + "=" + encodeURIComponent(obj.value);
 					}
 				});
@@ -538,7 +538,7 @@
 			}
 
 			this.handleReadyState(o, callback);
-			o.conn.send(postData || null);
+			o.conn.send(postData || '');
 
 
 			// Reset the HTML form data and state properties as
@@ -935,7 +935,7 @@
 		if(isUpload){
 
 			// Create iframe in preparation for file upload.
-			var io = this.createFrame(secureUri?secureUri:null);
+			var io = this.createFrame((window.location.href.toLowerCase().indexOf("https") === 0 || secureUri)?true:false);
 			// Set form reference and file upload properties to true.
 			this._isFormSubmit = true;
 			this._isFileUpload = true;
@@ -1056,10 +1056,6 @@
 			if(typeof secureUri == 'boolean'){
 				io.src = 'javascript:false';
 			}
-			else if(typeof secureURI == 'string'){
-				// Deprecated
-				io.src = secureUri;
-			}
 		}
 		else{
 			io = document.createElement('iframe');
@@ -1366,4 +1362,4 @@
 	}
 };
 
-YAHOO.register("connection", YAHOO.util.Connect, {version: "2.4.1", build: "742"});
+YAHOO.register("connection", YAHOO.util.Connect, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/container/README
===================================================================
--- trunk/root/static/yui/container/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/container/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +1,87 @@
 Container Release Notes
 
-*** version 2.4.1 ***
+*** version 2.5.1 ***
 
-No change
+Fixed the following bugs:
+-------------------------
 
++ Module.setBody, setHeader and setFooter methods now accept
+  DocumentFragments. This feature was implicitly available
+  in versions prior to 2.5.0 and is now officially supported.
+
+Changes:
+--------
+
++ Optimized addition of Modality focus handlers on masked
+  elements (which are used to enforce modality) and added 
+  ability to disable feature, to avoid timeout script errors 
+  in IE if your page contains a very large number of focusable 
+  elements.
+
+  Additionally changes to Event in 2.5.1 should allow
+  for increased scalability, when using Modal panels containing
+  large numbers of focusable elements on the page.
+
+  Added a YAHOO.widget.Panel.FOCUSABLE property, defining 
+  the set of elements which should have focus handlers applied 
+  when covered by the Modal mask.
+
+  If you wish to disable the addition of focus handlers to all
+  focusable elements on the page when a Modal Panel is displayed,
+  the property can be set to an empty array:
+
+        YAHOO.widget.Panel.FOCUSABLE = [];
+
+  NOTE: This will mean that elements under mask may still be
+  accessible using the keyboard, however the mask will still 
+  prevent mouse access to elements.
+
+*** version 2.5.0 ***
+
+Fixed the following bugs:
+-------------------------
+
++ We now add the text resize monitor iframe to the DOM in a timeout,
+  to help alleviate the perpetual loading indicator seen in 
+  Firefox 2.0.0.8 (Gecko 1.8.1.8) and above on Windows.
+
++ Changed the closing script tag string used in the resize monitor, to 
+  allow container-min.js, container_core-min.js content to be used inline.
+
++ Fixed problem with underlay size being too short in IE6 when setting up
+  an initially visible Dialog with buttons.
+  
++ Removed overflow:auto applied to the modal mask for all browsers other 
+  than gecko/MacOS to help avoid the "missing text cursor" Gecko bug. 
+  Overflow:auto is still applied to for Gecko/MacOS to help avoid 
+  scrollbar bleedthrough, another Gecko bug (discussed in Container's 
+  known issues section).
+  
+Added the following features:
+-----------------------------
+
++ Added a "hideaftersubmit" config property to Dialog, to allow the end
+  user to configure whether or not the Dialog should be hidden after
+  it has been submitted. By default it is set to false, to provide 
+  backwards compatibility.
+  
++ Added contextMouseOverEvent, contextMouseOutEvent and 
+  contextTriggerEvent events to Tooltip, which provide access to the 
+  context element when the user mouses over a context element, mouses 
+  out of a context element, and before a tooltip is about to be 
+  triggered (displayed) for a context element. See the API docs for
+  these events for futher details.
+  
++ Added a "disabled" config property to Tooltip, to allow the user
+  to dynamically disable a tooltip.
+  
+Changes:
+--------
+
++ Optimized constraintoviewport handling for Overlays which haven't
+  been specifically positioned, so that the constraint checks aren't
+  made before every show.
+
 *** version 2.4.0 ***
 
 Fixed the following bugs:

Modified: trunk/root/static/yui/container/assets/container-core.css
===================================================================
--- trunk/root/static/yui/container/assets/container-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/container/assets/container-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-overlay,
 .yui-panel-container {
@@ -23,9 +23,13 @@
     left: 0;
     right: 0;
     bottom: 0;
+}
+
+.mask.block-scrollbars {
     /*
         Application of "overflow:auto" prevents Mac scrollbars from bleeding
-        through the modality mask in Gecko.
+        through the modality mask in Gecko. The block-scollbars class is only 
+        added for Gecko on MacOS
     */
     overflow: auto;
 }
@@ -107,22 +111,16 @@
 }
 
 .hide-scrollbars select {
-
     display: none;
-
 }
 
 .show-scrollbars {
-
     overflow: auto;
-
 }
 
 .yui-panel-container.show-scrollbars,
 .yui-tt.show-scrollbars {
-
     overflow: visible;
-
 }
 
 .yui-panel-container.show-scrollbars .underlay,

Modified: trunk/root/static/yui/container/assets/container.css
===================================================================
--- trunk/root/static/yui/container/assets/container.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/container/assets/container.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-overlay,
 .yui-panel-container {

Modified: trunk/root/static/yui/container/assets/skins/sam/container-skin.css
===================================================================
--- trunk/root/static/yui/container/assets/skins/sam/container-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/container/assets/skins/sam/container-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* Panel modality mask styles */
 
@@ -190,11 +190,12 @@
 
 }
 
+/* Dialog default button style */
 .yui-skin-sam .yui-dialog .ft button.default {
     font-weight:bold;
 }
 
-/* Dialog default YUI Button styles */
+/* Dialog default YUI Button style */
 .yui-skin-sam .yui-dialog .ft span.default {
     border-color: #304369;
     background-position: 0 -1400px;

Modified: trunk/root/static/yui/container/assets/skins/sam/container.css
===================================================================
--- trunk/root/static/yui/container/assets/skins/sam/container.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/container/assets/skins/sam/container.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-.yui-overlay,.yui-panel-container{visibility:hidden;position:absolute;z-index:2;}.yui-panel-container form{margin:0;}.mask{z-index:1;display:none;position:absolute;top:0;left:0;right:0;bottom:0;overflow:auto;}.masked select,.drag select,.hide-select select{_visibility:hidden;}.yui-panel-container select{_visibility:inherit;}.hide-scrollbars,.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.show-scrollbars{overflow:auto;}.yui-panel-container.show-scrollbars,.yui-tt.show-scrollbars{overflow:visible;}.yui-panel-container.show-scrollbars .underlay,.yui-tt.show-scrollbars .yui-tt-shadow{overflow:auto;}.yui-panel-container.shadow .underlay.yui-force-redraw{padding-bottom:1px;}.yui-effect-fade .underlay{display:none;}.yui-tt-shadow{position:absolute;}.yui-skin-sam .mask{background-color:#000;opacity:.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-panel-container{padding:0 1px;*padding:2px 3px;}.yui-skin-sam .yui-panel{position:relative;*zoom:1;left:0;top!
 :0;border-style:solid;border-width:1px 0;border-color:#808080;z-index:1;}.yui-skin-sam .yui-panel .hd,.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{*zoom:1;*position:relative;border-style:solid;border-width:0 1px;border-color:#808080;margin:0 -1px;}.yui-skin-sam .yui-panel .hd{border-bottom:solid 1px #ccc;}.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{background-color:#F2F2F2;}.yui-skin-sam .yui-panel .hd{padding:0 10px;font-size:93%;line-height:2;*line-height:1.9;font-weight:bold;color:#000;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -200px;}.yui-skin-sam .yui-panel .bd{padding:10px;}.yui-skin-sam .yui-panel .ft{border-top:solid 1px #808080;padding:5px 10px;font-size:77%;}.yui-skin-sam .yui-panel-container.focused .yui-panel .hd{}.yui-skin-sam .container-close{position:absolute;top:5px;right:6px;width:25px;height:15px;background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -300px;cursor:pointer;}.yui-skin-sam .yui-!
 panel-container .underlay{right:-1px;left:-1px;}.yui-skin-sam !
 .yui-pan
el-container.matte{padding:9px 10px;background-color:#fff;}.yui-skin-sam .yui-panel-container.shadow{_padding:2px 5px 0 3px;}.yui-skin-sam .yui-panel-container.shadow .underlay{position:absolute;top:2px;right:-3px;bottom:-3px;left:-3px;*top:3px;*left:-1px;*right:-1px;*bottom:-1px;_top:0;_right:0;_bottom:0;_left:0;_margin-top:3px;_margin-left:-1px;background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yui-dialog .ft{border-top:none;padding:0 10px 10px 10px;font-size:100%;}.yui-skin-sam .yui-dialog .ft .button-group{display:block;text-align:right;}.yui-skin-sam .yui-dialog .ft button.default{font-weight:bold;}.yui-skin-sam .yui-dialog .ft span.default{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-dialog .ft span.default .first-child{border-color:#304369;}.yui-skin-sam .yui-dialog .ft span.default button{color:#fff;}.yui-skin-sam .yui-simple-dialog .bd .yui-icon{background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 0;w!
 idth:16px;height:16px;margin-right:10px;float:left;}.yui-skin-sam .yui-simple-dialog .bd span.blckicon{background-position:0 -1100px;}.yui-skin-sam .yui-simple-dialog .bd span.alrticon{background-position:0 -1050px;}.yui-skin-sam .yui-simple-dialog .bd span.hlpicon{background-position:0 -1150px;}.yui-skin-sam .yui-simple-dialog .bd span.infoicon{background-position:0 -1200px;}.yui-skin-sam .yui-simple-dialog .bd span.warnicon{background-position:0 -1900px;}.yui-skin-sam .yui-simple-dialog .bd span.tipicon{background-position:0 -1250px;}.yui-skin-sam .yui-tt .bd{position:relative;top:0;left:0;z-index:1;color:#000;padding:2px 5px;border-color:#D4C237 #A6982B #A6982B #A6982B;border-width:1px;border-style:solid;background-color:#FFEE69;}.yui-skin-sam .yui-tt.show-scrollbars .bd{overflow:auto;}.yui-skin-sam .yui-tt-shadow{top:2px;right:-3px;left:-3px;bottom:-3px;background-color:#000;}.yui-skin-sam .yui-tt-shadow-visible{opacity:.12;*filter:alpha(opacity=12);}
+.yui-overlay,.yui-panel-container{visibility:hidden;position:absolute;z-index:2;}.yui-panel-container form{margin:0;}.mask{z-index:1;display:none;position:absolute;top:0;left:0;right:0;bottom:0;}.mask.block-scrollbars{overflow:auto;}.masked select,.drag select,.hide-select select{_visibility:hidden;}.yui-panel-container select{_visibility:inherit;}.hide-scrollbars,.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.show-scrollbars{overflow:auto;}.yui-panel-container.show-scrollbars,.yui-tt.show-scrollbars{overflow:visible;}.yui-panel-container.show-scrollbars .underlay,.yui-tt.show-scrollbars .yui-tt-shadow{overflow:auto;}.yui-panel-container.shadow .underlay.yui-force-redraw{padding-bottom:1px;}.yui-effect-fade .underlay{display:none;}.yui-tt-shadow{position:absolute;}.yui-skin-sam .mask{background-color:#000;opacity:.25;*filter:alpha(opacity=25);}.yui-skin-sam .yui-panel-container{padding:0 1px;*padding:2px 3px;}.yui-skin-sam .yui-panel{position:rel!
 ative;*zoom:1;left:0;top:0;border-style:solid;border-width:1px 0;border-color:#808080;z-index:1;}.yui-skin-sam .yui-panel .hd,.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{*zoom:1;*position:relative;border-style:solid;border-width:0 1px;border-color:#808080;margin:0 -1px;}.yui-skin-sam .yui-panel .hd{border-bottom:solid 1px #ccc;}.yui-skin-sam .yui-panel .bd,.yui-skin-sam .yui-panel .ft{background-color:#F2F2F2;}.yui-skin-sam .yui-panel .hd{padding:0 10px;font-size:93%;line-height:2;*line-height:1.9;font-weight:bold;color:#000;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -200px;}.yui-skin-sam .yui-panel .bd{padding:10px;}.yui-skin-sam .yui-panel .ft{border-top:solid 1px #808080;padding:5px 10px;font-size:77%;}.yui-skin-sam .yui-panel-container.focused .yui-panel .hd{}.yui-skin-sam .container-close{position:absolute;top:5px;right:6px;width:25px;height:15px;background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -300px;cursor:poin!
 ter;}.yui-skin-sam .yui-panel-container .underlay{right:-1px;l!
 eft:-1px
;}.yui-skin-sam .yui-panel-container.matte{padding:9px 10px;background-color:#fff;}.yui-skin-sam .yui-panel-container.shadow{_padding:2px 5px 0 3px;}.yui-skin-sam .yui-panel-container.shadow .underlay{position:absolute;top:2px;right:-3px;bottom:-3px;left:-3px;*top:3px;*left:-1px;*right:-1px;*bottom:-1px;_top:0;_right:0;_bottom:0;_left:0;_margin-top:3px;_margin-left:-1px;background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yui-dialog .ft{border-top:none;padding:0 10px 10px 10px;font-size:100%;}.yui-skin-sam .yui-dialog .ft .button-group{display:block;text-align:right;}.yui-skin-sam .yui-dialog .ft button.default{font-weight:bold;}.yui-skin-sam .yui-dialog .ft span.default{border-color:#304369;background-position:0 -1400px;}.yui-skin-sam .yui-dialog .ft span.default .first-child{border-color:#304369;}.yui-skin-sam .yui-dialog .ft span.default button{color:#fff;}.yui-skin-sam .yui-simple-dialog .bd .yui-icon{background:url(../../../../assets/skins/sam/spr!
 ite.png) no-repeat 0 0;width:16px;height:16px;margin-right:10px;float:left;}.yui-skin-sam .yui-simple-dialog .bd span.blckicon{background-position:0 -1100px;}.yui-skin-sam .yui-simple-dialog .bd span.alrticon{background-position:0 -1050px;}.yui-skin-sam .yui-simple-dialog .bd span.hlpicon{background-position:0 -1150px;}.yui-skin-sam .yui-simple-dialog .bd span.infoicon{background-position:0 -1200px;}.yui-skin-sam .yui-simple-dialog .bd span.warnicon{background-position:0 -1900px;}.yui-skin-sam .yui-simple-dialog .bd span.tipicon{background-position:0 -1250px;}.yui-skin-sam .yui-tt .bd{position:relative;top:0;left:0;z-index:1;color:#000;padding:2px 5px;border-color:#D4C237 #A6982B #A6982B #A6982B;border-width:1px;border-style:solid;background-color:#FFEE69;}.yui-skin-sam .yui-tt.show-scrollbars .bd{overflow:auto;}.yui-skin-sam .yui-tt-shadow{top:2px;right:-3px;left:-3px;bottom:-3px;background-color:#000;}.yui-skin-sam .yui-tt-shadow-visible{opacity:.12;*filter:alpha(opacity=!
 12);}

Modified: trunk/root/static/yui/container/container-debug.js
===================================================================
--- trunk/root/static/yui/container/container-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/container/container-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 (function () {
 
@@ -745,7 +745,6 @@
         * @type Object
         */
         EVENT_TYPES = {
-        
             "BEFORE_INIT": "beforeInit",
             "INIT": "init",
             "APPEND": "append",
@@ -760,7 +759,6 @@
             "SHOW": "show",
             "BEFORE_HIDE": "beforeHide",
             "HIDE": "hide"
-        
         },
             
         /**
@@ -830,7 +828,7 @@
     * @type String
     */
     Module.CSS_HEADER = "hd";
-    
+
     /**
     * Constant representing the module body
     * @property YAHOO.widget.Module.CSS_BODY
@@ -1289,24 +1287,44 @@
         },
 
         /**
-        * Initialized an empty IFRAME that is placed out of the visible area 
+        * Initialize an empty IFRAME that is placed out of the visible area 
         * that can be used to detect text resize.
         * @method initResizeMonitor
         */
         initResizeMonitor: function () {
 
+            var isGeckoWin = (YAHOO.env.ua.gecko && this.platform == "windows");
+            if (isGeckoWin) {
+                // Help prevent spinning loading icon which 
+                // started with FireFox 2.0.0.8/Win
+                var self = this;
+                setTimeout(function(){self._initResizeMonitor();}, 0);
+            } else {
+                this._initResizeMonitor();
+            }
+        },
+
+        /**
+         * Create and initialize the text resize monitoring iframe.
+         * 
+         * @protected
+         * @method _initResizeMonitor
+         */
+        _initResizeMonitor : function() {
+
             var oDoc, 
                 oIFrame, 
                 sHTML;
 
             function fireTextResize() {
-                YAHOO.log("Module got iframe contentWindow resize event", "info");
                 Module.textResizeEvent.fire();
             }
 
             if (!YAHOO.env.ua.opera) {
                 oIFrame = Dom.get("_yuiResizeMonitor");
 
+                var supportsCWResize = this._supportsCWResize();
+
                 if (!oIFrame) {
                     oIFrame = document.createElement("iframe");
 
@@ -1314,21 +1332,17 @@
                         oIFrame.src = Module.RESIZE_MONITOR_SECURE_URL;
                     }
 
-                    /*
-                        Need to set the iframe document for Gecko
-                        to fire resize events on the iframe contentWindow.
-                     */
-                    if (YAHOO.env.ua.gecko) {
-                         sHTML = ["<html><head><script ",
-                                  "type=\"text/javascript\">",
-                                  "window.onresize=function(){window.parent.",
-                                  "YAHOO.widget.Module.textResizeEvent.",
-                                  "fire();}", 
-                                  "<\/script></head>",
-                                  "<body></body></html>"].join('');
+                    if (!supportsCWResize) {
+                        // Can't monitor on contentWindow, so fire from inside iframe
+                        sHTML = ["<html><head><script ",
+                                 "type=\"text/javascript\">",
+                                 "window.onresize=function(){window.parent.",
+                                 "YAHOO.widget.Module.textResizeEvent.",
+                                 "fire();};<",
+                                 "\/script></head>",
+                                 "<body></body></html>"].join('');
 
-                        oIFrame.src = "data:text/html;charset=utf-8," +
-                            encodeURIComponent(sHTML);
+                        oIFrame.src = "data:text/html;charset=utf-8," + encodeURIComponent(sHTML);
                     }
 
                     oIFrame.id = "_yuiResizeMonitor";
@@ -1341,11 +1355,12 @@
                     oIFrame.style.position = "absolute";
                     oIFrame.style.visibility = "hidden";
 
-                    var fc = document.body.firstChild;
+                    var db = document.body,
+                        fc = db.firstChild;
                     if (fc) {
-                        document.body.insertBefore(oIFrame, fc);
+                        db.insertBefore(oIFrame, fc);
                     } else {
-                        document.body.appendChild(oIFrame);
+                        db.appendChild(oIFrame);
                     }
 
                     oIFrame.style.width = "10em";
@@ -1370,8 +1385,7 @@
                     Module.textResizeEvent.subscribe(this.onDomResize, this, true);
 
                     if (!Module.textResizeInitialized) {
-                         // We already handle gecko using the iframe's document content
-                        if (!YAHOO.env.ua.gecko) {
+                        if (supportsCWResize) {
                             if (!Event.on(oIFrame.contentWindow, "resize", fireTextResize)) {
                                 /*
                                      This will fail in IE if document.domain has 
@@ -1389,13 +1403,46 @@
         },
 
         /**
+         * Text resize monitor helper method.
+         * Determines if the browser supports resize events on iframe content windows.
+         * 
+         * @private
+         * @method _supportsCWResize
+         */
+        _supportsCWResize : function() {
+            /*
+                Gecko 1.8.0 (FF1.5), 1.8.1.0-5 (FF2) won't fire resize on contentWindow.
+                Gecko 1.8.1.6+ (FF2.0.0.6+) and all other browsers will fire resize on contentWindow.
+
+                We don't want to start sniffing for patch versions, so fire textResize the same
+                way on all FF, until 1.9 (3.x) is out
+             */
+            var bSupported = true;
+            if (YAHOO.env.ua.gecko && YAHOO.env.ua.gecko <= 1.8) {
+                bSupported = false;
+                /*
+                var v = navigator.userAgent.match(/rv:([^\s\)]*)/); // From YAHOO.env.ua
+                if (v && v[0]) {
+                    var sv = v[0].match(/\d\.\d\.(\d)/);
+                    if (sv && sv[1]) {
+                        if (parseInt(sv[1], 10) > 0) {
+                            bSupported = true;
+                        }
+                    }
+                }
+                */
+            }
+            return bSupported;
+        },
+
+        /**
         * Event handler fired when the resize monitor element is resized.
         * @method onDomResize
         * @param {DOMEvent} e The DOM resize event
         * @param {Object} obj The scope object passed to the handler
         */
         onDomResize: function (e, obj) {
-        
+
             var nLeft = -1 * this.resizeMonitor.offsetWidth,
                 nTop = -1 * this.resizeMonitor.offsetHeight;
         
@@ -1403,90 +1450,97 @@
             this.resizeMonitor.style.left =  nLeft + "px";
 
         },
-        
+
         /**
-        * Sets the Module's header content to the HTML specified, or appends 
+        * Sets the Module's header content to the string specified, or appends 
         * the passed element to the header. If no header is present, one will 
-        * be automatically created.
+        * be automatically created. An empty string can be passed to the method
+        * to clear the contents of the header.
+        * 
         * @method setHeader
-        * @param {String} headerContent The HTML used to set the header 
+        * @param {String} headerContent The string used to set the header.
+        * As a convenience, non HTMLElement objects can also be passed into 
+        * the method, and will be treated as strings, with the header innerHTML
+        * set to their default toString implementations.
         * <em>OR</em>
         * @param {HTMLElement} headerContent The HTMLElement to append to 
-        * the header
+        * <em>OR</em>
+        * @param {DocumentFragment} headerContent The document fragment 
+        * containing elements which are to be added to the header
         */
         setHeader: function (headerContent) {
-
             var oHeader = this.header || (this.header = createHeader());
-        
-            if (typeof headerContent == "string") {
 
-                oHeader.innerHTML = headerContent;
-
-            } else {
-
+            if (headerContent.nodeName) {
                 oHeader.innerHTML = "";
                 oHeader.appendChild(headerContent);
+            } else {
+                oHeader.innerHTML = headerContent;
+            }
 
-            }
-        
             this.changeHeaderEvent.fire(headerContent);
             this.changeContentEvent.fire();
 
         },
-        
+
         /**
         * Appends the passed element to the header. If no header is present, 
         * one will be automatically created.
         * @method appendToHeader
-        * @param {HTMLElement} element The element to append to the header
+        * @param {HTMLElement | DocumentFragment} element The element to 
+        * append to the header. In the case of a document fragment, the
+        * children of the fragment will be appended to the header.
         */
         appendToHeader: function (element) {
+            var oHeader = this.header || (this.header = createHeader());
 
-            var oHeader = this.header || (this.header = createHeader());
-        
             oHeader.appendChild(element);
 
             this.changeHeaderEvent.fire(element);
             this.changeContentEvent.fire();
 
         },
-        
+
         /**
         * Sets the Module's body content to the HTML specified, or appends the
         * passed element to the body. If no body is present, one will be 
-        * automatically created.
+        * automatically created. An empty string can be passed to the method
+        * to clear the contents of the body.
         * @method setBody
-        * @param {String} bodyContent The HTML used to set the body <em>OR</em>
+        * @param {String} bodyContent The HTML used to set the body. 
+        * As a convenience, non HTMLElement objects can also be passed into 
+        * the method, and will be treated as strings, with the body innerHTML
+        * set to their default toString implementations.
+        * <em>OR</em>
         * @param {HTMLElement} bodyContent The HTMLElement to append to the body
+        * <em>OR</em>
+        * @param {DocumentFragment} bodyContent The document fragment 
+        * containing elements which are to be added to the body
         */
         setBody: function (bodyContent) {
-
             var oBody = this.body || (this.body = createBody());
-        
-            if (typeof bodyContent == "string") {
 
-                oBody.innerHTML = bodyContent;
-
-            } else {
-
+            if (bodyContent.nodeName) {
                 oBody.innerHTML = "";
                 oBody.appendChild(bodyContent);
+            } else {
+                oBody.innerHTML = bodyContent;
+            }
 
-            }
-        
             this.changeBodyEvent.fire(bodyContent);
             this.changeContentEvent.fire();
+        },
 
-        },
-        
         /**
         * Appends the passed element to the body. If no body is present, one 
         * will be automatically created.
         * @method appendToBody
-        * @param {HTMLElement} element The element to append to the body
+        * @param {HTMLElement | DocumentFragment} element The element to 
+        * append to the body. In the case of a document fragment, the
+        * children of the fragment will be appended to the body.
+        * 
         */
         appendToBody: function (element) {
-
             var oBody = this.body || (this.body = createBody());
         
             oBody.appendChild(element);
@@ -1499,50 +1553,54 @@
         /**
         * Sets the Module's footer content to the HTML specified, or appends 
         * the passed element to the footer. If no footer is present, one will 
-        * be automatically created.
+        * be automatically created. An empty string can be passed to the method
+        * to clear the contents of the footer.
         * @method setFooter
         * @param {String} footerContent The HTML used to set the footer 
+        * As a convenience, non HTMLElement objects can also be passed into 
+        * the method, and will be treated as strings, with the footer innerHTML
+        * set to their default toString implementations.
         * <em>OR</em>
         * @param {HTMLElement} footerContent The HTMLElement to append to 
         * the footer
+        * <em>OR</em>
+        * @param {DocumentFragment} footerContent The document fragment containing 
+        * elements which are to be added to the footer
         */
         setFooter: function (footerContent) {
 
             var oFooter = this.footer || (this.footer = createFooter());
-        
-            if (typeof footerContent == "string") {
 
-                oFooter.innerHTML = footerContent;
-
-            } else {
-
+            if (footerContent.nodeName) {
                 oFooter.innerHTML = "";
                 oFooter.appendChild(footerContent);
+            } else {
+                oFooter.innerHTML = footerContent;
+            }
 
-            }
-        
             this.changeFooterEvent.fire(footerContent);
             this.changeContentEvent.fire();
+        },
 
-        },
-        
         /**
         * Appends the passed element to the footer. If no footer is present, 
         * one will be automatically created.
         * @method appendToFooter
-        * @param {HTMLElement} element The element to append to the footer
+        * @param {HTMLElement | DocumentFragment} element The element to 
+        * append to the footer. In the case of a document fragment, the
+        * children of the fragment will be appended to the footer
         */
         appendToFooter: function (element) {
 
             var oFooter = this.footer || (this.footer = createFooter());
-        
+
             oFooter.appendChild(element);
 
             this.changeFooterEvent.fire(element);
             this.changeContentEvent.fire();
 
         },
-        
+
         /**
         * Renders the Module by inserting the elements that are not already 
         * in the main Module into their correct places. Optionally appends 
@@ -1669,7 +1727,7 @@
             }
 
         },
-        
+
         /**
         * Shows the Module element by setting the visible configuration 
         * property to true. Also fires two events: beforeShowEvent prior to 
@@ -1679,7 +1737,7 @@
         show: function () {
             this.cfg.setProperty("visible", true);
         },
-        
+
         /**
         * Hides the Module element by setting the visible configuration 
         * property to false. Also fires two events: beforeHideEvent prior to 
@@ -1871,12 +1929,12 @@
                 key: "height", 
                 suppressEvent: true, 
                 supercedes: ["context", "fixedcenter", "iframe"] 
-            }, 
+            },
 
             "ZINDEX": { 
                 key: "zindex", 
                 value: null 
-            }, 
+            },
 
             "CONSTRAIN_TO_VIEWPORT": { 
                 key: "constraintoviewport", 
@@ -2161,7 +2219,7 @@
                 supercedes: DEFAULT_CONFIG.X.supercedes
     
             });
-    
+
             /**
             * The absolute y-coordinate position of the Overlay
             * @config y
@@ -2169,12 +2227,12 @@
             * @default null
             */
             this.cfg.addProperty(DEFAULT_CONFIG.Y.key, {
-    
+
                 handler: this.configY, 
                 validator: DEFAULT_CONFIG.Y.validator, 
                 suppressEvent: DEFAULT_CONFIG.Y.suppressEvent, 
                 supercedes: DEFAULT_CONFIG.Y.supercedes
-    
+
             });
     
             /**
@@ -2252,7 +2310,7 @@
                 supercedes: DEFAULT_CONFIG.HEIGHT.supercedes
             
             });
-
+            
             /**
             * CSS z-index of the Overlay.
             * @config zIndex
@@ -2265,7 +2323,7 @@
                 value: DEFAULT_CONFIG.ZINDEX.value
 
             });
-            
+
             /**
             * True if the Overlay should be prevented from being positioned 
             * out of the viewport.
@@ -2281,7 +2339,7 @@
                 supercedes: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.supercedes
 
             });
-            
+
             /**
             * @config iframe
             * @description Boolean indicating whether or not the Overlay should 
@@ -2543,7 +2601,7 @@
         * this will usually equal the owner.
         */
         configHeight: function (type, args, obj) {
-    
+
             var height = args[0],
                 el = this.element;
 
@@ -2656,9 +2714,9 @@
             y = this.cfg.getProperty("y");
             
             Dom.setX(this.element, x, true);
-            
+
             this.cfg.setProperty("xy", [x, y], true);
-           
+
             this.cfg.refireEvent("iframe");
             this.moveEvent.fire([x, y]);
         },
@@ -2891,6 +2949,26 @@
         },
 
         /**
+         * Set's the container's XY value from DOM if not already set.
+         * 
+         * Differs from syncPosition, in that the XY value is only sync'd with DOM if 
+         * not already set. The method also refire's the XY config property event, so any
+         * beforeMove, Move event listeners are invoked.
+         * 
+         * @method _primeXYFromDOM
+         * @protected
+         */
+        _primeXYFromDOM : function() {
+            if (YAHOO.lang.isUndefined(this.cfg.getProperty("xy"))) {
+                // Set CFG XY based on DOM XY
+                this.syncPosition();
+                // Account for XY being set silently in syncPosition (no moveTo fired/called)
+                this.cfg.refireEvent("xy");
+                this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);
+            }
+        },
+
+        /**
         * The default event handler fired when the "constraintoviewport" 
         * property is changed.
         * @method configConstrainToViewport
@@ -2902,39 +2980,22 @@
         * this will usually equal the owner.
         */
         configConstrainToViewport: function (type, args, obj) {
-
-            function constrainBeforeShow() {
-                if (YAHOO.lang.isUndefined(this.cfg.getProperty("xy"))) {
-                    // Set CFG XY based on DOM XY
-                    this.syncPosition();
-                }
-                var x = this.cfg.getProperty("x");
-                var y = this.cfg.getProperty("y");
-
-                // Account for XY being set silently (no moveTo fired/called)
-                var cXY = this.getConstrainedXY(x, y);
-                if (cXY[0] !== x || cXY[1] !== y) {
-                    this.moveTo(cXY[0], cXY[1]);
-                }
-            }
-
             var val = args[0];
 
             if (val) {
                 if (! Config.alreadySubscribed(this.beforeMoveEvent, this.enforceConstraints, this)) {
                     this.beforeMoveEvent.subscribe(this.enforceConstraints, this, true);
                 }
-
-                if (! Config.alreadySubscribed(this.beforeShowEvent, constrainBeforeShow)) {
-                    this.beforeShowEvent.subscribe(constrainBeforeShow);
+                if (! Config.alreadySubscribed(this.beforeShowEvent, this._primeXYFromDOM)) {
+                    this.beforeShowEvent.subscribe(this._primeXYFromDOM);
                 }
             } else {
-                this.beforeShowEvent.unsubscribe(constrainBeforeShow);
+                this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);
                 this.beforeMoveEvent.unsubscribe(this.enforceConstraints, this);
             }
         },
 
-        /**
+         /**
         * The default event handler fired when the "context" property 
         * is changed.
         * @method configContext
@@ -2950,38 +3011,28 @@
                 contextEl,
                 elementMagnetCorner,
                 contextMagnetCorner;
-            
+
             if (contextArgs) {
-            
                 contextEl = contextArgs[0];
                 elementMagnetCorner = contextArgs[1];
                 contextMagnetCorner = contextArgs[2];
                 
                 if (contextEl) {
-    
                     if (typeof contextEl == "string") {
-
                         this.cfg.setProperty("context", 
                             [document.getElementById(contextEl), 
                                 elementMagnetCorner, contextMagnetCorner], 
                                 true);
-
                     }
                     
                     if (elementMagnetCorner && contextMagnetCorner) {
-
                         this.align(elementMagnetCorner, contextMagnetCorner);
-
                     }
-
                 }
-
             }
-
         },
 
         // END BUILT-IN PROPERTY EVENT HANDLERS //
-
         /**
         * Aligns the Overlay to its context element using the specified corner 
         * points (represented by the constants TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, 
@@ -3829,19 +3880,17 @@
     * documentation for more details.
     */
     YAHOO.widget.Tooltip = function (el, userConfig) {
-    
         YAHOO.widget.Tooltip.superclass.constructor.call(this, el, userConfig);
-    
     };
 
-
     var Lang = YAHOO.lang,
         Event = YAHOO.util.Event,
+        CustomEvent = YAHOO.util.CustomEvent,
         Dom = YAHOO.util.Dom,
         Tooltip = YAHOO.widget.Tooltip,
-    
+
         m_oShadowTemplate,
-        
+
         /**
         * Constant representing the Tooltip's configuration properties
         * @property DEFAULT_CONFIG
@@ -3850,44 +3899,61 @@
         * @type Object
         */
         DEFAULT_CONFIG = {
-        
+
             "PREVENT_OVERLAP": { 
                 key: "preventoverlap", 
                 value: true, 
                 validator: Lang.isBoolean, 
                 supercedes: ["x", "y", "xy"] 
             },
-        
+
             "SHOW_DELAY": { 
                 key: "showdelay", 
                 value: 200, 
                 validator: Lang.isNumber 
             }, 
-        
+
             "AUTO_DISMISS_DELAY": { 
                 key: "autodismissdelay", 
                 value: 5000, 
                 validator: Lang.isNumber 
             }, 
-        
+
             "HIDE_DELAY": { 
                 key: "hidedelay", 
                 value: 250, 
                 validator: Lang.isNumber 
             }, 
-        
+
             "TEXT": { 
                 key: "text", 
                 suppressEvent: true 
             }, 
-        
+
             "CONTAINER": { 
                 key: "container"
+            },
+
+            "DISABLED": {
+                key: "disabled",
+                value: false,
+                suppressEvent: true
             }
-        
+        },
+
+        /**
+        * Constant representing the name of the Tooltip's events
+        * @property EVENT_TYPES
+        * @private
+        * @final
+        * @type Object
+        */
+        EVENT_TYPES = {
+            "CONTEXT_MOUSE_OVER": "contextMouseOver",
+            "CONTEXT_MOUSE_OUT": "contextMouseOut",
+            "CONTEXT_TRIGGER": "contextTrigger"
         };
 
-    
     /**
     * Constant representing the Tooltip CSS class
     * @property YAHOO.widget.Tooltip.CSS_TOOLTIP
@@ -3897,13 +3963,11 @@
     */
     Tooltip.CSS_TOOLTIP = "yui-tt";
 
-
     /* 
         "hide" event handler that sets a Tooltip instance's "width"
         configuration property back to its original value before 
         "setWidthToOffsetWidth" was called.
     */
-    
     function restoreOriginalWidth(p_sType, p_aArgs, p_oObject) {
 
         var sOriginalWidth = p_oObject[0],
@@ -3912,13 +3976,10 @@
             sCurrentWidth = oConfig.getProperty("width");
 
         if (sCurrentWidth == sNewWidth) {
-            
             oConfig.setProperty("width", sOriginalWidth);
-        
         }
 
         this.unsubscribe("hide", this._onHide, p_oObject);
-    
     }
 
     /* 
@@ -3935,7 +3996,6 @@
             sNewWidth,
             oClone;
 
-        
         if ((!sOriginalWidth || sOriginalWidth == "auto") && 
             (oConfig.getProperty("container") != oBody || 
             oConfig.getProperty("x") >= Dom.getViewportWidth() || 
@@ -3945,46 +4005,35 @@
             oClone.style.visibility = "hidden";
             oClone.style.top = "0px";
             oClone.style.left = "0px";
-            
+
             oBody.appendChild(oClone);
 
             sNewWidth = (oClone.offsetWidth + "px");
 
             oBody.removeChild(oClone);
-
             oClone = null;
 
             oConfig.setProperty("width", sNewWidth);
-
             oConfig.refireEvent("xy");
 
-            this.subscribe("hide", restoreOriginalWidth, 
-                [(sOriginalWidth || ""), sNewWidth]);
-        
+            this.subscribe("hide", restoreOriginalWidth, [(sOriginalWidth || ""), sNewWidth]);
         }
-
     }
 
     // "onDOMReady" that renders the ToolTip
 
     function onDOMReady(p_sType, p_aArgs, p_oObject) {
-    
         this.render(p_oObject);
-    
     }
 
-
     //  "init" event handler that automatically renders the Tooltip
 
     function onInit() {
-
         Event.onDOMReady(onDOMReady, this.cfg.getProperty("container"), this);
-
     }
 
-    
     YAHOO.extend(Tooltip, YAHOO.widget.Overlay, { 
-    
+
         /**
         * The Tooltip initialization method. This method is automatically 
         * called by the constructor. A Tooltip is automatically rendered by 
@@ -4013,17 +4062,80 @@
 
             this.cfg.queueProperty("visible", false);
             this.cfg.queueProperty("constraintoviewport", true);
-    
+
             this.setBody("");
 
             this.subscribe("beforeShow", setWidthToOffsetWidth);
             this.subscribe("init", onInit);
             this.subscribe("render", this.onRender);
-    
+
             this.initEvent.fire(Tooltip);
+        },
 
+        /**
+        * Initializes the custom events for Tooltip
+        * @method initEvents
+        */
+        initEvents: function () {
+
+            Tooltip.superclass.initEvents.call(this);
+            var SIGNATURE = CustomEvent.LIST;
+
+            /**
+            * CustomEvent fired when user mouses over a context element. Returning false from
+            * a subscriber to this event will prevent the tooltip from being displayed for
+            * the current context element.
+            * 
+            * @event contextMouseOverEvent
+            * @param {HTMLElement} context The context element which the user just moused over
+            * @param {DOMEvent} e The DOM event object, associated with the mouse over
+            */
+            this.contextMouseOverEvent = this.createEvent(EVENT_TYPES.CONTEXT_MOUSE_OVER);
+            this.contextMouseOverEvent.signature = SIGNATURE;
+
+            /**
+            * CustomEvent fired when the user mouses out of a context element.
+            * 
+            * @event contextMouseOutEvent
+            * @param {HTMLElement} context The context element which the user just moused out of
+            * @param {DOMEvent} e The DOM event object, associated with the mouse out
+            */
+            this.contextMouseOutEvent = this.createEvent(EVENT_TYPES.CONTEXT_MOUSE_OUT);
+            this.contextMouseOutEvent.signature = SIGNATURE;
+
+            /**
+            * CustomEvent fired just before the tooltip is displayed for the current context.
+            * <p>
+            *  You can subscribe to this event if you need to set up the text for the 
+            *  tooltip based on the context element for which it is about to be displayed.
+            * </p>
+            * <p>This event differs from the beforeShow event in following respects:</p>
+            * <ol>
+            *   <li>
+            *    When moving from one context element to another, if the tooltip is not
+            *    hidden (the <code>hidedelay</code> is not reached), the beforeShow and Show events will not
+            *    be fired when the tooltip is displayed for the new context since it is already visible.
+            *    However the contextTrigger event is always fired before displaying the tooltip for
+            *    a new context.
+            *   </li>
+            *   <li>
+            *    The trigger event provides access to the context element, allowing you to 
+            *    set the text of the tooltip based on context element for which the tooltip is
+            *    triggered.
+            *   </li>
+            * </ol>
+            * <p>
+            *  It is not possible to prevent the tooltip from being displayed
+            *  using this event. You can use the contextMouseOverEvent if you need to prevent
+            *  the tooltip from being displayed.
+            * </p>
+            * @event contextTriggerEvent
+            * @param {HTMLElement} context The context element for which the tooltip is triggered
+            */
+            this.contextTriggerEvent = this.createEvent(EVENT_TYPES.CONTEXT_TRIGGER);
+            this.contextTriggerEvent.signature = SIGNATURE;
         },
-        
+
         /**
         * Initializes the class's configurable properties which can be 
         * changed using the Overlay's Config object (cfg).
@@ -4032,7 +4144,7 @@
         initDefaultConfig: function () {
 
             Tooltip.superclass.initDefaultConfig.call(this);
-        
+
             /**
             * Specifies whether the Tooltip should be kept from overlapping 
             * its context element.
@@ -4045,7 +4157,7 @@
                 validator: DEFAULT_CONFIG.PREVENT_OVERLAP.validator, 
                 supercedes: DEFAULT_CONFIG.PREVENT_OVERLAP.supercedes
             });
-        
+
             /**
             * The number of milliseconds to wait before showing a Tooltip 
             * on mouseover.
@@ -4058,7 +4170,7 @@
                 value: 200, 
                 validator: DEFAULT_CONFIG.SHOW_DELAY.validator
             });
-        
+
             /**
             * The number of milliseconds to wait before automatically 
             * dismissing a Tooltip after the mouse has been resting on the 
@@ -4072,7 +4184,7 @@
                 value: DEFAULT_CONFIG.AUTO_DISMISS_DELAY.value,
                 validator: DEFAULT_CONFIG.AUTO_DISMISS_DELAY.validator
             });
-        
+
             /**
             * The number of milliseconds to wait before hiding a Tooltip 
             * on mouseover.
@@ -4085,7 +4197,7 @@
                 value: DEFAULT_CONFIG.HIDE_DELAY.value, 
                 validator: DEFAULT_CONFIG.HIDE_DELAY.validator
             });
-        
+
             /**
             * Specifies the Tooltip's text. 
             * @config text
@@ -4108,8 +4220,24 @@
                 handler: this.configContainer,
                 value: document.body
             });
-        
+
             /**
+            * Specifies whether or not the tooltip is disabled. Disabled tooltips
+            * will not be displayed. If the tooltip is driven by the title attribute
+            * of the context element, the title attribute will still be removed for 
+            * disabled tooltips, to prevent default tooltip behavior.
+            * 
+            * @config disabled
+            * @type Boolean
+            * @default false
+            */
+            this.cfg.addProperty(DEFAULT_CONFIG.DISABLED.key, {
+                handler: this.configContainer,
+                value: DEFAULT_CONFIG.DISABLED.value,
+                supressEvent: DEFAULT_CONFIG.DISABLED.suppressEvent
+            });
+
+            /**
             * Specifies the element or elements that the Tooltip should be 
             * anchored to on mouseover.
             * @config context
@@ -4167,16 +4295,11 @@
         * this will usually equal the owner.
         */
         configContainer: function (type, args, obj) {
-
             var container = args[0];
 
             if (typeof container == 'string') {
-
-                this.cfg.setProperty("container", 
-                    document.getElementById(container), true);
-
+                this.cfg.setProperty("container", document.getElementById(container), true);
             }
-
         },
         
         /**
@@ -4191,23 +4314,16 @@
                 nElements,
                 oElement,
                 i;
-        
-            
+
             if (aElements) {
                 nElements = aElements.length;
                 if (nElements > 0) {
                     i = nElements - 1;
                     do {
                         oElement = aElements[i];
-        
-                        Event.removeListener(oElement, "mouseover", 
-                            this.onContextMouseOver);
-
-                        Event.removeListener(oElement, "mousemove", 
-                            this.onContextMouseMove);
-
-                        Event.removeListener(oElement, "mouseout", 
-                            this.onContextMouseOut);
+                        Event.removeListener(oElement, "mouseover", this.onContextMouseOver);
+                        Event.removeListener(oElement, "mousemove", this.onContextMouseMove);
+                        Event.removeListener(oElement, "mouseout", this.onContextMouseOut);
                     }
                     while (i--);
                 }
@@ -4231,72 +4347,47 @@
                 nElements,
                 oElement,
                 i;
-            
-        
+
             if (context) {
-        
+
                 // Normalize parameter into an array
                 if (! (context instanceof Array)) {
-
                     if (typeof context == "string") {
-
-                        this.cfg.setProperty("context", 
-                            [document.getElementById(context)], true);
-
+                        this.cfg.setProperty("context", [document.getElementById(context)], true);
                     } else { // Assuming this is an element
-
                         this.cfg.setProperty("context", [context], true);
-
                     }
-
                     context = this.cfg.getProperty("context");
+                }
 
-                }
-        
-        
                 // Remove any existing mouseover/mouseout listeners
                 this._removeEventListeners();
-        
+
                 // Add mouseover/mouseout listeners to context elements
                 this._context = context;
-        
+
                 aElements = this._context;
-                
+
                 if (aElements) {
-            
                     nElements = aElements.length;
-                    
                     if (nElements > 0) {
-                    
                         i = nElements - 1;
-                        
                         do {
-            
                             oElement = aElements[i];
-            
-                            Event.on(oElement, "mouseover", 
-                                this.onContextMouseOver, this);
-
-                            Event.on(oElement, "mousemove", 
-                                this.onContextMouseMove, this);
-
-                            Event.on(oElement, "mouseout", 
-                                this.onContextMouseOut, this);
-                        
+                            Event.on(oElement, "mouseover", this.onContextMouseOver, this);
+                            Event.on(oElement, "mousemove", this.onContextMouseMove, this);
+                            Event.on(oElement, "mouseout", this.onContextMouseOut, this);
                         }
                         while (i--);
-                    
                     }
-            
                 }
-        
             }
         },
-        
+
         // END BUILT-IN PROPERTY EVENT HANDLERS //
-        
+
         // BEGIN BUILT-IN DOM EVENT HANDLERS //
-        
+
         /**
         * The default event handler fired when the user moves the mouse while 
         * over the context element.
@@ -4307,9 +4398,8 @@
         onContextMouseMove: function (e, obj) {
             obj.pageX = Event.getPageX(e);
             obj.pageY = Event.getPageY(e);
-        
         },
-        
+
         /**
         * The default event handler fired when the user mouses over the 
         * context element.
@@ -4318,38 +4408,36 @@
         * @param {Object} obj The object argument
         */
         onContextMouseOver: function (e, obj) {
-        
             var context = this;
-        
-            if (obj.hideProcId) {
 
-                clearTimeout(obj.hideProcId);
-
-                obj.logger.log("Clearing hide timer: " + 
-                    obj.hideProcId, "time");
-
-                obj.hideProcId = null;
-
-            }
-
-            Event.on(context, "mousemove", obj.onContextMouseMove, obj);
-
             if (context.title) {
                 obj._tempTitle = context.title;
                 context.title = "";
             }
 
-            /**
-            * The unique process ID associated with the thread responsible 
-            * for showing the Tooltip.
-            * @type int
-            */
-            obj.showProcId = obj.doShow(e, context);
-            obj.logger.log("Setting show tooltip timeout: " + 
-                obj.showProcId, "time");
+            // Fire first, to honor disabled set in the listner
+            if (obj.fireEvent("contextMouseOver", context, e) !== false 
+                    && !obj.cfg.getProperty("disabled")) {
 
+                // Stop the tooltip from being hidden (set on last mouseout)
+                if (obj.hideProcId) {
+                    clearTimeout(obj.hideProcId);
+                    obj.logger.log("Clearing hide timer: " + obj.hideProcId, "time");
+                    obj.hideProcId = null;
+                }
+
+                Event.on(context, "mousemove", obj.onContextMouseMove, obj);
+
+                /**
+                * The unique process ID associated with the thread responsible 
+                * for showing the Tooltip.
+                * @type int
+                */
+                obj.showProcId = obj.doShow(e, context);
+                obj.logger.log("Setting show tooltip timeout: " + obj.showProcId, "time");
+            }
         },
-        
+
         /**
         * The default event handler fired when the user mouses out of 
         * the context element.
@@ -4359,36 +4447,33 @@
         */
         onContextMouseOut: function (e, obj) {
             var el = this;
-        
+
             if (obj._tempTitle) {
                 el.title = obj._tempTitle;
                 obj._tempTitle = null;
             }
-        
+
             if (obj.showProcId) {
                 clearTimeout(obj.showProcId);
-                obj.logger.log("Clearing show timer: " + 
-                    obj.showProcId, "time");
+                obj.logger.log("Clearing show timer: " + obj.showProcId, "time");
                 obj.showProcId = null;
             }
-        
+
             if (obj.hideProcId) {
                 clearTimeout(obj.hideProcId);
-                obj.logger.log("Clearing hide timer: " + 
-                    obj.hideProcId, "time");
+                obj.logger.log("Clearing hide timer: " + obj.hideProcId, "time");
                 obj.hideProcId = null;
             }
-        
-        
+
+            obj.fireEvent("contextMouseOut", el, e);
+
             obj.hideProcId = setTimeout(function () {
                 obj.hide();
-    
             }, obj.cfg.getProperty("hidedelay"));
-    
         },
-        
+
         // END BUILT-IN DOM EVENT HANDLERS //
-        
+
         /**
         * Processes the showing of the Tooltip by setting the timeout delay 
         * and offset of the Tooltip.
@@ -4404,14 +4489,13 @@
 
             if (YAHOO.env.ua.opera && context.tagName && 
                 context.tagName.toUpperCase() == "A") {
-
                 yOffset += 12;
-
             }
 
             return setTimeout(function () {
 
                 var txt = me.cfg.getProperty("text");
+
                 // title does not over-ride text
                 if (me._tempTitle && (txt === "" || YAHOO.lang.isUndefined(txt) || YAHOO.lang.isNull(txt))) {
                     me.setBody(me._tempTitle);
@@ -4426,19 +4510,18 @@
                     me.preventOverlap(me.pageX, me.pageY);
                 }
 
-                Event.removeListener(context, "mousemove", 
-                    me.onContextMouseMove);
+                Event.removeListener(context, "mousemove", me.onContextMouseMove);
 
+                me.contextTriggerEvent.fire(context);
+
                 me.show();
+
                 me.hideProcId = me.doHide();
+                me.logger.log("Hide tooltip time active: " + me.hideProcId, "time");
 
-                me.logger.log("Hide tooltip time active: " +
-                    me.hideProcId, "time");
-
             }, this.cfg.getProperty("showdelay"));
-        
         },
-        
+
         /**
         * Sets the timeout for the auto-dismiss delay, which by default is 5 
         * seconds, meaning that a tooltip will automatically dismiss itself 
@@ -4446,18 +4529,18 @@
         * @method doHide
         */
         doHide: function () {
-        
+
             var me = this;
-        
+
             me.logger.log("Setting hide tooltip timeout", "time");
-        
+
             return setTimeout(function () {
-        
+
                 me.logger.log("Hide tooltip", "time");
                 me.hide();
-        
+
             }, this.cfg.getProperty("autodismissdelay"));
-        
+
         },
         
         /**
@@ -4504,29 +4587,21 @@
                     oShadow = this._shadow;
             
                 if (oShadow) {
-            
                     oShadow.style.width = (oElement.offsetWidth + 6) + "px";
                     oShadow.style.height = (oElement.offsetHeight + 1) + "px"; 
-            
                 }
             
             }
 
-
             function addShadowVisibleClass() {
-            
                 Dom.addClass(this._shadow, "yui-tt-shadow-visible");
-            
             }
             
 
             function removeShadowVisibleClass() {
-        
                 Dom.removeClass(this._shadow, "yui-tt-shadow-visible");
-            
             }
-    
-    
+
             function createShadow() {
     
                 var oShadow = this._shadow,
@@ -4541,73 +4616,49 @@
                     Module = YAHOO.widget.Module;
                     nIE = YAHOO.env.ua.ie;
                     me = this;
-    
+
                     if (!m_oShadowTemplate) {
-        
                         m_oShadowTemplate = document.createElement("div");
                         m_oShadowTemplate.className = "yui-tt-shadow";
-                    
                     }
-        
+
                     oShadow = m_oShadowTemplate.cloneNode(false);
-        
+
                     oElement.appendChild(oShadow);
-                    
+
                     this._shadow = oShadow;
-    
+
                     addShadowVisibleClass.call(this);
-        
+
                     this.subscribe("beforeShow", addShadowVisibleClass);
                     this.subscribe("beforeHide", removeShadowVisibleClass);
 
-                    if (nIE == 6 || 
-                        (nIE == 7 && document.compatMode == "BackCompat")) {
-                
+                    if (nIE == 6 || (nIE == 7 && document.compatMode == "BackCompat")) {
                         window.setTimeout(function () { 
-        
                             sizeShadow.call(me); 
-        
                         }, 0);
     
                         this.cfg.subscribeToConfigEvent("width", sizeShadow);
                         this.cfg.subscribeToConfigEvent("height", sizeShadow);
                         this.subscribe("changeContent", sizeShadow);
-    
-                        Module.textResizeEvent.subscribe(sizeShadow, 
-                                                            this, true);
-                        
+
+                        Module.textResizeEvent.subscribe(sizeShadow, this, true);
                         this.subscribe("destroy", function () {
-                        
-                            Module.textResizeEvent.unsubscribe(sizeShadow, 
-                                                                    this);
-                        
+                            Module.textResizeEvent.unsubscribe(sizeShadow, this);
                         });
-                
                     }
-                
                 }
-    
             }
-    
-    
+
             function onBeforeShow() {
-            
                 createShadow.call(this);
-    
                 this.unsubscribe("beforeShow", onBeforeShow);
-            
             }
-    
-    
+
             if (this.cfg.getProperty("visible")) {
-    
                 createShadow.call(this);
-            
-            }
-            else {
-    
+            } else {
                 this.subscribe("beforeShow", onBeforeShow);
-            
             }
         
         },
@@ -4621,7 +4672,7 @@
         
             // Remove any existing mouseover/mouseout listeners
             this._removeEventListeners();
-        
+
             Tooltip.superclass.destroy.call(this);  
         
         },
@@ -4679,11 +4730,9 @@
         * @type Object
         */
         EVENT_TYPES = {
-        
             "SHOW_MASK": "showMask",
             "HIDE_MASK": "hideMask",
             "DRAG": "drag"
-        
         },
 
         /**
@@ -4755,6 +4804,23 @@
     */
     Panel.CSS_PANEL_CONTAINER = "yui-panel-container";
 
+    /**
+     * Constant representing the default set of focusable elements 
+     * on the pagewhich Modal Panels will prevent access to, when
+     * the modal mask is displayed
+     * 
+     * @property YAHOO.widget.Panel.FOCUSABLE
+     * @static
+     * @type Array
+     */
+    Panel.FOCUSABLE = [
+        "a",
+        "button",
+        "select",
+        "textarea",
+        "input"
+    ];
+
     // Private CustomEvent listeners
 
     /* 
@@ -4820,86 +4886,6 @@
         }
     }
 
-    /* 
-        "focus" event handler for a focuable element.  Used to automatically 
-        blur the element when it receives focus to ensure that a Panel 
-        instance's modality is not compromised.
-    */
-
-    function onElementFocus() {
-        this.blur();
-    }
-
-    /* 
-        "showMask" event handler that adds a "focus" event handler to all
-        focusable elements in the document to enforce a Panel instance's 
-        modality from being compromised.
-    */
-
-    function addFocusEventHandlers(p_sType, p_aArgs) {
-
-        var me = this;
-
-        function isFocusable(el) {
-
-            var sTagName = el.tagName.toUpperCase(),
-                bFocusable = false;
-            
-            switch (sTagName) {
-            
-            case "A":
-            case "BUTTON":
-            case "SELECT":
-            case "TEXTAREA":
-
-                if (!Dom.isAncestor(me.element, el)) {
-                    Event.on(el, "focus", onElementFocus, el, true);
-                    bFocusable = true;
-                }
-
-                break;
-
-            case "INPUT":
-
-                if (el.type != "hidden" && 
-                    !Dom.isAncestor(me.element, el)) {
-
-                    Event.on(el, "focus", onElementFocus, el, true);
-                    bFocusable = true;
-
-                }
-
-                break;
-            
-            }
-
-            return bFocusable;
-
-        }
-
-        this.focusableElements = Dom.getElementsBy(isFocusable);
-    
-    }
-
-    /* 
-        "hideMask" event handler that removes all "focus" event handlers added 
-        by the "addFocusEventHandlers" method.
-    */
-    
-    function removeFocusEventHandlers(p_sType, p_aArgs) {
-
-        var aElements = this.focusableElements,
-            nElements = aElements.length,
-            el2,
-            i;
-
-        for (i = 0; i < nElements; i++) {
-            el2 = aElements[i];
-            Event.removeListener(el2, "focus", onElementFocus);
-        }
-
-    }
-
     YAHOO.extend(Panel, Overlay, {
 
         /**
@@ -4933,14 +4919,87 @@
                 this.cfg.applyConfig(userConfig, true);
             }
 
-            this.subscribe("showMask", addFocusEventHandlers);
-            this.subscribe("hideMask", removeFocusEventHandlers);
+            this.subscribe("showMask", this._addFocusHandlers);
+            this.subscribe("hideMask", this._removeFocusHandlers);
             this.subscribe("beforeRender", createHeader);
 
             this.initEvent.fire(Panel);
         },
-        
+
         /**
+         * @method _onElementFocus 
+         * @private
+         * 
+         * "focus" event handler for a focuable element. Used to automatically 
+         * blur the element when it receives focus to ensure that a Panel 
+         * instance's modality is not compromised.
+         * 
+         * @param {Event} e The DOM event object
+         */
+        _onElementFocus : function(e){
+            this.blur();
+        },
+
+        /** 
+         *  @method _addFocusHandlers
+         *  @protected
+         *  
+         *  "showMask" event handler that adds a "focus" event handler to all
+         *  focusable elements in the document to enforce a Panel instance's 
+         *  modality from being compromised.
+         *  
+         *  @param p_sType {String} Custom event type
+         *  @param p_aArgs {Array} Custom event arguments
+         */
+        _addFocusHandlers: function(p_sType, p_aArgs) {
+            var me = this,
+                focus = "focus",
+                hidden = "hidden";
+
+            function isFocusable(el) {
+                // NOTE: if e.type is undefined that's fine, want to avoid perf 
+                // impact of tagName check to filter for inputs
+                if (el.type !== hidden && !Dom.isAncestor(me.element, el)) {
+                    Event.on(el, focus, me._onElementFocus);
+                    return true;
+                }
+                return false;
+            }
+
+            var focusable = Panel.FOCUSABLE,
+                l = focusable.length,
+                arr = [];
+
+            for (var i = 0; i < l; i++) {
+                arr = arr.concat(Dom.getElementsBy(isFocusable, focusable[i]));
+            }
+
+            this.focusableElements = arr;
+        },
+
+        /** 
+         *  @method _removeFocusHandlers
+         *  @protected
+         *  
+         *  "hideMask" event handler that removes all "focus" event handlers added 
+         *  by the "addFocusEventHandlers" method.
+         *  
+         *  @param p_sType {String} Event type
+         *  @param p_aArgs {Array} Event Arguments
+         */
+        _removeFocusHandlers: function(p_sType, p_aArgs) {
+            var aElements = this.focusableElements,
+                nElements = aElements.length,
+                focus = "focus";
+
+            if (aElements) {
+                for (var i = 0; i < nElements; i++) {
+                    Event.removeListener(aElements[i], focus, this._onElementFocus);
+                }
+            }
+        },
+
+        /**
         * Initializes the custom events for Module which are fired 
         * automatically at appropriate times by the Module class.
         */
@@ -5199,9 +5258,10 @@
         * this will usually equal the owner.
         */
         configUnderlay: function (type, args, obj) {
-    
+
             var UA = YAHOO.env.ua,
                 bMacGecko = (this.platform == "mac" && UA.gecko),
+                bIEQuirks = (UA.ie == 6 || (UA.ie == 7 && document.compatMode == "BackCompat")),
                 sUnderlay = args[0].toLowerCase(),
                 oUnderlay = this.underlay,
                 oElement = this.element;
@@ -5220,9 +5280,7 @@
             }
 
             function createUnderlay() {
-
-                var nIE;
-
+                var bNew = false;
                 if (!oUnderlay) { // create if not already in DOM
 
                     if (!m_oUnderlayTemplate) {
@@ -5235,28 +5293,26 @@
 
                     this.underlay = oUnderlay;
 
-                    nIE = UA.ie;
-
-                    if (nIE == 6 || (nIE == 7 && document.compatMode == "BackCompat")) {
-
+                    if (bIEQuirks) {
                         this.sizeUnderlay();
-
                         this.cfg.subscribeToConfigEvent("width", this.sizeUnderlay);
                         this.cfg.subscribeToConfigEvent("height",this.sizeUnderlay);
                         this.changeContentEvent.subscribe(this.sizeUnderlay);
-
                         YAHOO.widget.Module.textResizeEvent.subscribe(this.sizeUnderlay, this, true);
                     }
 
                     if (UA.webkit && UA.webkit < 420) {
                         this.changeContentEvent.subscribe(fixWebkitUnderlay);
                     }
+                    bNew = true;
                 }
-
             }
 
             function onBeforeShow() {
-                createUnderlay.call(this);
+                var bNew = createUnderlay.call(this);
+                if (!bNew && bIEQuirks) {
+                    this.sizeUnderlay();
+                }
                 this._underlayDeferred = false;
                 this.beforeShowEvent.unsubscribe(onBeforeShow);
             }
@@ -5279,51 +5335,41 @@
                     this.underlay = null;
                 }
             }
-        
 
             switch (sUnderlay) {
-    
                 case "shadow":
-    
                     Dom.removeClass(oElement, "matte");
                     Dom.addClass(oElement, "shadow");
-    
                     break;
-    
                 case "matte":
-    
                     if (!bMacGecko) {
                         destroyUnderlay.call(this);
                     }
-    
                     Dom.removeClass(oElement, "shadow");
                     Dom.addClass(oElement, "matte");
-    
                     break;
                 default:
-    
                     if (!bMacGecko) {
                         destroyUnderlay.call(this);
                     }
                     Dom.removeClass(oElement, "shadow");
                     Dom.removeClass(oElement, "matte");
-    
                     break;
             }
 
             if ((sUnderlay == "shadow") || (bMacGecko && !oUnderlay)) {
-                
                 if (this.cfg.getProperty("visible")) {
-                    createUnderlay.call(this);
-                }
-                else {
+                    var bNew = createUnderlay.call(this);
+                    if (!bNew && bIEQuirks) {
+                        this.sizeUnderlay();
+                    }
+                } else {
                     if (!this._underlayDeferred) {
                         this.beforeShowEvent.subscribe(onBeforeShow);
                         this._underlayDeferred = true;
                     }
                 }
             }
-    
         },
         
         /**
@@ -5571,19 +5617,14 @@
         * @method sizeUnderlay
         */
         sizeUnderlay: function () {
-
             var oUnderlay = this.underlay,
                 oElement;
 
             if (oUnderlay) {
-
                 oElement = this.element;
-
                 oUnderlay.style.width = oElement.offsetWidth + "px";
                 oUnderlay.style.height = oElement.offsetHeight + "px";
-
             }
-
         },
 
         
@@ -5709,6 +5750,10 @@
 
                 this.mask = oMask;
 
+                if (YAHOO.env.ua.gecko && this.platform == "mac") {
+                    Dom.addClass(this.mask, "block-scrollbars");
+                }
+
                 // Stack mask based on the element zindex
                 this.stackMask();
             }
@@ -5831,12 +5876,22 @@
 (function () {
 
     /**
+    * <p>
     * Dialog is an implementation of Panel that can be used to submit form 
-    * data. Built-in functionality for buttons with event handlers is included, 
-    * and button sets can be build dynamically, or the preincluded ones for 
-    * Submit/Cancel and OK/Cancel can be utilized. Forms can be processed in 3
-    * ways -- via an asynchronous Connection utility call, a simple form 
-    * POST or GET, or manually.
+    * data.
+    * </p>
+    * <p>
+    * Built-in functionality for buttons with event handlers is included. 
+    * If the optional YUI Button dependancy is included on the page, the buttons
+    * created will be instances of YAHOO.widget.Button, otherwise regular HTML buttons
+    * will be created.
+    * </p>
+    * <p>
+    * Forms can be processed in 3 ways -- via an asynchronous Connection utility call, 
+    * a simple form POST or GET, or manually. The YUI Connection utility should be
+    * included if you're using the default "async" postmethod, but is not required if
+    * you're using any of the other postmethod values.
+    * </p>
     * @namespace YAHOO.widget
     * @class Dialog
     * @extends YAHOO.widget.Panel
@@ -5848,12 +5903,9 @@
     * documentation for more details.
     */
     YAHOO.widget.Dialog = function (el, userConfig) {
-    
         YAHOO.widget.Dialog.superclass.constructor.call(this, el, userConfig);
-    
     };
 
-
     var Event = YAHOO.util.Event,
         CustomEvent = YAHOO.util.CustomEvent,
         Dom = YAHOO.util.Dom,
@@ -5879,7 +5931,7 @@
             "CANCEL": "cancel"
         
         },
-        
+
         /**
         * Constant representing the Dialog's configuration properties
         * @property DEFAULT_CONFIG
@@ -5888,17 +5940,22 @@
         * @type Object
         */
         DEFAULT_CONFIG = {
-        
+
             "POST_METHOD": { 
                 key: "postmethod", 
                 value: "async" 
             },
-            
+
             "BUTTONS": { 
                 key: "buttons", 
                 value: "none" 
+            },
+
+            "HIDEAFTERSUBMIT" : {
+                key: "hideaftersubmit",
+                value: true
             }
-        };    
+        };
 
     /**
     * Constant representing the default CSS class used for a Dialog
@@ -5939,7 +5996,6 @@
     
     YAHOO.extend(Dialog, YAHOO.widget.Panel, { 
 
-        
         /**
         * @property form
         * @description Object reference to the Dialog's 
@@ -5957,23 +6013,28 @@
         */
         initDefaultConfig: function () {
             Dialog.superclass.initDefaultConfig.call(this);
-        
+
             /**
             * The internally maintained callback object for use with the 
-            * Connection utility
+            * Connection utility. The format of the callback object is 
+            * similar to Connection Manager's callback object and is 
+            * simply passed through to Connection Manager when the async 
+            * request is made.
             * @property callback
             * @type Object
             */
             this.callback = {
-    
+
                 /**
                 * The function to execute upon success of the 
-                * Connection submission
+                * Connection submission (when the form does not
+                * contain a file input element).
+                * 
                 * @property callback.success
                 * @type Function
                 */
                 success: null,
-    
+
                 /**
                 * The function to execute upon failure of the 
                 * Connection submission
@@ -5981,20 +6042,38 @@
                 * @type Function
                 */
                 failure: null,
-    
+
                 /**
+                 *<p>
+                * The function to execute upon success of the 
+                * Connection submission, when the form contains
+                * a file input element.
+                * </p>
+                * <p>
+                * <em>NOTE:</em> Connection manager will not
+                * invoke the success or failure handlers for the file
+                * upload use case. This will be the only callback
+                * handler invoked.
+                * </p>
+                * <p>
+                * For more information, see the <a href="http://developer.yahoo.com/yui/connection/#file">
+                * Connection Manager documenation on file uploads</a>.
+                * </p>
+                * @property callback.upload
+                * @type Function
+                */
+
+                /**
                 * The arbitraty argument or arguments to pass to the Connection 
                 * callback functions
                 * @property callback.argument
                 * @type Object
                 */
                 argument: null
-    
+
             };
-        
 
             // Add form dialog config properties //
-            
             /**
             * The method to use for posting the Dialog's form. Possible values 
             * are "async", "form", and "manual".
@@ -6014,15 +6093,28 @@
                     }
                 }
             });
-            
+
             /**
+            * This property is used to configure whether or not the 
+            * dialog should be automatically hidden after submit.
+            * 
+            * @config hideaftersubmit
+            * @type Boolean
+            * @default true
+            */
+            this.cfg.addProperty(DEFAULT_CONFIG.HIDEAFTERSUBMIT.key, {
+                value: DEFAULT_CONFIG.HIDEAFTERSUBMIT.value
+            }); 
+
+            /**
             * Array of object literals, each containing a set of properties 
             * defining a button to be appended into the Dialog's footer.
+            * 
             * Each button object in the buttons array can have three properties:
             * <dt>text:</dt>
-            * <dd>The text that will display on the face of the button.  <em>
-            * Please note:</em> As of version 2.3, the text can include 
-            * HTML.</dd>
+            * <dd>The text that will display on the face of the button. The text can 
+            * include HTML, as long as it is compliant with HTML Button specifications.
+            * </dd>
             * <dt>handler:</dt>
             * <dd>Can be either:
             *     <ol>
@@ -6030,18 +6122,23 @@
             * button is clicked.  (In this case scope of this function is 
             * always its Dialog instance.)</li>
             *         <li>An object literal representing the code to be 
-            * executed when the button is clicked.  Format:<br> <code> {<br>  
+            * executed when the button is clicked.  Format:<br> <code> {<br>
             * <strong>fn:</strong> Function,   // The handler to call 
-            * when  the event fires.<br> <strong>obj:</strong> Object, 
+            * when  the event fires.<br> <strong>obj:</strong> Object,
             * // An  object to pass back to the handler.<br> <strong>
             * scope:</strong>  Object // The object to use for the 
-            * scope of the handler. <br> } </code> <br><em>Please note: this 
-            * functionality was added in version 2.3.</em></li>
+            * scope of the handler. <br> } </code> <br></li>
             *     </ol>
             * </dd>
             * <dt>isDefault:</dt>
             * <dd>An optional boolean value that specifies that a button 
             * should be highlighted and focused by default.</dd>
+            * 
+            * <em>NOTE:</em>If the YUI Button Widget is included on the page, 
+            * the buttons created will be instances of YAHOO.widget.Button. 
+            * Otherwise, HTML Buttons (<code><BUTTON></code>) will be 
+            * created.
+            * 
             * @config buttons
             * @type {Array|String}
             * @default "none"
@@ -6050,9 +6147,9 @@
                 handler: this.configButtons,
                 value: DEFAULT_CONFIG.BUTTONS.value
             }); 
-            
+
         },
-        
+
         /**
         * Initializes the custom events for Dialog which are fired 
         * automatically at appropriate times by the Dialog class.
@@ -6060,9 +6157,9 @@
         */
         initEvents: function () {
             Dialog.superclass.initEvents.call(this);
-        
+
             var SIGNATURE = CustomEvent.LIST;
-        
+
             /**
             * CustomEvent fired prior to submission
             * @event beforeSubmitEvent
@@ -6172,7 +6269,6 @@
                 i,
                 sMethod;
 
-
             switch (this.cfg.getProperty("postmethod")) {
     
             case "async":
@@ -6181,37 +6277,25 @@
                 nElements = aElements.length;
 
                 if (nElements > 0) {
-                
                     i = nElements - 1;
-                
                     do {
-                    
                         if (aElements[i].type == "file") {
-                        
                             bUseFileUpload = true;
                             break;
-                        
                         }
-                    
                     }
                     while(i--);
-                
                 }
 
                 if (bUseFileUpload && YAHOO.env.ua.ie && this.isSecure) {
-
                     bUseSecureFileUpload = true;
-                
                 }
 
-                sMethod = 
-                    (oForm.getAttribute("method") || "POST").toUpperCase();
+                sMethod = (oForm.getAttribute("method") || "POST").toUpperCase();
 
                 Connect.setForm(oForm, bUseFileUpload, bUseSecureFileUpload);
+                Connect.asyncRequest(sMethod, oForm.getAttribute("action"), this.callback);
 
-                Connect.asyncRequest(sMethod, oForm.getAttribute("action"), 
-                    this.callback);
-
                 this.asyncSubmitEvent.fire();
 
                 break;
@@ -6523,14 +6607,12 @@
 
             this.cfg.refireEvent("iframe");
             this.cfg.refireEvent("underlay");
-
         },
 
-
         /**
         * @method getButtons
         * @description Returns an array containing each of the Dialog's 
-        * buttons, by default an array of HTML <code><BUTTON<</code> 
+        * buttons, by default an array of HTML <code><BUTTON></code> 
         * elements.  If the Dialog's buttons were created using the 
         * YAHOO.widget.Button class (via the inclusion of the optional Button 
         * dependancy on the page), an array of YAHOO.widget.Button instances 
@@ -6538,17 +6620,11 @@
         * @return {Array}
         */
         getButtons: function () {
-        
             var aButtons = this._aButtons;
-            
             if (aButtons) {
-            
                 return aButtons;
-            
             }
-        
         },
-
         
         /**
         * Sets focus to the first element in the Dialog's form or the first 
@@ -6562,41 +6638,27 @@
                 oEvent;
 
             if (args) {
-
                 oEvent = args[1];
-
                 if (oEvent) {
-
                     Event.stopEvent(oEvent);
-
                 }
-
             }
-        
 
             if (oElement) {
-
                 /*
                     Place the call to the "focus" method inside a try/catch
                     block to prevent IE from throwing JavaScript errors if
                     the element is disabled or hidden.
                 */
-
                 try {
-
                     oElement.focus();
-
                 }
                 catch(oException) {
-
                 }
 
             } else {
-
                 this.focusDefaultButton();
-
             }
-
         },
         
         /**
@@ -6611,25 +6673,16 @@
                 oEvent;
     
             if (args) {
-
                 oEvent = args[1];
-
                 if (oEvent) {
-
                     Event.stopEvent(oEvent);
-
                 }
-
             }
             
             if (aButtons && Lang.isArray(aButtons)) {
-
                 this.focusLastButton();
-
             } else {
-
                 if (oElement) {
-
                     /*
                         Place the call to the "focus" method inside a try/catch
                         block to prevent IE from throwing JavaScript errors if
@@ -6637,18 +6690,11 @@
                     */
     
                     try {
-    
                         oElement.focus();
-    
+                    } catch(oException) {
                     }
-                    catch(oException) {
-    
-                    }
-
                 }
-
             }
-
         },
         
         /**
@@ -6668,15 +6714,10 @@
                     block to prevent IE from throwing JavaScript errors if
                     the element is disabled or hidden.
                 */
-
                 try {
-
                     oElement.focus();
-                
+                } catch(oException) {
                 }
-                catch(oException) {
-                
-                }
 
             }
         },
@@ -6703,7 +6744,6 @@
                     i = (nButtons - 1);
                     
                     do {
-                    
                         oButton = aButtons[i];
                         
                         if (oButton) {
@@ -6711,35 +6751,22 @@
                             oElement = oButton.htmlButton;
 
                             if (oElement) {
-
                                 /*
                                     Place the call to the "blur" method inside  
                                     a try/catch block to prevent IE from  
                                     throwing JavaScript errors if the element 
                                     is disabled or hidden.
                                 */
-    
                                 try {
-            
                                     oElement.blur();
-                                
+                                } catch(oException) {
                                 }
-                                catch(oException) {
-                                
-                                
-                                }
-                            
                             }
-
                         }
                     
-                    }
-                    while(i--);
-                
+                    } while(i--);
                 }
-            
             }
-
         },
         
         /**
@@ -6771,19 +6798,12 @@
                         */
     
                         try {
-    
                             oElement.focus();
-                        
                         }
                         catch(oException) {
-                        
-                        
                         }
-                    
                     }
-
                 }
-
             }
         },
         
@@ -6804,15 +6824,11 @@
                 nButtons = aButtons.length;
                 
                 if (nButtons > 0) {
-
                     oButton = aButtons[(nButtons - 1)];
                     
                     if (oButton) {
-                    
                         oElement = oButton.htmlButton;
-
                         if (oElement) {
-
                             /*
                                 Place the call to the "focus" method inside a 
                                 try/catch block to prevent IE from throwing 
@@ -6821,23 +6837,13 @@
                             */
         
                             try {
-        
                                 oElement.focus();
-                            
+                            } catch(oException) {
                             }
-                            catch(oException) {
-                            
-                            
-                            }
-                        
                         }
-                    
                     }
-                
                 }
-            
             }
-
         },
         
         /**
@@ -6868,8 +6874,12 @@
         },
         
         /**
-        * Executes a submit of the Dialog followed by a hide, if validation 
-        * is successful.
+        * Executes a submit of the Dialog if validation 
+        * is successful. By default the Dialog is hidden
+        * after submission, but you can set the "hideaftersubmit"
+        * configuration property to false, to prevent the Dialog
+        * from being hidden.
+        * 
         * @method submit
         */
         submit: function () {
@@ -6877,13 +6887,17 @@
                 this.beforeSubmitEvent.fire();
                 this.doSubmit();
                 this.submitEvent.fire();
-                this.hide();
+
+                if (this.cfg.getProperty("hideaftersubmit")) {
+                    this.hide();
+                }
+
                 return true;
             } else {
                 return false;
             }
         },
-        
+
         /**
         * Executes the cancel of the Dialog followed by a hide.
         * @method cancel
@@ -7836,4 +7850,4 @@
 
 })();
 
-YAHOO.register("container", YAHOO.widget.Module, {version: "2.4.1", build: "742"});
+YAHOO.register("container", YAHOO.widget.Module, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/container/container-min.js
===================================================================
--- trunk/root/static/yui/container/container-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/container/container-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,17 +1,17 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-(function(){YAHOO.util.Config=function(D){if(D){this.init(D);}};var B=YAHOO.lang,C=YAHOO.util.CustomEvent,A=YAHOO.util.Config;A.CONFIG_CHANGED_EVENT="configChanged";A.BOOLEAN_TYPE="boolean";A.prototype={owner:null,queueInProgress:false,config:null,initialConfig:null,eventQueue:null,configChangedEvent:null,init:function(D){this.owner=D;this.configChangedEvent=this.createEvent(A.CONFIG_CHANGED_EVENT);this.configChangedEvent.signature=C.LIST;this.queueInProgress=false;this.config={};this.initialConfig={};this.eventQueue=[];},checkBoolean:function(D){return(typeof D==A.BOOLEAN_TYPE);},checkNumber:function(D){return(!isNaN(D));},fireEvent:function(D,F){var E=this.config[D];if(E&&E.event){E.event.fire(F);}},addProperty:function(E,D){E=E.toLowerCase();this.config[E]=D;D.event=this.createEvent(E,{scope:this.owner});D.event.signature=C.LIST;D.key=E;if(D.handler){D.event.subscribe(D.handler,this.owner);}this.setProperty(E,D.value,true);if(!D.suppressEvent){this.queueProperty(E,D.valu!
 e);}},getConfig:function(){var D={},F,E;for(F in this.config){E=this.config[F];if(E&&E.event){D[F]=E.value;}}return D;},getProperty:function(D){var E=this.config[D.toLowerCase()];if(E&&E.event){return E.value;}else{return undefined;}},resetProperty:function(D){D=D.toLowerCase();var E=this.config[D];if(E&&E.event){if(this.initialConfig[D]&&!B.isUndefined(this.initialConfig[D])){this.setProperty(D,this.initialConfig[D]);return true;}}else{return false;}},setProperty:function(E,G,D){var F;E=E.toLowerCase();if(this.queueInProgress&&!D){this.queueProperty(E,G);return true;}else{F=this.config[E];if(F&&F.event){if(F.validator&&!F.validator(G)){return false;}else{F.value=G;if(!D){this.fireEvent(E,G);this.configChangedEvent.fire([E,G]);}return true;}}else{return false;}}},queueProperty:function(S,P){S=S.toLowerCase();var R=this.config[S],K=false,J,G,H,I,O,Q,F,M,N,D,L,T,E;if(R&&R.event){if(!B.isUndefined(P)&&R.validator&&!R.validator(P)){return false;}else{if(!B.isUndefined(P)){R.val!
 ue=P;}else{P=R.value;}K=false;J=this.eventQueue.length;for(L=0!
 ;L<J;L++
){G=this.eventQueue[L];if(G){H=G[0];I=G[1];if(H==S){this.eventQueue[L]=null;this.eventQueue.push([S,(!B.isUndefined(P)?P:I)]);K=true;break;}}}if(!K&&!B.isUndefined(P)){this.eventQueue.push([S,P]);}}if(R.supercedes){O=R.supercedes.length;for(T=0;T<O;T++){Q=R.supercedes[T];F=this.eventQueue.length;for(E=0;E<F;E++){M=this.eventQueue[E];if(M){N=M[0];D=M[1];if(N==Q.toLowerCase()){this.eventQueue.push([N,D]);this.eventQueue[E]=null;break;}}}}}return true;}else{return false;}},refireEvent:function(D){D=D.toLowerCase();var E=this.config[D];if(E&&E.event&&!B.isUndefined(E.value)){if(this.queueInProgress){this.queueProperty(D);}else{this.fireEvent(D,E.value);}}},applyConfig:function(D,G){var F,E;if(G){E={};for(F in D){if(B.hasOwnProperty(D,F)){E[F.toLowerCase()]=D[F];}}this.initialConfig=E;}for(F in D){if(B.hasOwnProperty(D,F)){this.queueProperty(F,D[F]);}}},refresh:function(){var D;for(D in this.config){this.refireEvent(D);}},fireQueue:function(){var E,H,D,G,F;this.queueInProgress=tr!
 ue;for(E=0;E<this.eventQueue.length;E++){H=this.eventQueue[E];if(H){D=H[0];G=H[1];F=this.config[D];F.value=G;this.fireEvent(D,G);}}this.queueInProgress=false;this.eventQueue=[];},subscribeToConfigEvent:function(E,F,H,D){var G=this.config[E.toLowerCase()];if(G&&G.event){if(!A.alreadySubscribed(G.event,F,H)){G.event.subscribe(F,H,D);}return true;}else{return false;}},unsubscribeFromConfigEvent:function(D,E,G){var F=this.config[D.toLowerCase()];if(F&&F.event){return F.event.unsubscribe(E,G);}else{return false;}},toString:function(){var D="Config";if(this.owner){D+=" ["+this.owner.toString()+"]";}return D;},outputEventQueue:function(){var D="",G,E,F=this.eventQueue.length;for(E=0;E<F;E++){G=this.eventQueue[E];if(G){D+=G[0]+"="+G[1]+", ";}}return D;},destroy:function(){var E=this.config,D,F;for(D in E){if(B.hasOwnProperty(E,D)){F=E[D];F.event.unsubscribeAll();F.event=null;}}this.configChangedEvent.unsubscribeAll();this.configChangedEvent=null;this.owner=null;this.config=null;thi!
 s.initialConfig=null;this.eventQueue=null;}};A.alreadySubscrib!
 ed=funct
ion(E,H,I){var F=E.subscribers.length,D,G;if(F>0){G=F-1;do{D=E.subscribers[G];if(D&&D.obj==I&&D.fn==H){return true;}}while(G--);}return false;};YAHOO.lang.augmentProto(A,YAHOO.util.EventProvider);}());(function(){YAHOO.widget.Module=function(Q,P){if(Q){this.init(Q,P);}else{}};var F=YAHOO.util.Dom,D=YAHOO.util.Config,M=YAHOO.util.Event,L=YAHOO.util.CustomEvent,G=YAHOO.widget.Module,H,O,N,E,A={"BEFORE_INIT":"beforeInit","INIT":"init","APPEND":"append","BEFORE_RENDER":"beforeRender","RENDER":"render","CHANGE_HEADER":"changeHeader","CHANGE_BODY":"changeBody","CHANGE_FOOTER":"changeFooter","CHANGE_CONTENT":"changeContent","DESTORY":"destroy","BEFORE_SHOW":"beforeShow","SHOW":"show","BEFORE_HIDE":"beforeHide","HIDE":"hide"},I={"VISIBLE":{key:"visible",value:true,validator:YAHOO.lang.isBoolean},"EFFECT":{key:"effect",suppressEvent:true,supercedes:["visible"]},"MONITOR_RESIZE":{key:"monitorresize",value:true},"APPEND_TO_DOCUMENT_BODY":{key:"appendtodocumentbody",value:false}};G.IMG_!
 ROOT=null;G.IMG_ROOT_SSL=null;G.CSS_MODULE="yui-module";G.CSS_HEADER="hd";G.CSS_BODY="bd";G.CSS_FOOTER="ft";G.RESIZE_MONITOR_SECURE_URL="javascript:false;";G.textResizeEvent=new L("textResize");function K(){if(!H){H=document.createElement("div");H.innerHTML=("<div class=\""+G.CSS_HEADER+"\"></div><div class=\""+G.CSS_BODY+"\"></div><div class=\""+G.CSS_FOOTER+"\"></div>");O=H.firstChild;N=O.nextSibling;E=N.nextSibling;}return H;}function J(){if(!O){K();}return(O.cloneNode(false));}function B(){if(!N){K();}return(N.cloneNode(false));}function C(){if(!E){K();}return(E.cloneNode(false));}G.prototype={constructor:G,element:null,header:null,body:null,footer:null,id:null,imageRoot:G.IMG_ROOT,initEvents:function(){var P=L.LIST;this.beforeInitEvent=this.createEvent(A.BEFORE_INIT);this.beforeInitEvent.signature=P;this.initEvent=this.createEvent(A.INIT);this.initEvent.signature=P;this.appendEvent=this.createEvent(A.APPEND);
-this.appendEvent.signature=P;this.beforeRenderEvent=this.createEvent(A.BEFORE_RENDER);this.beforeRenderEvent.signature=P;this.renderEvent=this.createEvent(A.RENDER);this.renderEvent.signature=P;this.changeHeaderEvent=this.createEvent(A.CHANGE_HEADER);this.changeHeaderEvent.signature=P;this.changeBodyEvent=this.createEvent(A.CHANGE_BODY);this.changeBodyEvent.signature=P;this.changeFooterEvent=this.createEvent(A.CHANGE_FOOTER);this.changeFooterEvent.signature=P;this.changeContentEvent=this.createEvent(A.CHANGE_CONTENT);this.changeContentEvent.signature=P;this.destroyEvent=this.createEvent(A.DESTORY);this.destroyEvent.signature=P;this.beforeShowEvent=this.createEvent(A.BEFORE_SHOW);this.beforeShowEvent.signature=P;this.showEvent=this.createEvent(A.SHOW);this.showEvent.signature=P;this.beforeHideEvent=this.createEvent(A.BEFORE_HIDE);this.beforeHideEvent.signature=P;this.hideEvent=this.createEvent(A.HIDE);this.hideEvent.signature=P;},platform:function(){var P=navigator.userAgent!
 .toLowerCase();if(P.indexOf("windows")!=-1||P.indexOf("win32")!=-1){return"windows";}else{if(P.indexOf("macintosh")!=-1){return"mac";}else{return false;}}}(),browser:function(){var P=navigator.userAgent.toLowerCase();if(P.indexOf("opera")!=-1){return"opera";}else{if(P.indexOf("msie 7")!=-1){return"ie7";}else{if(P.indexOf("msie")!=-1){return"ie";}else{if(P.indexOf("safari")!=-1){return"safari";}else{if(P.indexOf("gecko")!=-1){return"gecko";}else{return false;}}}}}}(),isSecure:function(){if(window.location.href.toLowerCase().indexOf("https")===0){return true;}else{return false;}}(),initDefaultConfig:function(){this.cfg.addProperty(I.VISIBLE.key,{handler:this.configVisible,value:I.VISIBLE.value,validator:I.VISIBLE.validator});this.cfg.addProperty(I.EFFECT.key,{suppressEvent:I.EFFECT.suppressEvent,supercedes:I.EFFECT.supercedes});this.cfg.addProperty(I.MONITOR_RESIZE.key,{handler:this.configMonitorResize,value:I.MONITOR_RESIZE.value});this.cfg.addProperty(I.APPEND_TO_DOCUMENT_B!
 ODY.key,{value:I.APPEND_TO_DOCUMENT_BODY.value});},init:functi!
 on(U,T){
var R,V;this.initEvents();this.beforeInitEvent.fire(G);this.cfg=new D(this);if(this.isSecure){this.imageRoot=G.IMG_ROOT_SSL;}if(typeof U=="string"){R=U;U=document.getElementById(U);if(!U){U=(K()).cloneNode(false);U.id=R;}}this.element=U;if(U.id){this.id=U.id;}V=this.element.firstChild;if(V){var Q=false,P=false,S=false;do{if(1==V.nodeType){if(!Q&&F.hasClass(V,G.CSS_HEADER)){this.header=V;Q=true;}else{if(!P&&F.hasClass(V,G.CSS_BODY)){this.body=V;P=true;}else{if(!S&&F.hasClass(V,G.CSS_FOOTER)){this.footer=V;S=true;}}}}}while((V=V.nextSibling));}this.initDefaultConfig();F.addClass(this.element,G.CSS_MODULE);if(T){this.cfg.applyConfig(T,true);}if(!D.alreadySubscribed(this.renderEvent,this.cfg.fireQueue,this.cfg)){this.renderEvent.subscribe(this.cfg.fireQueue,this.cfg,true);}this.initEvent.fire(G);},initResizeMonitor:function(){var P,Q,S;function T(){G.textResizeEvent.fire();}if(!YAHOO.env.ua.opera){Q=F.get("_yuiResizeMonitor");if(!Q){Q=document.createElement("iframe");if(this.isS!
 ecure&&G.RESIZE_MONITOR_SECURE_URL&&YAHOO.env.ua.ie){Q.src=G.RESIZE_MONITOR_SECURE_URL;}if(YAHOO.env.ua.gecko){S=["<html><head><script ","type=\"text/javascript\">","window.onresize=function(){window.parent.","YAHOO.widget.Module.textResizeEvent.","fire();}","</script></head>","<body></body></html>"].join("");Q.src="data:text/html;charset=utf-8,"+encodeURIComponent(S);}Q.id="_yuiResizeMonitor";Q.style.position="absolute";Q.style.visibility="hidden";var R=document.body.firstChild;if(R){document.body.insertBefore(Q,R);}else{document.body.appendChild(Q);}Q.style.width="10em";Q.style.height="10em";Q.style.top=(-1*Q.offsetHeight)+"px";Q.style.left=(-1*Q.offsetWidth)+"px";Q.style.borderWidth="0";Q.style.visibility="visible";if(YAHOO.env.ua.webkit){P=Q.contentWindow.document;P.open();P.close();}}if(Q&&Q.contentWindow){G.textResizeEvent.subscribe(this.onDomResize,this,true);if(!G.textResizeInitialized){if(!YAHOO.env.ua.gecko){if(!M.on(Q.contentWindow,"resize",T)){M.on(Q,"resize",T)!
 ;}}G.textResizeInitialized=true;}this.resizeMonitor=Q;}}},onDo!
 mResize:
function(S,R){var Q=-1*this.resizeMonitor.offsetWidth,P=-1*this.resizeMonitor.offsetHeight;this.resizeMonitor.style.top=P+"px";this.resizeMonitor.style.left=Q+"px";},setHeader:function(Q){var P=this.header||(this.header=J());if(typeof Q=="string"){P.innerHTML=Q;}else{P.innerHTML="";P.appendChild(Q);}this.changeHeaderEvent.fire(Q);this.changeContentEvent.fire();},appendToHeader:function(Q){var P=this.header||(this.header=J());P.appendChild(Q);this.changeHeaderEvent.fire(Q);this.changeContentEvent.fire();},setBody:function(Q){var P=this.body||(this.body=B());if(typeof Q=="string"){P.innerHTML=Q;}else{P.innerHTML="";P.appendChild(Q);}this.changeBodyEvent.fire(Q);this.changeContentEvent.fire();},appendToBody:function(Q){var P=this.body||(this.body=B());P.appendChild(Q);this.changeBodyEvent.fire(Q);this.changeContentEvent.fire();},setFooter:function(Q){var P=this.footer||(this.footer=C());if(typeof Q=="string"){P.innerHTML=Q;}else{P.innerHTML="";P.appendChild(Q);}this.changeFoote!
 rEvent.fire(Q);this.changeContentEvent.fire();},appendToFooter:function(Q){var P=this.footer||(this.footer=C());P.appendChild(Q);this.changeFooterEvent.fire(Q);this.changeContentEvent.fire();},render:function(R,P){var S=this,T;function Q(U){if(typeof U=="string"){U=document.getElementById(U);}if(U){S._addToParent(U,S.element);S.appendEvent.fire();}}this.beforeRenderEvent.fire();if(!P){P=this.element;}if(R){Q(R);}else{if(!F.inDocument(this.element)){return false;}}if(this.header&&!F.inDocument(this.header)){T=P.firstChild;if(T){P.insertBefore(this.header,T);}else{P.appendChild(this.header);}}if(this.body&&!F.inDocument(this.body)){if(this.footer&&F.isAncestor(this.moduleElement,this.footer)){P.insertBefore(this.body,this.footer);}else{P.appendChild(this.body);}}if(this.footer&&!F.inDocument(this.footer)){P.appendChild(this.footer);}this.renderEvent.fire();return true;},destroy:function(){var P,Q;if(this.element){M.purgeElement(this.element,true);
-P=this.element.parentNode;}if(P){P.removeChild(this.element);}this.element=null;this.header=null;this.body=null;this.footer=null;G.textResizeEvent.unsubscribe(this.onDomResize,this);this.cfg.destroy();this.cfg=null;this.destroyEvent.fire();for(Q in this){if(Q instanceof L){Q.unsubscribeAll();}}},show:function(){this.cfg.setProperty("visible",true);},hide:function(){this.cfg.setProperty("visible",false);},configVisible:function(Q,P,R){var S=P[0];if(S){this.beforeShowEvent.fire();F.setStyle(this.element,"display","block");this.showEvent.fire();}else{this.beforeHideEvent.fire();F.setStyle(this.element,"display","none");this.hideEvent.fire();}},configMonitorResize:function(R,Q,S){var P=Q[0];if(P){this.initResizeMonitor();}else{G.textResizeEvent.unsubscribe(this.onDomResize,this,true);this.resizeMonitor=null;}},_addToParent:function(P,Q){if(!this.cfg.getProperty("appendtodocumentbody")&&P===document.body&&P.firstChild){P.insertBefore(Q,P.firstChild);}else{P.appendChild(Q);}},toS!
 tring:function(){return"Module "+this.id;}};YAHOO.lang.augmentProto(G,YAHOO.util.EventProvider);}());(function(){YAHOO.widget.Overlay=function(L,K){YAHOO.widget.Overlay.superclass.constructor.call(this,L,K);};var F=YAHOO.lang,I=YAHOO.util.CustomEvent,E=YAHOO.widget.Module,J=YAHOO.util.Event,D=YAHOO.util.Dom,C=YAHOO.util.Config,B=YAHOO.widget.Overlay,G,A={"BEFORE_MOVE":"beforeMove","MOVE":"move"},H={"X":{key:"x",validator:F.isNumber,suppressEvent:true,supercedes:["iframe"]},"Y":{key:"y",validator:F.isNumber,suppressEvent:true,supercedes:["iframe"]},"XY":{key:"xy",suppressEvent:true,supercedes:["iframe"]},"CONTEXT":{key:"context",suppressEvent:true,supercedes:["iframe"]},"FIXED_CENTER":{key:"fixedcenter",value:false,validator:F.isBoolean,supercedes:["iframe","visible"]},"WIDTH":{key:"width",suppressEvent:true,supercedes:["context","fixedcenter","iframe"]},"HEIGHT":{key:"height",suppressEvent:true,supercedes:["context","fixedcenter","iframe"]},"ZINDEX":{key:"zindex",value:null!
 },"CONSTRAIN_TO_VIEWPORT":{key:"constraintoviewport",value:fal!
 se,valid
ator:F.isBoolean,supercedes:["iframe","x","y","xy"]},"IFRAME":{key:"iframe",value:(YAHOO.env.ua.ie==6?true:false),validator:F.isBoolean,supercedes:["zindex"]}};B.IFRAME_SRC="javascript:false;";B.IFRAME_OFFSET=3;B.VIEWPORT_OFFSET=10;B.TOP_LEFT="tl";B.TOP_RIGHT="tr";B.BOTTOM_LEFT="bl";B.BOTTOM_RIGHT="br";B.CSS_OVERLAY="yui-overlay";B.windowScrollEvent=new I("windowScroll");B.windowResizeEvent=new I("windowResize");B.windowScrollHandler=function(K){if(YAHOO.env.ua.ie){if(!window.scrollEnd){window.scrollEnd=-1;}clearTimeout(window.scrollEnd);window.scrollEnd=setTimeout(function(){B.windowScrollEvent.fire();},1);}else{B.windowScrollEvent.fire();}};B.windowResizeHandler=function(K){if(YAHOO.env.ua.ie){if(!window.resizeEnd){window.resizeEnd=-1;}clearTimeout(window.resizeEnd);window.resizeEnd=setTimeout(function(){B.windowResizeEvent.fire();},100);}else{B.windowResizeEvent.fire();}};B._initialized=null;if(B._initialized===null){J.on(window,"scroll",B.windowScrollHandler);J.on(window!
 ,"resize",B.windowResizeHandler);B._initialized=true;}YAHOO.extend(B,E,{init:function(L,K){B.superclass.init.call(this,L);this.beforeInitEvent.fire(B);D.addClass(this.element,B.CSS_OVERLAY);if(K){this.cfg.applyConfig(K,true);}if(this.platform=="mac"&&YAHOO.env.ua.gecko){if(!C.alreadySubscribed(this.showEvent,this.showMacGeckoScrollbars,this)){this.showEvent.subscribe(this.showMacGeckoScrollbars,this,true);}if(!C.alreadySubscribed(this.hideEvent,this.hideMacGeckoScrollbars,this)){this.hideEvent.subscribe(this.hideMacGeckoScrollbars,this,true);}}this.initEvent.fire(B);},initEvents:function(){B.superclass.initEvents.call(this);var K=I.LIST;this.beforeMoveEvent=this.createEvent(A.BEFORE_MOVE);this.beforeMoveEvent.signature=K;this.moveEvent=this.createEvent(A.MOVE);this.moveEvent.signature=K;},initDefaultConfig:function(){B.superclass.initDefaultConfig.call(this);this.cfg.addProperty(H.X.key,{handler:this.configX,validator:H.X.validator,suppressEvent:H.X.suppressEvent,supercedes!
 :H.X.supercedes});this.cfg.addProperty(H.Y.key,{handler:this.c!
 onfigY,v
alidator:H.Y.validator,suppressEvent:H.Y.suppressEvent,supercedes:H.Y.supercedes});this.cfg.addProperty(H.XY.key,{handler:this.configXY,suppressEvent:H.XY.suppressEvent,supercedes:H.XY.supercedes});this.cfg.addProperty(H.CONTEXT.key,{handler:this.configContext,suppressEvent:H.CONTEXT.suppressEvent,supercedes:H.CONTEXT.supercedes});this.cfg.addProperty(H.FIXED_CENTER.key,{handler:this.configFixedCenter,value:H.FIXED_CENTER.value,validator:H.FIXED_CENTER.validator,supercedes:H.FIXED_CENTER.supercedes});this.cfg.addProperty(H.WIDTH.key,{handler:this.configWidth,suppressEvent:H.WIDTH.suppressEvent,supercedes:H.WIDTH.supercedes});this.cfg.addProperty(H.HEIGHT.key,{handler:this.configHeight,suppressEvent:H.HEIGHT.suppressEvent,supercedes:H.HEIGHT.supercedes});this.cfg.addProperty(H.ZINDEX.key,{handler:this.configzIndex,value:H.ZINDEX.value});this.cfg.addProperty(H.CONSTRAIN_TO_VIEWPORT.key,{handler:this.configConstrainToViewport,value:H.CONSTRAIN_TO_VIEWPORT.value,validator:H.CONS!
 TRAIN_TO_VIEWPORT.validator,supercedes:H.CONSTRAIN_TO_VIEWPORT.supercedes});this.cfg.addProperty(H.IFRAME.key,{handler:this.configIframe,value:H.IFRAME.value,validator:H.IFRAME.validator,supercedes:H.IFRAME.supercedes});},moveTo:function(K,L){this.cfg.setProperty("xy",[K,L]);},hideMacGeckoScrollbars:function(){D.removeClass(this.element,"show-scrollbars");D.addClass(this.element,"hide-scrollbars");},showMacGeckoScrollbars:function(){D.removeClass(this.element,"hide-scrollbars");D.addClass(this.element,"show-scrollbars");},configVisible:function(N,K,T){var M=K[0],O=D.getStyle(this.element,"visibility"),U=this.cfg.getProperty("effect"),R=[],Q=(this.platform=="mac"&&YAHOO.env.ua.gecko),b=C.alreadySubscribed,S,L,a,Y,X,W,Z,V,P;if(O=="inherit"){a=this.element.parentNode;while(a.nodeType!=9&&a.nodeType!=11){O=D.getStyle(a,"visibility");if(O!="inherit"){break;}a=a.parentNode;}if(O=="inherit"){O="visible";}}if(U){if(U instanceof Array){V=U.length;
-for(Y=0;Y<V;Y++){S=U[Y];R[R.length]=S.effect(this,S.duration);}}else{R[R.length]=U.effect(this,U.duration);}}if(M){if(Q){this.showMacGeckoScrollbars();}if(U){if(M){if(O!="visible"||O===""){this.beforeShowEvent.fire();P=R.length;for(X=0;X<P;X++){L=R[X];if(X===0&&!b(L.animateInCompleteEvent,this.showEvent.fire,this.showEvent)){L.animateInCompleteEvent.subscribe(this.showEvent.fire,this.showEvent,true);}L.animateIn();}}}}else{if(O!="visible"||O===""){this.beforeShowEvent.fire();D.setStyle(this.element,"visibility","visible");this.cfg.refireEvent("iframe");this.showEvent.fire();}}}else{if(Q){this.hideMacGeckoScrollbars();}if(U){if(O=="visible"){this.beforeHideEvent.fire();P=R.length;for(W=0;W<P;W++){Z=R[W];if(W===0&&!b(Z.animateOutCompleteEvent,this.hideEvent.fire,this.hideEvent)){Z.animateOutCompleteEvent.subscribe(this.hideEvent.fire,this.hideEvent,true);}Z.animateOut();}}else{if(O===""){D.setStyle(this.element,"visibility","hidden");}}}else{if(O=="visible"||O===""){this.befo!
 reHideEvent.fire();D.setStyle(this.element,"visibility","hidden");this.hideEvent.fire();}}}},doCenterOnDOMEvent:function(){if(this.cfg.getProperty("visible")){this.center();}},configFixedCenter:function(O,M,P){var Q=M[0],L=C.alreadySubscribed,N=B.windowResizeEvent,K=B.windowScrollEvent;if(Q){this.center();if(!L(this.beforeShowEvent,this.center,this)){this.beforeShowEvent.subscribe(this.center);}if(!L(N,this.doCenterOnDOMEvent,this)){N.subscribe(this.doCenterOnDOMEvent,this,true);}if(!L(K,this.doCenterOnDOMEvent,this)){K.subscribe(this.doCenterOnDOMEvent,this,true);}}else{this.beforeShowEvent.unsubscribe(this.center);N.unsubscribe(this.doCenterOnDOMEvent,this);K.unsubscribe(this.doCenterOnDOMEvent,this);}},configHeight:function(N,L,O){var K=L[0],M=this.element;D.setStyle(M,"height",K);this.cfg.refireEvent("iframe");},configWidth:function(N,K,O){var M=K[0],L=this.element;D.setStyle(L,"width",M);this.cfg.refireEvent("iframe");},configzIndex:function(M,K,N){var O=K[0],L=this.el!
 ement;if(!O){O=D.getStyle(L,"zIndex");if(!O||isNaN(O)){O=0;}}i!
 f(this.i
frame||this.cfg.getProperty("iframe")===true){if(O<=0){O=1;}}D.setStyle(L,"zIndex",O);this.cfg.setProperty("zIndex",O,true);if(this.iframe){this.stackIframe();}},configXY:function(M,L,N){var P=L[0],K=P[0],O=P[1];this.cfg.setProperty("x",K);this.cfg.setProperty("y",O);this.beforeMoveEvent.fire([K,O]);K=this.cfg.getProperty("x");O=this.cfg.getProperty("y");this.cfg.refireEvent("iframe");this.moveEvent.fire([K,O]);},configX:function(M,L,N){var K=L[0],O=this.cfg.getProperty("y");this.cfg.setProperty("x",K,true);this.cfg.setProperty("y",O,true);this.beforeMoveEvent.fire([K,O]);K=this.cfg.getProperty("x");O=this.cfg.getProperty("y");D.setX(this.element,K,true);this.cfg.setProperty("xy",[K,O],true);this.cfg.refireEvent("iframe");this.moveEvent.fire([K,O]);},configY:function(M,L,N){var K=this.cfg.getProperty("x"),O=L[0];this.cfg.setProperty("x",K,true);this.cfg.setProperty("y",O,true);this.beforeMoveEvent.fire([K,O]);K=this.cfg.getProperty("x");O=this.cfg.getProperty("y");D.setY(thi!
 s.element,O,true);this.cfg.setProperty("xy",[K,O],true);this.cfg.refireEvent("iframe");this.moveEvent.fire([K,O]);},showIframe:function(){var L=this.iframe,K;if(L){K=this.element.parentNode;if(K!=L.parentNode){this._addToParent(K,L);}L.style.display="block";}},hideIframe:function(){if(this.iframe){this.iframe.style.display="none";}},syncIframe:function(){var K=this.iframe,M=this.element,O=B.IFRAME_OFFSET,L=(O*2),N;if(K){K.style.width=(M.offsetWidth+L+"px");K.style.height=(M.offsetHeight+L+"px");N=this.cfg.getProperty("xy");if(!F.isArray(N)||(isNaN(N[0])||isNaN(N[1]))){this.syncPosition();N=this.cfg.getProperty("xy");}D.setXY(K,[(N[0]-O),(N[1]-O)]);}},stackIframe:function(){if(this.iframe){var K=D.getStyle(this.element,"zIndex");if(!YAHOO.lang.isUndefined(K)&&!isNaN(K)){D.setStyle(this.iframe,"zIndex",(K-1));}}},configIframe:function(N,M,O){var K=M[0];function P(){var R=this.iframe,S=this.element,T;if(!R){if(!G){G=document.createElement("iframe");if(this.isSecure){G.src=B.IF!
 RAME_SRC;}if(YAHOO.env.ua.ie){G.style.filter="alpha(opacity=0)!
 ";G.fram
eBorder=0;}else{G.style.opacity="0";}G.style.position="absolute";G.style.border="none";G.style.margin="0";G.style.padding="0";G.style.display="none";}R=G.cloneNode(false);T=S.parentNode;var Q=T||document.body;this._addToParent(Q,R);this.iframe=R;}this.showIframe();this.syncIframe();this.stackIframe();if(!this._hasIframeEventListeners){this.showEvent.subscribe(this.showIframe);this.hideEvent.subscribe(this.hideIframe);this.changeContentEvent.subscribe(this.syncIframe);this._hasIframeEventListeners=true;}}function L(){P.call(this);this.beforeShowEvent.unsubscribe(L);this._iframeDeferred=false;}if(K){if(this.cfg.getProperty("visible")){P.call(this);}else{if(!this._iframeDeferred){this.beforeShowEvent.subscribe(L);this._iframeDeferred=true;}}}else{this.hideIframe();if(this._hasIframeEventListeners){this.showEvent.unsubscribe(this.showIframe);this.hideEvent.unsubscribe(this.hideIframe);this.changeContentEvent.unsubscribe(this.syncIframe);this._hasIframeEventListeners=false;}}},co!
 nfigConstrainToViewport:function(M,K,N){function L(){if(YAHOO.lang.isUndefined(this.cfg.getProperty("xy"))){this.syncPosition();}var P=this.cfg.getProperty("x");var R=this.cfg.getProperty("y");var Q=this.getConstrainedXY(P,R);if(Q[0]!==P||Q[1]!==R){this.moveTo(Q[0],Q[1]);}}var O=K[0];if(O){if(!C.alreadySubscribed(this.beforeMoveEvent,this.enforceConstraints,this)){this.beforeMoveEvent.subscribe(this.enforceConstraints,this,true);}if(!C.alreadySubscribed(this.beforeShowEvent,L)){this.beforeShowEvent.subscribe(L);}}else{this.beforeShowEvent.unsubscribe(L);this.beforeMoveEvent.unsubscribe(this.enforceConstraints,this);}},configContext:function(M,L,O){var Q=L[0],N,P,K;if(Q){N=Q[0];P=Q[1];K=Q[2];if(N){if(typeof N=="string"){this.cfg.setProperty("context",[document.getElementById(N),P,K],true);}if(P&&K){this.align(P,K);}}}},align:function(L,K){var Q=this.cfg.getProperty("context"),P=this,O,N,R;function M(S,T){switch(L){case B.TOP_LEFT:P.moveTo(T,S);
-break;case B.TOP_RIGHT:P.moveTo((T-N.offsetWidth),S);break;case B.BOTTOM_LEFT:P.moveTo(T,(S-N.offsetHeight));break;case B.BOTTOM_RIGHT:P.moveTo((T-N.offsetWidth),(S-N.offsetHeight));break;}}if(Q){O=Q[0];N=this.element;P=this;if(!L){L=Q[1];}if(!K){K=Q[2];}if(N&&O){R=D.getRegion(O);switch(K){case B.TOP_LEFT:M(R.top,R.left);break;case B.TOP_RIGHT:M(R.top,R.right);break;case B.BOTTOM_LEFT:M(R.bottom,R.left);break;case B.BOTTOM_RIGHT:M(R.bottom,R.right);break;}}}},enforceConstraints:function(L,K,M){var O=K[0];var N=this.getConstrainedXY(O[0],O[1]);this.cfg.setProperty("x",N[0],true);this.cfg.setProperty("y",N[1],true);this.cfg.setProperty("xy",N,true);},getConstrainedXY:function(V,T){var N=B.VIEWPORT_OFFSET,U=D.getViewportWidth(),Q=D.getViewportHeight(),M=this.element.offsetHeight,S=this.element.offsetWidth,Y=D.getDocumentScrollLeft(),W=D.getDocumentScrollTop();var P=V;var L=T;if(S+N<U){var R=Y+N;var X=Y+U-S-N;if(V<R){P=R;}else{if(V>X){P=X;}}}else{P=N+Y;}if(M+N<Q){var O=W+N;var !
 K=W+Q-M-N;if(T<O){L=O;}else{if(T>K){L=K;}}}else{L=N+W;}return[P,L];},center:function(){var N=B.VIEWPORT_OFFSET,O=this.element.offsetWidth,M=this.element.offsetHeight,L=D.getViewportWidth(),P=D.getViewportHeight(),K,Q;if(O<L){K=(L/2)-(O/2)+D.getDocumentScrollLeft();}else{K=N+D.getDocumentScrollLeft();}if(M<P){Q=(P/2)-(M/2)+D.getDocumentScrollTop();}else{Q=N+D.getDocumentScrollTop();}this.cfg.setProperty("xy",[parseInt(K,10),parseInt(Q,10)]);this.cfg.refireEvent("iframe");},syncPosition:function(){var K=D.getXY(this.element);this.cfg.setProperty("x",K[0],true);this.cfg.setProperty("y",K[1],true);this.cfg.setProperty("xy",K,true);},onDomResize:function(M,L){var K=this;B.superclass.onDomResize.call(this,M,L);setTimeout(function(){K.syncPosition();K.cfg.refireEvent("iframe");K.cfg.refireEvent("context");},0);},bringToTop:function(){var O=[],N=this.element;function R(V,U){var X=D.getStyle(V,"zIndex"),W=D.getStyle(U,"zIndex"),T=(!X||isNaN(X))?0:parseInt(X,10),S=(!W||isNaN(W))?0:pa!
 rseInt(W,10);if(T>S){return -1;}else{if(T<S){return 1;}else{re!
 turn 0;}
}}function M(U){var S=D.hasClass(U,B.CSS_OVERLAY),T=YAHOO.widget.Panel;if(S&&!D.isAncestor(N,S)){if(T&&D.hasClass(U,T.CSS_PANEL)){O[O.length]=U.parentNode;}else{O[O.length]=U;}}}D.getElementsBy(M,"DIV",document.body);O.sort(R);var K=O[0],Q;if(K){Q=D.getStyle(K,"zIndex");if(!isNaN(Q)){var P=false;if(K!=N){P=true;}else{if(O.length>1){var L=D.getStyle(O[1],"zIndex");if(!isNaN(L)&&(Q==L)){P=true;}}}if(P){this.cfg.setProperty("zindex",(parseInt(Q,10)+2));}}}},destroy:function(){if(this.iframe){this.iframe.parentNode.removeChild(this.iframe);}this.iframe=null;B.windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent,this);B.windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent,this);B.superclass.destroy.call(this);},toString:function(){return"Overlay "+this.id;}});}());(function(){YAHOO.widget.OverlayManager=function(G){this.init(G);};var D=YAHOO.widget.Overlay,C=YAHOO.util.Event,E=YAHOO.util.Dom,B=YAHOO.util.Config,F=YAHOO.util.CustomEvent,A=YAHOO.widget.OverlayManager;A.CSS_FOCUSE!
 D="focused";A.prototype={constructor:A,overlays:null,initDefaultConfig:function(){this.cfg.addProperty("overlays",{suppressEvent:true});this.cfg.addProperty("focusevent",{value:"mousedown"});},init:function(I){this.cfg=new B(this);this.initDefaultConfig();if(I){this.cfg.applyConfig(I,true);}this.cfg.fireQueue();var H=null;this.getActive=function(){return H;};this.focus=function(J){var K=this.find(J);if(K){if(H!=K){if(H){H.blur();}this.bringToTop(K);H=K;E.addClass(H.element,A.CSS_FOCUSED);K.focusEvent.fire();}}};this.remove=function(K){var M=this.find(K),J;if(M){if(H==M){H=null;}var L=(M.element===null&&M.cfg===null)?true:false;if(!L){J=E.getStyle(M.element,"zIndex");M.cfg.setProperty("zIndex",-1000,true);}this.overlays.sort(this.compareZIndexDesc);this.overlays=this.overlays.slice(0,(this.overlays.length-1));M.hideEvent.unsubscribe(M.blur);M.destroyEvent.unsubscribe(this._onOverlayDestroy,M);if(!L){C.removeListener(M.element,this.cfg.getProperty("focusevent"),this._onOverla!
 yElementFocus);M.cfg.setProperty("zIndex",J,true);M.cfg.setPro!
 perty("m
anager",null);}M.focusEvent.unsubscribeAll();M.blurEvent.unsubscribeAll();M.focusEvent=null;M.blurEvent=null;M.focus=null;M.blur=null;}};this.blurAll=function(){var K=this.overlays.length,J;if(K>0){J=K-1;do{this.overlays[J].blur();}while(J--);}};this._onOverlayBlur=function(K,J){H=null;};var G=this.cfg.getProperty("overlays");if(!this.overlays){this.overlays=[];}if(G){this.register(G);this.overlays.sort(this.compareZIndexDesc);}},_onOverlayElementFocus:function(I){var G=C.getTarget(I),H=this.close;if(H&&(G==H||E.isAncestor(H,G))){this.blur();}else{this.focus();}},_onOverlayDestroy:function(H,G,I){this.remove(I);},register:function(G){var K=this,L,I,H,J;if(G instanceof D){G.cfg.addProperty("manager",{value:this});G.focusEvent=G.createEvent("focus");G.focusEvent.signature=F.LIST;G.blurEvent=G.createEvent("blur");G.blurEvent.signature=F.LIST;G.focus=function(){K.focus(this);};G.blur=function(){if(K.getActive()==this){E.removeClass(this.element,A.CSS_FOCUSED);this.blurEvent.fire!
 ();}};G.blurEvent.subscribe(K._onOverlayBlur);G.hideEvent.subscribe(G.blur);G.destroyEvent.subscribe(this._onOverlayDestroy,G,this);C.on(G.element,this.cfg.getProperty("focusevent"),this._onOverlayElementFocus,null,G);L=E.getStyle(G.element,"zIndex");if(!isNaN(L)){G.cfg.setProperty("zIndex",parseInt(L,10));}else{G.cfg.setProperty("zIndex",0);}this.overlays.push(G);this.bringToTop(G);return true;}else{if(G instanceof Array){I=0;J=G.length;for(H=0;H<J;H++){if(this.register(G[H])){I++;}}if(I>0){return true;}}else{return false;}}},bringToTop:function(M){var I=this.find(M),L,G,J;if(I){J=this.overlays;J.sort(this.compareZIndexDesc);G=J[0];if(G){L=E.getStyle(G.element,"zIndex");if(!isNaN(L)){var K=false;if(G!==I){K=true;}else{if(J.length>1){var H=E.getStyle(J[1].element,"zIndex");if(!isNaN(H)&&(L==H)){K=true;}}}if(K){I.cfg.setProperty("zindex",(parseInt(L,10)+2));}}J.sort(this.compareZIndexDesc);}}},find:function(G){var I=this.overlays,J=I.length,H;
-if(J>0){H=J-1;if(G instanceof D){do{if(I[H]==G){return I[H];}}while(H--);}else{if(typeof G=="string"){do{if(I[H].id==G){return I[H];}}while(H--);}}return null;}},compareZIndexDesc:function(J,I){var H=(J.cfg)?J.cfg.getProperty("zIndex"):null,G=(I.cfg)?I.cfg.getProperty("zIndex"):null;if(H===null&&G===null){return 0;}else{if(H===null){return 1;}else{if(G===null){return -1;}else{if(H>G){return -1;}else{if(H<G){return 1;}else{return 0;}}}}}},showAll:function(){var H=this.overlays,I=H.length,G;if(I>0){G=I-1;do{H[G].show();}while(G--);}},hideAll:function(){var H=this.overlays,I=H.length,G;if(I>0){G=I-1;do{H[G].hide();}while(G--);}},toString:function(){return"OverlayManager";}};}());(function(){YAHOO.widget.Tooltip=function(L,K){YAHOO.widget.Tooltip.superclass.constructor.call(this,L,K);};var D=YAHOO.lang,J=YAHOO.util.Event,B=YAHOO.util.Dom,F=YAHOO.widget.Tooltip,E,G={"PREVENT_OVERLAP":{key:"preventoverlap",value:true,validator:D.isBoolean,supercedes:["x","y","xy"]},"SHOW_DELAY":{!
 key:"showdelay",value:200,validator:D.isNumber},"AUTO_DISMISS_DELAY":{key:"autodismissdelay",value:5000,validator:D.isNumber},"HIDE_DELAY":{key:"hidedelay",value:250,validator:D.isNumber},"TEXT":{key:"text",suppressEvent:true},"CONTAINER":{key:"container"}};F.CSS_TOOLTIP="yui-tt";function H(L,K,M){var P=M[0],N=M[1],O=this.cfg,Q=O.getProperty("width");if(Q==N){O.setProperty("width",P);}this.unsubscribe("hide",this._onHide,M);}function C(L,K){var M=document.body,Q=this.cfg,P=Q.getProperty("width"),N,O;if((!P||P=="auto")&&(Q.getProperty("container")!=M||Q.getProperty("x")>=B.getViewportWidth()||Q.getProperty("y")>=B.getViewportHeight())){O=this.element.cloneNode(true);O.style.visibility="hidden";O.style.top="0px";O.style.left="0px";M.appendChild(O);N=(O.offsetWidth+"px");M.removeChild(O);O=null;Q.setProperty("width",N);Q.refireEvent("xy");this.subscribe("hide",H,[(P||""),N]);}}function A(L,K,M){this.render(M);}function I(){J.onDOMReady(A,this.cfg.getProperty("container"),this)!
 ;}YAHOO.extend(F,YAHOO.widget.Overlay,{init:function(L,K){F.su!
 perclass
.init.call(this,L);this.beforeInitEvent.fire(F);B.addClass(this.element,F.CSS_TOOLTIP);if(K){this.cfg.applyConfig(K,true);}this.cfg.queueProperty("visible",false);this.cfg.queueProperty("constraintoviewport",true);this.setBody("");this.subscribe("beforeShow",C);this.subscribe("init",I);this.subscribe("render",this.onRender);this.initEvent.fire(F);},initDefaultConfig:function(){F.superclass.initDefaultConfig.call(this);this.cfg.addProperty(G.PREVENT_OVERLAP.key,{value:G.PREVENT_OVERLAP.value,validator:G.PREVENT_OVERLAP.validator,supercedes:G.PREVENT_OVERLAP.supercedes});this.cfg.addProperty(G.SHOW_DELAY.key,{handler:this.configShowDelay,value:200,validator:G.SHOW_DELAY.validator});this.cfg.addProperty(G.AUTO_DISMISS_DELAY.key,{handler:this.configAutoDismissDelay,value:G.AUTO_DISMISS_DELAY.value,validator:G.AUTO_DISMISS_DELAY.validator});this.cfg.addProperty(G.HIDE_DELAY.key,{handler:this.configHideDelay,value:G.HIDE_DELAY.value,validator:G.HIDE_DELAY.validator});this.cfg.addP!
 roperty(G.TEXT.key,{handler:this.configText,suppressEvent:G.TEXT.suppressEvent});this.cfg.addProperty(G.CONTAINER.key,{handler:this.configContainer,value:document.body});},configText:function(L,K,M){var N=K[0];if(N){this.setBody(N);}},configContainer:function(M,L,N){var K=L[0];if(typeof K=="string"){this.cfg.setProperty("container",document.getElementById(K),true);}},_removeEventListeners:function(){var N=this._context,K,M,L;if(N){K=N.length;if(K>0){L=K-1;do{M=N[L];J.removeListener(M,"mouseover",this.onContextMouseOver);J.removeListener(M,"mousemove",this.onContextMouseMove);J.removeListener(M,"mouseout",this.onContextMouseOut);}while(L--);}}},configContext:function(P,L,Q){var O=L[0],R,K,N,M;if(O){if(!(O instanceof Array)){if(typeof O=="string"){this.cfg.setProperty("context",[document.getElementById(O)],true);}else{this.cfg.setProperty("context",[O],true);}O=this.cfg.getProperty("context");}this._removeEventListeners();this._context=O;R=this._context;if(R){K=R.length;if(K>!
 0){M=K-1;do{N=R[M];J.on(N,"mouseover",this.onContextMouseOver,!
 this);J.
on(N,"mousemove",this.onContextMouseMove,this);J.on(N,"mouseout",this.onContextMouseOut,this);}while(M--);}}}},onContextMouseMove:function(L,K){K.pageX=J.getPageX(L);K.pageY=J.getPageY(L);},onContextMouseOver:function(M,L){var K=this;if(L.hideProcId){clearTimeout(L.hideProcId);L.hideProcId=null;}J.on(K,"mousemove",L.onContextMouseMove,L);if(K.title){L._tempTitle=K.title;K.title="";}L.showProcId=L.doShow(M,K);},onContextMouseOut:function(M,L){var K=this;if(L._tempTitle){K.title=L._tempTitle;L._tempTitle=null;}if(L.showProcId){clearTimeout(L.showProcId);L.showProcId=null;}if(L.hideProcId){clearTimeout(L.hideProcId);L.hideProcId=null;}L.hideProcId=setTimeout(function(){L.hide();},L.cfg.getProperty("hidedelay"));},doShow:function(M,K){var N=25,L=this;if(YAHOO.env.ua.opera&&K.tagName&&K.tagName.toUpperCase()=="A"){N+=12;}return setTimeout(function(){var O=L.cfg.getProperty("text");if(L._tempTitle&&(O===""||YAHOO.lang.isUndefined(O)||YAHOO.lang.isNull(O))){L.setBody(L._tempTitle);!
 }else{L.cfg.refireEvent("text");}L.moveTo(L.pageX,L.pageY+N);if(L.cfg.getProperty("preventoverlap")){L.preventOverlap(L.pageX,L.pageY);}J.removeListener(K,"mousemove",L.onContextMouseMove);L.show();L.hideProcId=L.doHide();},this.cfg.getProperty("showdelay"));},doHide:function(){var K=this;return setTimeout(function(){K.hide();},this.cfg.getProperty("autodismissdelay"));},preventOverlap:function(O,N){var K=this.element.offsetHeight,M=new YAHOO.util.Point(O,N),L=B.getRegion(this.element);L.top-=5;L.left-=5;L.right+=5;L.bottom+=5;if(L.contains(M)){this.cfg.setProperty("y",(N-K-5));}},onRender:function(O,N){function P(){var S=this.element,R=this._shadow;if(R){R.style.width=(S.offsetWidth+6)+"px";R.style.height=(S.offsetHeight+1)+"px";}}function L(){B.addClass(this._shadow,"yui-tt-shadow-visible");}function K(){B.removeClass(this._shadow,"yui-tt-shadow-visible");}function Q(){var T=this._shadow,S,R,V,U;if(!T){S=this.element;
-R=YAHOO.widget.Module;V=YAHOO.env.ua.ie;U=this;if(!E){E=document.createElement("div");E.className="yui-tt-shadow";}T=E.cloneNode(false);S.appendChild(T);this._shadow=T;L.call(this);this.subscribe("beforeShow",L);this.subscribe("beforeHide",K);if(V==6||(V==7&&document.compatMode=="BackCompat")){window.setTimeout(function(){P.call(U);},0);this.cfg.subscribeToConfigEvent("width",P);this.cfg.subscribeToConfigEvent("height",P);this.subscribe("changeContent",P);R.textResizeEvent.subscribe(P,this,true);this.subscribe("destroy",function(){R.textResizeEvent.unsubscribe(P,this);});}}}function M(){Q.call(this);this.unsubscribe("beforeShow",M);}if(this.cfg.getProperty("visible")){Q.call(this);}else{this.subscribe("beforeShow",M);}},destroy:function(){this._removeEventListeners();F.superclass.destroy.call(this);},toString:function(){return"Tooltip "+this.id;}});}());(function(){YAHOO.widget.Panel=function(U,T){YAHOO.widget.Panel.superclass.constructor.call(this,U,T);};var G=YAHOO.lang,N!
 =YAHOO.util.DD,A=YAHOO.util.Dom,S=YAHOO.util.Event,I=YAHOO.widget.Overlay,L=YAHOO.util.CustomEvent,J=YAHOO.util.Config,O=YAHOO.widget.Panel,H,Q,D,E={"SHOW_MASK":"showMask","HIDE_MASK":"hideMask","DRAG":"drag"},M={"CLOSE":{key:"close",value:true,validator:G.isBoolean,supercedes:["visible"]},"DRAGGABLE":{key:"draggable",value:(N?true:false),validator:G.isBoolean,supercedes:["visible"]},"DRAG_ONLY":{key:"dragonly",value:false,validator:G.isBoolean,supercedes:["draggable"]},"UNDERLAY":{key:"underlay",value:"shadow",supercedes:["visible"]},"MODAL":{key:"modal",value:false,validator:G.isBoolean,supercedes:["visible","zindex"]},"KEY_LISTENERS":{key:"keylisteners",suppressEvent:true,supercedes:["visible"]}};O.CSS_PANEL="yui-panel";O.CSS_PANEL_CONTAINER="yui-panel-container";function K(U,T){if(!this.header&&this.cfg.getProperty("draggable")){this.setHeader(" ");}}function R(U,T,V){var Y=V[0],W=V[1],X=this.cfg,Z=X.getProperty("width");if(Z==W){X.setProperty("width",Y);}this.unsu!
 bscribe("hide",R,V);}function C(U,T){var Y=YAHOO.env.ua.ie,X,W!
 ,V;if(Y=
=6||(Y==7&&document.compatMode=="BackCompat")){X=this.cfg;W=X.getProperty("width");if(!W||W=="auto"){V=(this.element.offsetWidth+"px");X.setProperty("width",V);this.subscribe("hide",R,[(W||""),V]);}}}function F(){this.blur();}function P(V,U){var W=this;function T(Z){var Y=Z.tagName.toUpperCase(),X=false;switch(Y){case"A":case"BUTTON":case"SELECT":case"TEXTAREA":if(!A.isAncestor(W.element,Z)){S.on(Z,"focus",F,Z,true);X=true;}break;case"INPUT":if(Z.type!="hidden"&&!A.isAncestor(W.element,Z)){S.on(Z,"focus",F,Z,true);X=true;}break;}return X;}this.focusableElements=A.getElementsBy(T);}function B(V,U){var Y=this.focusableElements,T=Y.length,W,X;for(X=0;X<T;X++){W=Y[X];S.removeListener(W,"focus",F);}}YAHOO.extend(O,I,{init:function(U,T){O.superclass.init.call(this,U);this.beforeInitEvent.fire(O);A.addClass(this.element,O.CSS_PANEL);this.buildWrapper();if(T){this.cfg.applyConfig(T,true);}this.subscribe("showMask",P);this.subscribe("hideMask",B);this.subscribe("beforeRender",K);this!
 .initEvent.fire(O);},initEvents:function(){O.superclass.initEvents.call(this);var T=L.LIST;this.showMaskEvent=this.createEvent(E.SHOW_MASK);this.showMaskEvent.signature=T;this.hideMaskEvent=this.createEvent(E.HIDE_MASK);this.hideMaskEvent.signature=T;this.dragEvent=this.createEvent(E.DRAG);this.dragEvent.signature=T;},initDefaultConfig:function(){O.superclass.initDefaultConfig.call(this);this.cfg.addProperty(M.CLOSE.key,{handler:this.configClose,value:M.CLOSE.value,validator:M.CLOSE.validator,supercedes:M.CLOSE.supercedes});this.cfg.addProperty(M.DRAGGABLE.key,{handler:this.configDraggable,value:M.DRAGGABLE.value,validator:M.DRAGGABLE.validator,supercedes:M.DRAGGABLE.supercedes});this.cfg.addProperty(M.DRAG_ONLY.key,{value:M.DRAG_ONLY.value,validator:M.DRAG_ONLY.validator,supercedes:M.DRAG_ONLY.supercedes});this.cfg.addProperty(M.UNDERLAY.key,{handler:this.configUnderlay,value:M.UNDERLAY.value,supercedes:M.UNDERLAY.supercedes});this.cfg.addProperty(M.MODAL.key,{handler:this!
 .configModal,value:M.MODAL.value,validator:M.MODAL.validator,s!
 upercede
s:M.MODAL.supercedes});this.cfg.addProperty(M.KEY_LISTENERS.key,{handler:this.configKeyListeners,suppressEvent:M.KEY_LISTENERS.suppressEvent,supercedes:M.KEY_LISTENERS.supercedes});},configClose:function(V,T,X){var Y=T[0],U=this.close;function W(a,Z){Z.hide();}if(Y){if(!U){if(!D){D=document.createElement("span");D.innerHTML=" ";D.className="container-close";}U=D.cloneNode(true);this.innerElement.appendChild(U);S.on(U,"click",W,this);this.close=U;}else{U.style.display="block";}}else{if(U){U.style.display="none";}}},configDraggable:function(U,T,V){var W=T[0];if(W){if(!N){this.cfg.setProperty("draggable",false);return ;}if(this.header){A.setStyle(this.header,"cursor","move");this.registerDragDrop();}this.subscribe("beforeShow",C);}else{if(this.dd){this.dd.unreg();}if(this.header){A.setStyle(this.header,"cursor","auto");}this.unsubscribe("beforeShow",C);}},configUnderlay:function(c,b,X){var a=YAHOO.env.ua,Z=(this.platform=="mac"&&a.gecko),d=b[0].toLowerCase(),T=this.underla!
 y,U=this.element;function e(){var f=this.underlay;A.addClass(f,"yui-force-redraw");window.setTimeout(function(){A.removeClass(f,"yui-force-redraw");},0);}function V(){var f;if(!T){if(!Q){Q=document.createElement("div");Q.className="underlay";}T=Q.cloneNode(false);this.element.appendChild(T);this.underlay=T;f=a.ie;if(f==6||(f==7&&document.compatMode=="BackCompat")){this.sizeUnderlay();this.cfg.subscribeToConfigEvent("width",this.sizeUnderlay);this.cfg.subscribeToConfigEvent("height",this.sizeUnderlay);this.changeContentEvent.subscribe(this.sizeUnderlay);YAHOO.widget.Module.textResizeEvent.subscribe(this.sizeUnderlay,this,true);}if(a.webkit&&a.webkit<420){this.changeContentEvent.subscribe(e);}}}function Y(){V.call(this);this._underlayDeferred=false;this.beforeShowEvent.unsubscribe(Y);}function W(){if(this._underlayDeferred){this.beforeShowEvent.unsubscribe(Y);this._underlayDeferred=false;}if(T){this.cfg.unsubscribeFromConfigEvent("width",this.sizeUnderlay);
-this.cfg.unsubscribeFromConfigEvent("height",this.sizeUnderlay);this.changeContentEvent.unsubscribe(this.sizeUnderlay);this.changeContentEvent.unsubscribe(e);YAHOO.widget.Module.textResizeEvent.unsubscribe(this.sizeUnderlay,this,true);this.element.removeChild(T);this.underlay=null;}}switch(d){case"shadow":A.removeClass(U,"matte");A.addClass(U,"shadow");break;case"matte":if(!Z){W.call(this);}A.removeClass(U,"shadow");A.addClass(U,"matte");break;default:if(!Z){W.call(this);}A.removeClass(U,"shadow");A.removeClass(U,"matte");break;}if((d=="shadow")||(Z&&!T)){if(this.cfg.getProperty("visible")){V.call(this);}else{if(!this._underlayDeferred){this.beforeShowEvent.subscribe(Y);this._underlayDeferred=true;}}}},configModal:function(U,T,W){var V=T[0];if(V){if(!this._hasModalityEventListeners){this.subscribe("beforeShow",this.buildMask);this.subscribe("beforeShow",this.bringToTop);this.subscribe("beforeShow",this.showMask);this.subscribe("hide",this.hideMask);I.windowResizeEvent.subsc!
 ribe(this.sizeMask,this,true);this._hasModalityEventListeners=true;}}else{if(this._hasModalityEventListeners){if(this.cfg.getProperty("visible")){this.hideMask();this.removeMask();}this.unsubscribe("beforeShow",this.buildMask);this.unsubscribe("beforeShow",this.bringToTop);this.unsubscribe("beforeShow",this.showMask);this.unsubscribe("hide",this.hideMask);I.windowResizeEvent.unsubscribe(this.sizeMask,this);this._hasModalityEventListeners=false;}}},removeMask:function(){var U=this.mask,T;if(U){this.hideMask();T=U.parentNode;if(T){T.removeChild(U);}this.mask=null;}},configKeyListeners:function(W,T,Z){var V=T[0],Y,X,U;if(V){if(V instanceof Array){X=V.length;for(U=0;U<X;U++){Y=V[U];if(!J.alreadySubscribed(this.showEvent,Y.enable,Y)){this.showEvent.subscribe(Y.enable,Y,true);}if(!J.alreadySubscribed(this.hideEvent,Y.disable,Y)){this.hideEvent.subscribe(Y.disable,Y,true);this.destroyEvent.subscribe(Y.disable,Y,true);}}}else{if(!J.alreadySubscribed(this.showEvent,V.enable,V)){this!
 .showEvent.subscribe(V.enable,V,true);}if(!J.alreadySubscribed!
 (this.hi
deEvent,V.disable,V)){this.hideEvent.subscribe(V.disable,V,true);this.destroyEvent.subscribe(V.disable,V,true);}}}},configHeight:function(W,U,X){var T=U[0],V=this.innerElement;A.setStyle(V,"height",T);this.cfg.refireEvent("iframe");},configWidth:function(W,T,X){var V=T[0],U=this.innerElement;A.setStyle(U,"width",V);this.cfg.refireEvent("iframe");},configzIndex:function(U,T,W){O.superclass.configzIndex.call(this,U,T,W);if(this.mask||this.cfg.getProperty("modal")===true){var V=A.getStyle(this.element,"zIndex");if(!V||isNaN(V)){V=0;}if(V===0){this.cfg.setProperty("zIndex",1);}else{this.stackMask();}}},buildWrapper:function(){var V=this.element.parentNode,T=this.element,U=document.createElement("div");U.className=O.CSS_PANEL_CONTAINER;U.id=T.id+"_c";if(V){V.insertBefore(U,T);}U.appendChild(T);this.element=U;this.innerElement=T;A.setStyle(this.innerElement,"visibility","inherit");},sizeUnderlay:function(){var U=this.underlay,T;if(U){T=this.element;U.style.width=T.offsetWidth+"px"!
 ;U.style.height=T.offsetHeight+"px";}},registerDragDrop:function(){var U=this;if(this.header){if(!N){return ;}var T=(this.cfg.getProperty("dragonly")===true);this.dd=new N(this.element.id,this.id,{dragOnly:T});if(!this.header.id){this.header.id=this.id+"_h";}this.dd.startDrag=function(){var W,Y,V,b,a,Z;if(YAHOO.env.ua.ie==6){A.addClass(U.element,"drag");}if(U.cfg.getProperty("constraintoviewport")){var X=I.VIEWPORT_OFFSET;W=U.element.offsetHeight;Y=U.element.offsetWidth;V=A.getViewportWidth();b=A.getViewportHeight();a=A.getDocumentScrollLeft();Z=A.getDocumentScrollTop();if(W+X<b){this.minY=Z+X;this.maxY=Z+b-W-X;}else{this.minY=Z+X;this.maxY=Z+X;}if(Y+X<V){this.minX=a+X;this.maxX=a+V-Y-X;}else{this.minX=a+X;this.maxX=a+X;}this.constrainX=true;this.constrainY=true;}else{this.constrainX=false;this.constrainY=false;}U.dragEvent.fire("startDrag",arguments);};this.dd.onDrag=function(){U.syncPosition();U.cfg.refireEvent("iframe");if(this.platform=="mac"&&YAHOO.env.ua.gecko){this.s!
 howMacGeckoScrollbars();}U.dragEvent.fire("onDrag",arguments);!
 };this.d
d.endDrag=function(){if(YAHOO.env.ua.ie==6){A.removeClass(U.element,"drag");}U.dragEvent.fire("endDrag",arguments);U.moveEvent.fire(U.cfg.getProperty("xy"));};this.dd.setHandleElId(this.header.id);this.dd.addInvalidHandleType("INPUT");this.dd.addInvalidHandleType("SELECT");this.dd.addInvalidHandleType("TEXTAREA");}},buildMask:function(){var T=this.mask;if(!T){if(!H){H=document.createElement("div");H.className="mask";H.innerHTML=" ";}T=H.cloneNode(true);T.id=this.id+"_mask";document.body.insertBefore(T,document.body.firstChild);this.mask=T;this.stackMask();}},hideMask:function(){if(this.cfg.getProperty("modal")&&this.mask){this.mask.style.display="none";this.hideMaskEvent.fire();A.removeClass(document.body,"masked");}},showMask:function(){if(this.cfg.getProperty("modal")&&this.mask){A.addClass(document.body,"masked");this.sizeMask();this.mask.style.display="block";this.showMaskEvent.fire();}},sizeMask:function(){if(this.mask){this.mask.style.height=A.getDocumentHeight()+!
 "px";this.mask.style.width=A.getDocumentWidth()+"px";}},stackMask:function(){if(this.mask){var T=A.getStyle(this.element,"zIndex");if(!YAHOO.lang.isUndefined(T)&&!isNaN(T)){A.setStyle(this.mask,"zIndex",T-1);}}},render:function(T){return O.superclass.render.call(this,T,this.innerElement);},destroy:function(){I.windowResizeEvent.unsubscribe(this.sizeMask,this);this.removeMask();if(this.close){S.purgeElement(this.close);}O.superclass.destroy.call(this);},toString:function(){return"Panel "+this.id;}});}());(function(){YAHOO.widget.Dialog=function(L,K){YAHOO.widget.Dialog.superclass.constructor.call(this,L,K);};var J=YAHOO.util.Event,I=YAHOO.util.CustomEvent,D=YAHOO.util.Dom,B=YAHOO.util.KeyListener,H=YAHOO.util.Connect,F=YAHOO.widget.Dialog,E=YAHOO.lang,A={"BEFORE_SUBMIT":"beforeSubmit","SUBMIT":"submit","MANUAL_SUBMIT":"manualSubmit","ASYNC_SUBMIT":"asyncSubmit","FORM_SUBMIT":"formSubmit","CANCEL":"cancel"},G={"POST_METHOD":{key:"postmethod",value:"async"},"BUTTONS":{key:"but!
 tons",value:"none"}};
-F.CSS_DIALOG="yui-dialog";function C(){var N=this._aButtons,L,M,K;if(E.isArray(N)){L=N.length;if(L>0){K=L-1;do{M=N[K];if(YAHOO.widget.Button&&M instanceof YAHOO.widget.Button){M.destroy();}else{if(M.tagName.toUpperCase()=="BUTTON"){J.purgeElement(M);J.purgeElement(M,false);}}}while(K--);}}}YAHOO.extend(F,YAHOO.widget.Panel,{form:null,initDefaultConfig:function(){F.superclass.initDefaultConfig.call(this);this.callback={success:null,failure:null,argument:null};this.cfg.addProperty(G.POST_METHOD.key,{handler:this.configPostMethod,value:G.POST_METHOD.value,validator:function(K){if(K!="form"&&K!="async"&&K!="none"&&K!="manual"){return false;}else{return true;}}});this.cfg.addProperty(G.BUTTONS.key,{handler:this.configButtons,value:G.BUTTONS.value});},initEvents:function(){F.superclass.initEvents.call(this);var K=I.LIST;this.beforeSubmitEvent=this.createEvent(A.BEFORE_SUBMIT);this.beforeSubmitEvent.signature=K;this.submitEvent=this.createEvent(A.SUBMIT);this.submitEvent.signature!
 =K;this.manualSubmitEvent=this.createEvent(A.MANUAL_SUBMIT);this.manualSubmitEvent.signature=K;this.asyncSubmitEvent=this.createEvent(A.ASYNC_SUBMIT);this.asyncSubmitEvent.signature=K;this.formSubmitEvent=this.createEvent(A.FORM_SUBMIT);this.formSubmitEvent.signature=K;this.cancelEvent=this.createEvent(A.CANCEL);this.cancelEvent.signature=K;},init:function(L,K){F.superclass.init.call(this,L);this.beforeInitEvent.fire(F);D.addClass(this.element,F.CSS_DIALOG);this.cfg.setProperty("visible",false);if(K){this.cfg.applyConfig(K,true);}this.showEvent.subscribe(this.focusFirst,this,true);this.beforeHideEvent.subscribe(this.blurButtons,this,true);this.subscribe("changeBody",this.registerForm);this.initEvent.fire(F);},doSubmit:function(){var Q=this.form,O=false,N=false,P,K,M,L;switch(this.cfg.getProperty("postmethod")){case"async":P=Q.elements;K=P.length;if(K>0){M=K-1;do{if(P[M].type=="file"){O=true;break;}}while(M--);}if(O&&YAHOO.env.ua.ie&&this.isSecure){N=true;}L=(Q.getAttribute(!
 "method")||"POST").toUpperCase();H.setForm(Q,O,N);H.asyncReque!
 st(L,Q.g
etAttribute("action"),this.callback);this.asyncSubmitEvent.fire();break;case"form":Q.submit();this.formSubmitEvent.fire();break;case"none":case"manual":this.manualSubmitEvent.fire();break;}},registerForm:function(){var M=this.element.getElementsByTagName("form")[0],L=this,K,N;if(this.form){if(this.form==M&&D.isAncestor(this.element,this.form)){return ;}else{J.purgeElement(this.form);this.form=null;}}if(!M){M=document.createElement("form");M.name="frm_"+this.id;this.body.appendChild(M);}if(M){this.form=M;J.on(M,"submit",function(O){J.stopEvent(O);this.submit();this.form.blur();},this,true);this.firstFormElement=function(){var Q,P,O=M.elements.length;for(Q=0;Q<O;Q++){P=M.elements[Q];if(P.focus&&!P.disabled&&P.type!="hidden"){return P;}}return null;}();this.lastFormElement=function(){var Q,P,O=M.elements.length;for(Q=O-1;Q>=0;Q--){P=M.elements[Q];if(P.focus&&!P.disabled&&P.type!="hidden"){return P;}}return null;}();if(this.cfg.getProperty("modal")){K=this.firstFormElement||this!
 .firstButton;if(K){this.preventBackTab=new B(K,{shift:true,keys:9},{fn:L.focusLast,scope:L,correctScope:true});this.showEvent.subscribe(this.preventBackTab.enable,this.preventBackTab,true);this.hideEvent.subscribe(this.preventBackTab.disable,this.preventBackTab,true);}N=this.lastButton||this.lastFormElement;if(N){this.preventTabOut=new B(N,{shift:false,keys:9},{fn:L.focusFirst,scope:L,correctScope:true});this.showEvent.subscribe(this.preventTabOut.enable,this.preventTabOut,true);this.hideEvent.subscribe(this.preventTabOut.disable,this.preventTabOut,true);}}}},configClose:function(M,K,N){var O=K[0];function L(Q,P){P.cancel();}if(O){if(!this.close){this.close=document.createElement("div");D.addClass(this.close,"container-close");this.close.innerHTML=" ";this.innerElement.appendChild(this.close);J.on(this.close,"click",L,this);}else{this.close.style.display="block";}}else{if(this.close){this.close.style.display="none";}}},configButtons:function(U,T,O){var P=YAHOO.widget.B!
 utton,W=T[0],M=this.innerElement,V,R,L,S,Q,K,N;C.call(this);th!
 is._aBut
tons=null;if(E.isArray(W)){Q=document.createElement("span");Q.className="button-group";S=W.length;this._aButtons=[];for(N=0;N<S;N++){V=W[N];if(P){L=new P({label:V.text,container:Q});R=L.get("element");if(V.isDefault){L.addClass("default");this.defaultHtmlButton=R;}if(E.isFunction(V.handler)){L.set("onclick",{fn:V.handler,obj:this,scope:this});}else{if(E.isObject(V.handler)&&E.isFunction(V.handler.fn)){L.set("onclick",{fn:V.handler.fn,obj:((!E.isUndefined(V.handler.obj))?V.handler.obj:this),scope:(V.handler.scope||this)});}}this._aButtons[this._aButtons.length]=L;}else{R=document.createElement("button");R.setAttribute("type","button");if(V.isDefault){R.className="default";this.defaultHtmlButton=R;}R.innerHTML=V.text;if(E.isFunction(V.handler)){J.on(R,"click",V.handler,this,true);}else{if(E.isObject(V.handler)&&E.isFunction(V.handler.fn)){J.on(R,"click",V.handler.fn,((!E.isUndefined(V.handler.obj))?V.handler.obj:this),(V.handler.scope||this));}}Q.appendChild(R);this._aButtons[!
 this._aButtons.length]=R;}V.htmlButton=R;if(N===0){this.firstButton=R;}if(N==(S-1)){this.lastButton=R;}}this.setFooter(Q);K=this.footer;if(D.inDocument(this.element)&&!D.isAncestor(M,K)){M.appendChild(K);}this.buttonSpan=Q;}else{Q=this.buttonSpan;K=this.footer;if(Q&&K){K.removeChild(Q);this.buttonSpan=null;this.firstButton=null;this.lastButton=null;this.defaultHtmlButton=null;}}this.cfg.refireEvent("iframe");this.cfg.refireEvent("underlay");},getButtons:function(){var K=this._aButtons;if(K){return K;}},focusFirst:function(N,L,P){var M=this.firstFormElement,K;if(L){K=L[1];if(K){J.stopEvent(K);}}if(M){try{M.focus();}catch(O){}}else{this.focusDefaultButton();}},focusLast:function(N,L,P){var Q=this.cfg.getProperty("buttons"),M=this.lastFormElement,K;if(L){K=L[1];if(K){J.stopEvent(K);}}if(Q&&E.isArray(Q)){this.focusLastButton();}else{if(M){try{M.focus();}catch(O){}}}},focusDefaultButton:function(){var K=this.defaultHtmlButton;
-if(K){try{K.focus();}catch(L){}}},blurButtons:function(){var P=this.cfg.getProperty("buttons"),M,O,L,K;if(P&&E.isArray(P)){M=P.length;if(M>0){K=(M-1);do{O=P[K];if(O){L=O.htmlButton;if(L){try{L.blur();}catch(N){}}}}while(K--);}}},focusFirstButton:function(){var N=this.cfg.getProperty("buttons"),M,K;if(N&&E.isArray(N)){M=N[0];if(M){K=M.htmlButton;if(K){try{K.focus();}catch(L){}}}}},focusLastButton:function(){var O=this.cfg.getProperty("buttons"),L,N,K;if(O&&E.isArray(O)){L=O.length;if(L>0){N=O[(L-1)];if(N){K=N.htmlButton;if(K){try{K.focus();}catch(M){}}}}}},configPostMethod:function(L,K,M){this.registerForm();},validate:function(){return true;},submit:function(){if(this.validate()){this.beforeSubmitEvent.fire();this.doSubmit();this.submitEvent.fire();this.hide();return true;}else{return false;}},cancel:function(){this.cancelEvent.fire();this.hide();},getData:function(){var a=this.form,M,T,W,O,U,R,Q,L,X,N,Y,b,K,P,c,Z,V;function S(e){var d=e.tagName.toUpperCase();return((d=="IN!
 PUT"||d=="TEXTAREA"||d=="SELECT")&&e.name==O);}if(a){M=a.elements;T=M.length;W={};for(Z=0;Z<T;Z++){O=M[Z].name;U=D.getElementsBy(S,"*",a);R=U.length;if(R>0){if(R==1){U=U[0];Q=U.type;L=U.tagName.toUpperCase();switch(L){case"INPUT":if(Q=="checkbox"){W[O]=U.checked;}else{if(Q!="radio"){W[O]=U.value;}}break;case"TEXTAREA":W[O]=U.value;break;case"SELECT":X=U.options;N=X.length;Y=[];for(V=0;V<N;V++){b=X[V];if(b.selected){K=b.value;if(!K||K===""){K=b.text;}Y[Y.length]=K;}}W[O]=Y;break;}}else{Q=U[0].type;switch(Q){case"radio":for(V=0;V<R;V++){P=U[V];if(P.checked){W[O]=P.value;break;}}break;case"checkbox":Y=[];for(V=0;V<R;V++){c=U[V];if(c.checked){Y[Y.length]=c.value;}}W[O]=Y;break;}}}}}return W;},destroy:function(){C.call(this);this._aButtons=null;var K=this.element.getElementsByTagName("form"),L;if(K.length>0){L=K[0];if(L){J.purgeElement(L);if(L.parentNode){L.parentNode.removeChild(L);}this.form=null;}}F.superclass.destroy.call(this);},toString:function(){return"Dialog "+this.id;}!
 });}());(function(){YAHOO.widget.SimpleDialog=function(E,D){YA!
 HOO.widg
et.SimpleDialog.superclass.constructor.call(this,E,D);};var C=YAHOO.util.Dom,B=YAHOO.widget.SimpleDialog,A={"ICON":{key:"icon",value:"none",suppressEvent:true},"TEXT":{key:"text",value:"",suppressEvent:true,supercedes:["icon"]}};B.ICON_BLOCK="blckicon";B.ICON_ALARM="alrticon";B.ICON_HELP="hlpicon";B.ICON_INFO="infoicon";B.ICON_WARN="warnicon";B.ICON_TIP="tipicon";B.ICON_CSS_CLASSNAME="yui-icon";B.CSS_SIMPLEDIALOG="yui-simple-dialog";YAHOO.extend(B,YAHOO.widget.Dialog,{initDefaultConfig:function(){B.superclass.initDefaultConfig.call(this);this.cfg.addProperty(A.ICON.key,{handler:this.configIcon,value:A.ICON.value,suppressEvent:A.ICON.suppressEvent});this.cfg.addProperty(A.TEXT.key,{handler:this.configText,value:A.TEXT.value,suppressEvent:A.TEXT.suppressEvent,supercedes:A.TEXT.supercedes});},init:function(E,D){B.superclass.init.call(this,E);this.beforeInitEvent.fire(B);C.addClass(this.element,B.CSS_SIMPLEDIALOG);this.cfg.queueProperty("postmethod","manual");if(D){this.cfg.appl!
 yConfig(D,true);}this.beforeRenderEvent.subscribe(function(){if(!this.body){this.setBody("");}},this,true);this.initEvent.fire(B);},registerForm:function(){B.superclass.registerForm.call(this);this.form.innerHTML+="<input type=\"hidden\" name=\""+this.id+"\" value=\"\"/>";},configIcon:function(F,E,J){var K=E[0],D=this.body,I=B.ICON_CSS_CLASSNAME,H,G;if(K&&K!="none"){H=C.getElementsByClassName(I,"*",D);if(H){G=H.parentNode;if(G){G.removeChild(H);H=null;}}if(K.indexOf(".")==-1){H=document.createElement("span");H.className=(I+" "+K);H.innerHTML=" ";}else{H=document.createElement("img");H.src=(this.imageRoot+K);H.className=I;}if(H){D.insertBefore(H,D.firstChild);}}},configText:function(E,D,F){var G=D[0];if(G){this.setBody(G);this.cfg.refireEvent("icon");}},toString:function(){return"SimpleDialog "+this.id;}});}());(function(){YAHOO.widget.ContainerEffect=function(F,I,H,E,G){if(!G){G=YAHOO.util.Anim;}this.overlay=F;this.attrIn=I;this.attrOut=H;this.targetElement=E||F.elemen!
 t;this.animClass=G;};var B=YAHOO.util.Dom,D=YAHOO.util.CustomE!
 vent,C=Y
AHOO.util.Easing,A=YAHOO.widget.ContainerEffect;A.FADE=function(E,G){var I={attributes:{opacity:{from:0,to:1}},duration:G,method:C.easeIn};var F={attributes:{opacity:{to:0}},duration:G,method:C.easeOut};var H=new A(E,I,F,E.element);H.handleUnderlayStart=function(){var K=this.overlay.underlay;if(K&&YAHOO.env.ua.ie){var J=(K.filters&&K.filters.length>0);if(J){B.addClass(E.element,"yui-effect-fade");}}};H.handleUnderlayComplete=function(){var J=this.overlay.underlay;if(J&&YAHOO.env.ua.ie){B.removeClass(E.element,"yui-effect-fade");}};H.handleStartAnimateIn=function(K,J,L){B.addClass(L.overlay.element,"hide-select");if(!L.overlay.underlay){L.overlay.cfg.refireEvent("underlay");}L.handleUnderlayStart();B.setStyle(L.overlay.element,"visibility","visible");B.setStyle(L.overlay.element,"opacity",0);};H.handleCompleteAnimateIn=function(K,J,L){B.removeClass(L.overlay.element,"hide-select");if(L.overlay.element.style.filter){L.overlay.element.style.filter=null;}L.handleUnderlayComplete!
 ();L.overlay.cfg.refireEvent("iframe");L.animateInCompleteEvent.fire();};H.handleStartAnimateOut=function(K,J,L){B.addClass(L.overlay.element,"hide-select");L.handleUnderlayStart();};H.handleCompleteAnimateOut=function(K,J,L){B.removeClass(L.overlay.element,"hide-select");if(L.overlay.element.style.filter){L.overlay.element.style.filter=null;}B.setStyle(L.overlay.element,"visibility","hidden");B.setStyle(L.overlay.element,"opacity",1);L.handleUnderlayComplete();L.overlay.cfg.refireEvent("iframe");L.animateOutCompleteEvent.fire();};H.init();return H;};A.SLIDE=function(G,I){var F=G.cfg.getProperty("x")||B.getX(G.element),K=G.cfg.getProperty("y")||B.getY(G.element),J=B.getClientWidth(),H=G.element.offsetWidth,E=new A(G,{attributes:{points:{to:[F,K]}},duration:I,method:C.easeIn},{attributes:{points:{to:[(J+25),K]}},duration:I,method:C.easeOut},G.element,YAHOO.util.Motion);E.handleStartAnimateIn=function(M,L,N){N.overlay.element.style.left=((-25)-H)+"px";
-N.overlay.element.style.top=K+"px";};E.handleTweenAnimateIn=function(O,N,P){var Q=B.getXY(P.overlay.element),M=Q[0],L=Q[1];if(B.getStyle(P.overlay.element,"visibility")=="hidden"&&M<F){B.setStyle(P.overlay.element,"visibility","visible");}P.overlay.cfg.setProperty("xy",[M,L],true);P.overlay.cfg.refireEvent("iframe");};E.handleCompleteAnimateIn=function(M,L,N){N.overlay.cfg.setProperty("xy",[F,K],true);N.startX=F;N.startY=K;N.overlay.cfg.refireEvent("iframe");N.animateInCompleteEvent.fire();};E.handleStartAnimateOut=function(M,L,P){var N=B.getViewportWidth(),Q=B.getXY(P.overlay.element),O=Q[1];P.animOut.attributes.points.to=[(N+25),O];};E.handleTweenAnimateOut=function(N,M,O){var Q=B.getXY(O.overlay.element),L=Q[0],P=Q[1];O.overlay.cfg.setProperty("xy",[L,P],true);O.overlay.cfg.refireEvent("iframe");};E.handleCompleteAnimateOut=function(M,L,N){B.setStyle(N.overlay.element,"visibility","hidden");N.overlay.cfg.setProperty("xy",[F,K]);N.animateOutCompleteEvent.fire();};E.init()!
 ;return E;};A.prototype={init:function(){this.beforeAnimateInEvent=this.createEvent("beforeAnimateIn");this.beforeAnimateInEvent.signature=D.LIST;this.beforeAnimateOutEvent=this.createEvent("beforeAnimateOut");this.beforeAnimateOutEvent.signature=D.LIST;this.animateInCompleteEvent=this.createEvent("animateInComplete");this.animateInCompleteEvent.signature=D.LIST;this.animateOutCompleteEvent=this.createEvent("animateOutComplete");this.animateOutCompleteEvent.signature=D.LIST;this.animIn=new this.animClass(this.targetElement,this.attrIn.attributes,this.attrIn.duration,this.attrIn.method);this.animIn.onStart.subscribe(this.handleStartAnimateIn,this);this.animIn.onTween.subscribe(this.handleTweenAnimateIn,this);this.animIn.onComplete.subscribe(this.handleCompleteAnimateIn,this);this.animOut=new this.animClass(this.targetElement,this.attrOut.attributes,this.attrOut.duration,this.attrOut.method);this.animOut.onStart.subscribe(this.handleStartAnimateOut,this);this.animOut.onTween.!
 subscribe(this.handleTweenAnimateOut,this);this.animOut.onComp!
 lete.sub
scribe(this.handleCompleteAnimateOut,this);},animateIn:function(){this.beforeAnimateInEvent.fire();this.animIn.animate();},animateOut:function(){this.beforeAnimateOutEvent.fire();this.animOut.animate();},handleStartAnimateIn:function(F,E,G){},handleTweenAnimateIn:function(F,E,G){},handleCompleteAnimateIn:function(F,E,G){},handleStartAnimateOut:function(F,E,G){},handleTweenAnimateOut:function(F,E,G){},handleCompleteAnimateOut:function(F,E,G){},toString:function(){var E="ContainerEffect";if(this.overlay){E+=" ["+this.overlay.toString()+"]";}return E;}};YAHOO.lang.augmentProto(A,YAHOO.util.EventProvider);})();YAHOO.register("container",YAHOO.widget.Module,{version:"2.4.1",build:"742"});
\ No newline at end of file
+(function(){YAHOO.util.Config=function(D){if(D){this.init(D);}};var B=YAHOO.lang,C=YAHOO.util.CustomEvent,A=YAHOO.util.Config;A.CONFIG_CHANGED_EVENT="configChanged";A.BOOLEAN_TYPE="boolean";A.prototype={owner:null,queueInProgress:false,config:null,initialConfig:null,eventQueue:null,configChangedEvent:null,init:function(D){this.owner=D;this.configChangedEvent=this.createEvent(A.CONFIG_CHANGED_EVENT);this.configChangedEvent.signature=C.LIST;this.queueInProgress=false;this.config={};this.initialConfig={};this.eventQueue=[];},checkBoolean:function(D){return(typeof D==A.BOOLEAN_TYPE);},checkNumber:function(D){return(!isNaN(D));},fireEvent:function(D,F){var E=this.config[D];if(E&&E.event){E.event.fire(F);}},addProperty:function(E,D){E=E.toLowerCase();this.config[E]=D;D.event=this.createEvent(E,{scope:this.owner});D.event.signature=C.LIST;D.key=E;if(D.handler){D.event.subscribe(D.handler,this.owner);}this.setProperty(E,D.value,true);if(!D.suppressEvent){this.queueProperty(E,D.valu!
 e);}},getConfig:function(){var D={},F,E;for(F in this.config){E=this.config[F];if(E&&E.event){D[F]=E.value;}}return D;},getProperty:function(D){var E=this.config[D.toLowerCase()];if(E&&E.event){return E.value;}else{return undefined;}},resetProperty:function(D){D=D.toLowerCase();var E=this.config[D];if(E&&E.event){if(this.initialConfig[D]&&!B.isUndefined(this.initialConfig[D])){this.setProperty(D,this.initialConfig[D]);return true;}}else{return false;}},setProperty:function(E,G,D){var F;E=E.toLowerCase();if(this.queueInProgress&&!D){this.queueProperty(E,G);return true;}else{F=this.config[E];if(F&&F.event){if(F.validator&&!F.validator(G)){return false;}else{F.value=G;if(!D){this.fireEvent(E,G);this.configChangedEvent.fire([E,G]);}return true;}}else{return false;}}},queueProperty:function(S,P){S=S.toLowerCase();var R=this.config[S],K=false,J,G,H,I,O,Q,F,M,N,D,L,T,E;if(R&&R.event){if(!B.isUndefined(P)&&R.validator&&!R.validator(P)){return false;}else{if(!B.isUndefined(P)){R.val!
 ue=P;}else{P=R.value;}K=false;J=this.eventQueue.length;for(L=0!
 ;L<J;L++
){G=this.eventQueue[L];if(G){H=G[0];I=G[1];if(H==S){this.eventQueue[L]=null;this.eventQueue.push([S,(!B.isUndefined(P)?P:I)]);K=true;break;}}}if(!K&&!B.isUndefined(P)){this.eventQueue.push([S,P]);}}if(R.supercedes){O=R.supercedes.length;for(T=0;T<O;T++){Q=R.supercedes[T];F=this.eventQueue.length;for(E=0;E<F;E++){M=this.eventQueue[E];if(M){N=M[0];D=M[1];if(N==Q.toLowerCase()){this.eventQueue.push([N,D]);this.eventQueue[E]=null;break;}}}}}return true;}else{return false;}},refireEvent:function(D){D=D.toLowerCase();var E=this.config[D];if(E&&E.event&&!B.isUndefined(E.value)){if(this.queueInProgress){this.queueProperty(D);}else{this.fireEvent(D,E.value);}}},applyConfig:function(D,G){var F,E;if(G){E={};for(F in D){if(B.hasOwnProperty(D,F)){E[F.toLowerCase()]=D[F];}}this.initialConfig=E;}for(F in D){if(B.hasOwnProperty(D,F)){this.queueProperty(F,D[F]);}}},refresh:function(){var D;for(D in this.config){this.refireEvent(D);}},fireQueue:function(){var E,H,D,G,F;this.queueInProgress=tr!
 ue;for(E=0;E<this.eventQueue.length;E++){H=this.eventQueue[E];if(H){D=H[0];G=H[1];F=this.config[D];F.value=G;this.fireEvent(D,G);}}this.queueInProgress=false;this.eventQueue=[];},subscribeToConfigEvent:function(E,F,H,D){var G=this.config[E.toLowerCase()];if(G&&G.event){if(!A.alreadySubscribed(G.event,F,H)){G.event.subscribe(F,H,D);}return true;}else{return false;}},unsubscribeFromConfigEvent:function(D,E,G){var F=this.config[D.toLowerCase()];if(F&&F.event){return F.event.unsubscribe(E,G);}else{return false;}},toString:function(){var D="Config";if(this.owner){D+=" ["+this.owner.toString()+"]";}return D;},outputEventQueue:function(){var D="",G,E,F=this.eventQueue.length;for(E=0;E<F;E++){G=this.eventQueue[E];if(G){D+=G[0]+"="+G[1]+", ";}}return D;},destroy:function(){var E=this.config,D,F;for(D in E){if(B.hasOwnProperty(E,D)){F=E[D];F.event.unsubscribeAll();F.event=null;}}this.configChangedEvent.unsubscribeAll();this.configChangedEvent=null;this.owner=null;this.config=null;thi!
 s.initialConfig=null;this.eventQueue=null;}};A.alreadySubscrib!
 ed=funct
ion(E,H,I){var F=E.subscribers.length,D,G;if(F>0){G=F-1;do{D=E.subscribers[G];if(D&&D.obj==I&&D.fn==H){return true;}}while(G--);}return false;};YAHOO.lang.augmentProto(A,YAHOO.util.EventProvider);}());(function(){YAHOO.widget.Module=function(Q,P){if(Q){this.init(Q,P);}else{}};var F=YAHOO.util.Dom,D=YAHOO.util.Config,M=YAHOO.util.Event,L=YAHOO.util.CustomEvent,G=YAHOO.widget.Module,H,O,N,E,A={"BEFORE_INIT":"beforeInit","INIT":"init","APPEND":"append","BEFORE_RENDER":"beforeRender","RENDER":"render","CHANGE_HEADER":"changeHeader","CHANGE_BODY":"changeBody","CHANGE_FOOTER":"changeFooter","CHANGE_CONTENT":"changeContent","DESTORY":"destroy","BEFORE_SHOW":"beforeShow","SHOW":"show","BEFORE_HIDE":"beforeHide","HIDE":"hide"},I={"VISIBLE":{key:"visible",value:true,validator:YAHOO.lang.isBoolean},"EFFECT":{key:"effect",suppressEvent:true,supercedes:["visible"]},"MONITOR_RESIZE":{key:"monitorresize",value:true},"APPEND_TO_DOCUMENT_BODY":{key:"appendtodocumentbody",value:false}};G.IMG_!
 ROOT=null;G.IMG_ROOT_SSL=null;G.CSS_MODULE="yui-module";G.CSS_HEADER="hd";G.CSS_BODY="bd";G.CSS_FOOTER="ft";G.RESIZE_MONITOR_SECURE_URL="javascript:false;";G.textResizeEvent=new L("textResize");function K(){if(!H){H=document.createElement("div");H.innerHTML=('<div class="'+G.CSS_HEADER+'"></div>'+'<div class="'+G.CSS_BODY+'"></div><div class="'+G.CSS_FOOTER+'"></div>');O=H.firstChild;N=O.nextSibling;E=N.nextSibling;}return H;}function J(){if(!O){K();}return(O.cloneNode(false));}function B(){if(!N){K();}return(N.cloneNode(false));}function C(){if(!E){K();}return(E.cloneNode(false));}G.prototype={constructor:G,element:null,header:null,body:null,footer:null,id:null,imageRoot:G.IMG_ROOT,initEvents:function(){var P=L.LIST;this.beforeInitEvent=this.createEvent(A.BEFORE_INIT);this.beforeInitEvent.signature=P;this.initEvent=this.createEvent(A.INIT);this.initEvent.signature=P;this.appendEvent=this.createEvent(A.APPEND);
+this.appendEvent.signature=P;this.beforeRenderEvent=this.createEvent(A.BEFORE_RENDER);this.beforeRenderEvent.signature=P;this.renderEvent=this.createEvent(A.RENDER);this.renderEvent.signature=P;this.changeHeaderEvent=this.createEvent(A.CHANGE_HEADER);this.changeHeaderEvent.signature=P;this.changeBodyEvent=this.createEvent(A.CHANGE_BODY);this.changeBodyEvent.signature=P;this.changeFooterEvent=this.createEvent(A.CHANGE_FOOTER);this.changeFooterEvent.signature=P;this.changeContentEvent=this.createEvent(A.CHANGE_CONTENT);this.changeContentEvent.signature=P;this.destroyEvent=this.createEvent(A.DESTORY);this.destroyEvent.signature=P;this.beforeShowEvent=this.createEvent(A.BEFORE_SHOW);this.beforeShowEvent.signature=P;this.showEvent=this.createEvent(A.SHOW);this.showEvent.signature=P;this.beforeHideEvent=this.createEvent(A.BEFORE_HIDE);this.beforeHideEvent.signature=P;this.hideEvent=this.createEvent(A.HIDE);this.hideEvent.signature=P;},platform:function(){var P=navigator.userAgent!
 .toLowerCase();if(P.indexOf("windows")!=-1||P.indexOf("win32")!=-1){return"windows";}else{if(P.indexOf("macintosh")!=-1){return"mac";}else{return false;}}}(),browser:function(){var P=navigator.userAgent.toLowerCase();if(P.indexOf("opera")!=-1){return"opera";}else{if(P.indexOf("msie 7")!=-1){return"ie7";}else{if(P.indexOf("msie")!=-1){return"ie";}else{if(P.indexOf("safari")!=-1){return"safari";}else{if(P.indexOf("gecko")!=-1){return"gecko";}else{return false;}}}}}}(),isSecure:function(){if(window.location.href.toLowerCase().indexOf("https")===0){return true;}else{return false;}}(),initDefaultConfig:function(){this.cfg.addProperty(I.VISIBLE.key,{handler:this.configVisible,value:I.VISIBLE.value,validator:I.VISIBLE.validator});this.cfg.addProperty(I.EFFECT.key,{suppressEvent:I.EFFECT.suppressEvent,supercedes:I.EFFECT.supercedes});this.cfg.addProperty(I.MONITOR_RESIZE.key,{handler:this.configMonitorResize,value:I.MONITOR_RESIZE.value});this.cfg.addProperty(I.APPEND_TO_DOCUMENT_B!
 ODY.key,{value:I.APPEND_TO_DOCUMENT_BODY.value});},init:functi!
 on(U,T){
var R,V;this.initEvents();this.beforeInitEvent.fire(G);this.cfg=new D(this);if(this.isSecure){this.imageRoot=G.IMG_ROOT_SSL;}if(typeof U=="string"){R=U;U=document.getElementById(U);if(!U){U=(K()).cloneNode(false);U.id=R;}}this.element=U;if(U.id){this.id=U.id;}V=this.element.firstChild;if(V){var Q=false,P=false,S=false;do{if(1==V.nodeType){if(!Q&&F.hasClass(V,G.CSS_HEADER)){this.header=V;Q=true;}else{if(!P&&F.hasClass(V,G.CSS_BODY)){this.body=V;P=true;}else{if(!S&&F.hasClass(V,G.CSS_FOOTER)){this.footer=V;S=true;}}}}}while((V=V.nextSibling));}this.initDefaultConfig();F.addClass(this.element,G.CSS_MODULE);if(T){this.cfg.applyConfig(T,true);}if(!D.alreadySubscribed(this.renderEvent,this.cfg.fireQueue,this.cfg)){this.renderEvent.subscribe(this.cfg.fireQueue,this.cfg,true);}this.initEvent.fire(G);},initResizeMonitor:function(){var Q=(YAHOO.env.ua.gecko&&this.platform=="windows");if(Q){var P=this;setTimeout(function(){P._initResizeMonitor();},0);}else{this._initResizeMonitor();}},!
 _initResizeMonitor:function(){var P,R,T;function V(){G.textResizeEvent.fire();}if(!YAHOO.env.ua.opera){R=F.get("_yuiResizeMonitor");var U=this._supportsCWResize();if(!R){R=document.createElement("iframe");if(this.isSecure&&G.RESIZE_MONITOR_SECURE_URL&&YAHOO.env.ua.ie){R.src=G.RESIZE_MONITOR_SECURE_URL;}if(!U){T=["<html><head><script ",'type="text/javascript">',"window.onresize=function(){window.parent.","YAHOO.widget.Module.textResizeEvent.","fire();};<","/script></head>","<body></body></html>"].join("");R.src="data:text/html;charset=utf-8,"+encodeURIComponent(T);}R.id="_yuiResizeMonitor";R.style.position="absolute";R.style.visibility="hidden";var Q=document.body,S=Q.firstChild;if(S){Q.insertBefore(R,S);}else{Q.appendChild(R);}R.style.width="10em";R.style.height="10em";R.style.top=(-1*R.offsetHeight)+"px";R.style.left=(-1*R.offsetWidth)+"px";R.style.borderWidth="0";R.style.visibility="visible";if(YAHOO.env.ua.webkit){P=R.contentWindow.document;P.open();P.close();}}if(R&&R.c!
 ontentWindow){G.textResizeEvent.subscribe(this.onDomResize,thi!
 s,true);
if(!G.textResizeInitialized){if(U){if(!M.on(R.contentWindow,"resize",V)){M.on(R,"resize",V);}}G.textResizeInitialized=true;}this.resizeMonitor=R;}}},_supportsCWResize:function(){var P=true;if(YAHOO.env.ua.gecko&&YAHOO.env.ua.gecko<=1.8){P=false;}return P;},onDomResize:function(S,R){var Q=-1*this.resizeMonitor.offsetWidth,P=-1*this.resizeMonitor.offsetHeight;this.resizeMonitor.style.top=P+"px";this.resizeMonitor.style.left=Q+"px";},setHeader:function(Q){var P=this.header||(this.header=J());if(Q.nodeName){P.innerHTML="";P.appendChild(Q);}else{P.innerHTML=Q;}this.changeHeaderEvent.fire(Q);this.changeContentEvent.fire();},appendToHeader:function(Q){var P=this.header||(this.header=J());P.appendChild(Q);this.changeHeaderEvent.fire(Q);this.changeContentEvent.fire();},setBody:function(Q){var P=this.body||(this.body=B());if(Q.nodeName){P.innerHTML="";P.appendChild(Q);}else{P.innerHTML=Q;}this.changeBodyEvent.fire(Q);this.changeContentEvent.fire();},appendToBody:function(Q){var P=this!
 .body||(this.body=B());P.appendChild(Q);this.changeBodyEvent.fire(Q);this.changeContentEvent.fire();},setFooter:function(Q){var P=this.footer||(this.footer=C());if(Q.nodeName){P.innerHTML="";P.appendChild(Q);}else{P.innerHTML=Q;}this.changeFooterEvent.fire(Q);this.changeContentEvent.fire();},appendToFooter:function(Q){var P=this.footer||(this.footer=C());P.appendChild(Q);this.changeFooterEvent.fire(Q);this.changeContentEvent.fire();},render:function(R,P){var S=this,T;function Q(U){if(typeof U=="string"){U=document.getElementById(U);}if(U){S._addToParent(U,S.element);S.appendEvent.fire();}}this.beforeRenderEvent.fire();if(!P){P=this.element;}if(R){Q(R);}else{if(!F.inDocument(this.element)){return false;}}if(this.header&&!F.inDocument(this.header)){T=P.firstChild;if(T){P.insertBefore(this.header,T);}else{P.appendChild(this.header);}}if(this.body&&!F.inDocument(this.body)){if(this.footer&&F.isAncestor(this.moduleElement,this.footer)){P.insertBefore(this.body,this.footer);
+}else{P.appendChild(this.body);}}if(this.footer&&!F.inDocument(this.footer)){P.appendChild(this.footer);}this.renderEvent.fire();return true;},destroy:function(){var P,Q;if(this.element){M.purgeElement(this.element,true);P=this.element.parentNode;}if(P){P.removeChild(this.element);}this.element=null;this.header=null;this.body=null;this.footer=null;G.textResizeEvent.unsubscribe(this.onDomResize,this);this.cfg.destroy();this.cfg=null;this.destroyEvent.fire();for(Q in this){if(Q instanceof L){Q.unsubscribeAll();}}},show:function(){this.cfg.setProperty("visible",true);},hide:function(){this.cfg.setProperty("visible",false);},configVisible:function(Q,P,R){var S=P[0];if(S){this.beforeShowEvent.fire();F.setStyle(this.element,"display","block");this.showEvent.fire();}else{this.beforeHideEvent.fire();F.setStyle(this.element,"display","none");this.hideEvent.fire();}},configMonitorResize:function(R,Q,S){var P=Q[0];if(P){this.initResizeMonitor();}else{G.textResizeEvent.unsubscribe(this!
 .onDomResize,this,true);this.resizeMonitor=null;}},_addToParent:function(P,Q){if(!this.cfg.getProperty("appendtodocumentbody")&&P===document.body&&P.firstChild){P.insertBefore(Q,P.firstChild);}else{P.appendChild(Q);}},toString:function(){return"Module "+this.id;}};YAHOO.lang.augmentProto(G,YAHOO.util.EventProvider);}());(function(){YAHOO.widget.Overlay=function(L,K){YAHOO.widget.Overlay.superclass.constructor.call(this,L,K);};var F=YAHOO.lang,I=YAHOO.util.CustomEvent,E=YAHOO.widget.Module,J=YAHOO.util.Event,D=YAHOO.util.Dom,C=YAHOO.util.Config,B=YAHOO.widget.Overlay,G,A={"BEFORE_MOVE":"beforeMove","MOVE":"move"},H={"X":{key:"x",validator:F.isNumber,suppressEvent:true,supercedes:["iframe"]},"Y":{key:"y",validator:F.isNumber,suppressEvent:true,supercedes:["iframe"]},"XY":{key:"xy",suppressEvent:true,supercedes:["iframe"]},"CONTEXT":{key:"context",suppressEvent:true,supercedes:["iframe"]},"FIXED_CENTER":{key:"fixedcenter",value:false,validator:F.isBoolean,supercedes:["iframe",!
 "visible"]},"WIDTH":{key:"width",suppressEvent:true,supercedes!
 :["conte
xt","fixedcenter","iframe"]},"HEIGHT":{key:"height",suppressEvent:true,supercedes:["context","fixedcenter","iframe"]},"ZINDEX":{key:"zindex",value:null},"CONSTRAIN_TO_VIEWPORT":{key:"constraintoviewport",value:false,validator:F.isBoolean,supercedes:["iframe","x","y","xy"]},"IFRAME":{key:"iframe",value:(YAHOO.env.ua.ie==6?true:false),validator:F.isBoolean,supercedes:["zindex"]}};B.IFRAME_SRC="javascript:false;";B.IFRAME_OFFSET=3;B.VIEWPORT_OFFSET=10;B.TOP_LEFT="tl";B.TOP_RIGHT="tr";B.BOTTOM_LEFT="bl";B.BOTTOM_RIGHT="br";B.CSS_OVERLAY="yui-overlay";B.windowScrollEvent=new I("windowScroll");B.windowResizeEvent=new I("windowResize");B.windowScrollHandler=function(K){if(YAHOO.env.ua.ie){if(!window.scrollEnd){window.scrollEnd=-1;}clearTimeout(window.scrollEnd);window.scrollEnd=setTimeout(function(){B.windowScrollEvent.fire();},1);}else{B.windowScrollEvent.fire();}};B.windowResizeHandler=function(K){if(YAHOO.env.ua.ie){if(!window.resizeEnd){window.resizeEnd=-1;}clearTimeout(window.!
 resizeEnd);window.resizeEnd=setTimeout(function(){B.windowResizeEvent.fire();},100);}else{B.windowResizeEvent.fire();}};B._initialized=null;if(B._initialized===null){J.on(window,"scroll",B.windowScrollHandler);J.on(window,"resize",B.windowResizeHandler);B._initialized=true;}YAHOO.extend(B,E,{init:function(L,K){B.superclass.init.call(this,L);this.beforeInitEvent.fire(B);D.addClass(this.element,B.CSS_OVERLAY);if(K){this.cfg.applyConfig(K,true);}if(this.platform=="mac"&&YAHOO.env.ua.gecko){if(!C.alreadySubscribed(this.showEvent,this.showMacGeckoScrollbars,this)){this.showEvent.subscribe(this.showMacGeckoScrollbars,this,true);}if(!C.alreadySubscribed(this.hideEvent,this.hideMacGeckoScrollbars,this)){this.hideEvent.subscribe(this.hideMacGeckoScrollbars,this,true);}}this.initEvent.fire(B);},initEvents:function(){B.superclass.initEvents.call(this);var K=I.LIST;this.beforeMoveEvent=this.createEvent(A.BEFORE_MOVE);this.beforeMoveEvent.signature=K;this.moveEvent=this.createEvent(A.MO!
 VE);this.moveEvent.signature=K;},initDefaultConfig:function(){!
 B.superc
lass.initDefaultConfig.call(this);this.cfg.addProperty(H.X.key,{handler:this.configX,validator:H.X.validator,suppressEvent:H.X.suppressEvent,supercedes:H.X.supercedes});this.cfg.addProperty(H.Y.key,{handler:this.configY,validator:H.Y.validator,suppressEvent:H.Y.suppressEvent,supercedes:H.Y.supercedes});this.cfg.addProperty(H.XY.key,{handler:this.configXY,suppressEvent:H.XY.suppressEvent,supercedes:H.XY.supercedes});this.cfg.addProperty(H.CONTEXT.key,{handler:this.configContext,suppressEvent:H.CONTEXT.suppressEvent,supercedes:H.CONTEXT.supercedes});this.cfg.addProperty(H.FIXED_CENTER.key,{handler:this.configFixedCenter,value:H.FIXED_CENTER.value,validator:H.FIXED_CENTER.validator,supercedes:H.FIXED_CENTER.supercedes});this.cfg.addProperty(H.WIDTH.key,{handler:this.configWidth,suppressEvent:H.WIDTH.suppressEvent,supercedes:H.WIDTH.supercedes});this.cfg.addProperty(H.HEIGHT.key,{handler:this.configHeight,suppressEvent:H.HEIGHT.suppressEvent,supercedes:H.HEIGHT.supercedes});this!
 .cfg.addProperty(H.ZINDEX.key,{handler:this.configzIndex,value:H.ZINDEX.value});this.cfg.addProperty(H.CONSTRAIN_TO_VIEWPORT.key,{handler:this.configConstrainToViewport,value:H.CONSTRAIN_TO_VIEWPORT.value,validator:H.CONSTRAIN_TO_VIEWPORT.validator,supercedes:H.CONSTRAIN_TO_VIEWPORT.supercedes});this.cfg.addProperty(H.IFRAME.key,{handler:this.configIframe,value:H.IFRAME.value,validator:H.IFRAME.validator,supercedes:H.IFRAME.supercedes});},moveTo:function(K,L){this.cfg.setProperty("xy",[K,L]);},hideMacGeckoScrollbars:function(){D.removeClass(this.element,"show-scrollbars");D.addClass(this.element,"hide-scrollbars");},showMacGeckoScrollbars:function(){D.removeClass(this.element,"hide-scrollbars");D.addClass(this.element,"show-scrollbars");},configVisible:function(N,K,T){var M=K[0],O=D.getStyle(this.element,"visibility"),U=this.cfg.getProperty("effect"),R=[],Q=(this.platform=="mac"&&YAHOO.env.ua.gecko),b=C.alreadySubscribed,S,L,a,Y,X,W,Z,V,P;
+if(O=="inherit"){a=this.element.parentNode;while(a.nodeType!=9&&a.nodeType!=11){O=D.getStyle(a,"visibility");if(O!="inherit"){break;}a=a.parentNode;}if(O=="inherit"){O="visible";}}if(U){if(U instanceof Array){V=U.length;for(Y=0;Y<V;Y++){S=U[Y];R[R.length]=S.effect(this,S.duration);}}else{R[R.length]=U.effect(this,U.duration);}}if(M){if(Q){this.showMacGeckoScrollbars();}if(U){if(M){if(O!="visible"||O===""){this.beforeShowEvent.fire();P=R.length;for(X=0;X<P;X++){L=R[X];if(X===0&&!b(L.animateInCompleteEvent,this.showEvent.fire,this.showEvent)){L.animateInCompleteEvent.subscribe(this.showEvent.fire,this.showEvent,true);}L.animateIn();}}}}else{if(O!="visible"||O===""){this.beforeShowEvent.fire();D.setStyle(this.element,"visibility","visible");this.cfg.refireEvent("iframe");this.showEvent.fire();}}}else{if(Q){this.hideMacGeckoScrollbars();}if(U){if(O=="visible"){this.beforeHideEvent.fire();P=R.length;for(W=0;W<P;W++){Z=R[W];if(W===0&&!b(Z.animateOutCompleteEvent,this.hideEvent.fi!
 re,this.hideEvent)){Z.animateOutCompleteEvent.subscribe(this.hideEvent.fire,this.hideEvent,true);}Z.animateOut();}}else{if(O===""){D.setStyle(this.element,"visibility","hidden");}}}else{if(O=="visible"||O===""){this.beforeHideEvent.fire();D.setStyle(this.element,"visibility","hidden");this.hideEvent.fire();}}}},doCenterOnDOMEvent:function(){if(this.cfg.getProperty("visible")){this.center();}},configFixedCenter:function(O,M,P){var Q=M[0],L=C.alreadySubscribed,N=B.windowResizeEvent,K=B.windowScrollEvent;if(Q){this.center();if(!L(this.beforeShowEvent,this.center,this)){this.beforeShowEvent.subscribe(this.center);}if(!L(N,this.doCenterOnDOMEvent,this)){N.subscribe(this.doCenterOnDOMEvent,this,true);}if(!L(K,this.doCenterOnDOMEvent,this)){K.subscribe(this.doCenterOnDOMEvent,this,true);}}else{this.beforeShowEvent.unsubscribe(this.center);N.unsubscribe(this.doCenterOnDOMEvent,this);K.unsubscribe(this.doCenterOnDOMEvent,this);}},configHeight:function(N,L,O){var K=L[0],M=this.elemen!
 t;D.setStyle(M,"height",K);this.cfg.refireEvent("iframe");},co!
 nfigWidt
h:function(N,K,O){var M=K[0],L=this.element;D.setStyle(L,"width",M);this.cfg.refireEvent("iframe");},configzIndex:function(M,K,N){var O=K[0],L=this.element;if(!O){O=D.getStyle(L,"zIndex");if(!O||isNaN(O)){O=0;}}if(this.iframe||this.cfg.getProperty("iframe")===true){if(O<=0){O=1;}}D.setStyle(L,"zIndex",O);this.cfg.setProperty("zIndex",O,true);if(this.iframe){this.stackIframe();}},configXY:function(M,L,N){var P=L[0],K=P[0],O=P[1];this.cfg.setProperty("x",K);this.cfg.setProperty("y",O);this.beforeMoveEvent.fire([K,O]);K=this.cfg.getProperty("x");O=this.cfg.getProperty("y");this.cfg.refireEvent("iframe");this.moveEvent.fire([K,O]);},configX:function(M,L,N){var K=L[0],O=this.cfg.getProperty("y");this.cfg.setProperty("x",K,true);this.cfg.setProperty("y",O,true);this.beforeMoveEvent.fire([K,O]);K=this.cfg.getProperty("x");O=this.cfg.getProperty("y");D.setX(this.element,K,true);this.cfg.setProperty("xy",[K,O],true);this.cfg.refireEvent("iframe");this.moveEvent.fire([K,O]);},configY:!
 function(M,L,N){var K=this.cfg.getProperty("x"),O=L[0];this.cfg.setProperty("x",K,true);this.cfg.setProperty("y",O,true);this.beforeMoveEvent.fire([K,O]);K=this.cfg.getProperty("x");O=this.cfg.getProperty("y");D.setY(this.element,O,true);this.cfg.setProperty("xy",[K,O],true);this.cfg.refireEvent("iframe");this.moveEvent.fire([K,O]);},showIframe:function(){var L=this.iframe,K;if(L){K=this.element.parentNode;if(K!=L.parentNode){this._addToParent(K,L);}L.style.display="block";}},hideIframe:function(){if(this.iframe){this.iframe.style.display="none";}},syncIframe:function(){var K=this.iframe,M=this.element,O=B.IFRAME_OFFSET,L=(O*2),N;if(K){K.style.width=(M.offsetWidth+L+"px");K.style.height=(M.offsetHeight+L+"px");N=this.cfg.getProperty("xy");if(!F.isArray(N)||(isNaN(N[0])||isNaN(N[1]))){this.syncPosition();N=this.cfg.getProperty("xy");}D.setXY(K,[(N[0]-O),(N[1]-O)]);}},stackIframe:function(){if(this.iframe){var K=D.getStyle(this.element,"zIndex");if(!YAHOO.lang.isUndefined(K)&!
 &!isNaN(K)){D.setStyle(this.iframe,"zIndex",(K-1));}}},configI!
 frame:fu
nction(N,M,O){var K=M[0];function P(){var R=this.iframe,S=this.element,T;if(!R){if(!G){G=document.createElement("iframe");if(this.isSecure){G.src=B.IFRAME_SRC;}if(YAHOO.env.ua.ie){G.style.filter="alpha(opacity=0)";G.frameBorder=0;}else{G.style.opacity="0";}G.style.position="absolute";G.style.border="none";G.style.margin="0";G.style.padding="0";G.style.display="none";}R=G.cloneNode(false);T=S.parentNode;var Q=T||document.body;this._addToParent(Q,R);this.iframe=R;}this.showIframe();this.syncIframe();this.stackIframe();if(!this._hasIframeEventListeners){this.showEvent.subscribe(this.showIframe);this.hideEvent.subscribe(this.hideIframe);this.changeContentEvent.subscribe(this.syncIframe);this._hasIframeEventListeners=true;}}function L(){P.call(this);this.beforeShowEvent.unsubscribe(L);this._iframeDeferred=false;}if(K){if(this.cfg.getProperty("visible")){P.call(this);}else{if(!this._iframeDeferred){this.beforeShowEvent.subscribe(L);this._iframeDeferred=true;}}}else{this.hideIframe!
 ();if(this._hasIframeEventListeners){this.showEvent.unsubscribe(this.showIframe);this.hideEvent.unsubscribe(this.hideIframe);this.changeContentEvent.unsubscribe(this.syncIframe);this._hasIframeEventListeners=false;}}},_primeXYFromDOM:function(){if(YAHOO.lang.isUndefined(this.cfg.getProperty("xy"))){this.syncPosition();this.cfg.refireEvent("xy");this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);}},configConstrainToViewport:function(L,K,M){var N=K[0];if(N){if(!C.alreadySubscribed(this.beforeMoveEvent,this.enforceConstraints,this)){this.beforeMoveEvent.subscribe(this.enforceConstraints,this,true);}if(!C.alreadySubscribed(this.beforeShowEvent,this._primeXYFromDOM)){this.beforeShowEvent.subscribe(this._primeXYFromDOM);}}else{this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);this.beforeMoveEvent.unsubscribe(this.enforceConstraints,this);}},configContext:function(M,L,O){var Q=L[0],N,P,K;if(Q){N=Q[0];P=Q[1];
+K=Q[2];if(N){if(typeof N=="string"){this.cfg.setProperty("context",[document.getElementById(N),P,K],true);}if(P&&K){this.align(P,K);}}}},align:function(L,K){var Q=this.cfg.getProperty("context"),P=this,O,N,R;function M(S,T){switch(L){case B.TOP_LEFT:P.moveTo(T,S);break;case B.TOP_RIGHT:P.moveTo((T-N.offsetWidth),S);break;case B.BOTTOM_LEFT:P.moveTo(T,(S-N.offsetHeight));break;case B.BOTTOM_RIGHT:P.moveTo((T-N.offsetWidth),(S-N.offsetHeight));break;}}if(Q){O=Q[0];N=this.element;P=this;if(!L){L=Q[1];}if(!K){K=Q[2];}if(N&&O){R=D.getRegion(O);switch(K){case B.TOP_LEFT:M(R.top,R.left);break;case B.TOP_RIGHT:M(R.top,R.right);break;case B.BOTTOM_LEFT:M(R.bottom,R.left);break;case B.BOTTOM_RIGHT:M(R.bottom,R.right);break;}}}},enforceConstraints:function(L,K,M){var O=K[0];var N=this.getConstrainedXY(O[0],O[1]);this.cfg.setProperty("x",N[0],true);this.cfg.setProperty("y",N[1],true);this.cfg.setProperty("xy",N,true);},getConstrainedXY:function(V,T){var N=B.VIEWPORT_OFFSET,U=D.getViewp!
 ortWidth(),Q=D.getViewportHeight(),M=this.element.offsetHeight,S=this.element.offsetWidth,Y=D.getDocumentScrollLeft(),W=D.getDocumentScrollTop();var P=V;var L=T;if(S+N<U){var R=Y+N;var X=Y+U-S-N;if(V<R){P=R;}else{if(V>X){P=X;}}}else{P=N+Y;}if(M+N<Q){var O=W+N;var K=W+Q-M-N;if(T<O){L=O;}else{if(T>K){L=K;}}}else{L=N+W;}return[P,L];},center:function(){var N=B.VIEWPORT_OFFSET,O=this.element.offsetWidth,M=this.element.offsetHeight,L=D.getViewportWidth(),P=D.getViewportHeight(),K,Q;if(O<L){K=(L/2)-(O/2)+D.getDocumentScrollLeft();}else{K=N+D.getDocumentScrollLeft();}if(M<P){Q=(P/2)-(M/2)+D.getDocumentScrollTop();}else{Q=N+D.getDocumentScrollTop();}this.cfg.setProperty("xy",[parseInt(K,10),parseInt(Q,10)]);this.cfg.refireEvent("iframe");},syncPosition:function(){var K=D.getXY(this.element);this.cfg.setProperty("x",K[0],true);this.cfg.setProperty("y",K[1],true);this.cfg.setProperty("xy",K,true);},onDomResize:function(M,L){var K=this;B.superclass.onDomResize.call(this,M,L);setTimeout!
 (function(){K.syncPosition();K.cfg.refireEvent("iframe");K.cfg!
 .refireE
vent("context");},0);},bringToTop:function(){var O=[],N=this.element;function R(V,U){var X=D.getStyle(V,"zIndex"),W=D.getStyle(U,"zIndex"),T=(!X||isNaN(X))?0:parseInt(X,10),S=(!W||isNaN(W))?0:parseInt(W,10);if(T>S){return -1;}else{if(T<S){return 1;}else{return 0;}}}function M(U){var S=D.hasClass(U,B.CSS_OVERLAY),T=YAHOO.widget.Panel;if(S&&!D.isAncestor(N,S)){if(T&&D.hasClass(U,T.CSS_PANEL)){O[O.length]=U.parentNode;}else{O[O.length]=U;}}}D.getElementsBy(M,"DIV",document.body);O.sort(R);var K=O[0],Q;if(K){Q=D.getStyle(K,"zIndex");if(!isNaN(Q)){var P=false;if(K!=N){P=true;}else{if(O.length>1){var L=D.getStyle(O[1],"zIndex");if(!isNaN(L)&&(Q==L)){P=true;}}}if(P){this.cfg.setProperty("zindex",(parseInt(Q,10)+2));}}}},destroy:function(){if(this.iframe){this.iframe.parentNode.removeChild(this.iframe);}this.iframe=null;B.windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent,this);B.windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent,this);B.superclass.destroy.call(this);},toStrin!
 g:function(){return"Overlay "+this.id;}});}());(function(){YAHOO.widget.OverlayManager=function(G){this.init(G);};var D=YAHOO.widget.Overlay,C=YAHOO.util.Event,E=YAHOO.util.Dom,B=YAHOO.util.Config,F=YAHOO.util.CustomEvent,A=YAHOO.widget.OverlayManager;A.CSS_FOCUSED="focused";A.prototype={constructor:A,overlays:null,initDefaultConfig:function(){this.cfg.addProperty("overlays",{suppressEvent:true});this.cfg.addProperty("focusevent",{value:"mousedown"});},init:function(I){this.cfg=new B(this);this.initDefaultConfig();if(I){this.cfg.applyConfig(I,true);}this.cfg.fireQueue();var H=null;this.getActive=function(){return H;};this.focus=function(J){var K=this.find(J);if(K){if(H!=K){if(H){H.blur();}this.bringToTop(K);H=K;E.addClass(H.element,A.CSS_FOCUSED);K.focusEvent.fire();}}};this.remove=function(K){var M=this.find(K),J;if(M){if(H==M){H=null;}var L=(M.element===null&&M.cfg===null)?true:false;if(!L){J=E.getStyle(M.element,"zIndex");M.cfg.setProperty("zIndex",-1000,true);}this.over!
 lays.sort(this.compareZIndexDesc);this.overlays=this.overlays.!
 slice(0,
(this.overlays.length-1));M.hideEvent.unsubscribe(M.blur);M.destroyEvent.unsubscribe(this._onOverlayDestroy,M);if(!L){C.removeListener(M.element,this.cfg.getProperty("focusevent"),this._onOverlayElementFocus);M.cfg.setProperty("zIndex",J,true);M.cfg.setProperty("manager",null);}M.focusEvent.unsubscribeAll();M.blurEvent.unsubscribeAll();M.focusEvent=null;M.blurEvent=null;M.focus=null;M.blur=null;}};this.blurAll=function(){var K=this.overlays.length,J;if(K>0){J=K-1;do{this.overlays[J].blur();}while(J--);}};this._onOverlayBlur=function(K,J){H=null;};var G=this.cfg.getProperty("overlays");if(!this.overlays){this.overlays=[];}if(G){this.register(G);this.overlays.sort(this.compareZIndexDesc);}},_onOverlayElementFocus:function(I){var G=C.getTarget(I),H=this.close;if(H&&(G==H||E.isAncestor(H,G))){this.blur();}else{this.focus();}},_onOverlayDestroy:function(H,G,I){this.remove(I);},register:function(G){var K=this,L,I,H,J;if(G instanceof D){G.cfg.addProperty("manager",{value:this});G.f!
 ocusEvent=G.createEvent("focus");G.focusEvent.signature=F.LIST;G.blurEvent=G.createEvent("blur");G.blurEvent.signature=F.LIST;G.focus=function(){K.focus(this);};G.blur=function(){if(K.getActive()==this){E.removeClass(this.element,A.CSS_FOCUSED);this.blurEvent.fire();}};G.blurEvent.subscribe(K._onOverlayBlur);G.hideEvent.subscribe(G.blur);G.destroyEvent.subscribe(this._onOverlayDestroy,G,this);C.on(G.element,this.cfg.getProperty("focusevent"),this._onOverlayElementFocus,null,G);L=E.getStyle(G.element,"zIndex");if(!isNaN(L)){G.cfg.setProperty("zIndex",parseInt(L,10));}else{G.cfg.setProperty("zIndex",0);}this.overlays.push(G);this.bringToTop(G);return true;}else{if(G instanceof Array){I=0;J=G.length;for(H=0;H<J;H++){if(this.register(G[H])){I++;}}if(I>0){return true;}}else{return false;}}},bringToTop:function(M){var I=this.find(M),L,G,J;if(I){J=this.overlays;J.sort(this.compareZIndexDesc);G=J[0];if(G){L=E.getStyle(G.element,"zIndex");
+if(!isNaN(L)){var K=false;if(G!==I){K=true;}else{if(J.length>1){var H=E.getStyle(J[1].element,"zIndex");if(!isNaN(H)&&(L==H)){K=true;}}}if(K){I.cfg.setProperty("zindex",(parseInt(L,10)+2));}}J.sort(this.compareZIndexDesc);}}},find:function(G){var I=this.overlays,J=I.length,H;if(J>0){H=J-1;if(G instanceof D){do{if(I[H]==G){return I[H];}}while(H--);}else{if(typeof G=="string"){do{if(I[H].id==G){return I[H];}}while(H--);}}return null;}},compareZIndexDesc:function(J,I){var H=(J.cfg)?J.cfg.getProperty("zIndex"):null,G=(I.cfg)?I.cfg.getProperty("zIndex"):null;if(H===null&&G===null){return 0;}else{if(H===null){return 1;}else{if(G===null){return -1;}else{if(H>G){return -1;}else{if(H<G){return 1;}else{return 0;}}}}}},showAll:function(){var H=this.overlays,I=H.length,G;if(I>0){G=I-1;do{H[G].show();}while(G--);}},hideAll:function(){var H=this.overlays,I=H.length,G;if(I>0){G=I-1;do{H[G].hide();}while(G--);}},toString:function(){return"OverlayManager";}};}());(function(){YAHOO.widget.To!
 oltip=function(N,M){YAHOO.widget.Tooltip.superclass.constructor.call(this,N,M);};var E=YAHOO.lang,L=YAHOO.util.Event,K=YAHOO.util.CustomEvent,C=YAHOO.util.Dom,G=YAHOO.widget.Tooltip,F,H={"PREVENT_OVERLAP":{key:"preventoverlap",value:true,validator:E.isBoolean,supercedes:["x","y","xy"]},"SHOW_DELAY":{key:"showdelay",value:200,validator:E.isNumber},"AUTO_DISMISS_DELAY":{key:"autodismissdelay",value:5000,validator:E.isNumber},"HIDE_DELAY":{key:"hidedelay",value:250,validator:E.isNumber},"TEXT":{key:"text",suppressEvent:true},"CONTAINER":{key:"container"},"DISABLED":{key:"disabled",value:false,suppressEvent:true}},A={"CONTEXT_MOUSE_OVER":"contextMouseOver","CONTEXT_MOUSE_OUT":"contextMouseOut","CONTEXT_TRIGGER":"contextTrigger"};G.CSS_TOOLTIP="yui-tt";function I(N,M,O){var R=O[0],P=O[1],Q=this.cfg,S=Q.getProperty("width");if(S==P){Q.setProperty("width",R);}this.unsubscribe("hide",this._onHide,O);}function D(N,M){var O=document.body,S=this.cfg,R=S.getProperty("width"),P,Q;if((!R!
 ||R=="auto")&&(S.getProperty("container")!=O||S.getProperty("x!
 ")>=C.ge
tViewportWidth()||S.getProperty("y")>=C.getViewportHeight())){Q=this.element.cloneNode(true);Q.style.visibility="hidden";Q.style.top="0px";Q.style.left="0px";O.appendChild(Q);P=(Q.offsetWidth+"px");O.removeChild(Q);Q=null;S.setProperty("width",P);S.refireEvent("xy");this.subscribe("hide",I,[(R||""),P]);}}function B(N,M,O){this.render(O);}function J(){L.onDOMReady(B,this.cfg.getProperty("container"),this);}YAHOO.extend(G,YAHOO.widget.Overlay,{init:function(N,M){G.superclass.init.call(this,N);this.beforeInitEvent.fire(G);C.addClass(this.element,G.CSS_TOOLTIP);if(M){this.cfg.applyConfig(M,true);}this.cfg.queueProperty("visible",false);this.cfg.queueProperty("constraintoviewport",true);this.setBody("");this.subscribe("beforeShow",D);this.subscribe("init",J);this.subscribe("render",this.onRender);this.initEvent.fire(G);},initEvents:function(){G.superclass.initEvents.call(this);var M=K.LIST;this.contextMouseOverEvent=this.createEvent(A.CONTEXT_MOUSE_OVER);this.contextMouseOverEven!
 t.signature=M;this.contextMouseOutEvent=this.createEvent(A.CONTEXT_MOUSE_OUT);this.contextMouseOutEvent.signature=M;this.contextTriggerEvent=this.createEvent(A.CONTEXT_TRIGGER);this.contextTriggerEvent.signature=M;},initDefaultConfig:function(){G.superclass.initDefaultConfig.call(this);this.cfg.addProperty(H.PREVENT_OVERLAP.key,{value:H.PREVENT_OVERLAP.value,validator:H.PREVENT_OVERLAP.validator,supercedes:H.PREVENT_OVERLAP.supercedes});this.cfg.addProperty(H.SHOW_DELAY.key,{handler:this.configShowDelay,value:200,validator:H.SHOW_DELAY.validator});this.cfg.addProperty(H.AUTO_DISMISS_DELAY.key,{handler:this.configAutoDismissDelay,value:H.AUTO_DISMISS_DELAY.value,validator:H.AUTO_DISMISS_DELAY.validator});this.cfg.addProperty(H.HIDE_DELAY.key,{handler:this.configHideDelay,value:H.HIDE_DELAY.value,validator:H.HIDE_DELAY.validator});this.cfg.addProperty(H.TEXT.key,{handler:this.configText,suppressEvent:H.TEXT.suppressEvent});this.cfg.addProperty(H.CONTAINER.key,{handler:this.co!
 nfigContainer,value:document.body});this.cfg.addProperty(H.DIS!
 ABLED.ke
y,{handler:this.configContainer,value:H.DISABLED.value,supressEvent:H.DISABLED.suppressEvent});},configText:function(N,M,O){var P=M[0];if(P){this.setBody(P);}},configContainer:function(O,N,P){var M=N[0];if(typeof M=="string"){this.cfg.setProperty("container",document.getElementById(M),true);}},_removeEventListeners:function(){var P=this._context,M,O,N;if(P){M=P.length;if(M>0){N=M-1;do{O=P[N];L.removeListener(O,"mouseover",this.onContextMouseOver);L.removeListener(O,"mousemove",this.onContextMouseMove);L.removeListener(O,"mouseout",this.onContextMouseOut);}while(N--);}}},configContext:function(R,N,S){var Q=N[0],T,M,P,O;if(Q){if(!(Q instanceof Array)){if(typeof Q=="string"){this.cfg.setProperty("context",[document.getElementById(Q)],true);}else{this.cfg.setProperty("context",[Q],true);}Q=this.cfg.getProperty("context");}this._removeEventListeners();this._context=Q;T=this._context;if(T){M=T.length;if(M>0){O=M-1;do{P=T[O];L.on(P,"mouseover",this.onContextMouseOver,this);L.on(P,"!
 mousemove",this.onContextMouseMove,this);L.on(P,"mouseout",this.onContextMouseOut,this);}while(O--);}}}},onContextMouseMove:function(N,M){M.pageX=L.getPageX(N);M.pageY=L.getPageY(N);},onContextMouseOver:function(O,N){var M=this;if(M.title){N._tempTitle=M.title;M.title="";}if(N.fireEvent("contextMouseOver",M,O)!==false&&!N.cfg.getProperty("disabled")){if(N.hideProcId){clearTimeout(N.hideProcId);N.hideProcId=null;}L.on(M,"mousemove",N.onContextMouseMove,N);N.showProcId=N.doShow(O,M);}},onContextMouseOut:function(O,N){var M=this;if(N._tempTitle){M.title=N._tempTitle;N._tempTitle=null;}if(N.showProcId){clearTimeout(N.showProcId);N.showProcId=null;}if(N.hideProcId){clearTimeout(N.hideProcId);N.hideProcId=null;}N.fireEvent("contextMouseOut",M,O);N.hideProcId=setTimeout(function(){N.hide();},N.cfg.getProperty("hidedelay"));},doShow:function(O,M){var P=25,N=this;if(YAHOO.env.ua.opera&&M.tagName&&M.tagName.toUpperCase()=="A"){P+=12;
+}return setTimeout(function(){var Q=N.cfg.getProperty("text");if(N._tempTitle&&(Q===""||YAHOO.lang.isUndefined(Q)||YAHOO.lang.isNull(Q))){N.setBody(N._tempTitle);}else{N.cfg.refireEvent("text");}N.moveTo(N.pageX,N.pageY+P);if(N.cfg.getProperty("preventoverlap")){N.preventOverlap(N.pageX,N.pageY);}L.removeListener(M,"mousemove",N.onContextMouseMove);N.contextTriggerEvent.fire(M);N.show();N.hideProcId=N.doHide();},this.cfg.getProperty("showdelay"));},doHide:function(){var M=this;return setTimeout(function(){M.hide();},this.cfg.getProperty("autodismissdelay"));},preventOverlap:function(Q,P){var M=this.element.offsetHeight,O=new YAHOO.util.Point(Q,P),N=C.getRegion(this.element);N.top-=5;N.left-=5;N.right+=5;N.bottom+=5;if(N.contains(O)){this.cfg.setProperty("y",(P-M-5));}},onRender:function(Q,P){function R(){var U=this.element,T=this._shadow;if(T){T.style.width=(U.offsetWidth+6)+"px";T.style.height=(U.offsetHeight+1)+"px";}}function N(){C.addClass(this._shadow,"yui-tt-shadow-vi!
 sible");}function M(){C.removeClass(this._shadow,"yui-tt-shadow-visible");}function S(){var V=this._shadow,U,T,X,W;if(!V){U=this.element;T=YAHOO.widget.Module;X=YAHOO.env.ua.ie;W=this;if(!F){F=document.createElement("div");F.className="yui-tt-shadow";}V=F.cloneNode(false);U.appendChild(V);this._shadow=V;N.call(this);this.subscribe("beforeShow",N);this.subscribe("beforeHide",M);if(X==6||(X==7&&document.compatMode=="BackCompat")){window.setTimeout(function(){R.call(W);},0);this.cfg.subscribeToConfigEvent("width",R);this.cfg.subscribeToConfigEvent("height",R);this.subscribe("changeContent",R);T.textResizeEvent.subscribe(R,this,true);this.subscribe("destroy",function(){T.textResizeEvent.unsubscribe(R,this);});}}}function O(){S.call(this);this.unsubscribe("beforeShow",O);}if(this.cfg.getProperty("visible")){S.call(this);}else{this.subscribe("beforeShow",O);}},destroy:function(){this._removeEventListeners();G.superclass.destroy.call(this);},toString:function(){return"Tooltip "+th!
 is.id;}});}());(function(){YAHOO.widget.Panel=function(R,Q){YA!
 HOO.widg
et.Panel.superclass.constructor.call(this,R,Q);};var I=YAHOO.lang,E=YAHOO.util.DD,F=YAHOO.util.Dom,P=YAHOO.util.Event,B=YAHOO.widget.Overlay,O=YAHOO.util.CustomEvent,C=YAHOO.util.Config,N=YAHOO.widget.Panel,H,L,D,A={"SHOW_MASK":"showMask","HIDE_MASK":"hideMask","DRAG":"drag"},J={"CLOSE":{key:"close",value:true,validator:I.isBoolean,supercedes:["visible"]},"DRAGGABLE":{key:"draggable",value:(E?true:false),validator:I.isBoolean,supercedes:["visible"]},"DRAG_ONLY":{key:"dragonly",value:false,validator:I.isBoolean,supercedes:["draggable"]},"UNDERLAY":{key:"underlay",value:"shadow",supercedes:["visible"]},"MODAL":{key:"modal",value:false,validator:I.isBoolean,supercedes:["visible","zindex"]},"KEY_LISTENERS":{key:"keylisteners",suppressEvent:true,supercedes:["visible"]}};N.CSS_PANEL="yui-panel";N.CSS_PANEL_CONTAINER="yui-panel-container";N.FOCUSABLE=["a","button","select","textarea","input"];function M(R,Q){if(!this.header&&this.cfg.getProperty("draggable")){this.setHeader(" !
 ");}}function K(R,Q,S){var V=S[0],T=S[1],U=this.cfg,W=U.getProperty("width");if(W==T){U.setProperty("width",V);}this.unsubscribe("hide",K,S);}function G(R,Q){var V=YAHOO.env.ua.ie,U,T,S;if(V==6||(V==7&&document.compatMode=="BackCompat")){U=this.cfg;T=U.getProperty("width");if(!T||T=="auto"){S=(this.element.offsetWidth+"px");U.setProperty("width",S);this.subscribe("hide",K,[(T||""),S]);}}}YAHOO.extend(N,B,{init:function(R,Q){N.superclass.init.call(this,R);this.beforeInitEvent.fire(N);F.addClass(this.element,N.CSS_PANEL);this.buildWrapper();if(Q){this.cfg.applyConfig(Q,true);}this.subscribe("showMask",this._addFocusHandlers);this.subscribe("hideMask",this._removeFocusHandlers);this.subscribe("beforeRender",M);this.initEvent.fire(N);},_onElementFocus:function(Q){this.blur();},_addFocusHandlers:function(Y,S){var V=this,Z="focus",U="hidden";function X(a){if(a.type!==U&&!F.isAncestor(V.element,a)){P.on(a,Z,V._onElementFocus);return true;}return false;}var W=N.FOCUSABLE,Q=W.length!
 ,T=[];for(var R=0;R<Q;R++){T=T.concat(F.getElementsBy(X,W[R]))!
 ;}this.f
ocusableElements=T;},_removeFocusHandlers:function(T,S){var V=this.focusableElements,Q=V.length,R="focus";if(V){for(var U=0;U<Q;U++){P.removeListener(V[U],R,this._onElementFocus);}}},initEvents:function(){N.superclass.initEvents.call(this);var Q=O.LIST;this.showMaskEvent=this.createEvent(A.SHOW_MASK);this.showMaskEvent.signature=Q;this.hideMaskEvent=this.createEvent(A.HIDE_MASK);this.hideMaskEvent.signature=Q;this.dragEvent=this.createEvent(A.DRAG);this.dragEvent.signature=Q;},initDefaultConfig:function(){N.superclass.initDefaultConfig.call(this);this.cfg.addProperty(J.CLOSE.key,{handler:this.configClose,value:J.CLOSE.value,validator:J.CLOSE.validator,supercedes:J.CLOSE.supercedes});this.cfg.addProperty(J.DRAGGABLE.key,{handler:this.configDraggable,value:J.DRAGGABLE.value,validator:J.DRAGGABLE.validator,supercedes:J.DRAGGABLE.supercedes});this.cfg.addProperty(J.DRAG_ONLY.key,{value:J.DRAG_ONLY.value,validator:J.DRAG_ONLY.validator,supercedes:J.DRAG_ONLY.supercedes});this.cfg!
 .addProperty(J.UNDERLAY.key,{handler:this.configUnderlay,value:J.UNDERLAY.value,supercedes:J.UNDERLAY.supercedes});this.cfg.addProperty(J.MODAL.key,{handler:this.configModal,value:J.MODAL.value,validator:J.MODAL.validator,supercedes:J.MODAL.supercedes});this.cfg.addProperty(J.KEY_LISTENERS.key,{handler:this.configKeyListeners,suppressEvent:J.KEY_LISTENERS.suppressEvent,supercedes:J.KEY_LISTENERS.supercedes});},configClose:function(S,Q,U){var V=Q[0],R=this.close;function T(X,W){W.hide();}if(V){if(!R){if(!D){D=document.createElement("span");D.innerHTML=" ";D.className="container-close";}R=D.cloneNode(true);this.innerElement.appendChild(R);P.on(R,"click",T,this);this.close=R;}else{R.style.display="block";}}else{if(R){R.style.display="none";}}},configDraggable:function(R,Q,S){var T=Q[0];if(T){if(!E){this.cfg.setProperty("draggable",false);return ;}if(this.header){F.setStyle(this.header,"cursor","move");this.registerDragDrop();
+}this.subscribe("beforeShow",G);}else{if(this.dd){this.dd.unreg();}if(this.header){F.setStyle(this.header,"cursor","auto");}this.unsubscribe("beforeShow",G);}},configUnderlay:function(b,a,V){var Z=YAHOO.env.ua,X=(this.platform=="mac"&&Z.gecko),Y=(Z.ie==6||(Z.ie==7&&document.compatMode=="BackCompat")),c=a[0].toLowerCase(),R=this.underlay,S=this.element;function d(){var e=this.underlay;F.addClass(e,"yui-force-redraw");window.setTimeout(function(){F.removeClass(e,"yui-force-redraw");},0);}function T(){var e=false;if(!R){if(!L){L=document.createElement("div");L.className="underlay";}R=L.cloneNode(false);this.element.appendChild(R);this.underlay=R;if(Y){this.sizeUnderlay();this.cfg.subscribeToConfigEvent("width",this.sizeUnderlay);this.cfg.subscribeToConfigEvent("height",this.sizeUnderlay);this.changeContentEvent.subscribe(this.sizeUnderlay);YAHOO.widget.Module.textResizeEvent.subscribe(this.sizeUnderlay,this,true);}if(Z.webkit&&Z.webkit<420){this.changeContentEvent.subscribe(d)!
 ;}e=true;}}function W(){var e=T.call(this);if(!e&&Y){this.sizeUnderlay();}this._underlayDeferred=false;this.beforeShowEvent.unsubscribe(W);}function U(){if(this._underlayDeferred){this.beforeShowEvent.unsubscribe(W);this._underlayDeferred=false;}if(R){this.cfg.unsubscribeFromConfigEvent("width",this.sizeUnderlay);this.cfg.unsubscribeFromConfigEvent("height",this.sizeUnderlay);this.changeContentEvent.unsubscribe(this.sizeUnderlay);this.changeContentEvent.unsubscribe(d);YAHOO.widget.Module.textResizeEvent.unsubscribe(this.sizeUnderlay,this,true);this.element.removeChild(R);this.underlay=null;}}switch(c){case"shadow":F.removeClass(S,"matte");F.addClass(S,"shadow");break;case"matte":if(!X){U.call(this);}F.removeClass(S,"shadow");F.addClass(S,"matte");break;default:if(!X){U.call(this);}F.removeClass(S,"shadow");F.removeClass(S,"matte");break;}if((c=="shadow")||(X&&!R)){if(this.cfg.getProperty("visible")){var Q=T.call(this);if(!Q&&Y){this.sizeUnderlay();}}else{if(!this._underlayD!
 eferred){this.beforeShowEvent.subscribe(W);this._underlayDefer!
 red=true
;}}}},configModal:function(R,Q,T){var S=Q[0];if(S){if(!this._hasModalityEventListeners){this.subscribe("beforeShow",this.buildMask);this.subscribe("beforeShow",this.bringToTop);this.subscribe("beforeShow",this.showMask);this.subscribe("hide",this.hideMask);B.windowResizeEvent.subscribe(this.sizeMask,this,true);this._hasModalityEventListeners=true;}}else{if(this._hasModalityEventListeners){if(this.cfg.getProperty("visible")){this.hideMask();this.removeMask();}this.unsubscribe("beforeShow",this.buildMask);this.unsubscribe("beforeShow",this.bringToTop);this.unsubscribe("beforeShow",this.showMask);this.unsubscribe("hide",this.hideMask);B.windowResizeEvent.unsubscribe(this.sizeMask,this);this._hasModalityEventListeners=false;}}},removeMask:function(){var R=this.mask,Q;if(R){this.hideMask();Q=R.parentNode;if(Q){Q.removeChild(R);}this.mask=null;}},configKeyListeners:function(T,Q,W){var S=Q[0],V,U,R;if(S){if(S instanceof Array){U=S.length;for(R=0;R<U;R++){V=S[R];if(!C.alreadySubscri!
 bed(this.showEvent,V.enable,V)){this.showEvent.subscribe(V.enable,V,true);}if(!C.alreadySubscribed(this.hideEvent,V.disable,V)){this.hideEvent.subscribe(V.disable,V,true);this.destroyEvent.subscribe(V.disable,V,true);}}}else{if(!C.alreadySubscribed(this.showEvent,S.enable,S)){this.showEvent.subscribe(S.enable,S,true);}if(!C.alreadySubscribed(this.hideEvent,S.disable,S)){this.hideEvent.subscribe(S.disable,S,true);this.destroyEvent.subscribe(S.disable,S,true);}}}},configHeight:function(T,R,U){var Q=R[0],S=this.innerElement;F.setStyle(S,"height",Q);this.cfg.refireEvent("iframe");},configWidth:function(T,Q,U){var S=Q[0],R=this.innerElement;F.setStyle(R,"width",S);this.cfg.refireEvent("iframe");},configzIndex:function(R,Q,T){N.superclass.configzIndex.call(this,R,Q,T);if(this.mask||this.cfg.getProperty("modal")===true){var S=F.getStyle(this.element,"zIndex");if(!S||isNaN(S)){S=0;}if(S===0){this.cfg.setProperty("zIndex",1);}else{this.stackMask();}}},buildWrapper:function(){var S=t!
 his.element.parentNode,Q=this.element,R=document.createElement!
 ("div");
R.className=N.CSS_PANEL_CONTAINER;R.id=Q.id+"_c";if(S){S.insertBefore(R,Q);}R.appendChild(Q);this.element=R;this.innerElement=Q;F.setStyle(this.innerElement,"visibility","inherit");},sizeUnderlay:function(){var R=this.underlay,Q;if(R){Q=this.element;R.style.width=Q.offsetWidth+"px";R.style.height=Q.offsetHeight+"px";}},registerDragDrop:function(){var R=this;if(this.header){if(!E){return ;}var Q=(this.cfg.getProperty("dragonly")===true);this.dd=new E(this.element.id,this.id,{dragOnly:Q});if(!this.header.id){this.header.id=this.id+"_h";}this.dd.startDrag=function(){var T,V,S,Y,X,W;if(YAHOO.env.ua.ie==6){F.addClass(R.element,"drag");}if(R.cfg.getProperty("constraintoviewport")){var U=B.VIEWPORT_OFFSET;T=R.element.offsetHeight;V=R.element.offsetWidth;S=F.getViewportWidth();Y=F.getViewportHeight();X=F.getDocumentScrollLeft();W=F.getDocumentScrollTop();if(T+U<Y){this.minY=W+U;this.maxY=W+Y-T-U;}else{this.minY=W+U;this.maxY=W+U;}if(V+U<S){this.minX=X+U;this.maxX=X+S-V-U;}else{this.!
 minX=X+U;this.maxX=X+U;}this.constrainX=true;this.constrainY=true;}else{this.constrainX=false;this.constrainY=false;}R.dragEvent.fire("startDrag",arguments);};this.dd.onDrag=function(){R.syncPosition();R.cfg.refireEvent("iframe");if(this.platform=="mac"&&YAHOO.env.ua.gecko){this.showMacGeckoScrollbars();}R.dragEvent.fire("onDrag",arguments);};this.dd.endDrag=function(){if(YAHOO.env.ua.ie==6){F.removeClass(R.element,"drag");}R.dragEvent.fire("endDrag",arguments);R.moveEvent.fire(R.cfg.getProperty("xy"));};this.dd.setHandleElId(this.header.id);this.dd.addInvalidHandleType("INPUT");this.dd.addInvalidHandleType("SELECT");this.dd.addInvalidHandleType("TEXTAREA");}},buildMask:function(){var Q=this.mask;if(!Q){if(!H){H=document.createElement("div");H.className="mask";H.innerHTML=" ";}Q=H.cloneNode(true);Q.id=this.id+"_mask";document.body.insertBefore(Q,document.body.firstChild);this.mask=Q;if(YAHOO.env.ua.gecko&&this.platform=="mac"){F.addClass(this.mask,"block-scrollbars");
+}this.stackMask();}},hideMask:function(){if(this.cfg.getProperty("modal")&&this.mask){this.mask.style.display="none";this.hideMaskEvent.fire();F.removeClass(document.body,"masked");}},showMask:function(){if(this.cfg.getProperty("modal")&&this.mask){F.addClass(document.body,"masked");this.sizeMask();this.mask.style.display="block";this.showMaskEvent.fire();}},sizeMask:function(){if(this.mask){this.mask.style.height=F.getDocumentHeight()+"px";this.mask.style.width=F.getDocumentWidth()+"px";}},stackMask:function(){if(this.mask){var Q=F.getStyle(this.element,"zIndex");if(!YAHOO.lang.isUndefined(Q)&&!isNaN(Q)){F.setStyle(this.mask,"zIndex",Q-1);}}},render:function(Q){return N.superclass.render.call(this,Q,this.innerElement);},destroy:function(){B.windowResizeEvent.unsubscribe(this.sizeMask,this);this.removeMask();if(this.close){P.purgeElement(this.close);}N.superclass.destroy.call(this);},toString:function(){return"Panel "+this.id;}});}());(function(){YAHOO.widget.Dialog=functio!
 n(L,K){YAHOO.widget.Dialog.superclass.constructor.call(this,L,K);};var J=YAHOO.util.Event,I=YAHOO.util.CustomEvent,D=YAHOO.util.Dom,B=YAHOO.util.KeyListener,H=YAHOO.util.Connect,F=YAHOO.widget.Dialog,E=YAHOO.lang,A={"BEFORE_SUBMIT":"beforeSubmit","SUBMIT":"submit","MANUAL_SUBMIT":"manualSubmit","ASYNC_SUBMIT":"asyncSubmit","FORM_SUBMIT":"formSubmit","CANCEL":"cancel"},G={"POST_METHOD":{key:"postmethod",value:"async"},"BUTTONS":{key:"buttons",value:"none"},"HIDEAFTERSUBMIT":{key:"hideaftersubmit",value:true}};F.CSS_DIALOG="yui-dialog";function C(){var N=this._aButtons,L,M,K;if(E.isArray(N)){L=N.length;if(L>0){K=L-1;do{M=N[K];if(YAHOO.widget.Button&&M instanceof YAHOO.widget.Button){M.destroy();}else{if(M.tagName.toUpperCase()=="BUTTON"){J.purgeElement(M);J.purgeElement(M,false);}}}while(K--);}}}YAHOO.extend(F,YAHOO.widget.Panel,{form:null,initDefaultConfig:function(){F.superclass.initDefaultConfig.call(this);this.callback={success:null,failure:null,argument:null};this.cfg.ad!
 dProperty(G.POST_METHOD.key,{handler:this.configPostMethod,val!
 ue:G.POS
T_METHOD.value,validator:function(K){if(K!="form"&&K!="async"&&K!="none"&&K!="manual"){return false;}else{return true;}}});this.cfg.addProperty(G.HIDEAFTERSUBMIT.key,{value:G.HIDEAFTERSUBMIT.value});this.cfg.addProperty(G.BUTTONS.key,{handler:this.configButtons,value:G.BUTTONS.value});},initEvents:function(){F.superclass.initEvents.call(this);var K=I.LIST;this.beforeSubmitEvent=this.createEvent(A.BEFORE_SUBMIT);this.beforeSubmitEvent.signature=K;this.submitEvent=this.createEvent(A.SUBMIT);this.submitEvent.signature=K;this.manualSubmitEvent=this.createEvent(A.MANUAL_SUBMIT);this.manualSubmitEvent.signature=K;this.asyncSubmitEvent=this.createEvent(A.ASYNC_SUBMIT);this.asyncSubmitEvent.signature=K;this.formSubmitEvent=this.createEvent(A.FORM_SUBMIT);this.formSubmitEvent.signature=K;this.cancelEvent=this.createEvent(A.CANCEL);this.cancelEvent.signature=K;},init:function(L,K){F.superclass.init.call(this,L);this.beforeInitEvent.fire(F);D.addClass(this.element,F.CSS_DIALOG);this.cf!
 g.setProperty("visible",false);if(K){this.cfg.applyConfig(K,true);}this.showEvent.subscribe(this.focusFirst,this,true);this.beforeHideEvent.subscribe(this.blurButtons,this,true);this.subscribe("changeBody",this.registerForm);this.initEvent.fire(F);},doSubmit:function(){var Q=this.form,O=false,N=false,P,K,M,L;switch(this.cfg.getProperty("postmethod")){case"async":P=Q.elements;K=P.length;if(K>0){M=K-1;do{if(P[M].type=="file"){O=true;break;}}while(M--);}if(O&&YAHOO.env.ua.ie&&this.isSecure){N=true;}L=(Q.getAttribute("method")||"POST").toUpperCase();H.setForm(Q,O,N);H.asyncRequest(L,Q.getAttribute("action"),this.callback);this.asyncSubmitEvent.fire();break;case"form":Q.submit();this.formSubmitEvent.fire();break;case"none":case"manual":this.manualSubmitEvent.fire();break;}},registerForm:function(){var M=this.element.getElementsByTagName("form")[0],L=this,K,N;if(this.form){if(this.form==M&&D.isAncestor(this.element,this.form)){return ;}else{J.purgeElement(this.form);this.form=nul!
 l;}}if(!M){M=document.createElement("form");M.name="frm_"+this!
 .id;this
.body.appendChild(M);}if(M){this.form=M;J.on(M,"submit",function(O){J.stopEvent(O);this.submit();this.form.blur();},this,true);this.firstFormElement=function(){var Q,P,O=M.elements.length;for(Q=0;Q<O;Q++){P=M.elements[Q];if(P.focus&&!P.disabled&&P.type!="hidden"){return P;}}return null;}();this.lastFormElement=function(){var Q,P,O=M.elements.length;for(Q=O-1;Q>=0;Q--){P=M.elements[Q];if(P.focus&&!P.disabled&&P.type!="hidden"){return P;}}return null;}();if(this.cfg.getProperty("modal")){K=this.firstFormElement||this.firstButton;if(K){this.preventBackTab=new B(K,{shift:true,keys:9},{fn:L.focusLast,scope:L,correctScope:true});this.showEvent.subscribe(this.preventBackTab.enable,this.preventBackTab,true);this.hideEvent.subscribe(this.preventBackTab.disable,this.preventBackTab,true);}N=this.lastButton||this.lastFormElement;if(N){this.preventTabOut=new B(N,{shift:false,keys:9},{fn:L.focusFirst,scope:L,correctScope:true});this.showEvent.subscribe(this.preventTabOut.enable,this.preve!
 ntTabOut,true);this.hideEvent.subscribe(this.preventTabOut.disable,this.preventTabOut,true);}}}},configClose:function(M,K,N){var O=K[0];function L(Q,P){P.cancel();}if(O){if(!this.close){this.close=document.createElement("div");D.addClass(this.close,"container-close");this.close.innerHTML=" ";this.innerElement.appendChild(this.close);J.on(this.close,"click",L,this);}else{this.close.style.display="block";}}else{if(this.close){this.close.style.display="none";}}},configButtons:function(U,T,O){var P=YAHOO.widget.Button,W=T[0],M=this.innerElement,V,R,L,S,Q,K,N;C.call(this);this._aButtons=null;if(E.isArray(W)){Q=document.createElement("span");Q.className="button-group";S=W.length;this._aButtons=[];for(N=0;N<S;N++){V=W[N];if(P){L=new P({label:V.text,container:Q});R=L.get("element");if(V.isDefault){L.addClass("default");this.defaultHtmlButton=R;}if(E.isFunction(V.handler)){L.set("onclick",{fn:V.handler,obj:this,scope:this});
+}else{if(E.isObject(V.handler)&&E.isFunction(V.handler.fn)){L.set("onclick",{fn:V.handler.fn,obj:((!E.isUndefined(V.handler.obj))?V.handler.obj:this),scope:(V.handler.scope||this)});}}this._aButtons[this._aButtons.length]=L;}else{R=document.createElement("button");R.setAttribute("type","button");if(V.isDefault){R.className="default";this.defaultHtmlButton=R;}R.innerHTML=V.text;if(E.isFunction(V.handler)){J.on(R,"click",V.handler,this,true);}else{if(E.isObject(V.handler)&&E.isFunction(V.handler.fn)){J.on(R,"click",V.handler.fn,((!E.isUndefined(V.handler.obj))?V.handler.obj:this),(V.handler.scope||this));}}Q.appendChild(R);this._aButtons[this._aButtons.length]=R;}V.htmlButton=R;if(N===0){this.firstButton=R;}if(N==(S-1)){this.lastButton=R;}}this.setFooter(Q);K=this.footer;if(D.inDocument(this.element)&&!D.isAncestor(M,K)){M.appendChild(K);}this.buttonSpan=Q;}else{Q=this.buttonSpan;K=this.footer;if(Q&&K){K.removeChild(Q);this.buttonSpan=null;this.firstButton=null;this.lastButto!
 n=null;this.defaultHtmlButton=null;}}this.cfg.refireEvent("iframe");this.cfg.refireEvent("underlay");},getButtons:function(){var K=this._aButtons;if(K){return K;}},focusFirst:function(N,L,P){var M=this.firstFormElement,K;if(L){K=L[1];if(K){J.stopEvent(K);}}if(M){try{M.focus();}catch(O){}}else{this.focusDefaultButton();}},focusLast:function(N,L,P){var Q=this.cfg.getProperty("buttons"),M=this.lastFormElement,K;if(L){K=L[1];if(K){J.stopEvent(K);}}if(Q&&E.isArray(Q)){this.focusLastButton();}else{if(M){try{M.focus();}catch(O){}}}},focusDefaultButton:function(){var K=this.defaultHtmlButton;if(K){try{K.focus();}catch(L){}}},blurButtons:function(){var P=this.cfg.getProperty("buttons"),M,O,L,K;if(P&&E.isArray(P)){M=P.length;if(M>0){K=(M-1);do{O=P[K];if(O){L=O.htmlButton;if(L){try{L.blur();}catch(N){}}}}while(K--);}}},focusFirstButton:function(){var N=this.cfg.getProperty("buttons"),M,K;if(N&&E.isArray(N)){M=N[0];if(M){K=M.htmlButton;if(K){try{K.focus();}catch(L){}}}}},focusLastButto!
 n:function(){var O=this.cfg.getProperty("buttons"),L,N,K;if(O&!
 &E.isArr
ay(O)){L=O.length;if(L>0){N=O[(L-1)];if(N){K=N.htmlButton;if(K){try{K.focus();}catch(M){}}}}}},configPostMethod:function(L,K,M){this.registerForm();},validate:function(){return true;},submit:function(){if(this.validate()){this.beforeSubmitEvent.fire();this.doSubmit();this.submitEvent.fire();if(this.cfg.getProperty("hideaftersubmit")){this.hide();}return true;}else{return false;}},cancel:function(){this.cancelEvent.fire();this.hide();},getData:function(){var a=this.form,M,T,W,O,U,R,Q,L,X,N,Y,b,K,P,c,Z,V;function S(e){var d=e.tagName.toUpperCase();return((d=="INPUT"||d=="TEXTAREA"||d=="SELECT")&&e.name==O);}if(a){M=a.elements;T=M.length;W={};for(Z=0;Z<T;Z++){O=M[Z].name;U=D.getElementsBy(S,"*",a);R=U.length;if(R>0){if(R==1){U=U[0];Q=U.type;L=U.tagName.toUpperCase();switch(L){case"INPUT":if(Q=="checkbox"){W[O]=U.checked;}else{if(Q!="radio"){W[O]=U.value;}}break;case"TEXTAREA":W[O]=U.value;break;case"SELECT":X=U.options;N=X.length;Y=[];for(V=0;V<N;V++){b=X[V];if(b.selected){K=b.!
 value;if(!K||K===""){K=b.text;}Y[Y.length]=K;}}W[O]=Y;break;}}else{Q=U[0].type;switch(Q){case"radio":for(V=0;V<R;V++){P=U[V];if(P.checked){W[O]=P.value;break;}}break;case"checkbox":Y=[];for(V=0;V<R;V++){c=U[V];if(c.checked){Y[Y.length]=c.value;}}W[O]=Y;break;}}}}}return W;},destroy:function(){C.call(this);this._aButtons=null;var K=this.element.getElementsByTagName("form"),L;if(K.length>0){L=K[0];if(L){J.purgeElement(L);if(L.parentNode){L.parentNode.removeChild(L);}this.form=null;}}F.superclass.destroy.call(this);},toString:function(){return"Dialog "+this.id;}});}());(function(){YAHOO.widget.SimpleDialog=function(E,D){YAHOO.widget.SimpleDialog.superclass.constructor.call(this,E,D);};var C=YAHOO.util.Dom,B=YAHOO.widget.SimpleDialog,A={"ICON":{key:"icon",value:"none",suppressEvent:true},"TEXT":{key:"text",value:"",suppressEvent:true,supercedes:["icon"]}};B.ICON_BLOCK="blckicon";B.ICON_ALARM="alrticon";B.ICON_HELP="hlpicon";B.ICON_INFO="infoicon";B.ICON_WARN="warnicon";B.ICON_T!
 IP="tipicon";B.ICON_CSS_CLASSNAME="yui-icon";B.CSS_SIMPLEDIALO!
 G="yui-s
imple-dialog";YAHOO.extend(B,YAHOO.widget.Dialog,{initDefaultConfig:function(){B.superclass.initDefaultConfig.call(this);this.cfg.addProperty(A.ICON.key,{handler:this.configIcon,value:A.ICON.value,suppressEvent:A.ICON.suppressEvent});this.cfg.addProperty(A.TEXT.key,{handler:this.configText,value:A.TEXT.value,suppressEvent:A.TEXT.suppressEvent,supercedes:A.TEXT.supercedes});},init:function(E,D){B.superclass.init.call(this,E);this.beforeInitEvent.fire(B);C.addClass(this.element,B.CSS_SIMPLEDIALOG);this.cfg.queueProperty("postmethod","manual");if(D){this.cfg.applyConfig(D,true);}this.beforeRenderEvent.subscribe(function(){if(!this.body){this.setBody("");}},this,true);this.initEvent.fire(B);},registerForm:function(){B.superclass.registerForm.call(this);this.form.innerHTML+='<input type="hidden" name="'+this.id+'" value=""/>';},configIcon:function(F,E,J){var K=E[0],D=this.body,I=B.ICON_CSS_CLASSNAME,H,G;if(K&&K!="none"){H=C.getElementsByClassName(I,"*",D);if(H){G=H.parentNode;if(!
 G){G.removeChild(H);H=null;}}if(K.indexOf(".")==-1){H=document.createElement("span");H.className=(I+" "+K);H.innerHTML=" ";}else{H=document.createElement("img");H.src=(this.imageRoot+K);H.className=I;}if(H){D.insertBefore(H,D.firstChild);}}},configText:function(E,D,F){var G=D[0];if(G){this.setBody(G);this.cfg.refireEvent("icon");}},toString:function(){return"SimpleDialog "+this.id;}});}());(function(){YAHOO.widget.ContainerEffect=function(F,I,H,E,G){if(!G){G=YAHOO.util.Anim;}this.overlay=F;this.attrIn=I;this.attrOut=H;this.targetElement=E||F.element;this.animClass=G;};var B=YAHOO.util.Dom,D=YAHOO.util.CustomEvent,C=YAHOO.util.Easing,A=YAHOO.widget.ContainerEffect;A.FADE=function(E,G){var I={attributes:{opacity:{from:0,to:1}},duration:G,method:C.easeIn};var F={attributes:{opacity:{to:0}},duration:G,method:C.easeOut};var H=new A(E,I,F,E.element);H.handleUnderlayStart=function(){var K=this.overlay.underlay;
+if(K&&YAHOO.env.ua.ie){var J=(K.filters&&K.filters.length>0);if(J){B.addClass(E.element,"yui-effect-fade");}}};H.handleUnderlayComplete=function(){var J=this.overlay.underlay;if(J&&YAHOO.env.ua.ie){B.removeClass(E.element,"yui-effect-fade");}};H.handleStartAnimateIn=function(K,J,L){B.addClass(L.overlay.element,"hide-select");if(!L.overlay.underlay){L.overlay.cfg.refireEvent("underlay");}L.handleUnderlayStart();B.setStyle(L.overlay.element,"visibility","visible");B.setStyle(L.overlay.element,"opacity",0);};H.handleCompleteAnimateIn=function(K,J,L){B.removeClass(L.overlay.element,"hide-select");if(L.overlay.element.style.filter){L.overlay.element.style.filter=null;}L.handleUnderlayComplete();L.overlay.cfg.refireEvent("iframe");L.animateInCompleteEvent.fire();};H.handleStartAnimateOut=function(K,J,L){B.addClass(L.overlay.element,"hide-select");L.handleUnderlayStart();};H.handleCompleteAnimateOut=function(K,J,L){B.removeClass(L.overlay.element,"hide-select");if(L.overlay.elemen!
 t.style.filter){L.overlay.element.style.filter=null;}B.setStyle(L.overlay.element,"visibility","hidden");B.setStyle(L.overlay.element,"opacity",1);L.handleUnderlayComplete();L.overlay.cfg.refireEvent("iframe");L.animateOutCompleteEvent.fire();};H.init();return H;};A.SLIDE=function(G,I){var F=G.cfg.getProperty("x")||B.getX(G.element),K=G.cfg.getProperty("y")||B.getY(G.element),J=B.getClientWidth(),H=G.element.offsetWidth,E=new A(G,{attributes:{points:{to:[F,K]}},duration:I,method:C.easeIn},{attributes:{points:{to:[(J+25),K]}},duration:I,method:C.easeOut},G.element,YAHOO.util.Motion);E.handleStartAnimateIn=function(M,L,N){N.overlay.element.style.left=((-25)-H)+"px";N.overlay.element.style.top=K+"px";};E.handleTweenAnimateIn=function(O,N,P){var Q=B.getXY(P.overlay.element),M=Q[0],L=Q[1];if(B.getStyle(P.overlay.element,"visibility")=="hidden"&&M<F){B.setStyle(P.overlay.element,"visibility","visible");}P.overlay.cfg.setProperty("xy",[M,L],true);P.overlay.cfg.refireEvent("iframe"!
 );};E.handleCompleteAnimateIn=function(M,L,N){N.overlay.cfg.se!
 tPropert
y("xy",[F,K],true);N.startX=F;N.startY=K;N.overlay.cfg.refireEvent("iframe");N.animateInCompleteEvent.fire();};E.handleStartAnimateOut=function(M,L,P){var N=B.getViewportWidth(),Q=B.getXY(P.overlay.element),O=Q[1];P.animOut.attributes.points.to=[(N+25),O];};E.handleTweenAnimateOut=function(N,M,O){var Q=B.getXY(O.overlay.element),L=Q[0],P=Q[1];O.overlay.cfg.setProperty("xy",[L,P],true);O.overlay.cfg.refireEvent("iframe");};E.handleCompleteAnimateOut=function(M,L,N){B.setStyle(N.overlay.element,"visibility","hidden");N.overlay.cfg.setProperty("xy",[F,K]);N.animateOutCompleteEvent.fire();};E.init();return E;};A.prototype={init:function(){this.beforeAnimateInEvent=this.createEvent("beforeAnimateIn");this.beforeAnimateInEvent.signature=D.LIST;this.beforeAnimateOutEvent=this.createEvent("beforeAnimateOut");this.beforeAnimateOutEvent.signature=D.LIST;this.animateInCompleteEvent=this.createEvent("animateInComplete");this.animateInCompleteEvent.signature=D.LIST;this.animateOutComplet!
 eEvent=this.createEvent("animateOutComplete");this.animateOutCompleteEvent.signature=D.LIST;this.animIn=new this.animClass(this.targetElement,this.attrIn.attributes,this.attrIn.duration,this.attrIn.method);this.animIn.onStart.subscribe(this.handleStartAnimateIn,this);this.animIn.onTween.subscribe(this.handleTweenAnimateIn,this);this.animIn.onComplete.subscribe(this.handleCompleteAnimateIn,this);this.animOut=new this.animClass(this.targetElement,this.attrOut.attributes,this.attrOut.duration,this.attrOut.method);this.animOut.onStart.subscribe(this.handleStartAnimateOut,this);this.animOut.onTween.subscribe(this.handleTweenAnimateOut,this);this.animOut.onComplete.subscribe(this.handleCompleteAnimateOut,this);},animateIn:function(){this.beforeAnimateInEvent.fire();this.animIn.animate();},animateOut:function(){this.beforeAnimateOutEvent.fire();this.animOut.animate();},handleStartAnimateIn:function(F,E,G){},handleTweenAnimateIn:function(F,E,G){},handleCompleteAnimateIn:function(F,!
 E,G){},handleStartAnimateOut:function(F,E,G){},handleTweenAnim!
 ateOut:f
unction(F,E,G){},handleCompleteAnimateOut:function(F,E,G){},toString:function(){var E="ContainerEffect";if(this.overlay){E+=" ["+this.overlay.toString()+"]";}return E;}};YAHOO.lang.augmentProto(A,YAHOO.util.EventProvider);})();YAHOO.register("container",YAHOO.widget.Module,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/container/container.js
===================================================================
--- trunk/root/static/yui/container/container.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/container/container.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 (function () {
 
@@ -737,7 +737,6 @@
         * @type Object
         */
         EVENT_TYPES = {
-        
             "BEFORE_INIT": "beforeInit",
             "INIT": "init",
             "APPEND": "append",
@@ -752,7 +751,6 @@
             "SHOW": "show",
             "BEFORE_HIDE": "beforeHide",
             "HIDE": "hide"
-        
         },
             
         /**
@@ -822,7 +820,7 @@
     * @type String
     */
     Module.CSS_HEADER = "hd";
-    
+
     /**
     * Constant representing the module body
     * @property YAHOO.widget.Module.CSS_BODY
@@ -1281,12 +1279,31 @@
         },
 
         /**
-        * Initialized an empty IFRAME that is placed out of the visible area 
+        * Initialize an empty IFRAME that is placed out of the visible area 
         * that can be used to detect text resize.
         * @method initResizeMonitor
         */
         initResizeMonitor: function () {
 
+            var isGeckoWin = (YAHOO.env.ua.gecko && this.platform == "windows");
+            if (isGeckoWin) {
+                // Help prevent spinning loading icon which 
+                // started with FireFox 2.0.0.8/Win
+                var self = this;
+                setTimeout(function(){self._initResizeMonitor();}, 0);
+            } else {
+                this._initResizeMonitor();
+            }
+        },
+
+        /**
+         * Create and initialize the text resize monitoring iframe.
+         * 
+         * @protected
+         * @method _initResizeMonitor
+         */
+        _initResizeMonitor : function() {
+
             var oDoc, 
                 oIFrame, 
                 sHTML;
@@ -1298,6 +1315,8 @@
             if (!YAHOO.env.ua.opera) {
                 oIFrame = Dom.get("_yuiResizeMonitor");
 
+                var supportsCWResize = this._supportsCWResize();
+
                 if (!oIFrame) {
                     oIFrame = document.createElement("iframe");
 
@@ -1305,21 +1324,17 @@
                         oIFrame.src = Module.RESIZE_MONITOR_SECURE_URL;
                     }
 
-                    /*
-                        Need to set the iframe document for Gecko
-                        to fire resize events on the iframe contentWindow.
-                     */
-                    if (YAHOO.env.ua.gecko) {
-                         sHTML = ["<html><head><script ",
-                                  "type=\"text/javascript\">",
-                                  "window.onresize=function(){window.parent.",
-                                  "YAHOO.widget.Module.textResizeEvent.",
-                                  "fire();}", 
-                                  "<\/script></head>",
-                                  "<body></body></html>"].join('');
+                    if (!supportsCWResize) {
+                        // Can't monitor on contentWindow, so fire from inside iframe
+                        sHTML = ["<html><head><script ",
+                                 "type=\"text/javascript\">",
+                                 "window.onresize=function(){window.parent.",
+                                 "YAHOO.widget.Module.textResizeEvent.",
+                                 "fire();};<",
+                                 "\/script></head>",
+                                 "<body></body></html>"].join('');
 
-                        oIFrame.src = "data:text/html;charset=utf-8," +
-                            encodeURIComponent(sHTML);
+                        oIFrame.src = "data:text/html;charset=utf-8," + encodeURIComponent(sHTML);
                     }
 
                     oIFrame.id = "_yuiResizeMonitor";
@@ -1332,11 +1347,12 @@
                     oIFrame.style.position = "absolute";
                     oIFrame.style.visibility = "hidden";
 
-                    var fc = document.body.firstChild;
+                    var db = document.body,
+                        fc = db.firstChild;
                     if (fc) {
-                        document.body.insertBefore(oIFrame, fc);
+                        db.insertBefore(oIFrame, fc);
                     } else {
-                        document.body.appendChild(oIFrame);
+                        db.appendChild(oIFrame);
                     }
 
                     oIFrame.style.width = "10em";
@@ -1361,8 +1377,7 @@
                     Module.textResizeEvent.subscribe(this.onDomResize, this, true);
 
                     if (!Module.textResizeInitialized) {
-                         // We already handle gecko using the iframe's document content
-                        if (!YAHOO.env.ua.gecko) {
+                        if (supportsCWResize) {
                             if (!Event.on(oIFrame.contentWindow, "resize", fireTextResize)) {
                                 /*
                                      This will fail in IE if document.domain has 
@@ -1380,13 +1395,46 @@
         },
 
         /**
+         * Text resize monitor helper method.
+         * Determines if the browser supports resize events on iframe content windows.
+         * 
+         * @private
+         * @method _supportsCWResize
+         */
+        _supportsCWResize : function() {
+            /*
+                Gecko 1.8.0 (FF1.5), 1.8.1.0-5 (FF2) won't fire resize on contentWindow.
+                Gecko 1.8.1.6+ (FF2.0.0.6+) and all other browsers will fire resize on contentWindow.
+
+                We don't want to start sniffing for patch versions, so fire textResize the same
+                way on all FF, until 1.9 (3.x) is out
+             */
+            var bSupported = true;
+            if (YAHOO.env.ua.gecko && YAHOO.env.ua.gecko <= 1.8) {
+                bSupported = false;
+                /*
+                var v = navigator.userAgent.match(/rv:([^\s\)]*)/); // From YAHOO.env.ua
+                if (v && v[0]) {
+                    var sv = v[0].match(/\d\.\d\.(\d)/);
+                    if (sv && sv[1]) {
+                        if (parseInt(sv[1], 10) > 0) {
+                            bSupported = true;
+                        }
+                    }
+                }
+                */
+            }
+            return bSupported;
+        },
+
+        /**
         * Event handler fired when the resize monitor element is resized.
         * @method onDomResize
         * @param {DOMEvent} e The DOM resize event
         * @param {Object} obj The scope object passed to the handler
         */
         onDomResize: function (e, obj) {
-        
+
             var nLeft = -1 * this.resizeMonitor.offsetWidth,
                 nTop = -1 * this.resizeMonitor.offsetHeight;
         
@@ -1394,90 +1442,97 @@
             this.resizeMonitor.style.left =  nLeft + "px";
 
         },
-        
+
         /**
-        * Sets the Module's header content to the HTML specified, or appends 
+        * Sets the Module's header content to the string specified, or appends 
         * the passed element to the header. If no header is present, one will 
-        * be automatically created.
+        * be automatically created. An empty string can be passed to the method
+        * to clear the contents of the header.
+        * 
         * @method setHeader
-        * @param {String} headerContent The HTML used to set the header 
+        * @param {String} headerContent The string used to set the header.
+        * As a convenience, non HTMLElement objects can also be passed into 
+        * the method, and will be treated as strings, with the header innerHTML
+        * set to their default toString implementations.
         * <em>OR</em>
         * @param {HTMLElement} headerContent The HTMLElement to append to 
-        * the header
+        * <em>OR</em>
+        * @param {DocumentFragment} headerContent The document fragment 
+        * containing elements which are to be added to the header
         */
         setHeader: function (headerContent) {
-
             var oHeader = this.header || (this.header = createHeader());
-        
-            if (typeof headerContent == "string") {
 
-                oHeader.innerHTML = headerContent;
-
-            } else {
-
+            if (headerContent.nodeName) {
                 oHeader.innerHTML = "";
                 oHeader.appendChild(headerContent);
+            } else {
+                oHeader.innerHTML = headerContent;
+            }
 
-            }
-        
             this.changeHeaderEvent.fire(headerContent);
             this.changeContentEvent.fire();
 
         },
-        
+
         /**
         * Appends the passed element to the header. If no header is present, 
         * one will be automatically created.
         * @method appendToHeader
-        * @param {HTMLElement} element The element to append to the header
+        * @param {HTMLElement | DocumentFragment} element The element to 
+        * append to the header. In the case of a document fragment, the
+        * children of the fragment will be appended to the header.
         */
         appendToHeader: function (element) {
+            var oHeader = this.header || (this.header = createHeader());
 
-            var oHeader = this.header || (this.header = createHeader());
-        
             oHeader.appendChild(element);
 
             this.changeHeaderEvent.fire(element);
             this.changeContentEvent.fire();
 
         },
-        
+
         /**
         * Sets the Module's body content to the HTML specified, or appends the
         * passed element to the body. If no body is present, one will be 
-        * automatically created.
+        * automatically created. An empty string can be passed to the method
+        * to clear the contents of the body.
         * @method setBody
-        * @param {String} bodyContent The HTML used to set the body <em>OR</em>
+        * @param {String} bodyContent The HTML used to set the body. 
+        * As a convenience, non HTMLElement objects can also be passed into 
+        * the method, and will be treated as strings, with the body innerHTML
+        * set to their default toString implementations.
+        * <em>OR</em>
         * @param {HTMLElement} bodyContent The HTMLElement to append to the body
+        * <em>OR</em>
+        * @param {DocumentFragment} bodyContent The document fragment 
+        * containing elements which are to be added to the body
         */
         setBody: function (bodyContent) {
-
             var oBody = this.body || (this.body = createBody());
-        
-            if (typeof bodyContent == "string") {
 
-                oBody.innerHTML = bodyContent;
-
-            } else {
-
+            if (bodyContent.nodeName) {
                 oBody.innerHTML = "";
                 oBody.appendChild(bodyContent);
+            } else {
+                oBody.innerHTML = bodyContent;
+            }
 
-            }
-        
             this.changeBodyEvent.fire(bodyContent);
             this.changeContentEvent.fire();
+        },
 
-        },
-        
         /**
         * Appends the passed element to the body. If no body is present, one 
         * will be automatically created.
         * @method appendToBody
-        * @param {HTMLElement} element The element to append to the body
+        * @param {HTMLElement | DocumentFragment} element The element to 
+        * append to the body. In the case of a document fragment, the
+        * children of the fragment will be appended to the body.
+        * 
         */
         appendToBody: function (element) {
-
             var oBody = this.body || (this.body = createBody());
         
             oBody.appendChild(element);
@@ -1490,50 +1545,54 @@
         /**
         * Sets the Module's footer content to the HTML specified, or appends 
         * the passed element to the footer. If no footer is present, one will 
-        * be automatically created.
+        * be automatically created. An empty string can be passed to the method
+        * to clear the contents of the footer.
         * @method setFooter
         * @param {String} footerContent The HTML used to set the footer 
+        * As a convenience, non HTMLElement objects can also be passed into 
+        * the method, and will be treated as strings, with the footer innerHTML
+        * set to their default toString implementations.
         * <em>OR</em>
         * @param {HTMLElement} footerContent The HTMLElement to append to 
         * the footer
+        * <em>OR</em>
+        * @param {DocumentFragment} footerContent The document fragment containing 
+        * elements which are to be added to the footer
         */
         setFooter: function (footerContent) {
 
             var oFooter = this.footer || (this.footer = createFooter());
-        
-            if (typeof footerContent == "string") {
 
-                oFooter.innerHTML = footerContent;
-
-            } else {
-
+            if (footerContent.nodeName) {
                 oFooter.innerHTML = "";
                 oFooter.appendChild(footerContent);
+            } else {
+                oFooter.innerHTML = footerContent;
+            }
 
-            }
-        
             this.changeFooterEvent.fire(footerContent);
             this.changeContentEvent.fire();
+        },
 
-        },
-        
         /**
         * Appends the passed element to the footer. If no footer is present, 
         * one will be automatically created.
         * @method appendToFooter
-        * @param {HTMLElement} element The element to append to the footer
+        * @param {HTMLElement | DocumentFragment} element The element to 
+        * append to the footer. In the case of a document fragment, the
+        * children of the fragment will be appended to the footer
         */
         appendToFooter: function (element) {
 
             var oFooter = this.footer || (this.footer = createFooter());
-        
+
             oFooter.appendChild(element);
 
             this.changeFooterEvent.fire(element);
             this.changeContentEvent.fire();
 
         },
-        
+
         /**
         * Renders the Module by inserting the elements that are not already 
         * in the main Module into their correct places. Optionally appends 
@@ -1659,7 +1718,7 @@
             }
 
         },
-        
+
         /**
         * Shows the Module element by setting the visible configuration 
         * property to true. Also fires two events: beforeShowEvent prior to 
@@ -1669,7 +1728,7 @@
         show: function () {
             this.cfg.setProperty("visible", true);
         },
-        
+
         /**
         * Hides the Module element by setting the visible configuration 
         * property to false. Also fires two events: beforeHideEvent prior to 
@@ -1861,12 +1920,12 @@
                 key: "height", 
                 suppressEvent: true, 
                 supercedes: ["context", "fixedcenter", "iframe"] 
-            }, 
+            },
 
             "ZINDEX": { 
                 key: "zindex", 
                 value: null 
-            }, 
+            },
 
             "CONSTRAIN_TO_VIEWPORT": { 
                 key: "constraintoviewport", 
@@ -2151,7 +2210,7 @@
                 supercedes: DEFAULT_CONFIG.X.supercedes
     
             });
-    
+
             /**
             * The absolute y-coordinate position of the Overlay
             * @config y
@@ -2159,12 +2218,12 @@
             * @default null
             */
             this.cfg.addProperty(DEFAULT_CONFIG.Y.key, {
-    
+
                 handler: this.configY, 
                 validator: DEFAULT_CONFIG.Y.validator, 
                 suppressEvent: DEFAULT_CONFIG.Y.suppressEvent, 
                 supercedes: DEFAULT_CONFIG.Y.supercedes
-    
+
             });
     
             /**
@@ -2242,7 +2301,7 @@
                 supercedes: DEFAULT_CONFIG.HEIGHT.supercedes
             
             });
-
+            
             /**
             * CSS z-index of the Overlay.
             * @config zIndex
@@ -2255,7 +2314,7 @@
                 value: DEFAULT_CONFIG.ZINDEX.value
 
             });
-            
+
             /**
             * True if the Overlay should be prevented from being positioned 
             * out of the viewport.
@@ -2271,7 +2330,7 @@
                 supercedes: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.supercedes
 
             });
-            
+
             /**
             * @config iframe
             * @description Boolean indicating whether or not the Overlay should 
@@ -2533,7 +2592,7 @@
         * this will usually equal the owner.
         */
         configHeight: function (type, args, obj) {
-    
+
             var height = args[0],
                 el = this.element;
 
@@ -2645,9 +2704,9 @@
             y = this.cfg.getProperty("y");
             
             Dom.setX(this.element, x, true);
-            
+
             this.cfg.setProperty("xy", [x, y], true);
-           
+
             this.cfg.refireEvent("iframe");
             this.moveEvent.fire([x, y]);
         },
@@ -2880,6 +2939,26 @@
         },
 
         /**
+         * Set's the container's XY value from DOM if not already set.
+         * 
+         * Differs from syncPosition, in that the XY value is only sync'd with DOM if 
+         * not already set. The method also refire's the XY config property event, so any
+         * beforeMove, Move event listeners are invoked.
+         * 
+         * @method _primeXYFromDOM
+         * @protected
+         */
+        _primeXYFromDOM : function() {
+            if (YAHOO.lang.isUndefined(this.cfg.getProperty("xy"))) {
+                // Set CFG XY based on DOM XY
+                this.syncPosition();
+                // Account for XY being set silently in syncPosition (no moveTo fired/called)
+                this.cfg.refireEvent("xy");
+                this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);
+            }
+        },
+
+        /**
         * The default event handler fired when the "constraintoviewport" 
         * property is changed.
         * @method configConstrainToViewport
@@ -2891,39 +2970,22 @@
         * this will usually equal the owner.
         */
         configConstrainToViewport: function (type, args, obj) {
-
-            function constrainBeforeShow() {
-                if (YAHOO.lang.isUndefined(this.cfg.getProperty("xy"))) {
-                    // Set CFG XY based on DOM XY
-                    this.syncPosition();
-                }
-                var x = this.cfg.getProperty("x");
-                var y = this.cfg.getProperty("y");
-
-                // Account for XY being set silently (no moveTo fired/called)
-                var cXY = this.getConstrainedXY(x, y);
-                if (cXY[0] !== x || cXY[1] !== y) {
-                    this.moveTo(cXY[0], cXY[1]);
-                }
-            }
-
             var val = args[0];
 
             if (val) {
                 if (! Config.alreadySubscribed(this.beforeMoveEvent, this.enforceConstraints, this)) {
                     this.beforeMoveEvent.subscribe(this.enforceConstraints, this, true);
                 }
-
-                if (! Config.alreadySubscribed(this.beforeShowEvent, constrainBeforeShow)) {
-                    this.beforeShowEvent.subscribe(constrainBeforeShow);
+                if (! Config.alreadySubscribed(this.beforeShowEvent, this._primeXYFromDOM)) {
+                    this.beforeShowEvent.subscribe(this._primeXYFromDOM);
                 }
             } else {
-                this.beforeShowEvent.unsubscribe(constrainBeforeShow);
+                this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);
                 this.beforeMoveEvent.unsubscribe(this.enforceConstraints, this);
             }
         },
 
-        /**
+         /**
         * The default event handler fired when the "context" property 
         * is changed.
         * @method configContext
@@ -2939,38 +3001,28 @@
                 contextEl,
                 elementMagnetCorner,
                 contextMagnetCorner;
-            
+
             if (contextArgs) {
-            
                 contextEl = contextArgs[0];
                 elementMagnetCorner = contextArgs[1];
                 contextMagnetCorner = contextArgs[2];
                 
                 if (contextEl) {
-    
                     if (typeof contextEl == "string") {
-
                         this.cfg.setProperty("context", 
                             [document.getElementById(contextEl), 
                                 elementMagnetCorner, contextMagnetCorner], 
                                 true);
-
                     }
                     
                     if (elementMagnetCorner && contextMagnetCorner) {
-
                         this.align(elementMagnetCorner, contextMagnetCorner);
-
                     }
-
                 }
-
             }
-
         },
 
         // END BUILT-IN PROPERTY EVENT HANDLERS //
-
         /**
         * Aligns the Overlay to its context element using the specified corner 
         * points (represented by the constants TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, 
@@ -3818,19 +3870,17 @@
     * documentation for more details.
     */
     YAHOO.widget.Tooltip = function (el, userConfig) {
-    
         YAHOO.widget.Tooltip.superclass.constructor.call(this, el, userConfig);
-    
     };
 
-
     var Lang = YAHOO.lang,
         Event = YAHOO.util.Event,
+        CustomEvent = YAHOO.util.CustomEvent,
         Dom = YAHOO.util.Dom,
         Tooltip = YAHOO.widget.Tooltip,
-    
+
         m_oShadowTemplate,
-        
+
         /**
         * Constant representing the Tooltip's configuration properties
         * @property DEFAULT_CONFIG
@@ -3839,44 +3889,61 @@
         * @type Object
         */
         DEFAULT_CONFIG = {
-        
+
             "PREVENT_OVERLAP": { 
                 key: "preventoverlap", 
                 value: true, 
                 validator: Lang.isBoolean, 
                 supercedes: ["x", "y", "xy"] 
             },
-        
+
             "SHOW_DELAY": { 
                 key: "showdelay", 
                 value: 200, 
                 validator: Lang.isNumber 
             }, 
-        
+
             "AUTO_DISMISS_DELAY": { 
                 key: "autodismissdelay", 
                 value: 5000, 
                 validator: Lang.isNumber 
             }, 
-        
+
             "HIDE_DELAY": { 
                 key: "hidedelay", 
                 value: 250, 
                 validator: Lang.isNumber 
             }, 
-        
+
             "TEXT": { 
                 key: "text", 
                 suppressEvent: true 
             }, 
-        
+
             "CONTAINER": { 
                 key: "container"
+            },
+
+            "DISABLED": {
+                key: "disabled",
+                value: false,
+                suppressEvent: true
             }
-        
+        },
+
+        /**
+        * Constant representing the name of the Tooltip's events
+        * @property EVENT_TYPES
+        * @private
+        * @final
+        * @type Object
+        */
+        EVENT_TYPES = {
+            "CONTEXT_MOUSE_OVER": "contextMouseOver",
+            "CONTEXT_MOUSE_OUT": "contextMouseOut",
+            "CONTEXT_TRIGGER": "contextTrigger"
         };
 
-    
     /**
     * Constant representing the Tooltip CSS class
     * @property YAHOO.widget.Tooltip.CSS_TOOLTIP
@@ -3886,13 +3953,11 @@
     */
     Tooltip.CSS_TOOLTIP = "yui-tt";
 
-
     /* 
         "hide" event handler that sets a Tooltip instance's "width"
         configuration property back to its original value before 
         "setWidthToOffsetWidth" was called.
     */
-    
     function restoreOriginalWidth(p_sType, p_aArgs, p_oObject) {
 
         var sOriginalWidth = p_oObject[0],
@@ -3901,13 +3966,10 @@
             sCurrentWidth = oConfig.getProperty("width");
 
         if (sCurrentWidth == sNewWidth) {
-            
             oConfig.setProperty("width", sOriginalWidth);
-        
         }
 
         this.unsubscribe("hide", this._onHide, p_oObject);
-    
     }
 
     /* 
@@ -3924,7 +3986,6 @@
             sNewWidth,
             oClone;
 
-        
         if ((!sOriginalWidth || sOriginalWidth == "auto") && 
             (oConfig.getProperty("container") != oBody || 
             oConfig.getProperty("x") >= Dom.getViewportWidth() || 
@@ -3934,46 +3995,35 @@
             oClone.style.visibility = "hidden";
             oClone.style.top = "0px";
             oClone.style.left = "0px";
-            
+
             oBody.appendChild(oClone);
 
             sNewWidth = (oClone.offsetWidth + "px");
 
             oBody.removeChild(oClone);
-
             oClone = null;
 
             oConfig.setProperty("width", sNewWidth);
-
             oConfig.refireEvent("xy");
 
-            this.subscribe("hide", restoreOriginalWidth, 
-                [(sOriginalWidth || ""), sNewWidth]);
-        
+            this.subscribe("hide", restoreOriginalWidth, [(sOriginalWidth || ""), sNewWidth]);
         }
-
     }
 
     // "onDOMReady" that renders the ToolTip
 
     function onDOMReady(p_sType, p_aArgs, p_oObject) {
-    
         this.render(p_oObject);
-    
     }
 
-
     //  "init" event handler that automatically renders the Tooltip
 
     function onInit() {
-
         Event.onDOMReady(onDOMReady, this.cfg.getProperty("container"), this);
-
     }
 
-    
     YAHOO.extend(Tooltip, YAHOO.widget.Overlay, { 
-    
+
         /**
         * The Tooltip initialization method. This method is automatically 
         * called by the constructor. A Tooltip is automatically rendered by 
@@ -4001,17 +4051,80 @@
 
             this.cfg.queueProperty("visible", false);
             this.cfg.queueProperty("constraintoviewport", true);
-    
+
             this.setBody("");
 
             this.subscribe("beforeShow", setWidthToOffsetWidth);
             this.subscribe("init", onInit);
             this.subscribe("render", this.onRender);
-    
+
             this.initEvent.fire(Tooltip);
+        },
 
+        /**
+        * Initializes the custom events for Tooltip
+        * @method initEvents
+        */
+        initEvents: function () {
+
+            Tooltip.superclass.initEvents.call(this);
+            var SIGNATURE = CustomEvent.LIST;
+
+            /**
+            * CustomEvent fired when user mouses over a context element. Returning false from
+            * a subscriber to this event will prevent the tooltip from being displayed for
+            * the current context element.
+            * 
+            * @event contextMouseOverEvent
+            * @param {HTMLElement} context The context element which the user just moused over
+            * @param {DOMEvent} e The DOM event object, associated with the mouse over
+            */
+            this.contextMouseOverEvent = this.createEvent(EVENT_TYPES.CONTEXT_MOUSE_OVER);
+            this.contextMouseOverEvent.signature = SIGNATURE;
+
+            /**
+            * CustomEvent fired when the user mouses out of a context element.
+            * 
+            * @event contextMouseOutEvent
+            * @param {HTMLElement} context The context element which the user just moused out of
+            * @param {DOMEvent} e The DOM event object, associated with the mouse out
+            */
+            this.contextMouseOutEvent = this.createEvent(EVENT_TYPES.CONTEXT_MOUSE_OUT);
+            this.contextMouseOutEvent.signature = SIGNATURE;
+
+            /**
+            * CustomEvent fired just before the tooltip is displayed for the current context.
+            * <p>
+            *  You can subscribe to this event if you need to set up the text for the 
+            *  tooltip based on the context element for which it is about to be displayed.
+            * </p>
+            * <p>This event differs from the beforeShow event in following respects:</p>
+            * <ol>
+            *   <li>
+            *    When moving from one context element to another, if the tooltip is not
+            *    hidden (the <code>hidedelay</code> is not reached), the beforeShow and Show events will not
+            *    be fired when the tooltip is displayed for the new context since it is already visible.
+            *    However the contextTrigger event is always fired before displaying the tooltip for
+            *    a new context.
+            *   </li>
+            *   <li>
+            *    The trigger event provides access to the context element, allowing you to 
+            *    set the text of the tooltip based on context element for which the tooltip is
+            *    triggered.
+            *   </li>
+            * </ol>
+            * <p>
+            *  It is not possible to prevent the tooltip from being displayed
+            *  using this event. You can use the contextMouseOverEvent if you need to prevent
+            *  the tooltip from being displayed.
+            * </p>
+            * @event contextTriggerEvent
+            * @param {HTMLElement} context The context element for which the tooltip is triggered
+            */
+            this.contextTriggerEvent = this.createEvent(EVENT_TYPES.CONTEXT_TRIGGER);
+            this.contextTriggerEvent.signature = SIGNATURE;
         },
-        
+
         /**
         * Initializes the class's configurable properties which can be 
         * changed using the Overlay's Config object (cfg).
@@ -4020,7 +4133,7 @@
         initDefaultConfig: function () {
 
             Tooltip.superclass.initDefaultConfig.call(this);
-        
+
             /**
             * Specifies whether the Tooltip should be kept from overlapping 
             * its context element.
@@ -4033,7 +4146,7 @@
                 validator: DEFAULT_CONFIG.PREVENT_OVERLAP.validator, 
                 supercedes: DEFAULT_CONFIG.PREVENT_OVERLAP.supercedes
             });
-        
+
             /**
             * The number of milliseconds to wait before showing a Tooltip 
             * on mouseover.
@@ -4046,7 +4159,7 @@
                 value: 200, 
                 validator: DEFAULT_CONFIG.SHOW_DELAY.validator
             });
-        
+
             /**
             * The number of milliseconds to wait before automatically 
             * dismissing a Tooltip after the mouse has been resting on the 
@@ -4060,7 +4173,7 @@
                 value: DEFAULT_CONFIG.AUTO_DISMISS_DELAY.value,
                 validator: DEFAULT_CONFIG.AUTO_DISMISS_DELAY.validator
             });
-        
+
             /**
             * The number of milliseconds to wait before hiding a Tooltip 
             * on mouseover.
@@ -4073,7 +4186,7 @@
                 value: DEFAULT_CONFIG.HIDE_DELAY.value, 
                 validator: DEFAULT_CONFIG.HIDE_DELAY.validator
             });
-        
+
             /**
             * Specifies the Tooltip's text. 
             * @config text
@@ -4096,8 +4209,24 @@
                 handler: this.configContainer,
                 value: document.body
             });
-        
+
             /**
+            * Specifies whether or not the tooltip is disabled. Disabled tooltips
+            * will not be displayed. If the tooltip is driven by the title attribute
+            * of the context element, the title attribute will still be removed for 
+            * disabled tooltips, to prevent default tooltip behavior.
+            * 
+            * @config disabled
+            * @type Boolean
+            * @default false
+            */
+            this.cfg.addProperty(DEFAULT_CONFIG.DISABLED.key, {
+                handler: this.configContainer,
+                value: DEFAULT_CONFIG.DISABLED.value,
+                supressEvent: DEFAULT_CONFIG.DISABLED.suppressEvent
+            });
+
+            /**
             * Specifies the element or elements that the Tooltip should be 
             * anchored to on mouseover.
             * @config context
@@ -4155,16 +4284,11 @@
         * this will usually equal the owner.
         */
         configContainer: function (type, args, obj) {
-
             var container = args[0];
 
             if (typeof container == 'string') {
-
-                this.cfg.setProperty("container", 
-                    document.getElementById(container), true);
-
+                this.cfg.setProperty("container", document.getElementById(container), true);
             }
-
         },
         
         /**
@@ -4179,23 +4303,16 @@
                 nElements,
                 oElement,
                 i;
-        
-            
+
             if (aElements) {
                 nElements = aElements.length;
                 if (nElements > 0) {
                     i = nElements - 1;
                     do {
                         oElement = aElements[i];
-        
-                        Event.removeListener(oElement, "mouseover", 
-                            this.onContextMouseOver);
-
-                        Event.removeListener(oElement, "mousemove", 
-                            this.onContextMouseMove);
-
-                        Event.removeListener(oElement, "mouseout", 
-                            this.onContextMouseOut);
+                        Event.removeListener(oElement, "mouseover", this.onContextMouseOver);
+                        Event.removeListener(oElement, "mousemove", this.onContextMouseMove);
+                        Event.removeListener(oElement, "mouseout", this.onContextMouseOut);
                     }
                     while (i--);
                 }
@@ -4219,72 +4336,47 @@
                 nElements,
                 oElement,
                 i;
-            
-        
+
             if (context) {
-        
+
                 // Normalize parameter into an array
                 if (! (context instanceof Array)) {
-
                     if (typeof context == "string") {
-
-                        this.cfg.setProperty("context", 
-                            [document.getElementById(context)], true);
-
+                        this.cfg.setProperty("context", [document.getElementById(context)], true);
                     } else { // Assuming this is an element
-
                         this.cfg.setProperty("context", [context], true);
-
                     }
-
                     context = this.cfg.getProperty("context");
+                }
 
-                }
-        
-        
                 // Remove any existing mouseover/mouseout listeners
                 this._removeEventListeners();
-        
+
                 // Add mouseover/mouseout listeners to context elements
                 this._context = context;
-        
+
                 aElements = this._context;
-                
+
                 if (aElements) {
-            
                     nElements = aElements.length;
-                    
                     if (nElements > 0) {
-                    
                         i = nElements - 1;
-                        
                         do {
-            
                             oElement = aElements[i];
-            
-                            Event.on(oElement, "mouseover", 
-                                this.onContextMouseOver, this);
-
-                            Event.on(oElement, "mousemove", 
-                                this.onContextMouseMove, this);
-
-                            Event.on(oElement, "mouseout", 
-                                this.onContextMouseOut, this);
-                        
+                            Event.on(oElement, "mouseover", this.onContextMouseOver, this);
+                            Event.on(oElement, "mousemove", this.onContextMouseMove, this);
+                            Event.on(oElement, "mouseout", this.onContextMouseOut, this);
                         }
                         while (i--);
-                    
                     }
-            
                 }
-        
             }
         },
-        
+
         // END BUILT-IN PROPERTY EVENT HANDLERS //
-        
+
         // BEGIN BUILT-IN DOM EVENT HANDLERS //
-        
+
         /**
         * The default event handler fired when the user moves the mouse while 
         * over the context element.
@@ -4295,9 +4387,8 @@
         onContextMouseMove: function (e, obj) {
             obj.pageX = Event.getPageX(e);
             obj.pageY = Event.getPageY(e);
-        
         },
-        
+
         /**
         * The default event handler fired when the user mouses over the 
         * context element.
@@ -4306,34 +4397,34 @@
         * @param {Object} obj The object argument
         */
         onContextMouseOver: function (e, obj) {
-        
             var context = this;
-        
-            if (obj.hideProcId) {
 
-                clearTimeout(obj.hideProcId);
-
-
-                obj.hideProcId = null;
-
-            }
-
-            Event.on(context, "mousemove", obj.onContextMouseMove, obj);
-
             if (context.title) {
                 obj._tempTitle = context.title;
                 context.title = "";
             }
 
-            /**
-            * The unique process ID associated with the thread responsible 
-            * for showing the Tooltip.
-            * @type int
-            */
-            obj.showProcId = obj.doShow(e, context);
+            // Fire first, to honor disabled set in the listner
+            if (obj.fireEvent("contextMouseOver", context, e) !== false 
+                    && !obj.cfg.getProperty("disabled")) {
 
+                // Stop the tooltip from being hidden (set on last mouseout)
+                if (obj.hideProcId) {
+                    clearTimeout(obj.hideProcId);
+                    obj.hideProcId = null;
+                }
+
+                Event.on(context, "mousemove", obj.onContextMouseMove, obj);
+
+                /**
+                * The unique process ID associated with the thread responsible 
+                * for showing the Tooltip.
+                * @type int
+                */
+                obj.showProcId = obj.doShow(e, context);
+            }
         },
-        
+
         /**
         * The default event handler fired when the user mouses out of 
         * the context element.
@@ -4343,32 +4434,31 @@
         */
         onContextMouseOut: function (e, obj) {
             var el = this;
-        
+
             if (obj._tempTitle) {
                 el.title = obj._tempTitle;
                 obj._tempTitle = null;
             }
-        
+
             if (obj.showProcId) {
                 clearTimeout(obj.showProcId);
                 obj.showProcId = null;
             }
-        
+
             if (obj.hideProcId) {
                 clearTimeout(obj.hideProcId);
                 obj.hideProcId = null;
             }
-        
-        
+
+            obj.fireEvent("contextMouseOut", el, e);
+
             obj.hideProcId = setTimeout(function () {
                 obj.hide();
-    
             }, obj.cfg.getProperty("hidedelay"));
-    
         },
-        
+
         // END BUILT-IN DOM EVENT HANDLERS //
-        
+
         /**
         * Processes the showing of the Tooltip by setting the timeout delay 
         * and offset of the Tooltip.
@@ -4384,14 +4474,13 @@
 
             if (YAHOO.env.ua.opera && context.tagName && 
                 context.tagName.toUpperCase() == "A") {
-
                 yOffset += 12;
-
             }
 
             return setTimeout(function () {
 
                 var txt = me.cfg.getProperty("text");
+
                 // title does not over-ride text
                 if (me._tempTitle && (txt === "" || YAHOO.lang.isUndefined(txt) || YAHOO.lang.isNull(txt))) {
                     me.setBody(me._tempTitle);
@@ -4405,17 +4494,17 @@
                     me.preventOverlap(me.pageX, me.pageY);
                 }
 
-                Event.removeListener(context, "mousemove", 
-                    me.onContextMouseMove);
+                Event.removeListener(context, "mousemove", me.onContextMouseMove);
 
+                me.contextTriggerEvent.fire(context);
+
                 me.show();
+
                 me.hideProcId = me.doHide();
 
-
             }, this.cfg.getProperty("showdelay"));
-        
         },
-        
+
         /**
         * Sets the timeout for the auto-dismiss delay, which by default is 5 
         * seconds, meaning that a tooltip will automatically dismiss itself 
@@ -4423,16 +4512,16 @@
         * @method doHide
         */
         doHide: function () {
-        
+
             var me = this;
-        
-        
+
+
             return setTimeout(function () {
-        
+
                 me.hide();
-        
+
             }, this.cfg.getProperty("autodismissdelay"));
-        
+
         },
         
         /**
@@ -4476,29 +4565,21 @@
                     oShadow = this._shadow;
             
                 if (oShadow) {
-            
                     oShadow.style.width = (oElement.offsetWidth + 6) + "px";
                     oShadow.style.height = (oElement.offsetHeight + 1) + "px"; 
-            
                 }
             
             }
 
-
             function addShadowVisibleClass() {
-            
                 Dom.addClass(this._shadow, "yui-tt-shadow-visible");
-            
             }
             
 
             function removeShadowVisibleClass() {
-        
                 Dom.removeClass(this._shadow, "yui-tt-shadow-visible");
-            
             }
-    
-    
+
             function createShadow() {
     
                 var oShadow = this._shadow,
@@ -4513,73 +4594,49 @@
                     Module = YAHOO.widget.Module;
                     nIE = YAHOO.env.ua.ie;
                     me = this;
-    
+
                     if (!m_oShadowTemplate) {
-        
                         m_oShadowTemplate = document.createElement("div");
                         m_oShadowTemplate.className = "yui-tt-shadow";
-                    
                     }
-        
+
                     oShadow = m_oShadowTemplate.cloneNode(false);
-        
+
                     oElement.appendChild(oShadow);
-                    
+
                     this._shadow = oShadow;
-    
+
                     addShadowVisibleClass.call(this);
-        
+
                     this.subscribe("beforeShow", addShadowVisibleClass);
                     this.subscribe("beforeHide", removeShadowVisibleClass);
 
-                    if (nIE == 6 || 
-                        (nIE == 7 && document.compatMode == "BackCompat")) {
-                
+                    if (nIE == 6 || (nIE == 7 && document.compatMode == "BackCompat")) {
                         window.setTimeout(function () { 
-        
                             sizeShadow.call(me); 
-        
                         }, 0);
     
                         this.cfg.subscribeToConfigEvent("width", sizeShadow);
                         this.cfg.subscribeToConfigEvent("height", sizeShadow);
                         this.subscribe("changeContent", sizeShadow);
-    
-                        Module.textResizeEvent.subscribe(sizeShadow, 
-                                                            this, true);
-                        
+
+                        Module.textResizeEvent.subscribe(sizeShadow, this, true);
                         this.subscribe("destroy", function () {
-                        
-                            Module.textResizeEvent.unsubscribe(sizeShadow, 
-                                                                    this);
-                        
+                            Module.textResizeEvent.unsubscribe(sizeShadow, this);
                         });
-                
                     }
-                
                 }
-    
             }
-    
-    
+
             function onBeforeShow() {
-            
                 createShadow.call(this);
-    
                 this.unsubscribe("beforeShow", onBeforeShow);
-            
             }
-    
-    
+
             if (this.cfg.getProperty("visible")) {
-    
                 createShadow.call(this);
-            
-            }
-            else {
-    
+            } else {
                 this.subscribe("beforeShow", onBeforeShow);
-            
             }
         
         },
@@ -4593,7 +4650,7 @@
         
             // Remove any existing mouseover/mouseout listeners
             this._removeEventListeners();
-        
+
             Tooltip.superclass.destroy.call(this);  
         
         },
@@ -4651,11 +4708,9 @@
         * @type Object
         */
         EVENT_TYPES = {
-        
             "SHOW_MASK": "showMask",
             "HIDE_MASK": "hideMask",
             "DRAG": "drag"
-        
         },
 
         /**
@@ -4727,6 +4782,23 @@
     */
     Panel.CSS_PANEL_CONTAINER = "yui-panel-container";
 
+    /**
+     * Constant representing the default set of focusable elements 
+     * on the pagewhich Modal Panels will prevent access to, when
+     * the modal mask is displayed
+     * 
+     * @property YAHOO.widget.Panel.FOCUSABLE
+     * @static
+     * @type Array
+     */
+    Panel.FOCUSABLE = [
+        "a",
+        "button",
+        "select",
+        "textarea",
+        "input"
+    ];
+
     // Private CustomEvent listeners
 
     /* 
@@ -4792,86 +4864,6 @@
         }
     }
 
-    /* 
-        "focus" event handler for a focuable element.  Used to automatically 
-        blur the element when it receives focus to ensure that a Panel 
-        instance's modality is not compromised.
-    */
-
-    function onElementFocus() {
-        this.blur();
-    }
-
-    /* 
-        "showMask" event handler that adds a "focus" event handler to all
-        focusable elements in the document to enforce a Panel instance's 
-        modality from being compromised.
-    */
-
-    function addFocusEventHandlers(p_sType, p_aArgs) {
-
-        var me = this;
-
-        function isFocusable(el) {
-
-            var sTagName = el.tagName.toUpperCase(),
-                bFocusable = false;
-            
-            switch (sTagName) {
-            
-            case "A":
-            case "BUTTON":
-            case "SELECT":
-            case "TEXTAREA":
-
-                if (!Dom.isAncestor(me.element, el)) {
-                    Event.on(el, "focus", onElementFocus, el, true);
-                    bFocusable = true;
-                }
-
-                break;
-
-            case "INPUT":
-
-                if (el.type != "hidden" && 
-                    !Dom.isAncestor(me.element, el)) {
-
-                    Event.on(el, "focus", onElementFocus, el, true);
-                    bFocusable = true;
-
-                }
-
-                break;
-            
-            }
-
-            return bFocusable;
-
-        }
-
-        this.focusableElements = Dom.getElementsBy(isFocusable);
-    
-    }
-
-    /* 
-        "hideMask" event handler that removes all "focus" event handlers added 
-        by the "addFocusEventHandlers" method.
-    */
-    
-    function removeFocusEventHandlers(p_sType, p_aArgs) {
-
-        var aElements = this.focusableElements,
-            nElements = aElements.length,
-            el2,
-            i;
-
-        for (i = 0; i < nElements; i++) {
-            el2 = aElements[i];
-            Event.removeListener(el2, "focus", onElementFocus);
-        }
-
-    }
-
     YAHOO.extend(Panel, Overlay, {
 
         /**
@@ -4905,14 +4897,87 @@
                 this.cfg.applyConfig(userConfig, true);
             }
 
-            this.subscribe("showMask", addFocusEventHandlers);
-            this.subscribe("hideMask", removeFocusEventHandlers);
+            this.subscribe("showMask", this._addFocusHandlers);
+            this.subscribe("hideMask", this._removeFocusHandlers);
             this.subscribe("beforeRender", createHeader);
 
             this.initEvent.fire(Panel);
         },
-        
+
         /**
+         * @method _onElementFocus 
+         * @private
+         * 
+         * "focus" event handler for a focuable element. Used to automatically 
+         * blur the element when it receives focus to ensure that a Panel 
+         * instance's modality is not compromised.
+         * 
+         * @param {Event} e The DOM event object
+         */
+        _onElementFocus : function(e){
+            this.blur();
+        },
+
+        /** 
+         *  @method _addFocusHandlers
+         *  @protected
+         *  
+         *  "showMask" event handler that adds a "focus" event handler to all
+         *  focusable elements in the document to enforce a Panel instance's 
+         *  modality from being compromised.
+         *  
+         *  @param p_sType {String} Custom event type
+         *  @param p_aArgs {Array} Custom event arguments
+         */
+        _addFocusHandlers: function(p_sType, p_aArgs) {
+            var me = this,
+                focus = "focus",
+                hidden = "hidden";
+
+            function isFocusable(el) {
+                // NOTE: if e.type is undefined that's fine, want to avoid perf 
+                // impact of tagName check to filter for inputs
+                if (el.type !== hidden && !Dom.isAncestor(me.element, el)) {
+                    Event.on(el, focus, me._onElementFocus);
+                    return true;
+                }
+                return false;
+            }
+
+            var focusable = Panel.FOCUSABLE,
+                l = focusable.length,
+                arr = [];
+
+            for (var i = 0; i < l; i++) {
+                arr = arr.concat(Dom.getElementsBy(isFocusable, focusable[i]));
+            }
+
+            this.focusableElements = arr;
+        },
+
+        /** 
+         *  @method _removeFocusHandlers
+         *  @protected
+         *  
+         *  "hideMask" event handler that removes all "focus" event handlers added 
+         *  by the "addFocusEventHandlers" method.
+         *  
+         *  @param p_sType {String} Event type
+         *  @param p_aArgs {Array} Event Arguments
+         */
+        _removeFocusHandlers: function(p_sType, p_aArgs) {
+            var aElements = this.focusableElements,
+                nElements = aElements.length,
+                focus = "focus";
+
+            if (aElements) {
+                for (var i = 0; i < nElements; i++) {
+                    Event.removeListener(aElements[i], focus, this._onElementFocus);
+                }
+            }
+        },
+
+        /**
         * Initializes the custom events for Module which are fired 
         * automatically at appropriate times by the Module class.
         */
@@ -5170,9 +5235,10 @@
         * this will usually equal the owner.
         */
         configUnderlay: function (type, args, obj) {
-    
+
             var UA = YAHOO.env.ua,
                 bMacGecko = (this.platform == "mac" && UA.gecko),
+                bIEQuirks = (UA.ie == 6 || (UA.ie == 7 && document.compatMode == "BackCompat")),
                 sUnderlay = args[0].toLowerCase(),
                 oUnderlay = this.underlay,
                 oElement = this.element;
@@ -5191,9 +5257,7 @@
             }
 
             function createUnderlay() {
-
-                var nIE;
-
+                var bNew = false;
                 if (!oUnderlay) { // create if not already in DOM
 
                     if (!m_oUnderlayTemplate) {
@@ -5206,28 +5270,26 @@
 
                     this.underlay = oUnderlay;
 
-                    nIE = UA.ie;
-
-                    if (nIE == 6 || (nIE == 7 && document.compatMode == "BackCompat")) {
-
+                    if (bIEQuirks) {
                         this.sizeUnderlay();
-
                         this.cfg.subscribeToConfigEvent("width", this.sizeUnderlay);
                         this.cfg.subscribeToConfigEvent("height",this.sizeUnderlay);
                         this.changeContentEvent.subscribe(this.sizeUnderlay);
-
                         YAHOO.widget.Module.textResizeEvent.subscribe(this.sizeUnderlay, this, true);
                     }
 
                     if (UA.webkit && UA.webkit < 420) {
                         this.changeContentEvent.subscribe(fixWebkitUnderlay);
                     }
+                    bNew = true;
                 }
-
             }
 
             function onBeforeShow() {
-                createUnderlay.call(this);
+                var bNew = createUnderlay.call(this);
+                if (!bNew && bIEQuirks) {
+                    this.sizeUnderlay();
+                }
                 this._underlayDeferred = false;
                 this.beforeShowEvent.unsubscribe(onBeforeShow);
             }
@@ -5250,51 +5312,41 @@
                     this.underlay = null;
                 }
             }
-        
 
             switch (sUnderlay) {
-    
                 case "shadow":
-    
                     Dom.removeClass(oElement, "matte");
                     Dom.addClass(oElement, "shadow");
-    
                     break;
-    
                 case "matte":
-    
                     if (!bMacGecko) {
                         destroyUnderlay.call(this);
                     }
-    
                     Dom.removeClass(oElement, "shadow");
                     Dom.addClass(oElement, "matte");
-    
                     break;
                 default:
-    
                     if (!bMacGecko) {
                         destroyUnderlay.call(this);
                     }
                     Dom.removeClass(oElement, "shadow");
                     Dom.removeClass(oElement, "matte");
-    
                     break;
             }
 
             if ((sUnderlay == "shadow") || (bMacGecko && !oUnderlay)) {
-                
                 if (this.cfg.getProperty("visible")) {
-                    createUnderlay.call(this);
-                }
-                else {
+                    var bNew = createUnderlay.call(this);
+                    if (!bNew && bIEQuirks) {
+                        this.sizeUnderlay();
+                    }
+                } else {
                     if (!this._underlayDeferred) {
                         this.beforeShowEvent.subscribe(onBeforeShow);
                         this._underlayDeferred = true;
                     }
                 }
             }
-    
         },
         
         /**
@@ -5542,19 +5594,14 @@
         * @method sizeUnderlay
         */
         sizeUnderlay: function () {
-
             var oUnderlay = this.underlay,
                 oElement;
 
             if (oUnderlay) {
-
                 oElement = this.element;
-
                 oUnderlay.style.width = oElement.offsetWidth + "px";
                 oUnderlay.style.height = oElement.offsetHeight + "px";
-
             }
-
         },
 
         
@@ -5679,6 +5726,10 @@
 
                 this.mask = oMask;
 
+                if (YAHOO.env.ua.gecko && this.platform == "mac") {
+                    Dom.addClass(this.mask, "block-scrollbars");
+                }
+
                 // Stack mask based on the element zindex
                 this.stackMask();
             }
@@ -5801,12 +5852,22 @@
 (function () {
 
     /**
+    * <p>
     * Dialog is an implementation of Panel that can be used to submit form 
-    * data. Built-in functionality for buttons with event handlers is included, 
-    * and button sets can be build dynamically, or the preincluded ones for 
-    * Submit/Cancel and OK/Cancel can be utilized. Forms can be processed in 3
-    * ways -- via an asynchronous Connection utility call, a simple form 
-    * POST or GET, or manually.
+    * data.
+    * </p>
+    * <p>
+    * Built-in functionality for buttons with event handlers is included. 
+    * If the optional YUI Button dependancy is included on the page, the buttons
+    * created will be instances of YAHOO.widget.Button, otherwise regular HTML buttons
+    * will be created.
+    * </p>
+    * <p>
+    * Forms can be processed in 3 ways -- via an asynchronous Connection utility call, 
+    * a simple form POST or GET, or manually. The YUI Connection utility should be
+    * included if you're using the default "async" postmethod, but is not required if
+    * you're using any of the other postmethod values.
+    * </p>
     * @namespace YAHOO.widget
     * @class Dialog
     * @extends YAHOO.widget.Panel
@@ -5818,12 +5879,9 @@
     * documentation for more details.
     */
     YAHOO.widget.Dialog = function (el, userConfig) {
-    
         YAHOO.widget.Dialog.superclass.constructor.call(this, el, userConfig);
-    
     };
 
-
     var Event = YAHOO.util.Event,
         CustomEvent = YAHOO.util.CustomEvent,
         Dom = YAHOO.util.Dom,
@@ -5849,7 +5907,7 @@
             "CANCEL": "cancel"
         
         },
-        
+
         /**
         * Constant representing the Dialog's configuration properties
         * @property DEFAULT_CONFIG
@@ -5858,17 +5916,22 @@
         * @type Object
         */
         DEFAULT_CONFIG = {
-        
+
             "POST_METHOD": { 
                 key: "postmethod", 
                 value: "async" 
             },
-            
+
             "BUTTONS": { 
                 key: "buttons", 
                 value: "none" 
+            },
+
+            "HIDEAFTERSUBMIT" : {
+                key: "hideaftersubmit",
+                value: true
             }
-        };    
+        };
 
     /**
     * Constant representing the default CSS class used for a Dialog
@@ -5909,7 +5972,6 @@
     
     YAHOO.extend(Dialog, YAHOO.widget.Panel, { 
 
-        
         /**
         * @property form
         * @description Object reference to the Dialog's 
@@ -5927,23 +5989,28 @@
         */
         initDefaultConfig: function () {
             Dialog.superclass.initDefaultConfig.call(this);
-        
+
             /**
             * The internally maintained callback object for use with the 
-            * Connection utility
+            * Connection utility. The format of the callback object is 
+            * similar to Connection Manager's callback object and is 
+            * simply passed through to Connection Manager when the async 
+            * request is made.
             * @property callback
             * @type Object
             */
             this.callback = {
-    
+
                 /**
                 * The function to execute upon success of the 
-                * Connection submission
+                * Connection submission (when the form does not
+                * contain a file input element).
+                * 
                 * @property callback.success
                 * @type Function
                 */
                 success: null,
-    
+
                 /**
                 * The function to execute upon failure of the 
                 * Connection submission
@@ -5951,20 +6018,38 @@
                 * @type Function
                 */
                 failure: null,
-    
+
                 /**
+                 *<p>
+                * The function to execute upon success of the 
+                * Connection submission, when the form contains
+                * a file input element.
+                * </p>
+                * <p>
+                * <em>NOTE:</em> Connection manager will not
+                * invoke the success or failure handlers for the file
+                * upload use case. This will be the only callback
+                * handler invoked.
+                * </p>
+                * <p>
+                * For more information, see the <a href="http://developer.yahoo.com/yui/connection/#file">
+                * Connection Manager documenation on file uploads</a>.
+                * </p>
+                * @property callback.upload
+                * @type Function
+                */
+
+                /**
                 * The arbitraty argument or arguments to pass to the Connection 
                 * callback functions
                 * @property callback.argument
                 * @type Object
                 */
                 argument: null
-    
+
             };
-        
 
             // Add form dialog config properties //
-            
             /**
             * The method to use for posting the Dialog's form. Possible values 
             * are "async", "form", and "manual".
@@ -5984,15 +6069,28 @@
                     }
                 }
             });
-            
+
             /**
+            * This property is used to configure whether or not the 
+            * dialog should be automatically hidden after submit.
+            * 
+            * @config hideaftersubmit
+            * @type Boolean
+            * @default true
+            */
+            this.cfg.addProperty(DEFAULT_CONFIG.HIDEAFTERSUBMIT.key, {
+                value: DEFAULT_CONFIG.HIDEAFTERSUBMIT.value
+            }); 
+
+            /**
             * Array of object literals, each containing a set of properties 
             * defining a button to be appended into the Dialog's footer.
+            * 
             * Each button object in the buttons array can have three properties:
             * <dt>text:</dt>
-            * <dd>The text that will display on the face of the button.  <em>
-            * Please note:</em> As of version 2.3, the text can include 
-            * HTML.</dd>
+            * <dd>The text that will display on the face of the button. The text can 
+            * include HTML, as long as it is compliant with HTML Button specifications.
+            * </dd>
             * <dt>handler:</dt>
             * <dd>Can be either:
             *     <ol>
@@ -6000,18 +6098,23 @@
             * button is clicked.  (In this case scope of this function is 
             * always its Dialog instance.)</li>
             *         <li>An object literal representing the code to be 
-            * executed when the button is clicked.  Format:<br> <code> {<br>  
+            * executed when the button is clicked.  Format:<br> <code> {<br>
             * <strong>fn:</strong> Function,   // The handler to call 
-            * when  the event fires.<br> <strong>obj:</strong> Object, 
+            * when  the event fires.<br> <strong>obj:</strong> Object,
             * // An  object to pass back to the handler.<br> <strong>
             * scope:</strong>  Object // The object to use for the 
-            * scope of the handler. <br> } </code> <br><em>Please note: this 
-            * functionality was added in version 2.3.</em></li>
+            * scope of the handler. <br> } </code> <br></li>
             *     </ol>
             * </dd>
             * <dt>isDefault:</dt>
             * <dd>An optional boolean value that specifies that a button 
             * should be highlighted and focused by default.</dd>
+            * 
+            * <em>NOTE:</em>If the YUI Button Widget is included on the page, 
+            * the buttons created will be instances of YAHOO.widget.Button. 
+            * Otherwise, HTML Buttons (<code><BUTTON></code>) will be 
+            * created.
+            * 
             * @config buttons
             * @type {Array|String}
             * @default "none"
@@ -6020,9 +6123,9 @@
                 handler: this.configButtons,
                 value: DEFAULT_CONFIG.BUTTONS.value
             }); 
-            
+
         },
-        
+
         /**
         * Initializes the custom events for Dialog which are fired 
         * automatically at appropriate times by the Dialog class.
@@ -6030,9 +6133,9 @@
         */
         initEvents: function () {
             Dialog.superclass.initEvents.call(this);
-        
+
             var SIGNATURE = CustomEvent.LIST;
-        
+
             /**
             * CustomEvent fired prior to submission
             * @event beforeSubmitEvent
@@ -6142,7 +6245,6 @@
                 i,
                 sMethod;
 
-
             switch (this.cfg.getProperty("postmethod")) {
     
             case "async":
@@ -6151,37 +6253,25 @@
                 nElements = aElements.length;
 
                 if (nElements > 0) {
-                
                     i = nElements - 1;
-                
                     do {
-                    
                         if (aElements[i].type == "file") {
-                        
                             bUseFileUpload = true;
                             break;
-                        
                         }
-                    
                     }
                     while(i--);
-                
                 }
 
                 if (bUseFileUpload && YAHOO.env.ua.ie && this.isSecure) {
-
                     bUseSecureFileUpload = true;
-                
                 }
 
-                sMethod = 
-                    (oForm.getAttribute("method") || "POST").toUpperCase();
+                sMethod = (oForm.getAttribute("method") || "POST").toUpperCase();
 
                 Connect.setForm(oForm, bUseFileUpload, bUseSecureFileUpload);
+                Connect.asyncRequest(sMethod, oForm.getAttribute("action"), this.callback);
 
-                Connect.asyncRequest(sMethod, oForm.getAttribute("action"), 
-                    this.callback);
-
                 this.asyncSubmitEvent.fire();
 
                 break;
@@ -6493,14 +6583,12 @@
 
             this.cfg.refireEvent("iframe");
             this.cfg.refireEvent("underlay");
-
         },
 
-
         /**
         * @method getButtons
         * @description Returns an array containing each of the Dialog's 
-        * buttons, by default an array of HTML <code><BUTTON<</code> 
+        * buttons, by default an array of HTML <code><BUTTON></code> 
         * elements.  If the Dialog's buttons were created using the 
         * YAHOO.widget.Button class (via the inclusion of the optional Button 
         * dependancy on the page), an array of YAHOO.widget.Button instances 
@@ -6508,17 +6596,11 @@
         * @return {Array}
         */
         getButtons: function () {
-        
             var aButtons = this._aButtons;
-            
             if (aButtons) {
-            
                 return aButtons;
-            
             }
-        
         },
-
         
         /**
         * Sets focus to the first element in the Dialog's form or the first 
@@ -6532,41 +6614,27 @@
                 oEvent;
 
             if (args) {
-
                 oEvent = args[1];
-
                 if (oEvent) {
-
                     Event.stopEvent(oEvent);
-
                 }
-
             }
-        
 
             if (oElement) {
-
                 /*
                     Place the call to the "focus" method inside a try/catch
                     block to prevent IE from throwing JavaScript errors if
                     the element is disabled or hidden.
                 */
-
                 try {
-
                     oElement.focus();
-
                 }
                 catch(oException) {
-
                 }
 
             } else {
-
                 this.focusDefaultButton();
-
             }
-
         },
         
         /**
@@ -6581,25 +6649,16 @@
                 oEvent;
     
             if (args) {
-
                 oEvent = args[1];
-
                 if (oEvent) {
-
                     Event.stopEvent(oEvent);
-
                 }
-
             }
             
             if (aButtons && Lang.isArray(aButtons)) {
-
                 this.focusLastButton();
-
             } else {
-
                 if (oElement) {
-
                     /*
                         Place the call to the "focus" method inside a try/catch
                         block to prevent IE from throwing JavaScript errors if
@@ -6607,18 +6666,11 @@
                     */
     
                     try {
-    
                         oElement.focus();
-    
+                    } catch(oException) {
                     }
-                    catch(oException) {
-    
-                    }
-
                 }
-
             }
-
         },
         
         /**
@@ -6638,15 +6690,10 @@
                     block to prevent IE from throwing JavaScript errors if
                     the element is disabled or hidden.
                 */
-
                 try {
-
                     oElement.focus();
-                
+                } catch(oException) {
                 }
-                catch(oException) {
-                
-                }
 
             }
         },
@@ -6673,7 +6720,6 @@
                     i = (nButtons - 1);
                     
                     do {
-                    
                         oButton = aButtons[i];
                         
                         if (oButton) {
@@ -6681,35 +6727,22 @@
                             oElement = oButton.htmlButton;
 
                             if (oElement) {
-
                                 /*
                                     Place the call to the "blur" method inside  
                                     a try/catch block to prevent IE from  
                                     throwing JavaScript errors if the element 
                                     is disabled or hidden.
                                 */
-    
                                 try {
-            
                                     oElement.blur();
-                                
+                                } catch(oException) {
                                 }
-                                catch(oException) {
-                                
-                                
-                                }
-                            
                             }
-
                         }
                     
-                    }
-                    while(i--);
-                
+                    } while(i--);
                 }
-            
             }
-
         },
         
         /**
@@ -6741,19 +6774,12 @@
                         */
     
                         try {
-    
                             oElement.focus();
-                        
                         }
                         catch(oException) {
-                        
-                        
                         }
-                    
                     }
-
                 }
-
             }
         },
         
@@ -6774,15 +6800,11 @@
                 nButtons = aButtons.length;
                 
                 if (nButtons > 0) {
-
                     oButton = aButtons[(nButtons - 1)];
                     
                     if (oButton) {
-                    
                         oElement = oButton.htmlButton;
-
                         if (oElement) {
-
                             /*
                                 Place the call to the "focus" method inside a 
                                 try/catch block to prevent IE from throwing 
@@ -6791,23 +6813,13 @@
                             */
         
                             try {
-        
                                 oElement.focus();
-                            
+                            } catch(oException) {
                             }
-                            catch(oException) {
-                            
-                            
-                            }
-                        
                         }
-                    
                     }
-                
                 }
-            
             }
-
         },
         
         /**
@@ -6838,8 +6850,12 @@
         },
         
         /**
-        * Executes a submit of the Dialog followed by a hide, if validation 
-        * is successful.
+        * Executes a submit of the Dialog if validation 
+        * is successful. By default the Dialog is hidden
+        * after submission, but you can set the "hideaftersubmit"
+        * configuration property to false, to prevent the Dialog
+        * from being hidden.
+        * 
         * @method submit
         */
         submit: function () {
@@ -6847,13 +6863,17 @@
                 this.beforeSubmitEvent.fire();
                 this.doSubmit();
                 this.submitEvent.fire();
-                this.hide();
+
+                if (this.cfg.getProperty("hideaftersubmit")) {
+                    this.hide();
+                }
+
                 return true;
             } else {
                 return false;
             }
         },
-        
+
         /**
         * Executes the cancel of the Dialog followed by a hide.
         * @method cancel
@@ -7806,4 +7826,4 @@
 
 })();
 
-YAHOO.register("container", YAHOO.widget.Module, {version: "2.4.1", build: "742"});
+YAHOO.register("container", YAHOO.widget.Module, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/container/container_core-debug.js
===================================================================
--- trunk/root/static/yui/container/container_core-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/container/container_core-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 (function () {
 
@@ -745,7 +745,6 @@
         * @type Object
         */
         EVENT_TYPES = {
-        
             "BEFORE_INIT": "beforeInit",
             "INIT": "init",
             "APPEND": "append",
@@ -760,7 +759,6 @@
             "SHOW": "show",
             "BEFORE_HIDE": "beforeHide",
             "HIDE": "hide"
-        
         },
             
         /**
@@ -830,7 +828,7 @@
     * @type String
     */
     Module.CSS_HEADER = "hd";
-    
+
     /**
     * Constant representing the module body
     * @property YAHOO.widget.Module.CSS_BODY
@@ -1289,24 +1287,44 @@
         },
 
         /**
-        * Initialized an empty IFRAME that is placed out of the visible area 
+        * Initialize an empty IFRAME that is placed out of the visible area 
         * that can be used to detect text resize.
         * @method initResizeMonitor
         */
         initResizeMonitor: function () {
 
+            var isGeckoWin = (YAHOO.env.ua.gecko && this.platform == "windows");
+            if (isGeckoWin) {
+                // Help prevent spinning loading icon which 
+                // started with FireFox 2.0.0.8/Win
+                var self = this;
+                setTimeout(function(){self._initResizeMonitor();}, 0);
+            } else {
+                this._initResizeMonitor();
+            }
+        },
+
+        /**
+         * Create and initialize the text resize monitoring iframe.
+         * 
+         * @protected
+         * @method _initResizeMonitor
+         */
+        _initResizeMonitor : function() {
+
             var oDoc, 
                 oIFrame, 
                 sHTML;
 
             function fireTextResize() {
-                YAHOO.log("Module got iframe contentWindow resize event", "info");
                 Module.textResizeEvent.fire();
             }
 
             if (!YAHOO.env.ua.opera) {
                 oIFrame = Dom.get("_yuiResizeMonitor");
 
+                var supportsCWResize = this._supportsCWResize();
+
                 if (!oIFrame) {
                     oIFrame = document.createElement("iframe");
 
@@ -1314,21 +1332,17 @@
                         oIFrame.src = Module.RESIZE_MONITOR_SECURE_URL;
                     }
 
-                    /*
-                        Need to set the iframe document for Gecko
-                        to fire resize events on the iframe contentWindow.
-                     */
-                    if (YAHOO.env.ua.gecko) {
-                         sHTML = ["<html><head><script ",
-                                  "type=\"text/javascript\">",
-                                  "window.onresize=function(){window.parent.",
-                                  "YAHOO.widget.Module.textResizeEvent.",
-                                  "fire();}", 
-                                  "<\/script></head>",
-                                  "<body></body></html>"].join('');
+                    if (!supportsCWResize) {
+                        // Can't monitor on contentWindow, so fire from inside iframe
+                        sHTML = ["<html><head><script ",
+                                 "type=\"text/javascript\">",
+                                 "window.onresize=function(){window.parent.",
+                                 "YAHOO.widget.Module.textResizeEvent.",
+                                 "fire();};<",
+                                 "\/script></head>",
+                                 "<body></body></html>"].join('');
 
-                        oIFrame.src = "data:text/html;charset=utf-8," +
-                            encodeURIComponent(sHTML);
+                        oIFrame.src = "data:text/html;charset=utf-8," + encodeURIComponent(sHTML);
                     }
 
                     oIFrame.id = "_yuiResizeMonitor";
@@ -1341,11 +1355,12 @@
                     oIFrame.style.position = "absolute";
                     oIFrame.style.visibility = "hidden";
 
-                    var fc = document.body.firstChild;
+                    var db = document.body,
+                        fc = db.firstChild;
                     if (fc) {
-                        document.body.insertBefore(oIFrame, fc);
+                        db.insertBefore(oIFrame, fc);
                     } else {
-                        document.body.appendChild(oIFrame);
+                        db.appendChild(oIFrame);
                     }
 
                     oIFrame.style.width = "10em";
@@ -1370,8 +1385,7 @@
                     Module.textResizeEvent.subscribe(this.onDomResize, this, true);
 
                     if (!Module.textResizeInitialized) {
-                         // We already handle gecko using the iframe's document content
-                        if (!YAHOO.env.ua.gecko) {
+                        if (supportsCWResize) {
                             if (!Event.on(oIFrame.contentWindow, "resize", fireTextResize)) {
                                 /*
                                      This will fail in IE if document.domain has 
@@ -1389,13 +1403,46 @@
         },
 
         /**
+         * Text resize monitor helper method.
+         * Determines if the browser supports resize events on iframe content windows.
+         * 
+         * @private
+         * @method _supportsCWResize
+         */
+        _supportsCWResize : function() {
+            /*
+                Gecko 1.8.0 (FF1.5), 1.8.1.0-5 (FF2) won't fire resize on contentWindow.
+                Gecko 1.8.1.6+ (FF2.0.0.6+) and all other browsers will fire resize on contentWindow.
+
+                We don't want to start sniffing for patch versions, so fire textResize the same
+                way on all FF, until 1.9 (3.x) is out
+             */
+            var bSupported = true;
+            if (YAHOO.env.ua.gecko && YAHOO.env.ua.gecko <= 1.8) {
+                bSupported = false;
+                /*
+                var v = navigator.userAgent.match(/rv:([^\s\)]*)/); // From YAHOO.env.ua
+                if (v && v[0]) {
+                    var sv = v[0].match(/\d\.\d\.(\d)/);
+                    if (sv && sv[1]) {
+                        if (parseInt(sv[1], 10) > 0) {
+                            bSupported = true;
+                        }
+                    }
+                }
+                */
+            }
+            return bSupported;
+        },
+
+        /**
         * Event handler fired when the resize monitor element is resized.
         * @method onDomResize
         * @param {DOMEvent} e The DOM resize event
         * @param {Object} obj The scope object passed to the handler
         */
         onDomResize: function (e, obj) {
-        
+
             var nLeft = -1 * this.resizeMonitor.offsetWidth,
                 nTop = -1 * this.resizeMonitor.offsetHeight;
         
@@ -1403,90 +1450,97 @@
             this.resizeMonitor.style.left =  nLeft + "px";
 
         },
-        
+
         /**
-        * Sets the Module's header content to the HTML specified, or appends 
+        * Sets the Module's header content to the string specified, or appends 
         * the passed element to the header. If no header is present, one will 
-        * be automatically created.
+        * be automatically created. An empty string can be passed to the method
+        * to clear the contents of the header.
+        * 
         * @method setHeader
-        * @param {String} headerContent The HTML used to set the header 
+        * @param {String} headerContent The string used to set the header.
+        * As a convenience, non HTMLElement objects can also be passed into 
+        * the method, and will be treated as strings, with the header innerHTML
+        * set to their default toString implementations.
         * <em>OR</em>
         * @param {HTMLElement} headerContent The HTMLElement to append to 
-        * the header
+        * <em>OR</em>
+        * @param {DocumentFragment} headerContent The document fragment 
+        * containing elements which are to be added to the header
         */
         setHeader: function (headerContent) {
-
             var oHeader = this.header || (this.header = createHeader());
-        
-            if (typeof headerContent == "string") {
 
-                oHeader.innerHTML = headerContent;
-
-            } else {
-
+            if (headerContent.nodeName) {
                 oHeader.innerHTML = "";
                 oHeader.appendChild(headerContent);
+            } else {
+                oHeader.innerHTML = headerContent;
+            }
 
-            }
-        
             this.changeHeaderEvent.fire(headerContent);
             this.changeContentEvent.fire();
 
         },
-        
+
         /**
         * Appends the passed element to the header. If no header is present, 
         * one will be automatically created.
         * @method appendToHeader
-        * @param {HTMLElement} element The element to append to the header
+        * @param {HTMLElement | DocumentFragment} element The element to 
+        * append to the header. In the case of a document fragment, the
+        * children of the fragment will be appended to the header.
         */
         appendToHeader: function (element) {
+            var oHeader = this.header || (this.header = createHeader());
 
-            var oHeader = this.header || (this.header = createHeader());
-        
             oHeader.appendChild(element);
 
             this.changeHeaderEvent.fire(element);
             this.changeContentEvent.fire();
 
         },
-        
+
         /**
         * Sets the Module's body content to the HTML specified, or appends the
         * passed element to the body. If no body is present, one will be 
-        * automatically created.
+        * automatically created. An empty string can be passed to the method
+        * to clear the contents of the body.
         * @method setBody
-        * @param {String} bodyContent The HTML used to set the body <em>OR</em>
+        * @param {String} bodyContent The HTML used to set the body. 
+        * As a convenience, non HTMLElement objects can also be passed into 
+        * the method, and will be treated as strings, with the body innerHTML
+        * set to their default toString implementations.
+        * <em>OR</em>
         * @param {HTMLElement} bodyContent The HTMLElement to append to the body
+        * <em>OR</em>
+        * @param {DocumentFragment} bodyContent The document fragment 
+        * containing elements which are to be added to the body
         */
         setBody: function (bodyContent) {
-
             var oBody = this.body || (this.body = createBody());
-        
-            if (typeof bodyContent == "string") {
 
-                oBody.innerHTML = bodyContent;
-
-            } else {
-
+            if (bodyContent.nodeName) {
                 oBody.innerHTML = "";
                 oBody.appendChild(bodyContent);
+            } else {
+                oBody.innerHTML = bodyContent;
+            }
 
-            }
-        
             this.changeBodyEvent.fire(bodyContent);
             this.changeContentEvent.fire();
+        },
 
-        },
-        
         /**
         * Appends the passed element to the body. If no body is present, one 
         * will be automatically created.
         * @method appendToBody
-        * @param {HTMLElement} element The element to append to the body
+        * @param {HTMLElement | DocumentFragment} element The element to 
+        * append to the body. In the case of a document fragment, the
+        * children of the fragment will be appended to the body.
+        * 
         */
         appendToBody: function (element) {
-
             var oBody = this.body || (this.body = createBody());
         
             oBody.appendChild(element);
@@ -1499,50 +1553,54 @@
         /**
         * Sets the Module's footer content to the HTML specified, or appends 
         * the passed element to the footer. If no footer is present, one will 
-        * be automatically created.
+        * be automatically created. An empty string can be passed to the method
+        * to clear the contents of the footer.
         * @method setFooter
         * @param {String} footerContent The HTML used to set the footer 
+        * As a convenience, non HTMLElement objects can also be passed into 
+        * the method, and will be treated as strings, with the footer innerHTML
+        * set to their default toString implementations.
         * <em>OR</em>
         * @param {HTMLElement} footerContent The HTMLElement to append to 
         * the footer
+        * <em>OR</em>
+        * @param {DocumentFragment} footerContent The document fragment containing 
+        * elements which are to be added to the footer
         */
         setFooter: function (footerContent) {
 
             var oFooter = this.footer || (this.footer = createFooter());
-        
-            if (typeof footerContent == "string") {
 
-                oFooter.innerHTML = footerContent;
-
-            } else {
-
+            if (footerContent.nodeName) {
                 oFooter.innerHTML = "";
                 oFooter.appendChild(footerContent);
+            } else {
+                oFooter.innerHTML = footerContent;
+            }
 
-            }
-        
             this.changeFooterEvent.fire(footerContent);
             this.changeContentEvent.fire();
+        },
 
-        },
-        
         /**
         * Appends the passed element to the footer. If no footer is present, 
         * one will be automatically created.
         * @method appendToFooter
-        * @param {HTMLElement} element The element to append to the footer
+        * @param {HTMLElement | DocumentFragment} element The element to 
+        * append to the footer. In the case of a document fragment, the
+        * children of the fragment will be appended to the footer
         */
         appendToFooter: function (element) {
 
             var oFooter = this.footer || (this.footer = createFooter());
-        
+
             oFooter.appendChild(element);
 
             this.changeFooterEvent.fire(element);
             this.changeContentEvent.fire();
 
         },
-        
+
         /**
         * Renders the Module by inserting the elements that are not already 
         * in the main Module into their correct places. Optionally appends 
@@ -1669,7 +1727,7 @@
             }
 
         },
-        
+
         /**
         * Shows the Module element by setting the visible configuration 
         * property to true. Also fires two events: beforeShowEvent prior to 
@@ -1679,7 +1737,7 @@
         show: function () {
             this.cfg.setProperty("visible", true);
         },
-        
+
         /**
         * Hides the Module element by setting the visible configuration 
         * property to false. Also fires two events: beforeHideEvent prior to 
@@ -1871,12 +1929,12 @@
                 key: "height", 
                 suppressEvent: true, 
                 supercedes: ["context", "fixedcenter", "iframe"] 
-            }, 
+            },
 
             "ZINDEX": { 
                 key: "zindex", 
                 value: null 
-            }, 
+            },
 
             "CONSTRAIN_TO_VIEWPORT": { 
                 key: "constraintoviewport", 
@@ -2161,7 +2219,7 @@
                 supercedes: DEFAULT_CONFIG.X.supercedes
     
             });
-    
+
             /**
             * The absolute y-coordinate position of the Overlay
             * @config y
@@ -2169,12 +2227,12 @@
             * @default null
             */
             this.cfg.addProperty(DEFAULT_CONFIG.Y.key, {
-    
+
                 handler: this.configY, 
                 validator: DEFAULT_CONFIG.Y.validator, 
                 suppressEvent: DEFAULT_CONFIG.Y.suppressEvent, 
                 supercedes: DEFAULT_CONFIG.Y.supercedes
-    
+
             });
     
             /**
@@ -2252,7 +2310,7 @@
                 supercedes: DEFAULT_CONFIG.HEIGHT.supercedes
             
             });
-
+            
             /**
             * CSS z-index of the Overlay.
             * @config zIndex
@@ -2265,7 +2323,7 @@
                 value: DEFAULT_CONFIG.ZINDEX.value
 
             });
-            
+
             /**
             * True if the Overlay should be prevented from being positioned 
             * out of the viewport.
@@ -2281,7 +2339,7 @@
                 supercedes: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.supercedes
 
             });
-            
+
             /**
             * @config iframe
             * @description Boolean indicating whether or not the Overlay should 
@@ -2543,7 +2601,7 @@
         * this will usually equal the owner.
         */
         configHeight: function (type, args, obj) {
-    
+
             var height = args[0],
                 el = this.element;
 
@@ -2656,9 +2714,9 @@
             y = this.cfg.getProperty("y");
             
             Dom.setX(this.element, x, true);
-            
+
             this.cfg.setProperty("xy", [x, y], true);
-           
+
             this.cfg.refireEvent("iframe");
             this.moveEvent.fire([x, y]);
         },
@@ -2891,6 +2949,26 @@
         },
 
         /**
+         * Set's the container's XY value from DOM if not already set.
+         * 
+         * Differs from syncPosition, in that the XY value is only sync'd with DOM if 
+         * not already set. The method also refire's the XY config property event, so any
+         * beforeMove, Move event listeners are invoked.
+         * 
+         * @method _primeXYFromDOM
+         * @protected
+         */
+        _primeXYFromDOM : function() {
+            if (YAHOO.lang.isUndefined(this.cfg.getProperty("xy"))) {
+                // Set CFG XY based on DOM XY
+                this.syncPosition();
+                // Account for XY being set silently in syncPosition (no moveTo fired/called)
+                this.cfg.refireEvent("xy");
+                this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);
+            }
+        },
+
+        /**
         * The default event handler fired when the "constraintoviewport" 
         * property is changed.
         * @method configConstrainToViewport
@@ -2902,39 +2980,22 @@
         * this will usually equal the owner.
         */
         configConstrainToViewport: function (type, args, obj) {
-
-            function constrainBeforeShow() {
-                if (YAHOO.lang.isUndefined(this.cfg.getProperty("xy"))) {
-                    // Set CFG XY based on DOM XY
-                    this.syncPosition();
-                }
-                var x = this.cfg.getProperty("x");
-                var y = this.cfg.getProperty("y");
-
-                // Account for XY being set silently (no moveTo fired/called)
-                var cXY = this.getConstrainedXY(x, y);
-                if (cXY[0] !== x || cXY[1] !== y) {
-                    this.moveTo(cXY[0], cXY[1]);
-                }
-            }
-
             var val = args[0];
 
             if (val) {
                 if (! Config.alreadySubscribed(this.beforeMoveEvent, this.enforceConstraints, this)) {
                     this.beforeMoveEvent.subscribe(this.enforceConstraints, this, true);
                 }
-
-                if (! Config.alreadySubscribed(this.beforeShowEvent, constrainBeforeShow)) {
-                    this.beforeShowEvent.subscribe(constrainBeforeShow);
+                if (! Config.alreadySubscribed(this.beforeShowEvent, this._primeXYFromDOM)) {
+                    this.beforeShowEvent.subscribe(this._primeXYFromDOM);
                 }
             } else {
-                this.beforeShowEvent.unsubscribe(constrainBeforeShow);
+                this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);
                 this.beforeMoveEvent.unsubscribe(this.enforceConstraints, this);
             }
         },
 
-        /**
+         /**
         * The default event handler fired when the "context" property 
         * is changed.
         * @method configContext
@@ -2950,38 +3011,28 @@
                 contextEl,
                 elementMagnetCorner,
                 contextMagnetCorner;
-            
+
             if (contextArgs) {
-            
                 contextEl = contextArgs[0];
                 elementMagnetCorner = contextArgs[1];
                 contextMagnetCorner = contextArgs[2];
                 
                 if (contextEl) {
-    
                     if (typeof contextEl == "string") {
-
                         this.cfg.setProperty("context", 
                             [document.getElementById(contextEl), 
                                 elementMagnetCorner, contextMagnetCorner], 
                                 true);
-
                     }
                     
                     if (elementMagnetCorner && contextMagnetCorner) {
-
                         this.align(elementMagnetCorner, contextMagnetCorner);
-
                     }
-
                 }
-
             }
-
         },
 
         // END BUILT-IN PROPERTY EVENT HANDLERS //
-
         /**
         * Aligns the Overlay to its context element using the specified corner 
         * points (represented by the constants TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, 
@@ -4204,4 +4255,4 @@
 
 })();
 
-YAHOO.register("containercore", YAHOO.widget.Module, {version: "2.4.1", build: "742"});
+YAHOO.register("containercore", YAHOO.widget.Module, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/container/container_core-min.js
===================================================================
--- trunk/root/static/yui/container/container_core-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/container/container_core-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,12 +1,12 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-(function(){YAHOO.util.Config=function(D){if(D){this.init(D);}};var B=YAHOO.lang,C=YAHOO.util.CustomEvent,A=YAHOO.util.Config;A.CONFIG_CHANGED_EVENT="configChanged";A.BOOLEAN_TYPE="boolean";A.prototype={owner:null,queueInProgress:false,config:null,initialConfig:null,eventQueue:null,configChangedEvent:null,init:function(D){this.owner=D;this.configChangedEvent=this.createEvent(A.CONFIG_CHANGED_EVENT);this.configChangedEvent.signature=C.LIST;this.queueInProgress=false;this.config={};this.initialConfig={};this.eventQueue=[];},checkBoolean:function(D){return(typeof D==A.BOOLEAN_TYPE);},checkNumber:function(D){return(!isNaN(D));},fireEvent:function(D,F){var E=this.config[D];if(E&&E.event){E.event.fire(F);}},addProperty:function(E,D){E=E.toLowerCase();this.config[E]=D;D.event=this.createEvent(E,{scope:this.owner});D.event.signature=C.LIST;D.key=E;if(D.handler){D.event.subscribe(D.handler,this.owner);}this.setProperty(E,D.value,true);if(!D.suppressEvent){this.queueProperty(E,D.valu!
 e);}},getConfig:function(){var D={},F,E;for(F in this.config){E=this.config[F];if(E&&E.event){D[F]=E.value;}}return D;},getProperty:function(D){var E=this.config[D.toLowerCase()];if(E&&E.event){return E.value;}else{return undefined;}},resetProperty:function(D){D=D.toLowerCase();var E=this.config[D];if(E&&E.event){if(this.initialConfig[D]&&!B.isUndefined(this.initialConfig[D])){this.setProperty(D,this.initialConfig[D]);return true;}}else{return false;}},setProperty:function(E,G,D){var F;E=E.toLowerCase();if(this.queueInProgress&&!D){this.queueProperty(E,G);return true;}else{F=this.config[E];if(F&&F.event){if(F.validator&&!F.validator(G)){return false;}else{F.value=G;if(!D){this.fireEvent(E,G);this.configChangedEvent.fire([E,G]);}return true;}}else{return false;}}},queueProperty:function(S,P){S=S.toLowerCase();var R=this.config[S],K=false,J,G,H,I,O,Q,F,M,N,D,L,T,E;if(R&&R.event){if(!B.isUndefined(P)&&R.validator&&!R.validator(P)){return false;}else{if(!B.isUndefined(P)){R.val!
 ue=P;}else{P=R.value;}K=false;J=this.eventQueue.length;for(L=0!
 ;L<J;L++
){G=this.eventQueue[L];if(G){H=G[0];I=G[1];if(H==S){this.eventQueue[L]=null;this.eventQueue.push([S,(!B.isUndefined(P)?P:I)]);K=true;break;}}}if(!K&&!B.isUndefined(P)){this.eventQueue.push([S,P]);}}if(R.supercedes){O=R.supercedes.length;for(T=0;T<O;T++){Q=R.supercedes[T];F=this.eventQueue.length;for(E=0;E<F;E++){M=this.eventQueue[E];if(M){N=M[0];D=M[1];if(N==Q.toLowerCase()){this.eventQueue.push([N,D]);this.eventQueue[E]=null;break;}}}}}return true;}else{return false;}},refireEvent:function(D){D=D.toLowerCase();var E=this.config[D];if(E&&E.event&&!B.isUndefined(E.value)){if(this.queueInProgress){this.queueProperty(D);}else{this.fireEvent(D,E.value);}}},applyConfig:function(D,G){var F,E;if(G){E={};for(F in D){if(B.hasOwnProperty(D,F)){E[F.toLowerCase()]=D[F];}}this.initialConfig=E;}for(F in D){if(B.hasOwnProperty(D,F)){this.queueProperty(F,D[F]);}}},refresh:function(){var D;for(D in this.config){this.refireEvent(D);}},fireQueue:function(){var E,H,D,G,F;this.queueInProgress=tr!
 ue;for(E=0;E<this.eventQueue.length;E++){H=this.eventQueue[E];if(H){D=H[0];G=H[1];F=this.config[D];F.value=G;this.fireEvent(D,G);}}this.queueInProgress=false;this.eventQueue=[];},subscribeToConfigEvent:function(E,F,H,D){var G=this.config[E.toLowerCase()];if(G&&G.event){if(!A.alreadySubscribed(G.event,F,H)){G.event.subscribe(F,H,D);}return true;}else{return false;}},unsubscribeFromConfigEvent:function(D,E,G){var F=this.config[D.toLowerCase()];if(F&&F.event){return F.event.unsubscribe(E,G);}else{return false;}},toString:function(){var D="Config";if(this.owner){D+=" ["+this.owner.toString()+"]";}return D;},outputEventQueue:function(){var D="",G,E,F=this.eventQueue.length;for(E=0;E<F;E++){G=this.eventQueue[E];if(G){D+=G[0]+"="+G[1]+", ";}}return D;},destroy:function(){var E=this.config,D,F;for(D in E){if(B.hasOwnProperty(E,D)){F=E[D];F.event.unsubscribeAll();F.event=null;}}this.configChangedEvent.unsubscribeAll();this.configChangedEvent=null;this.owner=null;this.config=null;thi!
 s.initialConfig=null;this.eventQueue=null;}};A.alreadySubscrib!
 ed=funct
ion(E,H,I){var F=E.subscribers.length,D,G;if(F>0){G=F-1;do{D=E.subscribers[G];if(D&&D.obj==I&&D.fn==H){return true;}}while(G--);}return false;};YAHOO.lang.augmentProto(A,YAHOO.util.EventProvider);}());(function(){YAHOO.widget.Module=function(Q,P){if(Q){this.init(Q,P);}else{}};var F=YAHOO.util.Dom,D=YAHOO.util.Config,M=YAHOO.util.Event,L=YAHOO.util.CustomEvent,G=YAHOO.widget.Module,H,O,N,E,A={"BEFORE_INIT":"beforeInit","INIT":"init","APPEND":"append","BEFORE_RENDER":"beforeRender","RENDER":"render","CHANGE_HEADER":"changeHeader","CHANGE_BODY":"changeBody","CHANGE_FOOTER":"changeFooter","CHANGE_CONTENT":"changeContent","DESTORY":"destroy","BEFORE_SHOW":"beforeShow","SHOW":"show","BEFORE_HIDE":"beforeHide","HIDE":"hide"},I={"VISIBLE":{key:"visible",value:true,validator:YAHOO.lang.isBoolean},"EFFECT":{key:"effect",suppressEvent:true,supercedes:["visible"]},"MONITOR_RESIZE":{key:"monitorresize",value:true},"APPEND_TO_DOCUMENT_BODY":{key:"appendtodocumentbody",value:false}};G.IMG_!
 ROOT=null;G.IMG_ROOT_SSL=null;G.CSS_MODULE="yui-module";G.CSS_HEADER="hd";G.CSS_BODY="bd";G.CSS_FOOTER="ft";G.RESIZE_MONITOR_SECURE_URL="javascript:false;";G.textResizeEvent=new L("textResize");function K(){if(!H){H=document.createElement("div");H.innerHTML=("<div class=\""+G.CSS_HEADER+"\"></div><div class=\""+G.CSS_BODY+"\"></div><div class=\""+G.CSS_FOOTER+"\"></div>");O=H.firstChild;N=O.nextSibling;E=N.nextSibling;}return H;}function J(){if(!O){K();}return(O.cloneNode(false));}function B(){if(!N){K();}return(N.cloneNode(false));}function C(){if(!E){K();}return(E.cloneNode(false));}G.prototype={constructor:G,element:null,header:null,body:null,footer:null,id:null,imageRoot:G.IMG_ROOT,initEvents:function(){var P=L.LIST;this.beforeInitEvent=this.createEvent(A.BEFORE_INIT);this.beforeInitEvent.signature=P;this.initEvent=this.createEvent(A.INIT);this.initEvent.signature=P;this.appendEvent=this.createEvent(A.APPEND);
-this.appendEvent.signature=P;this.beforeRenderEvent=this.createEvent(A.BEFORE_RENDER);this.beforeRenderEvent.signature=P;this.renderEvent=this.createEvent(A.RENDER);this.renderEvent.signature=P;this.changeHeaderEvent=this.createEvent(A.CHANGE_HEADER);this.changeHeaderEvent.signature=P;this.changeBodyEvent=this.createEvent(A.CHANGE_BODY);this.changeBodyEvent.signature=P;this.changeFooterEvent=this.createEvent(A.CHANGE_FOOTER);this.changeFooterEvent.signature=P;this.changeContentEvent=this.createEvent(A.CHANGE_CONTENT);this.changeContentEvent.signature=P;this.destroyEvent=this.createEvent(A.DESTORY);this.destroyEvent.signature=P;this.beforeShowEvent=this.createEvent(A.BEFORE_SHOW);this.beforeShowEvent.signature=P;this.showEvent=this.createEvent(A.SHOW);this.showEvent.signature=P;this.beforeHideEvent=this.createEvent(A.BEFORE_HIDE);this.beforeHideEvent.signature=P;this.hideEvent=this.createEvent(A.HIDE);this.hideEvent.signature=P;},platform:function(){var P=navigator.userAgent!
 .toLowerCase();if(P.indexOf("windows")!=-1||P.indexOf("win32")!=-1){return"windows";}else{if(P.indexOf("macintosh")!=-1){return"mac";}else{return false;}}}(),browser:function(){var P=navigator.userAgent.toLowerCase();if(P.indexOf("opera")!=-1){return"opera";}else{if(P.indexOf("msie 7")!=-1){return"ie7";}else{if(P.indexOf("msie")!=-1){return"ie";}else{if(P.indexOf("safari")!=-1){return"safari";}else{if(P.indexOf("gecko")!=-1){return"gecko";}else{return false;}}}}}}(),isSecure:function(){if(window.location.href.toLowerCase().indexOf("https")===0){return true;}else{return false;}}(),initDefaultConfig:function(){this.cfg.addProperty(I.VISIBLE.key,{handler:this.configVisible,value:I.VISIBLE.value,validator:I.VISIBLE.validator});this.cfg.addProperty(I.EFFECT.key,{suppressEvent:I.EFFECT.suppressEvent,supercedes:I.EFFECT.supercedes});this.cfg.addProperty(I.MONITOR_RESIZE.key,{handler:this.configMonitorResize,value:I.MONITOR_RESIZE.value});this.cfg.addProperty(I.APPEND_TO_DOCUMENT_B!
 ODY.key,{value:I.APPEND_TO_DOCUMENT_BODY.value});},init:functi!
 on(U,T){
var R,V;this.initEvents();this.beforeInitEvent.fire(G);this.cfg=new D(this);if(this.isSecure){this.imageRoot=G.IMG_ROOT_SSL;}if(typeof U=="string"){R=U;U=document.getElementById(U);if(!U){U=(K()).cloneNode(false);U.id=R;}}this.element=U;if(U.id){this.id=U.id;}V=this.element.firstChild;if(V){var Q=false,P=false,S=false;do{if(1==V.nodeType){if(!Q&&F.hasClass(V,G.CSS_HEADER)){this.header=V;Q=true;}else{if(!P&&F.hasClass(V,G.CSS_BODY)){this.body=V;P=true;}else{if(!S&&F.hasClass(V,G.CSS_FOOTER)){this.footer=V;S=true;}}}}}while((V=V.nextSibling));}this.initDefaultConfig();F.addClass(this.element,G.CSS_MODULE);if(T){this.cfg.applyConfig(T,true);}if(!D.alreadySubscribed(this.renderEvent,this.cfg.fireQueue,this.cfg)){this.renderEvent.subscribe(this.cfg.fireQueue,this.cfg,true);}this.initEvent.fire(G);},initResizeMonitor:function(){var P,Q,S;function T(){G.textResizeEvent.fire();}if(!YAHOO.env.ua.opera){Q=F.get("_yuiResizeMonitor");if(!Q){Q=document.createElement("iframe");if(this.isS!
 ecure&&G.RESIZE_MONITOR_SECURE_URL&&YAHOO.env.ua.ie){Q.src=G.RESIZE_MONITOR_SECURE_URL;}if(YAHOO.env.ua.gecko){S=["<html><head><script ","type=\"text/javascript\">","window.onresize=function(){window.parent.","YAHOO.widget.Module.textResizeEvent.","fire();}","</script></head>","<body></body></html>"].join("");Q.src="data:text/html;charset=utf-8,"+encodeURIComponent(S);}Q.id="_yuiResizeMonitor";Q.style.position="absolute";Q.style.visibility="hidden";var R=document.body.firstChild;if(R){document.body.insertBefore(Q,R);}else{document.body.appendChild(Q);}Q.style.width="10em";Q.style.height="10em";Q.style.top=(-1*Q.offsetHeight)+"px";Q.style.left=(-1*Q.offsetWidth)+"px";Q.style.borderWidth="0";Q.style.visibility="visible";if(YAHOO.env.ua.webkit){P=Q.contentWindow.document;P.open();P.close();}}if(Q&&Q.contentWindow){G.textResizeEvent.subscribe(this.onDomResize,this,true);if(!G.textResizeInitialized){if(!YAHOO.env.ua.gecko){if(!M.on(Q.contentWindow,"resize",T)){M.on(Q,"resize",T)!
 ;}}G.textResizeInitialized=true;}this.resizeMonitor=Q;}}},onDo!
 mResize:
function(S,R){var Q=-1*this.resizeMonitor.offsetWidth,P=-1*this.resizeMonitor.offsetHeight;this.resizeMonitor.style.top=P+"px";this.resizeMonitor.style.left=Q+"px";},setHeader:function(Q){var P=this.header||(this.header=J());if(typeof Q=="string"){P.innerHTML=Q;}else{P.innerHTML="";P.appendChild(Q);}this.changeHeaderEvent.fire(Q);this.changeContentEvent.fire();},appendToHeader:function(Q){var P=this.header||(this.header=J());P.appendChild(Q);this.changeHeaderEvent.fire(Q);this.changeContentEvent.fire();},setBody:function(Q){var P=this.body||(this.body=B());if(typeof Q=="string"){P.innerHTML=Q;}else{P.innerHTML="";P.appendChild(Q);}this.changeBodyEvent.fire(Q);this.changeContentEvent.fire();},appendToBody:function(Q){var P=this.body||(this.body=B());P.appendChild(Q);this.changeBodyEvent.fire(Q);this.changeContentEvent.fire();},setFooter:function(Q){var P=this.footer||(this.footer=C());if(typeof Q=="string"){P.innerHTML=Q;}else{P.innerHTML="";P.appendChild(Q);}this.changeFoote!
 rEvent.fire(Q);this.changeContentEvent.fire();},appendToFooter:function(Q){var P=this.footer||(this.footer=C());P.appendChild(Q);this.changeFooterEvent.fire(Q);this.changeContentEvent.fire();},render:function(R,P){var S=this,T;function Q(U){if(typeof U=="string"){U=document.getElementById(U);}if(U){S._addToParent(U,S.element);S.appendEvent.fire();}}this.beforeRenderEvent.fire();if(!P){P=this.element;}if(R){Q(R);}else{if(!F.inDocument(this.element)){return false;}}if(this.header&&!F.inDocument(this.header)){T=P.firstChild;if(T){P.insertBefore(this.header,T);}else{P.appendChild(this.header);}}if(this.body&&!F.inDocument(this.body)){if(this.footer&&F.isAncestor(this.moduleElement,this.footer)){P.insertBefore(this.body,this.footer);}else{P.appendChild(this.body);}}if(this.footer&&!F.inDocument(this.footer)){P.appendChild(this.footer);}this.renderEvent.fire();return true;},destroy:function(){var P,Q;if(this.element){M.purgeElement(this.element,true);
-P=this.element.parentNode;}if(P){P.removeChild(this.element);}this.element=null;this.header=null;this.body=null;this.footer=null;G.textResizeEvent.unsubscribe(this.onDomResize,this);this.cfg.destroy();this.cfg=null;this.destroyEvent.fire();for(Q in this){if(Q instanceof L){Q.unsubscribeAll();}}},show:function(){this.cfg.setProperty("visible",true);},hide:function(){this.cfg.setProperty("visible",false);},configVisible:function(Q,P,R){var S=P[0];if(S){this.beforeShowEvent.fire();F.setStyle(this.element,"display","block");this.showEvent.fire();}else{this.beforeHideEvent.fire();F.setStyle(this.element,"display","none");this.hideEvent.fire();}},configMonitorResize:function(R,Q,S){var P=Q[0];if(P){this.initResizeMonitor();}else{G.textResizeEvent.unsubscribe(this.onDomResize,this,true);this.resizeMonitor=null;}},_addToParent:function(P,Q){if(!this.cfg.getProperty("appendtodocumentbody")&&P===document.body&&P.firstChild){P.insertBefore(Q,P.firstChild);}else{P.appendChild(Q);}},toS!
 tring:function(){return"Module "+this.id;}};YAHOO.lang.augmentProto(G,YAHOO.util.EventProvider);}());(function(){YAHOO.widget.Overlay=function(L,K){YAHOO.widget.Overlay.superclass.constructor.call(this,L,K);};var F=YAHOO.lang,I=YAHOO.util.CustomEvent,E=YAHOO.widget.Module,J=YAHOO.util.Event,D=YAHOO.util.Dom,C=YAHOO.util.Config,B=YAHOO.widget.Overlay,G,A={"BEFORE_MOVE":"beforeMove","MOVE":"move"},H={"X":{key:"x",validator:F.isNumber,suppressEvent:true,supercedes:["iframe"]},"Y":{key:"y",validator:F.isNumber,suppressEvent:true,supercedes:["iframe"]},"XY":{key:"xy",suppressEvent:true,supercedes:["iframe"]},"CONTEXT":{key:"context",suppressEvent:true,supercedes:["iframe"]},"FIXED_CENTER":{key:"fixedcenter",value:false,validator:F.isBoolean,supercedes:["iframe","visible"]},"WIDTH":{key:"width",suppressEvent:true,supercedes:["context","fixedcenter","iframe"]},"HEIGHT":{key:"height",suppressEvent:true,supercedes:["context","fixedcenter","iframe"]},"ZINDEX":{key:"zindex",value:null!
 },"CONSTRAIN_TO_VIEWPORT":{key:"constraintoviewport",value:fal!
 se,valid
ator:F.isBoolean,supercedes:["iframe","x","y","xy"]},"IFRAME":{key:"iframe",value:(YAHOO.env.ua.ie==6?true:false),validator:F.isBoolean,supercedes:["zindex"]}};B.IFRAME_SRC="javascript:false;";B.IFRAME_OFFSET=3;B.VIEWPORT_OFFSET=10;B.TOP_LEFT="tl";B.TOP_RIGHT="tr";B.BOTTOM_LEFT="bl";B.BOTTOM_RIGHT="br";B.CSS_OVERLAY="yui-overlay";B.windowScrollEvent=new I("windowScroll");B.windowResizeEvent=new I("windowResize");B.windowScrollHandler=function(K){if(YAHOO.env.ua.ie){if(!window.scrollEnd){window.scrollEnd=-1;}clearTimeout(window.scrollEnd);window.scrollEnd=setTimeout(function(){B.windowScrollEvent.fire();},1);}else{B.windowScrollEvent.fire();}};B.windowResizeHandler=function(K){if(YAHOO.env.ua.ie){if(!window.resizeEnd){window.resizeEnd=-1;}clearTimeout(window.resizeEnd);window.resizeEnd=setTimeout(function(){B.windowResizeEvent.fire();},100);}else{B.windowResizeEvent.fire();}};B._initialized=null;if(B._initialized===null){J.on(window,"scroll",B.windowScrollHandler);J.on(window!
 ,"resize",B.windowResizeHandler);B._initialized=true;}YAHOO.extend(B,E,{init:function(L,K){B.superclass.init.call(this,L);this.beforeInitEvent.fire(B);D.addClass(this.element,B.CSS_OVERLAY);if(K){this.cfg.applyConfig(K,true);}if(this.platform=="mac"&&YAHOO.env.ua.gecko){if(!C.alreadySubscribed(this.showEvent,this.showMacGeckoScrollbars,this)){this.showEvent.subscribe(this.showMacGeckoScrollbars,this,true);}if(!C.alreadySubscribed(this.hideEvent,this.hideMacGeckoScrollbars,this)){this.hideEvent.subscribe(this.hideMacGeckoScrollbars,this,true);}}this.initEvent.fire(B);},initEvents:function(){B.superclass.initEvents.call(this);var K=I.LIST;this.beforeMoveEvent=this.createEvent(A.BEFORE_MOVE);this.beforeMoveEvent.signature=K;this.moveEvent=this.createEvent(A.MOVE);this.moveEvent.signature=K;},initDefaultConfig:function(){B.superclass.initDefaultConfig.call(this);this.cfg.addProperty(H.X.key,{handler:this.configX,validator:H.X.validator,suppressEvent:H.X.suppressEvent,supercedes!
 :H.X.supercedes});this.cfg.addProperty(H.Y.key,{handler:this.c!
 onfigY,v
alidator:H.Y.validator,suppressEvent:H.Y.suppressEvent,supercedes:H.Y.supercedes});this.cfg.addProperty(H.XY.key,{handler:this.configXY,suppressEvent:H.XY.suppressEvent,supercedes:H.XY.supercedes});this.cfg.addProperty(H.CONTEXT.key,{handler:this.configContext,suppressEvent:H.CONTEXT.suppressEvent,supercedes:H.CONTEXT.supercedes});this.cfg.addProperty(H.FIXED_CENTER.key,{handler:this.configFixedCenter,value:H.FIXED_CENTER.value,validator:H.FIXED_CENTER.validator,supercedes:H.FIXED_CENTER.supercedes});this.cfg.addProperty(H.WIDTH.key,{handler:this.configWidth,suppressEvent:H.WIDTH.suppressEvent,supercedes:H.WIDTH.supercedes});this.cfg.addProperty(H.HEIGHT.key,{handler:this.configHeight,suppressEvent:H.HEIGHT.suppressEvent,supercedes:H.HEIGHT.supercedes});this.cfg.addProperty(H.ZINDEX.key,{handler:this.configzIndex,value:H.ZINDEX.value});this.cfg.addProperty(H.CONSTRAIN_TO_VIEWPORT.key,{handler:this.configConstrainToViewport,value:H.CONSTRAIN_TO_VIEWPORT.value,validator:H.CONS!
 TRAIN_TO_VIEWPORT.validator,supercedes:H.CONSTRAIN_TO_VIEWPORT.supercedes});this.cfg.addProperty(H.IFRAME.key,{handler:this.configIframe,value:H.IFRAME.value,validator:H.IFRAME.validator,supercedes:H.IFRAME.supercedes});},moveTo:function(K,L){this.cfg.setProperty("xy",[K,L]);},hideMacGeckoScrollbars:function(){D.removeClass(this.element,"show-scrollbars");D.addClass(this.element,"hide-scrollbars");},showMacGeckoScrollbars:function(){D.removeClass(this.element,"hide-scrollbars");D.addClass(this.element,"show-scrollbars");},configVisible:function(N,K,T){var M=K[0],O=D.getStyle(this.element,"visibility"),U=this.cfg.getProperty("effect"),R=[],Q=(this.platform=="mac"&&YAHOO.env.ua.gecko),b=C.alreadySubscribed,S,L,a,Y,X,W,Z,V,P;if(O=="inherit"){a=this.element.parentNode;while(a.nodeType!=9&&a.nodeType!=11){O=D.getStyle(a,"visibility");if(O!="inherit"){break;}a=a.parentNode;}if(O=="inherit"){O="visible";}}if(U){if(U instanceof Array){V=U.length;
-for(Y=0;Y<V;Y++){S=U[Y];R[R.length]=S.effect(this,S.duration);}}else{R[R.length]=U.effect(this,U.duration);}}if(M){if(Q){this.showMacGeckoScrollbars();}if(U){if(M){if(O!="visible"||O===""){this.beforeShowEvent.fire();P=R.length;for(X=0;X<P;X++){L=R[X];if(X===0&&!b(L.animateInCompleteEvent,this.showEvent.fire,this.showEvent)){L.animateInCompleteEvent.subscribe(this.showEvent.fire,this.showEvent,true);}L.animateIn();}}}}else{if(O!="visible"||O===""){this.beforeShowEvent.fire();D.setStyle(this.element,"visibility","visible");this.cfg.refireEvent("iframe");this.showEvent.fire();}}}else{if(Q){this.hideMacGeckoScrollbars();}if(U){if(O=="visible"){this.beforeHideEvent.fire();P=R.length;for(W=0;W<P;W++){Z=R[W];if(W===0&&!b(Z.animateOutCompleteEvent,this.hideEvent.fire,this.hideEvent)){Z.animateOutCompleteEvent.subscribe(this.hideEvent.fire,this.hideEvent,true);}Z.animateOut();}}else{if(O===""){D.setStyle(this.element,"visibility","hidden");}}}else{if(O=="visible"||O===""){this.befo!
 reHideEvent.fire();D.setStyle(this.element,"visibility","hidden");this.hideEvent.fire();}}}},doCenterOnDOMEvent:function(){if(this.cfg.getProperty("visible")){this.center();}},configFixedCenter:function(O,M,P){var Q=M[0],L=C.alreadySubscribed,N=B.windowResizeEvent,K=B.windowScrollEvent;if(Q){this.center();if(!L(this.beforeShowEvent,this.center,this)){this.beforeShowEvent.subscribe(this.center);}if(!L(N,this.doCenterOnDOMEvent,this)){N.subscribe(this.doCenterOnDOMEvent,this,true);}if(!L(K,this.doCenterOnDOMEvent,this)){K.subscribe(this.doCenterOnDOMEvent,this,true);}}else{this.beforeShowEvent.unsubscribe(this.center);N.unsubscribe(this.doCenterOnDOMEvent,this);K.unsubscribe(this.doCenterOnDOMEvent,this);}},configHeight:function(N,L,O){var K=L[0],M=this.element;D.setStyle(M,"height",K);this.cfg.refireEvent("iframe");},configWidth:function(N,K,O){var M=K[0],L=this.element;D.setStyle(L,"width",M);this.cfg.refireEvent("iframe");},configzIndex:function(M,K,N){var O=K[0],L=this.el!
 ement;if(!O){O=D.getStyle(L,"zIndex");if(!O||isNaN(O)){O=0;}}i!
 f(this.i
frame||this.cfg.getProperty("iframe")===true){if(O<=0){O=1;}}D.setStyle(L,"zIndex",O);this.cfg.setProperty("zIndex",O,true);if(this.iframe){this.stackIframe();}},configXY:function(M,L,N){var P=L[0],K=P[0],O=P[1];this.cfg.setProperty("x",K);this.cfg.setProperty("y",O);this.beforeMoveEvent.fire([K,O]);K=this.cfg.getProperty("x");O=this.cfg.getProperty("y");this.cfg.refireEvent("iframe");this.moveEvent.fire([K,O]);},configX:function(M,L,N){var K=L[0],O=this.cfg.getProperty("y");this.cfg.setProperty("x",K,true);this.cfg.setProperty("y",O,true);this.beforeMoveEvent.fire([K,O]);K=this.cfg.getProperty("x");O=this.cfg.getProperty("y");D.setX(this.element,K,true);this.cfg.setProperty("xy",[K,O],true);this.cfg.refireEvent("iframe");this.moveEvent.fire([K,O]);},configY:function(M,L,N){var K=this.cfg.getProperty("x"),O=L[0];this.cfg.setProperty("x",K,true);this.cfg.setProperty("y",O,true);this.beforeMoveEvent.fire([K,O]);K=this.cfg.getProperty("x");O=this.cfg.getProperty("y");D.setY(thi!
 s.element,O,true);this.cfg.setProperty("xy",[K,O],true);this.cfg.refireEvent("iframe");this.moveEvent.fire([K,O]);},showIframe:function(){var L=this.iframe,K;if(L){K=this.element.parentNode;if(K!=L.parentNode){this._addToParent(K,L);}L.style.display="block";}},hideIframe:function(){if(this.iframe){this.iframe.style.display="none";}},syncIframe:function(){var K=this.iframe,M=this.element,O=B.IFRAME_OFFSET,L=(O*2),N;if(K){K.style.width=(M.offsetWidth+L+"px");K.style.height=(M.offsetHeight+L+"px");N=this.cfg.getProperty("xy");if(!F.isArray(N)||(isNaN(N[0])||isNaN(N[1]))){this.syncPosition();N=this.cfg.getProperty("xy");}D.setXY(K,[(N[0]-O),(N[1]-O)]);}},stackIframe:function(){if(this.iframe){var K=D.getStyle(this.element,"zIndex");if(!YAHOO.lang.isUndefined(K)&&!isNaN(K)){D.setStyle(this.iframe,"zIndex",(K-1));}}},configIframe:function(N,M,O){var K=M[0];function P(){var R=this.iframe,S=this.element,T;if(!R){if(!G){G=document.createElement("iframe");if(this.isSecure){G.src=B.IF!
 RAME_SRC;}if(YAHOO.env.ua.ie){G.style.filter="alpha(opacity=0)!
 ";G.fram
eBorder=0;}else{G.style.opacity="0";}G.style.position="absolute";G.style.border="none";G.style.margin="0";G.style.padding="0";G.style.display="none";}R=G.cloneNode(false);T=S.parentNode;var Q=T||document.body;this._addToParent(Q,R);this.iframe=R;}this.showIframe();this.syncIframe();this.stackIframe();if(!this._hasIframeEventListeners){this.showEvent.subscribe(this.showIframe);this.hideEvent.subscribe(this.hideIframe);this.changeContentEvent.subscribe(this.syncIframe);this._hasIframeEventListeners=true;}}function L(){P.call(this);this.beforeShowEvent.unsubscribe(L);this._iframeDeferred=false;}if(K){if(this.cfg.getProperty("visible")){P.call(this);}else{if(!this._iframeDeferred){this.beforeShowEvent.subscribe(L);this._iframeDeferred=true;}}}else{this.hideIframe();if(this._hasIframeEventListeners){this.showEvent.unsubscribe(this.showIframe);this.hideEvent.unsubscribe(this.hideIframe);this.changeContentEvent.unsubscribe(this.syncIframe);this._hasIframeEventListeners=false;}}},co!
 nfigConstrainToViewport:function(M,K,N){function L(){if(YAHOO.lang.isUndefined(this.cfg.getProperty("xy"))){this.syncPosition();}var P=this.cfg.getProperty("x");var R=this.cfg.getProperty("y");var Q=this.getConstrainedXY(P,R);if(Q[0]!==P||Q[1]!==R){this.moveTo(Q[0],Q[1]);}}var O=K[0];if(O){if(!C.alreadySubscribed(this.beforeMoveEvent,this.enforceConstraints,this)){this.beforeMoveEvent.subscribe(this.enforceConstraints,this,true);}if(!C.alreadySubscribed(this.beforeShowEvent,L)){this.beforeShowEvent.subscribe(L);}}else{this.beforeShowEvent.unsubscribe(L);this.beforeMoveEvent.unsubscribe(this.enforceConstraints,this);}},configContext:function(M,L,O){var Q=L[0],N,P,K;if(Q){N=Q[0];P=Q[1];K=Q[2];if(N){if(typeof N=="string"){this.cfg.setProperty("context",[document.getElementById(N),P,K],true);}if(P&&K){this.align(P,K);}}}},align:function(L,K){var Q=this.cfg.getProperty("context"),P=this,O,N,R;function M(S,T){switch(L){case B.TOP_LEFT:P.moveTo(T,S);
-break;case B.TOP_RIGHT:P.moveTo((T-N.offsetWidth),S);break;case B.BOTTOM_LEFT:P.moveTo(T,(S-N.offsetHeight));break;case B.BOTTOM_RIGHT:P.moveTo((T-N.offsetWidth),(S-N.offsetHeight));break;}}if(Q){O=Q[0];N=this.element;P=this;if(!L){L=Q[1];}if(!K){K=Q[2];}if(N&&O){R=D.getRegion(O);switch(K){case B.TOP_LEFT:M(R.top,R.left);break;case B.TOP_RIGHT:M(R.top,R.right);break;case B.BOTTOM_LEFT:M(R.bottom,R.left);break;case B.BOTTOM_RIGHT:M(R.bottom,R.right);break;}}}},enforceConstraints:function(L,K,M){var O=K[0];var N=this.getConstrainedXY(O[0],O[1]);this.cfg.setProperty("x",N[0],true);this.cfg.setProperty("y",N[1],true);this.cfg.setProperty("xy",N,true);},getConstrainedXY:function(V,T){var N=B.VIEWPORT_OFFSET,U=D.getViewportWidth(),Q=D.getViewportHeight(),M=this.element.offsetHeight,S=this.element.offsetWidth,Y=D.getDocumentScrollLeft(),W=D.getDocumentScrollTop();var P=V;var L=T;if(S+N<U){var R=Y+N;var X=Y+U-S-N;if(V<R){P=R;}else{if(V>X){P=X;}}}else{P=N+Y;}if(M+N<Q){var O=W+N;var !
 K=W+Q-M-N;if(T<O){L=O;}else{if(T>K){L=K;}}}else{L=N+W;}return[P,L];},center:function(){var N=B.VIEWPORT_OFFSET,O=this.element.offsetWidth,M=this.element.offsetHeight,L=D.getViewportWidth(),P=D.getViewportHeight(),K,Q;if(O<L){K=(L/2)-(O/2)+D.getDocumentScrollLeft();}else{K=N+D.getDocumentScrollLeft();}if(M<P){Q=(P/2)-(M/2)+D.getDocumentScrollTop();}else{Q=N+D.getDocumentScrollTop();}this.cfg.setProperty("xy",[parseInt(K,10),parseInt(Q,10)]);this.cfg.refireEvent("iframe");},syncPosition:function(){var K=D.getXY(this.element);this.cfg.setProperty("x",K[0],true);this.cfg.setProperty("y",K[1],true);this.cfg.setProperty("xy",K,true);},onDomResize:function(M,L){var K=this;B.superclass.onDomResize.call(this,M,L);setTimeout(function(){K.syncPosition();K.cfg.refireEvent("iframe");K.cfg.refireEvent("context");},0);},bringToTop:function(){var O=[],N=this.element;function R(V,U){var X=D.getStyle(V,"zIndex"),W=D.getStyle(U,"zIndex"),T=(!X||isNaN(X))?0:parseInt(X,10),S=(!W||isNaN(W))?0:pa!
 rseInt(W,10);if(T>S){return -1;}else{if(T<S){return 1;}else{re!
 turn 0;}
}}function M(U){var S=D.hasClass(U,B.CSS_OVERLAY),T=YAHOO.widget.Panel;if(S&&!D.isAncestor(N,S)){if(T&&D.hasClass(U,T.CSS_PANEL)){O[O.length]=U.parentNode;}else{O[O.length]=U;}}}D.getElementsBy(M,"DIV",document.body);O.sort(R);var K=O[0],Q;if(K){Q=D.getStyle(K,"zIndex");if(!isNaN(Q)){var P=false;if(K!=N){P=true;}else{if(O.length>1){var L=D.getStyle(O[1],"zIndex");if(!isNaN(L)&&(Q==L)){P=true;}}}if(P){this.cfg.setProperty("zindex",(parseInt(Q,10)+2));}}}},destroy:function(){if(this.iframe){this.iframe.parentNode.removeChild(this.iframe);}this.iframe=null;B.windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent,this);B.windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent,this);B.superclass.destroy.call(this);},toString:function(){return"Overlay "+this.id;}});}());(function(){YAHOO.widget.OverlayManager=function(G){this.init(G);};var D=YAHOO.widget.Overlay,C=YAHOO.util.Event,E=YAHOO.util.Dom,B=YAHOO.util.Config,F=YAHOO.util.CustomEvent,A=YAHOO.widget.OverlayManager;A.CSS_FOCUSE!
 D="focused";A.prototype={constructor:A,overlays:null,initDefaultConfig:function(){this.cfg.addProperty("overlays",{suppressEvent:true});this.cfg.addProperty("focusevent",{value:"mousedown"});},init:function(I){this.cfg=new B(this);this.initDefaultConfig();if(I){this.cfg.applyConfig(I,true);}this.cfg.fireQueue();var H=null;this.getActive=function(){return H;};this.focus=function(J){var K=this.find(J);if(K){if(H!=K){if(H){H.blur();}this.bringToTop(K);H=K;E.addClass(H.element,A.CSS_FOCUSED);K.focusEvent.fire();}}};this.remove=function(K){var M=this.find(K),J;if(M){if(H==M){H=null;}var L=(M.element===null&&M.cfg===null)?true:false;if(!L){J=E.getStyle(M.element,"zIndex");M.cfg.setProperty("zIndex",-1000,true);}this.overlays.sort(this.compareZIndexDesc);this.overlays=this.overlays.slice(0,(this.overlays.length-1));M.hideEvent.unsubscribe(M.blur);M.destroyEvent.unsubscribe(this._onOverlayDestroy,M);if(!L){C.removeListener(M.element,this.cfg.getProperty("focusevent"),this._onOverla!
 yElementFocus);M.cfg.setProperty("zIndex",J,true);M.cfg.setPro!
 perty("m
anager",null);}M.focusEvent.unsubscribeAll();M.blurEvent.unsubscribeAll();M.focusEvent=null;M.blurEvent=null;M.focus=null;M.blur=null;}};this.blurAll=function(){var K=this.overlays.length,J;if(K>0){J=K-1;do{this.overlays[J].blur();}while(J--);}};this._onOverlayBlur=function(K,J){H=null;};var G=this.cfg.getProperty("overlays");if(!this.overlays){this.overlays=[];}if(G){this.register(G);this.overlays.sort(this.compareZIndexDesc);}},_onOverlayElementFocus:function(I){var G=C.getTarget(I),H=this.close;if(H&&(G==H||E.isAncestor(H,G))){this.blur();}else{this.focus();}},_onOverlayDestroy:function(H,G,I){this.remove(I);},register:function(G){var K=this,L,I,H,J;if(G instanceof D){G.cfg.addProperty("manager",{value:this});G.focusEvent=G.createEvent("focus");G.focusEvent.signature=F.LIST;G.blurEvent=G.createEvent("blur");G.blurEvent.signature=F.LIST;G.focus=function(){K.focus(this);};G.blur=function(){if(K.getActive()==this){E.removeClass(this.element,A.CSS_FOCUSED);this.blurEvent.fire!
 ();}};G.blurEvent.subscribe(K._onOverlayBlur);G.hideEvent.subscribe(G.blur);G.destroyEvent.subscribe(this._onOverlayDestroy,G,this);C.on(G.element,this.cfg.getProperty("focusevent"),this._onOverlayElementFocus,null,G);L=E.getStyle(G.element,"zIndex");if(!isNaN(L)){G.cfg.setProperty("zIndex",parseInt(L,10));}else{G.cfg.setProperty("zIndex",0);}this.overlays.push(G);this.bringToTop(G);return true;}else{if(G instanceof Array){I=0;J=G.length;for(H=0;H<J;H++){if(this.register(G[H])){I++;}}if(I>0){return true;}}else{return false;}}},bringToTop:function(M){var I=this.find(M),L,G,J;if(I){J=this.overlays;J.sort(this.compareZIndexDesc);G=J[0];if(G){L=E.getStyle(G.element,"zIndex");if(!isNaN(L)){var K=false;if(G!==I){K=true;}else{if(J.length>1){var H=E.getStyle(J[1].element,"zIndex");if(!isNaN(H)&&(L==H)){K=true;}}}if(K){I.cfg.setProperty("zindex",(parseInt(L,10)+2));}}J.sort(this.compareZIndexDesc);}}},find:function(G){var I=this.overlays,J=I.length,H;
-if(J>0){H=J-1;if(G instanceof D){do{if(I[H]==G){return I[H];}}while(H--);}else{if(typeof G=="string"){do{if(I[H].id==G){return I[H];}}while(H--);}}return null;}},compareZIndexDesc:function(J,I){var H=(J.cfg)?J.cfg.getProperty("zIndex"):null,G=(I.cfg)?I.cfg.getProperty("zIndex"):null;if(H===null&&G===null){return 0;}else{if(H===null){return 1;}else{if(G===null){return -1;}else{if(H>G){return -1;}else{if(H<G){return 1;}else{return 0;}}}}}},showAll:function(){var H=this.overlays,I=H.length,G;if(I>0){G=I-1;do{H[G].show();}while(G--);}},hideAll:function(){var H=this.overlays,I=H.length,G;if(I>0){G=I-1;do{H[G].hide();}while(G--);}},toString:function(){return"OverlayManager";}};}());(function(){YAHOO.widget.ContainerEffect=function(F,I,H,E,G){if(!G){G=YAHOO.util.Anim;}this.overlay=F;this.attrIn=I;this.attrOut=H;this.targetElement=E||F.element;this.animClass=G;};var B=YAHOO.util.Dom,D=YAHOO.util.CustomEvent,C=YAHOO.util.Easing,A=YAHOO.widget.ContainerEffect;A.FADE=function(E,G){var!
  I={attributes:{opacity:{from:0,to:1}},duration:G,method:C.easeIn};var F={attributes:{opacity:{to:0}},duration:G,method:C.easeOut};var H=new A(E,I,F,E.element);H.handleUnderlayStart=function(){var K=this.overlay.underlay;if(K&&YAHOO.env.ua.ie){var J=(K.filters&&K.filters.length>0);if(J){B.addClass(E.element,"yui-effect-fade");}}};H.handleUnderlayComplete=function(){var J=this.overlay.underlay;if(J&&YAHOO.env.ua.ie){B.removeClass(E.element,"yui-effect-fade");}};H.handleStartAnimateIn=function(K,J,L){B.addClass(L.overlay.element,"hide-select");if(!L.overlay.underlay){L.overlay.cfg.refireEvent("underlay");}L.handleUnderlayStart();B.setStyle(L.overlay.element,"visibility","visible");B.setStyle(L.overlay.element,"opacity",0);};H.handleCompleteAnimateIn=function(K,J,L){B.removeClass(L.overlay.element,"hide-select");if(L.overlay.element.style.filter){L.overlay.element.style.filter=null;}L.handleUnderlayComplete();L.overlay.cfg.refireEvent("iframe");L.animateInCompleteEvent.fire();!
 };H.handleStartAnimateOut=function(K,J,L){B.addClass(L.overlay!
 .element
,"hide-select");L.handleUnderlayStart();};H.handleCompleteAnimateOut=function(K,J,L){B.removeClass(L.overlay.element,"hide-select");if(L.overlay.element.style.filter){L.overlay.element.style.filter=null;}B.setStyle(L.overlay.element,"visibility","hidden");B.setStyle(L.overlay.element,"opacity",1);L.handleUnderlayComplete();L.overlay.cfg.refireEvent("iframe");L.animateOutCompleteEvent.fire();};H.init();return H;};A.SLIDE=function(G,I){var F=G.cfg.getProperty("x")||B.getX(G.element),K=G.cfg.getProperty("y")||B.getY(G.element),J=B.getClientWidth(),H=G.element.offsetWidth,E=new A(G,{attributes:{points:{to:[F,K]}},duration:I,method:C.easeIn},{attributes:{points:{to:[(J+25),K]}},duration:I,method:C.easeOut},G.element,YAHOO.util.Motion);E.handleStartAnimateIn=function(M,L,N){N.overlay.element.style.left=((-25)-H)+"px";N.overlay.element.style.top=K+"px";};E.handleTweenAnimateIn=function(O,N,P){var Q=B.getXY(P.overlay.element),M=Q[0],L=Q[1];if(B.getStyle(P.overlay.element,"visibility!
 ")=="hidden"&&M<F){B.setStyle(P.overlay.element,"visibility","visible");}P.overlay.cfg.setProperty("xy",[M,L],true);P.overlay.cfg.refireEvent("iframe");};E.handleCompleteAnimateIn=function(M,L,N){N.overlay.cfg.setProperty("xy",[F,K],true);N.startX=F;N.startY=K;N.overlay.cfg.refireEvent("iframe");N.animateInCompleteEvent.fire();};E.handleStartAnimateOut=function(M,L,P){var N=B.getViewportWidth(),Q=B.getXY(P.overlay.element),O=Q[1];P.animOut.attributes.points.to=[(N+25),O];};E.handleTweenAnimateOut=function(N,M,O){var Q=B.getXY(O.overlay.element),L=Q[0],P=Q[1];O.overlay.cfg.setProperty("xy",[L,P],true);O.overlay.cfg.refireEvent("iframe");};E.handleCompleteAnimateOut=function(M,L,N){B.setStyle(N.overlay.element,"visibility","hidden");N.overlay.cfg.setProperty("xy",[F,K]);N.animateOutCompleteEvent.fire();};E.init();return E;};A.prototype={init:function(){this.beforeAnimateInEvent=this.createEvent("beforeAnimateIn");this.beforeAnimateInEvent.signature=D.LIST;this.beforeAnimateOu!
 tEvent=this.createEvent("beforeAnimateOut");this.beforeAnimate!
 OutEvent
.signature=D.LIST;this.animateInCompleteEvent=this.createEvent("animateInComplete");this.animateInCompleteEvent.signature=D.LIST;this.animateOutCompleteEvent=this.createEvent("animateOutComplete");this.animateOutCompleteEvent.signature=D.LIST;this.animIn=new this.animClass(this.targetElement,this.attrIn.attributes,this.attrIn.duration,this.attrIn.method);this.animIn.onStart.subscribe(this.handleStartAnimateIn,this);this.animIn.onTween.subscribe(this.handleTweenAnimateIn,this);this.animIn.onComplete.subscribe(this.handleCompleteAnimateIn,this);this.animOut=new this.animClass(this.targetElement,this.attrOut.attributes,this.attrOut.duration,this.attrOut.method);this.animOut.onStart.subscribe(this.handleStartAnimateOut,this);this.animOut.onTween.subscribe(this.handleTweenAnimateOut,this);this.animOut.onComplete.subscribe(this.handleCompleteAnimateOut,this);},animateIn:function(){this.beforeAnimateInEvent.fire();this.animIn.animate();},animateOut:function(){this.beforeAnimateOutE!
 vent.fire();this.animOut.animate();},handleStartAnimateIn:function(F,E,G){},handleTweenAnimateIn:function(F,E,G){},handleCompleteAnimateIn:function(F,E,G){},handleStartAnimateOut:function(F,E,G){},handleTweenAnimateOut:function(F,E,G){},handleCompleteAnimateOut:function(F,E,G){},toString:function(){var E="ContainerEffect";if(this.overlay){E+=" ["+this.overlay.toString()+"]";}return E;}};YAHOO.lang.augmentProto(A,YAHOO.util.EventProvider);})();YAHOO.register("containercore",YAHOO.widget.Module,{version:"2.4.1",build:"742"});
\ No newline at end of file
+(function(){YAHOO.util.Config=function(D){if(D){this.init(D);}};var B=YAHOO.lang,C=YAHOO.util.CustomEvent,A=YAHOO.util.Config;A.CONFIG_CHANGED_EVENT="configChanged";A.BOOLEAN_TYPE="boolean";A.prototype={owner:null,queueInProgress:false,config:null,initialConfig:null,eventQueue:null,configChangedEvent:null,init:function(D){this.owner=D;this.configChangedEvent=this.createEvent(A.CONFIG_CHANGED_EVENT);this.configChangedEvent.signature=C.LIST;this.queueInProgress=false;this.config={};this.initialConfig={};this.eventQueue=[];},checkBoolean:function(D){return(typeof D==A.BOOLEAN_TYPE);},checkNumber:function(D){return(!isNaN(D));},fireEvent:function(D,F){var E=this.config[D];if(E&&E.event){E.event.fire(F);}},addProperty:function(E,D){E=E.toLowerCase();this.config[E]=D;D.event=this.createEvent(E,{scope:this.owner});D.event.signature=C.LIST;D.key=E;if(D.handler){D.event.subscribe(D.handler,this.owner);}this.setProperty(E,D.value,true);if(!D.suppressEvent){this.queueProperty(E,D.valu!
 e);}},getConfig:function(){var D={},F,E;for(F in this.config){E=this.config[F];if(E&&E.event){D[F]=E.value;}}return D;},getProperty:function(D){var E=this.config[D.toLowerCase()];if(E&&E.event){return E.value;}else{return undefined;}},resetProperty:function(D){D=D.toLowerCase();var E=this.config[D];if(E&&E.event){if(this.initialConfig[D]&&!B.isUndefined(this.initialConfig[D])){this.setProperty(D,this.initialConfig[D]);return true;}}else{return false;}},setProperty:function(E,G,D){var F;E=E.toLowerCase();if(this.queueInProgress&&!D){this.queueProperty(E,G);return true;}else{F=this.config[E];if(F&&F.event){if(F.validator&&!F.validator(G)){return false;}else{F.value=G;if(!D){this.fireEvent(E,G);this.configChangedEvent.fire([E,G]);}return true;}}else{return false;}}},queueProperty:function(S,P){S=S.toLowerCase();var R=this.config[S],K=false,J,G,H,I,O,Q,F,M,N,D,L,T,E;if(R&&R.event){if(!B.isUndefined(P)&&R.validator&&!R.validator(P)){return false;}else{if(!B.isUndefined(P)){R.val!
 ue=P;}else{P=R.value;}K=false;J=this.eventQueue.length;for(L=0!
 ;L<J;L++
){G=this.eventQueue[L];if(G){H=G[0];I=G[1];if(H==S){this.eventQueue[L]=null;this.eventQueue.push([S,(!B.isUndefined(P)?P:I)]);K=true;break;}}}if(!K&&!B.isUndefined(P)){this.eventQueue.push([S,P]);}}if(R.supercedes){O=R.supercedes.length;for(T=0;T<O;T++){Q=R.supercedes[T];F=this.eventQueue.length;for(E=0;E<F;E++){M=this.eventQueue[E];if(M){N=M[0];D=M[1];if(N==Q.toLowerCase()){this.eventQueue.push([N,D]);this.eventQueue[E]=null;break;}}}}}return true;}else{return false;}},refireEvent:function(D){D=D.toLowerCase();var E=this.config[D];if(E&&E.event&&!B.isUndefined(E.value)){if(this.queueInProgress){this.queueProperty(D);}else{this.fireEvent(D,E.value);}}},applyConfig:function(D,G){var F,E;if(G){E={};for(F in D){if(B.hasOwnProperty(D,F)){E[F.toLowerCase()]=D[F];}}this.initialConfig=E;}for(F in D){if(B.hasOwnProperty(D,F)){this.queueProperty(F,D[F]);}}},refresh:function(){var D;for(D in this.config){this.refireEvent(D);}},fireQueue:function(){var E,H,D,G,F;this.queueInProgress=tr!
 ue;for(E=0;E<this.eventQueue.length;E++){H=this.eventQueue[E];if(H){D=H[0];G=H[1];F=this.config[D];F.value=G;this.fireEvent(D,G);}}this.queueInProgress=false;this.eventQueue=[];},subscribeToConfigEvent:function(E,F,H,D){var G=this.config[E.toLowerCase()];if(G&&G.event){if(!A.alreadySubscribed(G.event,F,H)){G.event.subscribe(F,H,D);}return true;}else{return false;}},unsubscribeFromConfigEvent:function(D,E,G){var F=this.config[D.toLowerCase()];if(F&&F.event){return F.event.unsubscribe(E,G);}else{return false;}},toString:function(){var D="Config";if(this.owner){D+=" ["+this.owner.toString()+"]";}return D;},outputEventQueue:function(){var D="",G,E,F=this.eventQueue.length;for(E=0;E<F;E++){G=this.eventQueue[E];if(G){D+=G[0]+"="+G[1]+", ";}}return D;},destroy:function(){var E=this.config,D,F;for(D in E){if(B.hasOwnProperty(E,D)){F=E[D];F.event.unsubscribeAll();F.event=null;}}this.configChangedEvent.unsubscribeAll();this.configChangedEvent=null;this.owner=null;this.config=null;thi!
 s.initialConfig=null;this.eventQueue=null;}};A.alreadySubscrib!
 ed=funct
ion(E,H,I){var F=E.subscribers.length,D,G;if(F>0){G=F-1;do{D=E.subscribers[G];if(D&&D.obj==I&&D.fn==H){return true;}}while(G--);}return false;};YAHOO.lang.augmentProto(A,YAHOO.util.EventProvider);}());(function(){YAHOO.widget.Module=function(Q,P){if(Q){this.init(Q,P);}else{}};var F=YAHOO.util.Dom,D=YAHOO.util.Config,M=YAHOO.util.Event,L=YAHOO.util.CustomEvent,G=YAHOO.widget.Module,H,O,N,E,A={"BEFORE_INIT":"beforeInit","INIT":"init","APPEND":"append","BEFORE_RENDER":"beforeRender","RENDER":"render","CHANGE_HEADER":"changeHeader","CHANGE_BODY":"changeBody","CHANGE_FOOTER":"changeFooter","CHANGE_CONTENT":"changeContent","DESTORY":"destroy","BEFORE_SHOW":"beforeShow","SHOW":"show","BEFORE_HIDE":"beforeHide","HIDE":"hide"},I={"VISIBLE":{key:"visible",value:true,validator:YAHOO.lang.isBoolean},"EFFECT":{key:"effect",suppressEvent:true,supercedes:["visible"]},"MONITOR_RESIZE":{key:"monitorresize",value:true},"APPEND_TO_DOCUMENT_BODY":{key:"appendtodocumentbody",value:false}};G.IMG_!
 ROOT=null;G.IMG_ROOT_SSL=null;G.CSS_MODULE="yui-module";G.CSS_HEADER="hd";G.CSS_BODY="bd";G.CSS_FOOTER="ft";G.RESIZE_MONITOR_SECURE_URL="javascript:false;";G.textResizeEvent=new L("textResize");function K(){if(!H){H=document.createElement("div");H.innerHTML=('<div class="'+G.CSS_HEADER+'"></div>'+'<div class="'+G.CSS_BODY+'"></div><div class="'+G.CSS_FOOTER+'"></div>');O=H.firstChild;N=O.nextSibling;E=N.nextSibling;}return H;}function J(){if(!O){K();}return(O.cloneNode(false));}function B(){if(!N){K();}return(N.cloneNode(false));}function C(){if(!E){K();}return(E.cloneNode(false));}G.prototype={constructor:G,element:null,header:null,body:null,footer:null,id:null,imageRoot:G.IMG_ROOT,initEvents:function(){var P=L.LIST;this.beforeInitEvent=this.createEvent(A.BEFORE_INIT);this.beforeInitEvent.signature=P;this.initEvent=this.createEvent(A.INIT);this.initEvent.signature=P;this.appendEvent=this.createEvent(A.APPEND);
+this.appendEvent.signature=P;this.beforeRenderEvent=this.createEvent(A.BEFORE_RENDER);this.beforeRenderEvent.signature=P;this.renderEvent=this.createEvent(A.RENDER);this.renderEvent.signature=P;this.changeHeaderEvent=this.createEvent(A.CHANGE_HEADER);this.changeHeaderEvent.signature=P;this.changeBodyEvent=this.createEvent(A.CHANGE_BODY);this.changeBodyEvent.signature=P;this.changeFooterEvent=this.createEvent(A.CHANGE_FOOTER);this.changeFooterEvent.signature=P;this.changeContentEvent=this.createEvent(A.CHANGE_CONTENT);this.changeContentEvent.signature=P;this.destroyEvent=this.createEvent(A.DESTORY);this.destroyEvent.signature=P;this.beforeShowEvent=this.createEvent(A.BEFORE_SHOW);this.beforeShowEvent.signature=P;this.showEvent=this.createEvent(A.SHOW);this.showEvent.signature=P;this.beforeHideEvent=this.createEvent(A.BEFORE_HIDE);this.beforeHideEvent.signature=P;this.hideEvent=this.createEvent(A.HIDE);this.hideEvent.signature=P;},platform:function(){var P=navigator.userAgent!
 .toLowerCase();if(P.indexOf("windows")!=-1||P.indexOf("win32")!=-1){return"windows";}else{if(P.indexOf("macintosh")!=-1){return"mac";}else{return false;}}}(),browser:function(){var P=navigator.userAgent.toLowerCase();if(P.indexOf("opera")!=-1){return"opera";}else{if(P.indexOf("msie 7")!=-1){return"ie7";}else{if(P.indexOf("msie")!=-1){return"ie";}else{if(P.indexOf("safari")!=-1){return"safari";}else{if(P.indexOf("gecko")!=-1){return"gecko";}else{return false;}}}}}}(),isSecure:function(){if(window.location.href.toLowerCase().indexOf("https")===0){return true;}else{return false;}}(),initDefaultConfig:function(){this.cfg.addProperty(I.VISIBLE.key,{handler:this.configVisible,value:I.VISIBLE.value,validator:I.VISIBLE.validator});this.cfg.addProperty(I.EFFECT.key,{suppressEvent:I.EFFECT.suppressEvent,supercedes:I.EFFECT.supercedes});this.cfg.addProperty(I.MONITOR_RESIZE.key,{handler:this.configMonitorResize,value:I.MONITOR_RESIZE.value});this.cfg.addProperty(I.APPEND_TO_DOCUMENT_B!
 ODY.key,{value:I.APPEND_TO_DOCUMENT_BODY.value});},init:functi!
 on(U,T){
var R,V;this.initEvents();this.beforeInitEvent.fire(G);this.cfg=new D(this);if(this.isSecure){this.imageRoot=G.IMG_ROOT_SSL;}if(typeof U=="string"){R=U;U=document.getElementById(U);if(!U){U=(K()).cloneNode(false);U.id=R;}}this.element=U;if(U.id){this.id=U.id;}V=this.element.firstChild;if(V){var Q=false,P=false,S=false;do{if(1==V.nodeType){if(!Q&&F.hasClass(V,G.CSS_HEADER)){this.header=V;Q=true;}else{if(!P&&F.hasClass(V,G.CSS_BODY)){this.body=V;P=true;}else{if(!S&&F.hasClass(V,G.CSS_FOOTER)){this.footer=V;S=true;}}}}}while((V=V.nextSibling));}this.initDefaultConfig();F.addClass(this.element,G.CSS_MODULE);if(T){this.cfg.applyConfig(T,true);}if(!D.alreadySubscribed(this.renderEvent,this.cfg.fireQueue,this.cfg)){this.renderEvent.subscribe(this.cfg.fireQueue,this.cfg,true);}this.initEvent.fire(G);},initResizeMonitor:function(){var Q=(YAHOO.env.ua.gecko&&this.platform=="windows");if(Q){var P=this;setTimeout(function(){P._initResizeMonitor();},0);}else{this._initResizeMonitor();}},!
 _initResizeMonitor:function(){var P,R,T;function V(){G.textResizeEvent.fire();}if(!YAHOO.env.ua.opera){R=F.get("_yuiResizeMonitor");var U=this._supportsCWResize();if(!R){R=document.createElement("iframe");if(this.isSecure&&G.RESIZE_MONITOR_SECURE_URL&&YAHOO.env.ua.ie){R.src=G.RESIZE_MONITOR_SECURE_URL;}if(!U){T=["<html><head><script ",'type="text/javascript">',"window.onresize=function(){window.parent.","YAHOO.widget.Module.textResizeEvent.","fire();};<","/script></head>","<body></body></html>"].join("");R.src="data:text/html;charset=utf-8,"+encodeURIComponent(T);}R.id="_yuiResizeMonitor";R.style.position="absolute";R.style.visibility="hidden";var Q=document.body,S=Q.firstChild;if(S){Q.insertBefore(R,S);}else{Q.appendChild(R);}R.style.width="10em";R.style.height="10em";R.style.top=(-1*R.offsetHeight)+"px";R.style.left=(-1*R.offsetWidth)+"px";R.style.borderWidth="0";R.style.visibility="visible";if(YAHOO.env.ua.webkit){P=R.contentWindow.document;P.open();P.close();}}if(R&&R.c!
 ontentWindow){G.textResizeEvent.subscribe(this.onDomResize,thi!
 s,true);
if(!G.textResizeInitialized){if(U){if(!M.on(R.contentWindow,"resize",V)){M.on(R,"resize",V);}}G.textResizeInitialized=true;}this.resizeMonitor=R;}}},_supportsCWResize:function(){var P=true;if(YAHOO.env.ua.gecko&&YAHOO.env.ua.gecko<=1.8){P=false;}return P;},onDomResize:function(S,R){var Q=-1*this.resizeMonitor.offsetWidth,P=-1*this.resizeMonitor.offsetHeight;this.resizeMonitor.style.top=P+"px";this.resizeMonitor.style.left=Q+"px";},setHeader:function(Q){var P=this.header||(this.header=J());if(Q.nodeName){P.innerHTML="";P.appendChild(Q);}else{P.innerHTML=Q;}this.changeHeaderEvent.fire(Q);this.changeContentEvent.fire();},appendToHeader:function(Q){var P=this.header||(this.header=J());P.appendChild(Q);this.changeHeaderEvent.fire(Q);this.changeContentEvent.fire();},setBody:function(Q){var P=this.body||(this.body=B());if(Q.nodeName){P.innerHTML="";P.appendChild(Q);}else{P.innerHTML=Q;}this.changeBodyEvent.fire(Q);this.changeContentEvent.fire();},appendToBody:function(Q){var P=this!
 .body||(this.body=B());P.appendChild(Q);this.changeBodyEvent.fire(Q);this.changeContentEvent.fire();},setFooter:function(Q){var P=this.footer||(this.footer=C());if(Q.nodeName){P.innerHTML="";P.appendChild(Q);}else{P.innerHTML=Q;}this.changeFooterEvent.fire(Q);this.changeContentEvent.fire();},appendToFooter:function(Q){var P=this.footer||(this.footer=C());P.appendChild(Q);this.changeFooterEvent.fire(Q);this.changeContentEvent.fire();},render:function(R,P){var S=this,T;function Q(U){if(typeof U=="string"){U=document.getElementById(U);}if(U){S._addToParent(U,S.element);S.appendEvent.fire();}}this.beforeRenderEvent.fire();if(!P){P=this.element;}if(R){Q(R);}else{if(!F.inDocument(this.element)){return false;}}if(this.header&&!F.inDocument(this.header)){T=P.firstChild;if(T){P.insertBefore(this.header,T);}else{P.appendChild(this.header);}}if(this.body&&!F.inDocument(this.body)){if(this.footer&&F.isAncestor(this.moduleElement,this.footer)){P.insertBefore(this.body,this.footer);
+}else{P.appendChild(this.body);}}if(this.footer&&!F.inDocument(this.footer)){P.appendChild(this.footer);}this.renderEvent.fire();return true;},destroy:function(){var P,Q;if(this.element){M.purgeElement(this.element,true);P=this.element.parentNode;}if(P){P.removeChild(this.element);}this.element=null;this.header=null;this.body=null;this.footer=null;G.textResizeEvent.unsubscribe(this.onDomResize,this);this.cfg.destroy();this.cfg=null;this.destroyEvent.fire();for(Q in this){if(Q instanceof L){Q.unsubscribeAll();}}},show:function(){this.cfg.setProperty("visible",true);},hide:function(){this.cfg.setProperty("visible",false);},configVisible:function(Q,P,R){var S=P[0];if(S){this.beforeShowEvent.fire();F.setStyle(this.element,"display","block");this.showEvent.fire();}else{this.beforeHideEvent.fire();F.setStyle(this.element,"display","none");this.hideEvent.fire();}},configMonitorResize:function(R,Q,S){var P=Q[0];if(P){this.initResizeMonitor();}else{G.textResizeEvent.unsubscribe(this!
 .onDomResize,this,true);this.resizeMonitor=null;}},_addToParent:function(P,Q){if(!this.cfg.getProperty("appendtodocumentbody")&&P===document.body&&P.firstChild){P.insertBefore(Q,P.firstChild);}else{P.appendChild(Q);}},toString:function(){return"Module "+this.id;}};YAHOO.lang.augmentProto(G,YAHOO.util.EventProvider);}());(function(){YAHOO.widget.Overlay=function(L,K){YAHOO.widget.Overlay.superclass.constructor.call(this,L,K);};var F=YAHOO.lang,I=YAHOO.util.CustomEvent,E=YAHOO.widget.Module,J=YAHOO.util.Event,D=YAHOO.util.Dom,C=YAHOO.util.Config,B=YAHOO.widget.Overlay,G,A={"BEFORE_MOVE":"beforeMove","MOVE":"move"},H={"X":{key:"x",validator:F.isNumber,suppressEvent:true,supercedes:["iframe"]},"Y":{key:"y",validator:F.isNumber,suppressEvent:true,supercedes:["iframe"]},"XY":{key:"xy",suppressEvent:true,supercedes:["iframe"]},"CONTEXT":{key:"context",suppressEvent:true,supercedes:["iframe"]},"FIXED_CENTER":{key:"fixedcenter",value:false,validator:F.isBoolean,supercedes:["iframe",!
 "visible"]},"WIDTH":{key:"width",suppressEvent:true,supercedes!
 :["conte
xt","fixedcenter","iframe"]},"HEIGHT":{key:"height",suppressEvent:true,supercedes:["context","fixedcenter","iframe"]},"ZINDEX":{key:"zindex",value:null},"CONSTRAIN_TO_VIEWPORT":{key:"constraintoviewport",value:false,validator:F.isBoolean,supercedes:["iframe","x","y","xy"]},"IFRAME":{key:"iframe",value:(YAHOO.env.ua.ie==6?true:false),validator:F.isBoolean,supercedes:["zindex"]}};B.IFRAME_SRC="javascript:false;";B.IFRAME_OFFSET=3;B.VIEWPORT_OFFSET=10;B.TOP_LEFT="tl";B.TOP_RIGHT="tr";B.BOTTOM_LEFT="bl";B.BOTTOM_RIGHT="br";B.CSS_OVERLAY="yui-overlay";B.windowScrollEvent=new I("windowScroll");B.windowResizeEvent=new I("windowResize");B.windowScrollHandler=function(K){if(YAHOO.env.ua.ie){if(!window.scrollEnd){window.scrollEnd=-1;}clearTimeout(window.scrollEnd);window.scrollEnd=setTimeout(function(){B.windowScrollEvent.fire();},1);}else{B.windowScrollEvent.fire();}};B.windowResizeHandler=function(K){if(YAHOO.env.ua.ie){if(!window.resizeEnd){window.resizeEnd=-1;}clearTimeout(window.!
 resizeEnd);window.resizeEnd=setTimeout(function(){B.windowResizeEvent.fire();},100);}else{B.windowResizeEvent.fire();}};B._initialized=null;if(B._initialized===null){J.on(window,"scroll",B.windowScrollHandler);J.on(window,"resize",B.windowResizeHandler);B._initialized=true;}YAHOO.extend(B,E,{init:function(L,K){B.superclass.init.call(this,L);this.beforeInitEvent.fire(B);D.addClass(this.element,B.CSS_OVERLAY);if(K){this.cfg.applyConfig(K,true);}if(this.platform=="mac"&&YAHOO.env.ua.gecko){if(!C.alreadySubscribed(this.showEvent,this.showMacGeckoScrollbars,this)){this.showEvent.subscribe(this.showMacGeckoScrollbars,this,true);}if(!C.alreadySubscribed(this.hideEvent,this.hideMacGeckoScrollbars,this)){this.hideEvent.subscribe(this.hideMacGeckoScrollbars,this,true);}}this.initEvent.fire(B);},initEvents:function(){B.superclass.initEvents.call(this);var K=I.LIST;this.beforeMoveEvent=this.createEvent(A.BEFORE_MOVE);this.beforeMoveEvent.signature=K;this.moveEvent=this.createEvent(A.MO!
 VE);this.moveEvent.signature=K;},initDefaultConfig:function(){!
 B.superc
lass.initDefaultConfig.call(this);this.cfg.addProperty(H.X.key,{handler:this.configX,validator:H.X.validator,suppressEvent:H.X.suppressEvent,supercedes:H.X.supercedes});this.cfg.addProperty(H.Y.key,{handler:this.configY,validator:H.Y.validator,suppressEvent:H.Y.suppressEvent,supercedes:H.Y.supercedes});this.cfg.addProperty(H.XY.key,{handler:this.configXY,suppressEvent:H.XY.suppressEvent,supercedes:H.XY.supercedes});this.cfg.addProperty(H.CONTEXT.key,{handler:this.configContext,suppressEvent:H.CONTEXT.suppressEvent,supercedes:H.CONTEXT.supercedes});this.cfg.addProperty(H.FIXED_CENTER.key,{handler:this.configFixedCenter,value:H.FIXED_CENTER.value,validator:H.FIXED_CENTER.validator,supercedes:H.FIXED_CENTER.supercedes});this.cfg.addProperty(H.WIDTH.key,{handler:this.configWidth,suppressEvent:H.WIDTH.suppressEvent,supercedes:H.WIDTH.supercedes});this.cfg.addProperty(H.HEIGHT.key,{handler:this.configHeight,suppressEvent:H.HEIGHT.suppressEvent,supercedes:H.HEIGHT.supercedes});this!
 .cfg.addProperty(H.ZINDEX.key,{handler:this.configzIndex,value:H.ZINDEX.value});this.cfg.addProperty(H.CONSTRAIN_TO_VIEWPORT.key,{handler:this.configConstrainToViewport,value:H.CONSTRAIN_TO_VIEWPORT.value,validator:H.CONSTRAIN_TO_VIEWPORT.validator,supercedes:H.CONSTRAIN_TO_VIEWPORT.supercedes});this.cfg.addProperty(H.IFRAME.key,{handler:this.configIframe,value:H.IFRAME.value,validator:H.IFRAME.validator,supercedes:H.IFRAME.supercedes});},moveTo:function(K,L){this.cfg.setProperty("xy",[K,L]);},hideMacGeckoScrollbars:function(){D.removeClass(this.element,"show-scrollbars");D.addClass(this.element,"hide-scrollbars");},showMacGeckoScrollbars:function(){D.removeClass(this.element,"hide-scrollbars");D.addClass(this.element,"show-scrollbars");},configVisible:function(N,K,T){var M=K[0],O=D.getStyle(this.element,"visibility"),U=this.cfg.getProperty("effect"),R=[],Q=(this.platform=="mac"&&YAHOO.env.ua.gecko),b=C.alreadySubscribed,S,L,a,Y,X,W,Z,V,P;
+if(O=="inherit"){a=this.element.parentNode;while(a.nodeType!=9&&a.nodeType!=11){O=D.getStyle(a,"visibility");if(O!="inherit"){break;}a=a.parentNode;}if(O=="inherit"){O="visible";}}if(U){if(U instanceof Array){V=U.length;for(Y=0;Y<V;Y++){S=U[Y];R[R.length]=S.effect(this,S.duration);}}else{R[R.length]=U.effect(this,U.duration);}}if(M){if(Q){this.showMacGeckoScrollbars();}if(U){if(M){if(O!="visible"||O===""){this.beforeShowEvent.fire();P=R.length;for(X=0;X<P;X++){L=R[X];if(X===0&&!b(L.animateInCompleteEvent,this.showEvent.fire,this.showEvent)){L.animateInCompleteEvent.subscribe(this.showEvent.fire,this.showEvent,true);}L.animateIn();}}}}else{if(O!="visible"||O===""){this.beforeShowEvent.fire();D.setStyle(this.element,"visibility","visible");this.cfg.refireEvent("iframe");this.showEvent.fire();}}}else{if(Q){this.hideMacGeckoScrollbars();}if(U){if(O=="visible"){this.beforeHideEvent.fire();P=R.length;for(W=0;W<P;W++){Z=R[W];if(W===0&&!b(Z.animateOutCompleteEvent,this.hideEvent.fi!
 re,this.hideEvent)){Z.animateOutCompleteEvent.subscribe(this.hideEvent.fire,this.hideEvent,true);}Z.animateOut();}}else{if(O===""){D.setStyle(this.element,"visibility","hidden");}}}else{if(O=="visible"||O===""){this.beforeHideEvent.fire();D.setStyle(this.element,"visibility","hidden");this.hideEvent.fire();}}}},doCenterOnDOMEvent:function(){if(this.cfg.getProperty("visible")){this.center();}},configFixedCenter:function(O,M,P){var Q=M[0],L=C.alreadySubscribed,N=B.windowResizeEvent,K=B.windowScrollEvent;if(Q){this.center();if(!L(this.beforeShowEvent,this.center,this)){this.beforeShowEvent.subscribe(this.center);}if(!L(N,this.doCenterOnDOMEvent,this)){N.subscribe(this.doCenterOnDOMEvent,this,true);}if(!L(K,this.doCenterOnDOMEvent,this)){K.subscribe(this.doCenterOnDOMEvent,this,true);}}else{this.beforeShowEvent.unsubscribe(this.center);N.unsubscribe(this.doCenterOnDOMEvent,this);K.unsubscribe(this.doCenterOnDOMEvent,this);}},configHeight:function(N,L,O){var K=L[0],M=this.elemen!
 t;D.setStyle(M,"height",K);this.cfg.refireEvent("iframe");},co!
 nfigWidt
h:function(N,K,O){var M=K[0],L=this.element;D.setStyle(L,"width",M);this.cfg.refireEvent("iframe");},configzIndex:function(M,K,N){var O=K[0],L=this.element;if(!O){O=D.getStyle(L,"zIndex");if(!O||isNaN(O)){O=0;}}if(this.iframe||this.cfg.getProperty("iframe")===true){if(O<=0){O=1;}}D.setStyle(L,"zIndex",O);this.cfg.setProperty("zIndex",O,true);if(this.iframe){this.stackIframe();}},configXY:function(M,L,N){var P=L[0],K=P[0],O=P[1];this.cfg.setProperty("x",K);this.cfg.setProperty("y",O);this.beforeMoveEvent.fire([K,O]);K=this.cfg.getProperty("x");O=this.cfg.getProperty("y");this.cfg.refireEvent("iframe");this.moveEvent.fire([K,O]);},configX:function(M,L,N){var K=L[0],O=this.cfg.getProperty("y");this.cfg.setProperty("x",K,true);this.cfg.setProperty("y",O,true);this.beforeMoveEvent.fire([K,O]);K=this.cfg.getProperty("x");O=this.cfg.getProperty("y");D.setX(this.element,K,true);this.cfg.setProperty("xy",[K,O],true);this.cfg.refireEvent("iframe");this.moveEvent.fire([K,O]);},configY:!
 function(M,L,N){var K=this.cfg.getProperty("x"),O=L[0];this.cfg.setProperty("x",K,true);this.cfg.setProperty("y",O,true);this.beforeMoveEvent.fire([K,O]);K=this.cfg.getProperty("x");O=this.cfg.getProperty("y");D.setY(this.element,O,true);this.cfg.setProperty("xy",[K,O],true);this.cfg.refireEvent("iframe");this.moveEvent.fire([K,O]);},showIframe:function(){var L=this.iframe,K;if(L){K=this.element.parentNode;if(K!=L.parentNode){this._addToParent(K,L);}L.style.display="block";}},hideIframe:function(){if(this.iframe){this.iframe.style.display="none";}},syncIframe:function(){var K=this.iframe,M=this.element,O=B.IFRAME_OFFSET,L=(O*2),N;if(K){K.style.width=(M.offsetWidth+L+"px");K.style.height=(M.offsetHeight+L+"px");N=this.cfg.getProperty("xy");if(!F.isArray(N)||(isNaN(N[0])||isNaN(N[1]))){this.syncPosition();N=this.cfg.getProperty("xy");}D.setXY(K,[(N[0]-O),(N[1]-O)]);}},stackIframe:function(){if(this.iframe){var K=D.getStyle(this.element,"zIndex");if(!YAHOO.lang.isUndefined(K)&!
 &!isNaN(K)){D.setStyle(this.iframe,"zIndex",(K-1));}}},configI!
 frame:fu
nction(N,M,O){var K=M[0];function P(){var R=this.iframe,S=this.element,T;if(!R){if(!G){G=document.createElement("iframe");if(this.isSecure){G.src=B.IFRAME_SRC;}if(YAHOO.env.ua.ie){G.style.filter="alpha(opacity=0)";G.frameBorder=0;}else{G.style.opacity="0";}G.style.position="absolute";G.style.border="none";G.style.margin="0";G.style.padding="0";G.style.display="none";}R=G.cloneNode(false);T=S.parentNode;var Q=T||document.body;this._addToParent(Q,R);this.iframe=R;}this.showIframe();this.syncIframe();this.stackIframe();if(!this._hasIframeEventListeners){this.showEvent.subscribe(this.showIframe);this.hideEvent.subscribe(this.hideIframe);this.changeContentEvent.subscribe(this.syncIframe);this._hasIframeEventListeners=true;}}function L(){P.call(this);this.beforeShowEvent.unsubscribe(L);this._iframeDeferred=false;}if(K){if(this.cfg.getProperty("visible")){P.call(this);}else{if(!this._iframeDeferred){this.beforeShowEvent.subscribe(L);this._iframeDeferred=true;}}}else{this.hideIframe!
 ();if(this._hasIframeEventListeners){this.showEvent.unsubscribe(this.showIframe);this.hideEvent.unsubscribe(this.hideIframe);this.changeContentEvent.unsubscribe(this.syncIframe);this._hasIframeEventListeners=false;}}},_primeXYFromDOM:function(){if(YAHOO.lang.isUndefined(this.cfg.getProperty("xy"))){this.syncPosition();this.cfg.refireEvent("xy");this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);}},configConstrainToViewport:function(L,K,M){var N=K[0];if(N){if(!C.alreadySubscribed(this.beforeMoveEvent,this.enforceConstraints,this)){this.beforeMoveEvent.subscribe(this.enforceConstraints,this,true);}if(!C.alreadySubscribed(this.beforeShowEvent,this._primeXYFromDOM)){this.beforeShowEvent.subscribe(this._primeXYFromDOM);}}else{this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);this.beforeMoveEvent.unsubscribe(this.enforceConstraints,this);}},configContext:function(M,L,O){var Q=L[0],N,P,K;if(Q){N=Q[0];P=Q[1];
+K=Q[2];if(N){if(typeof N=="string"){this.cfg.setProperty("context",[document.getElementById(N),P,K],true);}if(P&&K){this.align(P,K);}}}},align:function(L,K){var Q=this.cfg.getProperty("context"),P=this,O,N,R;function M(S,T){switch(L){case B.TOP_LEFT:P.moveTo(T,S);break;case B.TOP_RIGHT:P.moveTo((T-N.offsetWidth),S);break;case B.BOTTOM_LEFT:P.moveTo(T,(S-N.offsetHeight));break;case B.BOTTOM_RIGHT:P.moveTo((T-N.offsetWidth),(S-N.offsetHeight));break;}}if(Q){O=Q[0];N=this.element;P=this;if(!L){L=Q[1];}if(!K){K=Q[2];}if(N&&O){R=D.getRegion(O);switch(K){case B.TOP_LEFT:M(R.top,R.left);break;case B.TOP_RIGHT:M(R.top,R.right);break;case B.BOTTOM_LEFT:M(R.bottom,R.left);break;case B.BOTTOM_RIGHT:M(R.bottom,R.right);break;}}}},enforceConstraints:function(L,K,M){var O=K[0];var N=this.getConstrainedXY(O[0],O[1]);this.cfg.setProperty("x",N[0],true);this.cfg.setProperty("y",N[1],true);this.cfg.setProperty("xy",N,true);},getConstrainedXY:function(V,T){var N=B.VIEWPORT_OFFSET,U=D.getViewp!
 ortWidth(),Q=D.getViewportHeight(),M=this.element.offsetHeight,S=this.element.offsetWidth,Y=D.getDocumentScrollLeft(),W=D.getDocumentScrollTop();var P=V;var L=T;if(S+N<U){var R=Y+N;var X=Y+U-S-N;if(V<R){P=R;}else{if(V>X){P=X;}}}else{P=N+Y;}if(M+N<Q){var O=W+N;var K=W+Q-M-N;if(T<O){L=O;}else{if(T>K){L=K;}}}else{L=N+W;}return[P,L];},center:function(){var N=B.VIEWPORT_OFFSET,O=this.element.offsetWidth,M=this.element.offsetHeight,L=D.getViewportWidth(),P=D.getViewportHeight(),K,Q;if(O<L){K=(L/2)-(O/2)+D.getDocumentScrollLeft();}else{K=N+D.getDocumentScrollLeft();}if(M<P){Q=(P/2)-(M/2)+D.getDocumentScrollTop();}else{Q=N+D.getDocumentScrollTop();}this.cfg.setProperty("xy",[parseInt(K,10),parseInt(Q,10)]);this.cfg.refireEvent("iframe");},syncPosition:function(){var K=D.getXY(this.element);this.cfg.setProperty("x",K[0],true);this.cfg.setProperty("y",K[1],true);this.cfg.setProperty("xy",K,true);},onDomResize:function(M,L){var K=this;B.superclass.onDomResize.call(this,M,L);setTimeout!
 (function(){K.syncPosition();K.cfg.refireEvent("iframe");K.cfg!
 .refireE
vent("context");},0);},bringToTop:function(){var O=[],N=this.element;function R(V,U){var X=D.getStyle(V,"zIndex"),W=D.getStyle(U,"zIndex"),T=(!X||isNaN(X))?0:parseInt(X,10),S=(!W||isNaN(W))?0:parseInt(W,10);if(T>S){return -1;}else{if(T<S){return 1;}else{return 0;}}}function M(U){var S=D.hasClass(U,B.CSS_OVERLAY),T=YAHOO.widget.Panel;if(S&&!D.isAncestor(N,S)){if(T&&D.hasClass(U,T.CSS_PANEL)){O[O.length]=U.parentNode;}else{O[O.length]=U;}}}D.getElementsBy(M,"DIV",document.body);O.sort(R);var K=O[0],Q;if(K){Q=D.getStyle(K,"zIndex");if(!isNaN(Q)){var P=false;if(K!=N){P=true;}else{if(O.length>1){var L=D.getStyle(O[1],"zIndex");if(!isNaN(L)&&(Q==L)){P=true;}}}if(P){this.cfg.setProperty("zindex",(parseInt(Q,10)+2));}}}},destroy:function(){if(this.iframe){this.iframe.parentNode.removeChild(this.iframe);}this.iframe=null;B.windowResizeEvent.unsubscribe(this.doCenterOnDOMEvent,this);B.windowScrollEvent.unsubscribe(this.doCenterOnDOMEvent,this);B.superclass.destroy.call(this);},toStrin!
 g:function(){return"Overlay "+this.id;}});}());(function(){YAHOO.widget.OverlayManager=function(G){this.init(G);};var D=YAHOO.widget.Overlay,C=YAHOO.util.Event,E=YAHOO.util.Dom,B=YAHOO.util.Config,F=YAHOO.util.CustomEvent,A=YAHOO.widget.OverlayManager;A.CSS_FOCUSED="focused";A.prototype={constructor:A,overlays:null,initDefaultConfig:function(){this.cfg.addProperty("overlays",{suppressEvent:true});this.cfg.addProperty("focusevent",{value:"mousedown"});},init:function(I){this.cfg=new B(this);this.initDefaultConfig();if(I){this.cfg.applyConfig(I,true);}this.cfg.fireQueue();var H=null;this.getActive=function(){return H;};this.focus=function(J){var K=this.find(J);if(K){if(H!=K){if(H){H.blur();}this.bringToTop(K);H=K;E.addClass(H.element,A.CSS_FOCUSED);K.focusEvent.fire();}}};this.remove=function(K){var M=this.find(K),J;if(M){if(H==M){H=null;}var L=(M.element===null&&M.cfg===null)?true:false;if(!L){J=E.getStyle(M.element,"zIndex");M.cfg.setProperty("zIndex",-1000,true);}this.over!
 lays.sort(this.compareZIndexDesc);this.overlays=this.overlays.!
 slice(0,
(this.overlays.length-1));M.hideEvent.unsubscribe(M.blur);M.destroyEvent.unsubscribe(this._onOverlayDestroy,M);if(!L){C.removeListener(M.element,this.cfg.getProperty("focusevent"),this._onOverlayElementFocus);M.cfg.setProperty("zIndex",J,true);M.cfg.setProperty("manager",null);}M.focusEvent.unsubscribeAll();M.blurEvent.unsubscribeAll();M.focusEvent=null;M.blurEvent=null;M.focus=null;M.blur=null;}};this.blurAll=function(){var K=this.overlays.length,J;if(K>0){J=K-1;do{this.overlays[J].blur();}while(J--);}};this._onOverlayBlur=function(K,J){H=null;};var G=this.cfg.getProperty("overlays");if(!this.overlays){this.overlays=[];}if(G){this.register(G);this.overlays.sort(this.compareZIndexDesc);}},_onOverlayElementFocus:function(I){var G=C.getTarget(I),H=this.close;if(H&&(G==H||E.isAncestor(H,G))){this.blur();}else{this.focus();}},_onOverlayDestroy:function(H,G,I){this.remove(I);},register:function(G){var K=this,L,I,H,J;if(G instanceof D){G.cfg.addProperty("manager",{value:this});G.f!
 ocusEvent=G.createEvent("focus");G.focusEvent.signature=F.LIST;G.blurEvent=G.createEvent("blur");G.blurEvent.signature=F.LIST;G.focus=function(){K.focus(this);};G.blur=function(){if(K.getActive()==this){E.removeClass(this.element,A.CSS_FOCUSED);this.blurEvent.fire();}};G.blurEvent.subscribe(K._onOverlayBlur);G.hideEvent.subscribe(G.blur);G.destroyEvent.subscribe(this._onOverlayDestroy,G,this);C.on(G.element,this.cfg.getProperty("focusevent"),this._onOverlayElementFocus,null,G);L=E.getStyle(G.element,"zIndex");if(!isNaN(L)){G.cfg.setProperty("zIndex",parseInt(L,10));}else{G.cfg.setProperty("zIndex",0);}this.overlays.push(G);this.bringToTop(G);return true;}else{if(G instanceof Array){I=0;J=G.length;for(H=0;H<J;H++){if(this.register(G[H])){I++;}}if(I>0){return true;}}else{return false;}}},bringToTop:function(M){var I=this.find(M),L,G,J;if(I){J=this.overlays;J.sort(this.compareZIndexDesc);G=J[0];if(G){L=E.getStyle(G.element,"zIndex");
+if(!isNaN(L)){var K=false;if(G!==I){K=true;}else{if(J.length>1){var H=E.getStyle(J[1].element,"zIndex");if(!isNaN(H)&&(L==H)){K=true;}}}if(K){I.cfg.setProperty("zindex",(parseInt(L,10)+2));}}J.sort(this.compareZIndexDesc);}}},find:function(G){var I=this.overlays,J=I.length,H;if(J>0){H=J-1;if(G instanceof D){do{if(I[H]==G){return I[H];}}while(H--);}else{if(typeof G=="string"){do{if(I[H].id==G){return I[H];}}while(H--);}}return null;}},compareZIndexDesc:function(J,I){var H=(J.cfg)?J.cfg.getProperty("zIndex"):null,G=(I.cfg)?I.cfg.getProperty("zIndex"):null;if(H===null&&G===null){return 0;}else{if(H===null){return 1;}else{if(G===null){return -1;}else{if(H>G){return -1;}else{if(H<G){return 1;}else{return 0;}}}}}},showAll:function(){var H=this.overlays,I=H.length,G;if(I>0){G=I-1;do{H[G].show();}while(G--);}},hideAll:function(){var H=this.overlays,I=H.length,G;if(I>0){G=I-1;do{H[G].hide();}while(G--);}},toString:function(){return"OverlayManager";}};}());(function(){YAHOO.widget.Co!
 ntainerEffect=function(F,I,H,E,G){if(!G){G=YAHOO.util.Anim;}this.overlay=F;this.attrIn=I;this.attrOut=H;this.targetElement=E||F.element;this.animClass=G;};var B=YAHOO.util.Dom,D=YAHOO.util.CustomEvent,C=YAHOO.util.Easing,A=YAHOO.widget.ContainerEffect;A.FADE=function(E,G){var I={attributes:{opacity:{from:0,to:1}},duration:G,method:C.easeIn};var F={attributes:{opacity:{to:0}},duration:G,method:C.easeOut};var H=new A(E,I,F,E.element);H.handleUnderlayStart=function(){var K=this.overlay.underlay;if(K&&YAHOO.env.ua.ie){var J=(K.filters&&K.filters.length>0);if(J){B.addClass(E.element,"yui-effect-fade");}}};H.handleUnderlayComplete=function(){var J=this.overlay.underlay;if(J&&YAHOO.env.ua.ie){B.removeClass(E.element,"yui-effect-fade");}};H.handleStartAnimateIn=function(K,J,L){B.addClass(L.overlay.element,"hide-select");if(!L.overlay.underlay){L.overlay.cfg.refireEvent("underlay");}L.handleUnderlayStart();B.setStyle(L.overlay.element,"visibility","visible");B.setStyle(L.overlay.ele!
 ment,"opacity",0);};H.handleCompleteAnimateIn=function(K,J,L){!
 B.remove
Class(L.overlay.element,"hide-select");if(L.overlay.element.style.filter){L.overlay.element.style.filter=null;}L.handleUnderlayComplete();L.overlay.cfg.refireEvent("iframe");L.animateInCompleteEvent.fire();};H.handleStartAnimateOut=function(K,J,L){B.addClass(L.overlay.element,"hide-select");L.handleUnderlayStart();};H.handleCompleteAnimateOut=function(K,J,L){B.removeClass(L.overlay.element,"hide-select");if(L.overlay.element.style.filter){L.overlay.element.style.filter=null;}B.setStyle(L.overlay.element,"visibility","hidden");B.setStyle(L.overlay.element,"opacity",1);L.handleUnderlayComplete();L.overlay.cfg.refireEvent("iframe");L.animateOutCompleteEvent.fire();};H.init();return H;};A.SLIDE=function(G,I){var F=G.cfg.getProperty("x")||B.getX(G.element),K=G.cfg.getProperty("y")||B.getY(G.element),J=B.getClientWidth(),H=G.element.offsetWidth,E=new A(G,{attributes:{points:{to:[F,K]}},duration:I,method:C.easeIn},{attributes:{points:{to:[(J+25),K]}},duration:I,method:C.easeOut},G.!
 element,YAHOO.util.Motion);E.handleStartAnimateIn=function(M,L,N){N.overlay.element.style.left=((-25)-H)+"px";N.overlay.element.style.top=K+"px";};E.handleTweenAnimateIn=function(O,N,P){var Q=B.getXY(P.overlay.element),M=Q[0],L=Q[1];if(B.getStyle(P.overlay.element,"visibility")=="hidden"&&M<F){B.setStyle(P.overlay.element,"visibility","visible");}P.overlay.cfg.setProperty("xy",[M,L],true);P.overlay.cfg.refireEvent("iframe");};E.handleCompleteAnimateIn=function(M,L,N){N.overlay.cfg.setProperty("xy",[F,K],true);N.startX=F;N.startY=K;N.overlay.cfg.refireEvent("iframe");N.animateInCompleteEvent.fire();};E.handleStartAnimateOut=function(M,L,P){var N=B.getViewportWidth(),Q=B.getXY(P.overlay.element),O=Q[1];P.animOut.attributes.points.to=[(N+25),O];};E.handleTweenAnimateOut=function(N,M,O){var Q=B.getXY(O.overlay.element),L=Q[0],P=Q[1];O.overlay.cfg.setProperty("xy",[L,P],true);O.overlay.cfg.refireEvent("iframe");};E.handleCompleteAnimateOut=function(M,L,N){B.setStyle(N.overlay.el!
 ement,"visibility","hidden");N.overlay.cfg.setProperty("xy",[F!
 ,K]);N.a
nimateOutCompleteEvent.fire();};E.init();return E;};A.prototype={init:function(){this.beforeAnimateInEvent=this.createEvent("beforeAnimateIn");this.beforeAnimateInEvent.signature=D.LIST;this.beforeAnimateOutEvent=this.createEvent("beforeAnimateOut");this.beforeAnimateOutEvent.signature=D.LIST;this.animateInCompleteEvent=this.createEvent("animateInComplete");this.animateInCompleteEvent.signature=D.LIST;this.animateOutCompleteEvent=this.createEvent("animateOutComplete");this.animateOutCompleteEvent.signature=D.LIST;this.animIn=new this.animClass(this.targetElement,this.attrIn.attributes,this.attrIn.duration,this.attrIn.method);this.animIn.onStart.subscribe(this.handleStartAnimateIn,this);this.animIn.onTween.subscribe(this.handleTweenAnimateIn,this);this.animIn.onComplete.subscribe(this.handleCompleteAnimateIn,this);this.animOut=new this.animClass(this.targetElement,this.attrOut.attributes,this.attrOut.duration,this.attrOut.method);this.animOut.onStart.subscribe(this.handleStar!
 tAnimateOut,this);this.animOut.onTween.subscribe(this.handleTweenAnimateOut,this);this.animOut.onComplete.subscribe(this.handleCompleteAnimateOut,this);},animateIn:function(){this.beforeAnimateInEvent.fire();this.animIn.animate();},animateOut:function(){this.beforeAnimateOutEvent.fire();this.animOut.animate();},handleStartAnimateIn:function(F,E,G){},handleTweenAnimateIn:function(F,E,G){},handleCompleteAnimateIn:function(F,E,G){},handleStartAnimateOut:function(F,E,G){},handleTweenAnimateOut:function(F,E,G){},handleCompleteAnimateOut:function(F,E,G){},toString:function(){var E="ContainerEffect";if(this.overlay){E+=" ["+this.overlay.toString()+"]";}return E;}};YAHOO.lang.augmentProto(A,YAHOO.util.EventProvider);})();YAHOO.register("containercore",YAHOO.widget.Module,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/container/container_core.js
===================================================================
--- trunk/root/static/yui/container/container_core.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/container/container_core.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 (function () {
 
@@ -737,7 +737,6 @@
         * @type Object
         */
         EVENT_TYPES = {
-        
             "BEFORE_INIT": "beforeInit",
             "INIT": "init",
             "APPEND": "append",
@@ -752,7 +751,6 @@
             "SHOW": "show",
             "BEFORE_HIDE": "beforeHide",
             "HIDE": "hide"
-        
         },
             
         /**
@@ -822,7 +820,7 @@
     * @type String
     */
     Module.CSS_HEADER = "hd";
-    
+
     /**
     * Constant representing the module body
     * @property YAHOO.widget.Module.CSS_BODY
@@ -1281,12 +1279,31 @@
         },
 
         /**
-        * Initialized an empty IFRAME that is placed out of the visible area 
+        * Initialize an empty IFRAME that is placed out of the visible area 
         * that can be used to detect text resize.
         * @method initResizeMonitor
         */
         initResizeMonitor: function () {
 
+            var isGeckoWin = (YAHOO.env.ua.gecko && this.platform == "windows");
+            if (isGeckoWin) {
+                // Help prevent spinning loading icon which 
+                // started with FireFox 2.0.0.8/Win
+                var self = this;
+                setTimeout(function(){self._initResizeMonitor();}, 0);
+            } else {
+                this._initResizeMonitor();
+            }
+        },
+
+        /**
+         * Create and initialize the text resize monitoring iframe.
+         * 
+         * @protected
+         * @method _initResizeMonitor
+         */
+        _initResizeMonitor : function() {
+
             var oDoc, 
                 oIFrame, 
                 sHTML;
@@ -1298,6 +1315,8 @@
             if (!YAHOO.env.ua.opera) {
                 oIFrame = Dom.get("_yuiResizeMonitor");
 
+                var supportsCWResize = this._supportsCWResize();
+
                 if (!oIFrame) {
                     oIFrame = document.createElement("iframe");
 
@@ -1305,21 +1324,17 @@
                         oIFrame.src = Module.RESIZE_MONITOR_SECURE_URL;
                     }
 
-                    /*
-                        Need to set the iframe document for Gecko
-                        to fire resize events on the iframe contentWindow.
-                     */
-                    if (YAHOO.env.ua.gecko) {
-                         sHTML = ["<html><head><script ",
-                                  "type=\"text/javascript\">",
-                                  "window.onresize=function(){window.parent.",
-                                  "YAHOO.widget.Module.textResizeEvent.",
-                                  "fire();}", 
-                                  "<\/script></head>",
-                                  "<body></body></html>"].join('');
+                    if (!supportsCWResize) {
+                        // Can't monitor on contentWindow, so fire from inside iframe
+                        sHTML = ["<html><head><script ",
+                                 "type=\"text/javascript\">",
+                                 "window.onresize=function(){window.parent.",
+                                 "YAHOO.widget.Module.textResizeEvent.",
+                                 "fire();};<",
+                                 "\/script></head>",
+                                 "<body></body></html>"].join('');
 
-                        oIFrame.src = "data:text/html;charset=utf-8," +
-                            encodeURIComponent(sHTML);
+                        oIFrame.src = "data:text/html;charset=utf-8," + encodeURIComponent(sHTML);
                     }
 
                     oIFrame.id = "_yuiResizeMonitor";
@@ -1332,11 +1347,12 @@
                     oIFrame.style.position = "absolute";
                     oIFrame.style.visibility = "hidden";
 
-                    var fc = document.body.firstChild;
+                    var db = document.body,
+                        fc = db.firstChild;
                     if (fc) {
-                        document.body.insertBefore(oIFrame, fc);
+                        db.insertBefore(oIFrame, fc);
                     } else {
-                        document.body.appendChild(oIFrame);
+                        db.appendChild(oIFrame);
                     }
 
                     oIFrame.style.width = "10em";
@@ -1361,8 +1377,7 @@
                     Module.textResizeEvent.subscribe(this.onDomResize, this, true);
 
                     if (!Module.textResizeInitialized) {
-                         // We already handle gecko using the iframe's document content
-                        if (!YAHOO.env.ua.gecko) {
+                        if (supportsCWResize) {
                             if (!Event.on(oIFrame.contentWindow, "resize", fireTextResize)) {
                                 /*
                                      This will fail in IE if document.domain has 
@@ -1380,13 +1395,46 @@
         },
 
         /**
+         * Text resize monitor helper method.
+         * Determines if the browser supports resize events on iframe content windows.
+         * 
+         * @private
+         * @method _supportsCWResize
+         */
+        _supportsCWResize : function() {
+            /*
+                Gecko 1.8.0 (FF1.5), 1.8.1.0-5 (FF2) won't fire resize on contentWindow.
+                Gecko 1.8.1.6+ (FF2.0.0.6+) and all other browsers will fire resize on contentWindow.
+
+                We don't want to start sniffing for patch versions, so fire textResize the same
+                way on all FF, until 1.9 (3.x) is out
+             */
+            var bSupported = true;
+            if (YAHOO.env.ua.gecko && YAHOO.env.ua.gecko <= 1.8) {
+                bSupported = false;
+                /*
+                var v = navigator.userAgent.match(/rv:([^\s\)]*)/); // From YAHOO.env.ua
+                if (v && v[0]) {
+                    var sv = v[0].match(/\d\.\d\.(\d)/);
+                    if (sv && sv[1]) {
+                        if (parseInt(sv[1], 10) > 0) {
+                            bSupported = true;
+                        }
+                    }
+                }
+                */
+            }
+            return bSupported;
+        },
+
+        /**
         * Event handler fired when the resize monitor element is resized.
         * @method onDomResize
         * @param {DOMEvent} e The DOM resize event
         * @param {Object} obj The scope object passed to the handler
         */
         onDomResize: function (e, obj) {
-        
+
             var nLeft = -1 * this.resizeMonitor.offsetWidth,
                 nTop = -1 * this.resizeMonitor.offsetHeight;
         
@@ -1394,90 +1442,97 @@
             this.resizeMonitor.style.left =  nLeft + "px";
 
         },
-        
+
         /**
-        * Sets the Module's header content to the HTML specified, or appends 
+        * Sets the Module's header content to the string specified, or appends 
         * the passed element to the header. If no header is present, one will 
-        * be automatically created.
+        * be automatically created. An empty string can be passed to the method
+        * to clear the contents of the header.
+        * 
         * @method setHeader
-        * @param {String} headerContent The HTML used to set the header 
+        * @param {String} headerContent The string used to set the header.
+        * As a convenience, non HTMLElement objects can also be passed into 
+        * the method, and will be treated as strings, with the header innerHTML
+        * set to their default toString implementations.
         * <em>OR</em>
         * @param {HTMLElement} headerContent The HTMLElement to append to 
-        * the header
+        * <em>OR</em>
+        * @param {DocumentFragment} headerContent The document fragment 
+        * containing elements which are to be added to the header
         */
         setHeader: function (headerContent) {
-
             var oHeader = this.header || (this.header = createHeader());
-        
-            if (typeof headerContent == "string") {
 
-                oHeader.innerHTML = headerContent;
-
-            } else {
-
+            if (headerContent.nodeName) {
                 oHeader.innerHTML = "";
                 oHeader.appendChild(headerContent);
+            } else {
+                oHeader.innerHTML = headerContent;
+            }
 
-            }
-        
             this.changeHeaderEvent.fire(headerContent);
             this.changeContentEvent.fire();
 
         },
-        
+
         /**
         * Appends the passed element to the header. If no header is present, 
         * one will be automatically created.
         * @method appendToHeader
-        * @param {HTMLElement} element The element to append to the header
+        * @param {HTMLElement | DocumentFragment} element The element to 
+        * append to the header. In the case of a document fragment, the
+        * children of the fragment will be appended to the header.
         */
         appendToHeader: function (element) {
+            var oHeader = this.header || (this.header = createHeader());
 
-            var oHeader = this.header || (this.header = createHeader());
-        
             oHeader.appendChild(element);
 
             this.changeHeaderEvent.fire(element);
             this.changeContentEvent.fire();
 
         },
-        
+
         /**
         * Sets the Module's body content to the HTML specified, or appends the
         * passed element to the body. If no body is present, one will be 
-        * automatically created.
+        * automatically created. An empty string can be passed to the method
+        * to clear the contents of the body.
         * @method setBody
-        * @param {String} bodyContent The HTML used to set the body <em>OR</em>
+        * @param {String} bodyContent The HTML used to set the body. 
+        * As a convenience, non HTMLElement objects can also be passed into 
+        * the method, and will be treated as strings, with the body innerHTML
+        * set to their default toString implementations.
+        * <em>OR</em>
         * @param {HTMLElement} bodyContent The HTMLElement to append to the body
+        * <em>OR</em>
+        * @param {DocumentFragment} bodyContent The document fragment 
+        * containing elements which are to be added to the body
         */
         setBody: function (bodyContent) {
-
             var oBody = this.body || (this.body = createBody());
-        
-            if (typeof bodyContent == "string") {
 
-                oBody.innerHTML = bodyContent;
-
-            } else {
-
+            if (bodyContent.nodeName) {
                 oBody.innerHTML = "";
                 oBody.appendChild(bodyContent);
+            } else {
+                oBody.innerHTML = bodyContent;
+            }
 
-            }
-        
             this.changeBodyEvent.fire(bodyContent);
             this.changeContentEvent.fire();
+        },
 
-        },
-        
         /**
         * Appends the passed element to the body. If no body is present, one 
         * will be automatically created.
         * @method appendToBody
-        * @param {HTMLElement} element The element to append to the body
+        * @param {HTMLElement | DocumentFragment} element The element to 
+        * append to the body. In the case of a document fragment, the
+        * children of the fragment will be appended to the body.
+        * 
         */
         appendToBody: function (element) {
-
             var oBody = this.body || (this.body = createBody());
         
             oBody.appendChild(element);
@@ -1490,50 +1545,54 @@
         /**
         * Sets the Module's footer content to the HTML specified, or appends 
         * the passed element to the footer. If no footer is present, one will 
-        * be automatically created.
+        * be automatically created. An empty string can be passed to the method
+        * to clear the contents of the footer.
         * @method setFooter
         * @param {String} footerContent The HTML used to set the footer 
+        * As a convenience, non HTMLElement objects can also be passed into 
+        * the method, and will be treated as strings, with the footer innerHTML
+        * set to their default toString implementations.
         * <em>OR</em>
         * @param {HTMLElement} footerContent The HTMLElement to append to 
         * the footer
+        * <em>OR</em>
+        * @param {DocumentFragment} footerContent The document fragment containing 
+        * elements which are to be added to the footer
         */
         setFooter: function (footerContent) {
 
             var oFooter = this.footer || (this.footer = createFooter());
-        
-            if (typeof footerContent == "string") {
 
-                oFooter.innerHTML = footerContent;
-
-            } else {
-
+            if (footerContent.nodeName) {
                 oFooter.innerHTML = "";
                 oFooter.appendChild(footerContent);
+            } else {
+                oFooter.innerHTML = footerContent;
+            }
 
-            }
-        
             this.changeFooterEvent.fire(footerContent);
             this.changeContentEvent.fire();
+        },
 
-        },
-        
         /**
         * Appends the passed element to the footer. If no footer is present, 
         * one will be automatically created.
         * @method appendToFooter
-        * @param {HTMLElement} element The element to append to the footer
+        * @param {HTMLElement | DocumentFragment} element The element to 
+        * append to the footer. In the case of a document fragment, the
+        * children of the fragment will be appended to the footer
         */
         appendToFooter: function (element) {
 
             var oFooter = this.footer || (this.footer = createFooter());
-        
+
             oFooter.appendChild(element);
 
             this.changeFooterEvent.fire(element);
             this.changeContentEvent.fire();
 
         },
-        
+
         /**
         * Renders the Module by inserting the elements that are not already 
         * in the main Module into their correct places. Optionally appends 
@@ -1659,7 +1718,7 @@
             }
 
         },
-        
+
         /**
         * Shows the Module element by setting the visible configuration 
         * property to true. Also fires two events: beforeShowEvent prior to 
@@ -1669,7 +1728,7 @@
         show: function () {
             this.cfg.setProperty("visible", true);
         },
-        
+
         /**
         * Hides the Module element by setting the visible configuration 
         * property to false. Also fires two events: beforeHideEvent prior to 
@@ -1861,12 +1920,12 @@
                 key: "height", 
                 suppressEvent: true, 
                 supercedes: ["context", "fixedcenter", "iframe"] 
-            }, 
+            },
 
             "ZINDEX": { 
                 key: "zindex", 
                 value: null 
-            }, 
+            },
 
             "CONSTRAIN_TO_VIEWPORT": { 
                 key: "constraintoviewport", 
@@ -2151,7 +2210,7 @@
                 supercedes: DEFAULT_CONFIG.X.supercedes
     
             });
-    
+
             /**
             * The absolute y-coordinate position of the Overlay
             * @config y
@@ -2159,12 +2218,12 @@
             * @default null
             */
             this.cfg.addProperty(DEFAULT_CONFIG.Y.key, {
-    
+
                 handler: this.configY, 
                 validator: DEFAULT_CONFIG.Y.validator, 
                 suppressEvent: DEFAULT_CONFIG.Y.suppressEvent, 
                 supercedes: DEFAULT_CONFIG.Y.supercedes
-    
+
             });
     
             /**
@@ -2242,7 +2301,7 @@
                 supercedes: DEFAULT_CONFIG.HEIGHT.supercedes
             
             });
-
+            
             /**
             * CSS z-index of the Overlay.
             * @config zIndex
@@ -2255,7 +2314,7 @@
                 value: DEFAULT_CONFIG.ZINDEX.value
 
             });
-            
+
             /**
             * True if the Overlay should be prevented from being positioned 
             * out of the viewport.
@@ -2271,7 +2330,7 @@
                 supercedes: DEFAULT_CONFIG.CONSTRAIN_TO_VIEWPORT.supercedes
 
             });
-            
+
             /**
             * @config iframe
             * @description Boolean indicating whether or not the Overlay should 
@@ -2533,7 +2592,7 @@
         * this will usually equal the owner.
         */
         configHeight: function (type, args, obj) {
-    
+
             var height = args[0],
                 el = this.element;
 
@@ -2645,9 +2704,9 @@
             y = this.cfg.getProperty("y");
             
             Dom.setX(this.element, x, true);
-            
+
             this.cfg.setProperty("xy", [x, y], true);
-           
+
             this.cfg.refireEvent("iframe");
             this.moveEvent.fire([x, y]);
         },
@@ -2880,6 +2939,26 @@
         },
 
         /**
+         * Set's the container's XY value from DOM if not already set.
+         * 
+         * Differs from syncPosition, in that the XY value is only sync'd with DOM if 
+         * not already set. The method also refire's the XY config property event, so any
+         * beforeMove, Move event listeners are invoked.
+         * 
+         * @method _primeXYFromDOM
+         * @protected
+         */
+        _primeXYFromDOM : function() {
+            if (YAHOO.lang.isUndefined(this.cfg.getProperty("xy"))) {
+                // Set CFG XY based on DOM XY
+                this.syncPosition();
+                // Account for XY being set silently in syncPosition (no moveTo fired/called)
+                this.cfg.refireEvent("xy");
+                this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);
+            }
+        },
+
+        /**
         * The default event handler fired when the "constraintoviewport" 
         * property is changed.
         * @method configConstrainToViewport
@@ -2891,39 +2970,22 @@
         * this will usually equal the owner.
         */
         configConstrainToViewport: function (type, args, obj) {
-
-            function constrainBeforeShow() {
-                if (YAHOO.lang.isUndefined(this.cfg.getProperty("xy"))) {
-                    // Set CFG XY based on DOM XY
-                    this.syncPosition();
-                }
-                var x = this.cfg.getProperty("x");
-                var y = this.cfg.getProperty("y");
-
-                // Account for XY being set silently (no moveTo fired/called)
-                var cXY = this.getConstrainedXY(x, y);
-                if (cXY[0] !== x || cXY[1] !== y) {
-                    this.moveTo(cXY[0], cXY[1]);
-                }
-            }
-
             var val = args[0];
 
             if (val) {
                 if (! Config.alreadySubscribed(this.beforeMoveEvent, this.enforceConstraints, this)) {
                     this.beforeMoveEvent.subscribe(this.enforceConstraints, this, true);
                 }
-
-                if (! Config.alreadySubscribed(this.beforeShowEvent, constrainBeforeShow)) {
-                    this.beforeShowEvent.subscribe(constrainBeforeShow);
+                if (! Config.alreadySubscribed(this.beforeShowEvent, this._primeXYFromDOM)) {
+                    this.beforeShowEvent.subscribe(this._primeXYFromDOM);
                 }
             } else {
-                this.beforeShowEvent.unsubscribe(constrainBeforeShow);
+                this.beforeShowEvent.unsubscribe(this._primeXYFromDOM);
                 this.beforeMoveEvent.unsubscribe(this.enforceConstraints, this);
             }
         },
 
-        /**
+         /**
         * The default event handler fired when the "context" property 
         * is changed.
         * @method configContext
@@ -2939,38 +3001,28 @@
                 contextEl,
                 elementMagnetCorner,
                 contextMagnetCorner;
-            
+
             if (contextArgs) {
-            
                 contextEl = contextArgs[0];
                 elementMagnetCorner = contextArgs[1];
                 contextMagnetCorner = contextArgs[2];
                 
                 if (contextEl) {
-    
                     if (typeof contextEl == "string") {
-
                         this.cfg.setProperty("context", 
                             [document.getElementById(contextEl), 
                                 elementMagnetCorner, contextMagnetCorner], 
                                 true);
-
                     }
                     
                     if (elementMagnetCorner && contextMagnetCorner) {
-
                         this.align(elementMagnetCorner, contextMagnetCorner);
-
                     }
-
                 }
-
             }
-
         },
 
         // END BUILT-IN PROPERTY EVENT HANDLERS //
-
         /**
         * Aligns the Overlay to its context element using the specified corner 
         * points (represented by the constants TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, 
@@ -4193,4 +4245,4 @@
 
 })();
 
-YAHOO.register("containercore", YAHOO.widget.Module, {version: "2.4.1", build: "742"});
+YAHOO.register("containercore", YAHOO.widget.Module, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/cookie/README
===================================================================
--- trunk/root/static/yui/cookie/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/cookie/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,10 @@
+YUI Library - Cookie Utility - Release Notes
+
+2.5.1
+
+  * Fixed bug preventing cookies with numbers or non-alphanumeric
+    characters in the cookie name from working correctly.
+
+2.5.0
+
+  * Beta release
\ No newline at end of file

Added: trunk/root/static/yui/cookie/cookie-beta-debug.js
===================================================================
--- trunk/root/static/yui/cookie/cookie-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/cookie/cookie-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,385 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * Utilities for cookie management
+ * @namespace YAHOO.util
+ * @module cookie
+ * @beta
+ */
+YAHOO.namespace("util");
+
+/**
+ * Cookie utility.
+ * @class Cookie
+ * @static
+ */
+YAHOO.util.Cookie = {
+    
+    //-------------------------------------------------------------------------
+    // Private Methods
+    //-------------------------------------------------------------------------
+    
+    /**
+     * Creates a cookie string that can be assigned into document.cookie.
+     * @param {String} name The name of the cookie.
+     * @param {String} value The value of the cookie.
+     * @param {encodeValue} encodeValue True to encode the value, false to leave as-is.
+     * @param {Object} options (Optional) Options for the cookie.
+     * @return {String} The formatted cookie string.
+     * @method _createCookieString
+     * @private
+     * @static
+     */
+    _createCookieString : function (name /*:String*/, value /*:Variant*/, encodeValue /*:Boolean*/, options /*:Object*/) /*:String*/ {
+    
+        //shortcut
+        var lang = YAHOO.lang;
+    
+        var text /*:String*/ = encodeURIComponent(name) + "=" + (encodeValue ? encodeURIComponent(value) : value);
+        
+    
+        if (lang.isObject(options)){
+            //expiration date
+            if (options.expires instanceof Date){
+                text += "; expires=" + options.expires.toGMTString();
+            }
+        
+            //path
+            if (lang.isString(options.path) && options.path != ""){
+                text += "; path=" + options.path;
+            }
+    
+            //domain
+            if (lang.isString(options.domain) && options.domain != ""){
+                text += "; domain=" + options.domain;
+            }
+            
+            //secure
+            if (options.secure === true){
+                text += "; secure";
+            }
+        }
+        
+        return text;
+    },
+    
+    /**
+     * Formats a cookie value for an object containing multiple values.
+     * @param {Object} hash An object of key-value pairs to create a string for.
+     * @return {String} A string suitable for use as a cookie value.
+     * @method _createCookieHash
+     * @private
+     * @static
+     */
+    _createCookieHashString : function (hash /*:Object*/) /*:String*/ {
+        
+        //shortcuts
+        var lang = YAHOO.lang;
+        
+        if (!lang.isObject(hash)){
+            throw new TypeError("Cookie._createCookieHashString(): Argument must be an object.");
+        }
+        
+        var text /*:Array*/ = new Array();
+        
+        for (var key in hash){
+            if (lang.hasOwnProperty(hash, key) && !lang.isFunction(hash[key]) && !lang.isUndefined(hash[key])){
+                text.push(encodeURIComponent(key) + "=" + encodeURIComponent(String(hash[key])));
+            }
+        }
+        
+        return text.join("&");
+    },
+    
+    /**
+     * Parses a cookie hash string into an object.
+     * @param {String} text The cookie hash string to parse. The string should already be URL-decoded.
+     * @return {Object} An object containing entries for each cookie value.
+     * @method _parseCookieHash
+     * @private
+     * @static
+     */
+    _parseCookieHash : function (text /*:String*/) /*:Object*/ {
+    
+        var hashParts /*:Array*/ = text.split("&");
+        var hashPart /*:Array*/ = null;
+        var hash /*:Object*/ = new Object();
+        
+        for (var i=0, len=hashParts.length; i < len; i++){
+            hashPart = hashParts[i].split("=");
+            hash[decodeURIComponent(hashPart[0])] = decodeURIComponent(hashPart[1]);
+        }
+        
+        return hash;
+    },    
+    
+    /**
+     * Parses a cookie string into an object representing all accessible cookies.
+     * @param {String} text The cookie string to parse.
+     * @param {Boolean} decode (Optional) Indicates if the cookie values should be decoded or not. Default is true.
+     * @return {Object} An object containing entries for each accessible cookie.
+     * @method _parseCookieString
+     * @private
+     * @static
+     */
+    _parseCookieString : function (text /*:String*/, decode /*:Boolean*/) /*:Object*/ {
+    
+        var cookies /*:Object*/ = new Object();        
+        
+        if (YAHOO.lang.isString(text) && text.length > 0) {
+        
+            var decodeValue = (decode === false ? function(s){return s;} : decodeURIComponent);
+        
+            if (/[^=]+=[^=;]?(?:; [^=]+=[^=]?)?/.test(text)){            
+                var cookieParts /*:Array*/ = text.split(/;\s/g);
+                var cookieName /*:String*/ = null;
+                var cookieValue /*:String*/ = null;
+                var cookieNameValue /*:Array*/ = null;
+                
+                for (var i=0, len=cookieParts.length; i < len; i++){
+                
+                    //check for normally-formatted cookie (name-value)
+                    cookieNameValue = cookieParts[i].match(/([^=]+)=/i);
+                    if (cookieNameValue instanceof Array){
+                        cookieName = decodeURIComponent(cookieNameValue[1]);
+                        cookieValue = decodeValue(cookieParts[i].substring(cookieName.length+1));
+                    } else {
+                        //means the cookie does not have an "=", so treat it as a boolean flag
+                        cookieName = decodeURIComponent(cookieParts[i]);
+                        cookieValue = cookieName;
+                    }
+                    cookies[cookieName] = cookieValue;
+                }
+            }
+        }
+        
+        return cookies;
+    },    
+    
+    //-------------------------------------------------------------------------
+    // Public Methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Returns the cookie value for the given name.
+     * @param {String} name The name of the cookie to retrieve.
+     * @param {Function} converter (Optional) A function to run on the value before returning
+     *      it. The function is not used if the cookie doesn't exist.
+     * @return {Variant} If no converter is specified, returns a string or null if
+     *      the cookie doesn't exist. If the converter is specified, returns the value
+     *      returned from the converter or null if the cookie doesn't exist.
+     * @method get
+     * @static
+     */
+    get : function (name /*:String*/, converter /*:Function*/) /*:Variant*/{
+        
+        var lang = YAHOO.lang;
+        var cookies /*:Object*/ = this._parseCookieString(document.cookie);        
+        
+        if (!lang.isString(name) || name === ""){
+            throw new TypeError("Cookie.get(): Cookie name must be a non-empty string.");
+        }
+        
+        if (lang.isUndefined(cookies[name])) {
+            return null;
+        }
+        
+        if (!lang.isFunction(converter)){
+            return cookies[name];
+        } else {
+            return converter(cookies[name]);
+        }
+    },
+    
+    /**
+     * Returns the value of a subcookie.
+     * @param {String} name The name of the cookie to retrieve.
+     * @param {String} subName The name of the subcookie to retrieve.
+     * @param {Function} converter (Optional) A function to run on the value before returning
+     *      it. The function is not used if the cookie doesn't exist.
+     * @return {Variant} If the cookie doesn't exist, null is returned. If the subcookie
+     *      doesn't exist, null if also returned. If no converter is specified and the
+     *      subcookie exists, a string is returned. If a converter is specified and the
+     *      subcookie exists, the value returned from the converter is returned.
+     * @method getSub
+     * @static
+     */
+    getSub : function (name /*:String*/, subName /*:String*/, converter /*:Function*/) /*:Variant*/ {
+    
+        var lang = YAHOO.lang;    
+        var hash /*:Variant*/ = this.getSubs(name);  
+
+        if (hash !== null) {
+            
+            if (!lang.isString(subName) || subName === ""){
+                throw new TypeError("Cookie.getSub(): Subcookie name must be a non-empty string.");
+            }
+            
+            if (lang.isUndefined(hash[subName])){
+                return null;
+            }            
+        
+            if (!lang.isFunction(converter)){
+                return hash[subName];
+            } else {
+                return converter(hash[subName]);
+            }
+        } else {
+            return null;
+        }
+    
+    },
+    
+    /**
+     * Returns an object containing name-value pairs stored in the cookie with the given name.
+     * @param {String} name The name of the cookie to retrieve.
+     * @return {Object} An object of name-value pairs if the cookie with the given name
+     *      exists, null if it does not.
+     * @method getHash
+     * @static
+     */
+    getSubs : function (name /*:String*/) /*:Object*/ {
+        
+        //check cookie name
+        if (!YAHOO.lang.isString(name) || name === ""){
+            throw new TypeError("Cookie.getSubs(): Cookie name must be a non-empty string.");
+        }
+        
+        var cookies = this._parseCookieString(document.cookie, false);
+        if (YAHOO.lang.isString(cookies[name])){
+            return this._parseCookieHash(cookies[name]);
+        }
+        return null;
+    },
+    
+    /**
+     * Removes a cookie from the machine by setting its expiration date to
+     * sometime in the past.
+     * @param {String} name The name of the cookie to remove.
+     * @param {Object} options (Optional) An object containing one or more
+     *      cookie options: path (a string), domain (a string), 
+     *      and secure (true/false). The expires option will be overwritten
+     *      by the method.
+     * @return {String} The created cookie string.
+     * @method remove
+     * @static
+     */
+    remove : function (name /*:String*/, options /*:Object*/) /*:String*/ {
+        
+        //check cookie name
+        if (!YAHOO.lang.isString(name) || name === ""){
+            throw new TypeError("Cookie.remove(): Cookie name must be a non-empty string.");
+        }
+        
+        //set options
+        options = options || {};
+        options.expires = new Date(0);
+        
+        //set cookie
+        return this.set(name, "", options);
+    },
+
+    /**
+     * Sets a cookie with a given name and value.
+     * @param {String} name The name of the cookie to set.
+     * @param {Variant} value The value to set for the cookie.
+     * @param {Object} options (Optional) An object containing one or more
+     *      cookie options: path (a string), domain (a string), expires (a Date object),
+     *      and secure (true/false).
+     * @return {String} The created cookie string.
+     * @method set
+     * @static
+     */
+    set : function (name /*:String*/, value /*:Variant*/, options /*:Object*/) /*:String*/ {
+    
+        var lang = YAHOO.lang;
+    
+        if (!lang.isString(name)){
+            throw new TypeError("Cookie.set(): Cookie name must be a string.");
+        }
+        
+        if (lang.isUndefined(value)){
+            throw new TypeError("Cookie.set(): Value cannot be undefined.");
+        }
+        
+    
+        var text /*:String*/ = this._createCookieString(name, value, true, options);
+        document.cookie = text;
+        return text;
+    },
+        
+    /**
+     * Sets a sub cookie with a given name to a particular value.
+     * @param {String} name The name of the cookie to set.
+     * @param {String} subName The name of the subcookie to set.
+     * @param {Variant} value The value to set.
+     * @param {Object} options (Optional) An object containing one or more
+     *      cookie options: path (a string), domain (a string), expires (a Date object),
+     *      and secure (true/false).
+     * @return {String} The created cookie string.
+     * @method setSub
+     * @static
+     */
+    setSub : function (name /*:String*/, subName /*:String*/, value /*:Variant*/, options /*:Object*/) /*:String*/ {
+        
+        var lang = YAHOO.lang;
+
+        if (!lang.isString(name) || name === ""){
+            throw new TypeError("Cookie.setSub(): Cookie name must be a non-empty string.");
+        }
+
+        if (!lang.isString(subName) || subName === ""){
+            throw new TypeError("Cookie.setSub(): Subcookie name must be a non-empty string.");
+        }
+        
+        if (lang.isUndefined(value)){
+            throw new TypeError("Cookie.setSub(): Subcookie value cannot be undefined.");
+        }
+
+        var hash /*:Object*/ = this.getSubs(name);
+        
+        if (!lang.isObject(hash)){
+            hash = new Object();
+        }
+        
+        hash[subName] = value;        
+        
+        return this.setSubs(name, hash, options);
+        
+    },
+    
+    /**
+     * Sets a cookie with a given name to contain a hash of name-value pairs.
+     * @param {String} name The name of the cookie to set.
+     * @param {Object} value An object containing name-value pairs.
+     * @param {Object} options (Optional) An object containing one or more
+     *      cookie options: path (a string), domain (a string), expires (a Date object),
+     *      and secure (true/false).
+     * @return {String} The created cookie string.
+     * @method setSubs
+     * @static
+     */
+    setSubs : function (name /*:String*/, value /*:Object*/, options /*:Object*/) /*:String*/ {
+        
+        var lang = YAHOO.lang;
+        
+        if (!lang.isString(name)){
+            throw new TypeError("Cookie.setSubs(): Cookie name must be a string.");
+        }
+        
+        if (!lang.isObject(value)){
+            throw new TypeError("Cookie.setSubs(): Cookie value must be an object.");
+        }
+    
+        var text /*:String*/ = this._createCookieString(name, this._createCookieHashString(value), false, options);
+        document.cookie = text;
+        return text;        
+    }    
+
+};
+
+YAHOO.register("cookie", YAHOO.util.Cookie, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/cookie/cookie-beta-min.js
===================================================================
--- trunk/root/static/yui/cookie/cookie-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/cookie/cookie-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+YAHOO.namespace("util");YAHOO.util.Cookie={_createCookieString:function(B,D,C,A){var F=YAHOO.lang;var E=encodeURIComponent(B)+"="+(C?encodeURIComponent(D):D);if(F.isObject(A)){if(A.expires instanceof Date){E+="; expires="+A.expires.toGMTString();}if(F.isString(A.path)&&A.path!=""){E+="; path="+A.path;}if(F.isString(A.domain)&&A.domain!=""){E+="; domain="+A.domain;}if(A.secure===true){E+="; secure";}}return E;},_createCookieHashString:function(B){var D=YAHOO.lang;if(!D.isObject(B)){throw new TypeError("Cookie._createCookieHashString(): Argument must be an object.");}var C=new Array();for(var A in B){if(D.hasOwnProperty(B,A)&&!D.isFunction(B[A])&&!D.isUndefined(B[A])){C.push(encodeURIComponent(A)+"="+encodeURIComponent(String(B[A])));}}return C.join("&");},_parseCookieHash:function(E){var D=E.split("&");var F=null;var C=new Object();for(var B=0,A=D.length;B<A;B++){F=D[B].split("=");C[decodeURIComponent(F[0])]=decodeURIComponent(F[1]);}return C;},_parseCookieString:function(I,!
 A){var J=new Object();if(YAHOO.lang.isString(I)&&I.length>0){var B=(A===false?function(K){return K;}:decodeURIComponent);if(/[^=]+=[^=;]?(?:; [^=]+=[^=]?)?/.test(I)){var G=I.split(/;\s/g);var H=null;var C=null;var E=null;for(var D=0,F=G.length;D<F;D++){E=G[D].match(/([^=]+)=/i);if(E instanceof Array){H=decodeURIComponent(E[1]);C=B(G[D].substring(H.length+1));}else{H=decodeURIComponent(G[D]);C=H;}J[H]=C;}}}return J;},get:function(A,B){var D=YAHOO.lang;var C=this._parseCookieString(document.cookie);if(!D.isString(A)||A===""){throw new TypeError("Cookie.get(): Cookie name must be a non-empty string.");}if(D.isUndefined(C[A])){return null;}if(!D.isFunction(B)){return C[A];}else{return B(C[A]);}},getSub:function(A,C,B){var E=YAHOO.lang;var D=this.getSubs(A);if(D!==null){if(!E.isString(C)||C===""){throw new TypeError("Cookie.getSub(): Subcookie name must be a non-empty string.");}if(E.isUndefined(D[C])){return null;}if(!E.isFunction(B)){return D[C];}else{return B(D[C]);}}else{ret!
 urn null;}},getSubs:function(A){if(!YAHOO.lang.isString(A)||A=!
 ==""){th
row new TypeError("Cookie.getSubs(): Cookie name must be a non-empty string.");}var B=this._parseCookieString(document.cookie,false);if(YAHOO.lang.isString(B[A])){return this._parseCookieHash(B[A]);}return null;},remove:function(B,A){if(!YAHOO.lang.isString(B)||B===""){throw new TypeError("Cookie.remove(): Cookie name must be a non-empty string.");}A=A||{};A.expires=new Date(0);return this.set(B,"",A);},set:function(B,C,A){var E=YAHOO.lang;if(!E.isString(B)){throw new TypeError("Cookie.set(): Cookie name must be a string.");}if(E.isUndefined(C)){throw new TypeError("Cookie.set(): Value cannot be undefined.");}var D=this._createCookieString(B,C,true,A);document.cookie=D;return D;},setSub:function(B,D,C,A){var F=YAHOO.lang;if(!F.isString(B)||B===""){throw new TypeError("Cookie.setSub(): Cookie name must be a non-empty string.");}if(!F.isString(D)||D===""){throw new TypeError("Cookie.setSub(): Subcookie name must be a non-empty string.");}if(F.isUndefined(C)){throw new TypeErro!
 r("Cookie.setSub(): Subcookie value cannot be undefined.");}var E=this.getSubs(B);if(!F.isObject(E)){E=new Object();}E[D]=C;return this.setSubs(B,E,A);},setSubs:function(B,C,A){var E=YAHOO.lang;if(!E.isString(B)){throw new TypeError("Cookie.setSubs(): Cookie name must be a string.");}if(!E.isObject(C)){throw new TypeError("Cookie.setSubs(): Cookie value must be an object.");}var D=this._createCookieString(B,this._createCookieHashString(C),false,A);document.cookie=D;return D;}};YAHOO.register("cookie",YAHOO.util.Cookie,{version:"2.5.1",build:"984"});
\ No newline at end of file

Added: trunk/root/static/yui/cookie/cookie-beta.js
===================================================================
--- trunk/root/static/yui/cookie/cookie-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/cookie/cookie-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,385 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * Utilities for cookie management
+ * @namespace YAHOO.util
+ * @module cookie
+ * @beta
+ */
+YAHOO.namespace("util");
+
+/**
+ * Cookie utility.
+ * @class Cookie
+ * @static
+ */
+YAHOO.util.Cookie = {
+    
+    //-------------------------------------------------------------------------
+    // Private Methods
+    //-------------------------------------------------------------------------
+    
+    /**
+     * Creates a cookie string that can be assigned into document.cookie.
+     * @param {String} name The name of the cookie.
+     * @param {String} value The value of the cookie.
+     * @param {encodeValue} encodeValue True to encode the value, false to leave as-is.
+     * @param {Object} options (Optional) Options for the cookie.
+     * @return {String} The formatted cookie string.
+     * @method _createCookieString
+     * @private
+     * @static
+     */
+    _createCookieString : function (name /*:String*/, value /*:Variant*/, encodeValue /*:Boolean*/, options /*:Object*/) /*:String*/ {
+    
+        //shortcut
+        var lang = YAHOO.lang;
+    
+        var text /*:String*/ = encodeURIComponent(name) + "=" + (encodeValue ? encodeURIComponent(value) : value);
+        
+    
+        if (lang.isObject(options)){
+            //expiration date
+            if (options.expires instanceof Date){
+                text += "; expires=" + options.expires.toGMTString();
+            }
+        
+            //path
+            if (lang.isString(options.path) && options.path != ""){
+                text += "; path=" + options.path;
+            }
+    
+            //domain
+            if (lang.isString(options.domain) && options.domain != ""){
+                text += "; domain=" + options.domain;
+            }
+            
+            //secure
+            if (options.secure === true){
+                text += "; secure";
+            }
+        }
+        
+        return text;
+    },
+    
+    /**
+     * Formats a cookie value for an object containing multiple values.
+     * @param {Object} hash An object of key-value pairs to create a string for.
+     * @return {String} A string suitable for use as a cookie value.
+     * @method _createCookieHash
+     * @private
+     * @static
+     */
+    _createCookieHashString : function (hash /*:Object*/) /*:String*/ {
+        
+        //shortcuts
+        var lang = YAHOO.lang;
+        
+        if (!lang.isObject(hash)){
+            throw new TypeError("Cookie._createCookieHashString(): Argument must be an object.");
+        }
+        
+        var text /*:Array*/ = new Array();
+        
+        for (var key in hash){
+            if (lang.hasOwnProperty(hash, key) && !lang.isFunction(hash[key]) && !lang.isUndefined(hash[key])){
+                text.push(encodeURIComponent(key) + "=" + encodeURIComponent(String(hash[key])));
+            }
+        }
+        
+        return text.join("&");
+    },
+    
+    /**
+     * Parses a cookie hash string into an object.
+     * @param {String} text The cookie hash string to parse. The string should already be URL-decoded.
+     * @return {Object} An object containing entries for each cookie value.
+     * @method _parseCookieHash
+     * @private
+     * @static
+     */
+    _parseCookieHash : function (text /*:String*/) /*:Object*/ {
+    
+        var hashParts /*:Array*/ = text.split("&");
+        var hashPart /*:Array*/ = null;
+        var hash /*:Object*/ = new Object();
+        
+        for (var i=0, len=hashParts.length; i < len; i++){
+            hashPart = hashParts[i].split("=");
+            hash[decodeURIComponent(hashPart[0])] = decodeURIComponent(hashPart[1]);
+        }
+        
+        return hash;
+    },    
+    
+    /**
+     * Parses a cookie string into an object representing all accessible cookies.
+     * @param {String} text The cookie string to parse.
+     * @param {Boolean} decode (Optional) Indicates if the cookie values should be decoded or not. Default is true.
+     * @return {Object} An object containing entries for each accessible cookie.
+     * @method _parseCookieString
+     * @private
+     * @static
+     */
+    _parseCookieString : function (text /*:String*/, decode /*:Boolean*/) /*:Object*/ {
+    
+        var cookies /*:Object*/ = new Object();        
+        
+        if (YAHOO.lang.isString(text) && text.length > 0) {
+        
+            var decodeValue = (decode === false ? function(s){return s;} : decodeURIComponent);
+        
+            if (/[^=]+=[^=;]?(?:; [^=]+=[^=]?)?/.test(text)){            
+                var cookieParts /*:Array*/ = text.split(/;\s/g);
+                var cookieName /*:String*/ = null;
+                var cookieValue /*:String*/ = null;
+                var cookieNameValue /*:Array*/ = null;
+                
+                for (var i=0, len=cookieParts.length; i < len; i++){
+                
+                    //check for normally-formatted cookie (name-value)
+                    cookieNameValue = cookieParts[i].match(/([^=]+)=/i);
+                    if (cookieNameValue instanceof Array){
+                        cookieName = decodeURIComponent(cookieNameValue[1]);
+                        cookieValue = decodeValue(cookieParts[i].substring(cookieName.length+1));
+                    } else {
+                        //means the cookie does not have an "=", so treat it as a boolean flag
+                        cookieName = decodeURIComponent(cookieParts[i]);
+                        cookieValue = cookieName;
+                    }
+                    cookies[cookieName] = cookieValue;
+                }
+            }
+        }
+        
+        return cookies;
+    },    
+    
+    //-------------------------------------------------------------------------
+    // Public Methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Returns the cookie value for the given name.
+     * @param {String} name The name of the cookie to retrieve.
+     * @param {Function} converter (Optional) A function to run on the value before returning
+     *      it. The function is not used if the cookie doesn't exist.
+     * @return {Variant} If no converter is specified, returns a string or null if
+     *      the cookie doesn't exist. If the converter is specified, returns the value
+     *      returned from the converter or null if the cookie doesn't exist.
+     * @method get
+     * @static
+     */
+    get : function (name /*:String*/, converter /*:Function*/) /*:Variant*/{
+        
+        var lang = YAHOO.lang;
+        var cookies /*:Object*/ = this._parseCookieString(document.cookie);        
+        
+        if (!lang.isString(name) || name === ""){
+            throw new TypeError("Cookie.get(): Cookie name must be a non-empty string.");
+        }
+        
+        if (lang.isUndefined(cookies[name])) {
+            return null;
+        }
+        
+        if (!lang.isFunction(converter)){
+            return cookies[name];
+        } else {
+            return converter(cookies[name]);
+        }
+    },
+    
+    /**
+     * Returns the value of a subcookie.
+     * @param {String} name The name of the cookie to retrieve.
+     * @param {String} subName The name of the subcookie to retrieve.
+     * @param {Function} converter (Optional) A function to run on the value before returning
+     *      it. The function is not used if the cookie doesn't exist.
+     * @return {Variant} If the cookie doesn't exist, null is returned. If the subcookie
+     *      doesn't exist, null if also returned. If no converter is specified and the
+     *      subcookie exists, a string is returned. If a converter is specified and the
+     *      subcookie exists, the value returned from the converter is returned.
+     * @method getSub
+     * @static
+     */
+    getSub : function (name /*:String*/, subName /*:String*/, converter /*:Function*/) /*:Variant*/ {
+    
+        var lang = YAHOO.lang;    
+        var hash /*:Variant*/ = this.getSubs(name);  
+
+        if (hash !== null) {
+            
+            if (!lang.isString(subName) || subName === ""){
+                throw new TypeError("Cookie.getSub(): Subcookie name must be a non-empty string.");
+            }
+            
+            if (lang.isUndefined(hash[subName])){
+                return null;
+            }            
+        
+            if (!lang.isFunction(converter)){
+                return hash[subName];
+            } else {
+                return converter(hash[subName]);
+            }
+        } else {
+            return null;
+        }
+    
+    },
+    
+    /**
+     * Returns an object containing name-value pairs stored in the cookie with the given name.
+     * @param {String} name The name of the cookie to retrieve.
+     * @return {Object} An object of name-value pairs if the cookie with the given name
+     *      exists, null if it does not.
+     * @method getHash
+     * @static
+     */
+    getSubs : function (name /*:String*/) /*:Object*/ {
+        
+        //check cookie name
+        if (!YAHOO.lang.isString(name) || name === ""){
+            throw new TypeError("Cookie.getSubs(): Cookie name must be a non-empty string.");
+        }
+        
+        var cookies = this._parseCookieString(document.cookie, false);
+        if (YAHOO.lang.isString(cookies[name])){
+            return this._parseCookieHash(cookies[name]);
+        }
+        return null;
+    },
+    
+    /**
+     * Removes a cookie from the machine by setting its expiration date to
+     * sometime in the past.
+     * @param {String} name The name of the cookie to remove.
+     * @param {Object} options (Optional) An object containing one or more
+     *      cookie options: path (a string), domain (a string), 
+     *      and secure (true/false). The expires option will be overwritten
+     *      by the method.
+     * @return {String} The created cookie string.
+     * @method remove
+     * @static
+     */
+    remove : function (name /*:String*/, options /*:Object*/) /*:String*/ {
+        
+        //check cookie name
+        if (!YAHOO.lang.isString(name) || name === ""){
+            throw new TypeError("Cookie.remove(): Cookie name must be a non-empty string.");
+        }
+        
+        //set options
+        options = options || {};
+        options.expires = new Date(0);
+        
+        //set cookie
+        return this.set(name, "", options);
+    },
+
+    /**
+     * Sets a cookie with a given name and value.
+     * @param {String} name The name of the cookie to set.
+     * @param {Variant} value The value to set for the cookie.
+     * @param {Object} options (Optional) An object containing one or more
+     *      cookie options: path (a string), domain (a string), expires (a Date object),
+     *      and secure (true/false).
+     * @return {String} The created cookie string.
+     * @method set
+     * @static
+     */
+    set : function (name /*:String*/, value /*:Variant*/, options /*:Object*/) /*:String*/ {
+    
+        var lang = YAHOO.lang;
+    
+        if (!lang.isString(name)){
+            throw new TypeError("Cookie.set(): Cookie name must be a string.");
+        }
+        
+        if (lang.isUndefined(value)){
+            throw new TypeError("Cookie.set(): Value cannot be undefined.");
+        }
+        
+    
+        var text /*:String*/ = this._createCookieString(name, value, true, options);
+        document.cookie = text;
+        return text;
+    },
+        
+    /**
+     * Sets a sub cookie with a given name to a particular value.
+     * @param {String} name The name of the cookie to set.
+     * @param {String} subName The name of the subcookie to set.
+     * @param {Variant} value The value to set.
+     * @param {Object} options (Optional) An object containing one or more
+     *      cookie options: path (a string), domain (a string), expires (a Date object),
+     *      and secure (true/false).
+     * @return {String} The created cookie string.
+     * @method setSub
+     * @static
+     */
+    setSub : function (name /*:String*/, subName /*:String*/, value /*:Variant*/, options /*:Object*/) /*:String*/ {
+        
+        var lang = YAHOO.lang;
+
+        if (!lang.isString(name) || name === ""){
+            throw new TypeError("Cookie.setSub(): Cookie name must be a non-empty string.");
+        }
+
+        if (!lang.isString(subName) || subName === ""){
+            throw new TypeError("Cookie.setSub(): Subcookie name must be a non-empty string.");
+        }
+        
+        if (lang.isUndefined(value)){
+            throw new TypeError("Cookie.setSub(): Subcookie value cannot be undefined.");
+        }
+
+        var hash /*:Object*/ = this.getSubs(name);
+        
+        if (!lang.isObject(hash)){
+            hash = new Object();
+        }
+        
+        hash[subName] = value;        
+        
+        return this.setSubs(name, hash, options);
+        
+    },
+    
+    /**
+     * Sets a cookie with a given name to contain a hash of name-value pairs.
+     * @param {String} name The name of the cookie to set.
+     * @param {Object} value An object containing name-value pairs.
+     * @param {Object} options (Optional) An object containing one or more
+     *      cookie options: path (a string), domain (a string), expires (a Date object),
+     *      and secure (true/false).
+     * @return {String} The created cookie string.
+     * @method setSubs
+     * @static
+     */
+    setSubs : function (name /*:String*/, value /*:Object*/, options /*:Object*/) /*:String*/ {
+        
+        var lang = YAHOO.lang;
+        
+        if (!lang.isString(name)){
+            throw new TypeError("Cookie.setSubs(): Cookie name must be a string.");
+        }
+        
+        if (!lang.isObject(value)){
+            throw new TypeError("Cookie.setSubs(): Cookie value must be an object.");
+        }
+    
+        var text /*:String*/ = this._createCookieString(name, this._createCookieHashString(value), false, options);
+        document.cookie = text;
+        return text;        
+    }    
+
+};
+
+YAHOO.register("cookie", YAHOO.util.Cookie, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/datasource/README
===================================================================
--- trunk/root/static/yui/datasource/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/datasource/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,11 +1,53 @@
 DataSource Release Notes
 
-**** version 2.4.1 ***
+**** version 2.5.1 ****
 
-No change
+* Replaced custom function parsing with parsed/walked value locators for
+    responseSchema.resultsList, .fields, etc
+* Added metaFields to responseSchema to capture arbitrary response data
 
-**** version 2.4.0 ***
+**** version 2.5.0 ****
 
+* doBeforeCallback() - The second argument is now oFullResponse rather than oRawResponse.
+* handleResponse() -
+      o oCallback is now an object literal pointing to success and failure
+      handlers and can contain scope and argument values.
+      o The oCaller argument is now deprecated.
+      o When callback function is passed oRequest and oParsedResponse values,
+      the oParsedResponse object now consistently returns the following values:
+            + tId (Number)
+            + results (Array)
+            + error (Boolean)
+            + totalResults (Number) (when available)
+* makeConnection() -
+      o oCallback is now an object literal pointing to success and failure
+      handlers and can contain scope and argument values.
+      o The oCaller argument is now deprecated.
+* parseArrayData() - The second argument is now oFullResponse rather than oRawResponse.
+* parseHTMLTableData() - The second argument is now oFullResponse rather than oRawResponse.
+* parseJsonData() - The second argument is now oFullResponse rather than oRawResponse.
+* parseTextData() - The second argument is now oFullResponse rather than oRawResponse.
+* parseXMLData() - The second argument is now oFullResponse rather than oRawResponse.
+* sendRequest() -
+      o oCallback is now an object literal pointing to success and failure
+      handlers and can contain scope and argument values.
+      o The oCaller argument is now deprecated.
+* setInterval() -
+      o oCallback is now an object literal pointing to success and failure
+      handlers and can contain scope and argument values.
+      o The oCaller argument is now deprecated.
+* cacheRequestEvent - oArgs.caller is now deprecated in favor of oCallback object literal.
+* dataErrorEvent - oArgs.caller is now deprecated in favor of oCallback object literal.
+* getCachedResponseEvent - oArgs.caller is now deprecated in favor of oCallback object literal.
+* requestEvent - oArgs.caller is now deprecated in favor of oCallback object literal.
+* responseCacheEvent - oArgs.caller is now deprecated in favor of oCallback object literal.
+* responseEvent - oArgs.caller is now deprecated in favor of oCallback object literal.
+* responseParseEvent - oArgs.caller is now deprecated in favor of oCallback object literal.
+
+
+
+**** version 2.4.0 ****
+
 * Support for YUI JSON Utility.
 
 * Implemented setInterval(), clearInterval(), and clearAllIntervals() for polling.
@@ -14,7 +56,7 @@
 
 
 
-**** version 2.3.1 ***
+**** version 2.3.1 ****
 
 * No changes.
 

Modified: trunk/root/static/yui/datasource/datasource-beta-debug.js
===================================================================
--- trunk/root/static/yui/datasource/datasource-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/datasource/datasource-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The DataSource utility provides a common configurable interface for widgets
@@ -34,20 +34,14 @@
  * @param oConfigs {Object} (optional) Object literal of configuration values.
  */
 YAHOO.util.DataSource = function(oLiveData, oConfigs) {
-    // Set any config params passed in to override defaults
-    if(oConfigs && (oConfigs.constructor == Object)) {
-        for(var sConfig in oConfigs) {
-            if(sConfig) {
-                this[sConfig] = oConfigs[sConfig];
-            }
-        }
-    }
-    
     if(!oLiveData) {
         YAHOO.log("Could not instantiate DataSource due to invalid live database",
                 "error", this.toString());
         return;
     }
+    
+    this.liveData = oLiveData;
+    this._oQueue = {interval:null, conn:null, requests:[]};
 
     if(oLiveData.nodeType && oLiveData.nodeType == 9) {
         this.dataType = YAHOO.util.DataSource.TYPE_XML;
@@ -63,6 +57,7 @@
     }
     else if(oLiveData.nodeName && (oLiveData.nodeName.toLowerCase() == "table")) {
         this.dataType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
+        this.liveData = oLiveData.cloneNode(true);
     }
     else if(YAHOO.lang.isObject(oLiveData)) {
         this.dataType = YAHOO.util.DataSource.TYPE_JSON;
@@ -71,22 +66,21 @@
         this.dataType = YAHOO.util.DataSource.TYPE_UNKNOWN;
     }
 
-    this.liveData = oLiveData;
-    this._oQueue = {interval:null, conn:null, requests:[]};
-
-
+    // Set any config params passed in to override defaults
+    if(oConfigs && (oConfigs.constructor == Object)) {
+        for(var sConfig in oConfigs) {
+            if(sConfig) {
+                this[sConfig] = oConfigs[sConfig];
+            }
+        }
+    }
+    
     // Validate and initialize public configs
     var maxCacheEntries = this.maxCacheEntries;
     if(!YAHOO.lang.isNumber(maxCacheEntries) || (maxCacheEntries < 0)) {
         maxCacheEntries = 0;
     }
 
-    // Initialize local cache
-    if(maxCacheEntries > 0 && !this._aCache) {
-        this._aCache = [];
-        YAHOO.log("Cache initialized", "info", this.toString());
-    }
-    
     // Initialize interval tracker
     this._aIntervals = [];
 
@@ -107,18 +101,18 @@
      * @event cacheRequestEvent
      * @param oArgs.request {Object} The request object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      */
     this.createEvent("cacheRequestEvent");
 
     /**
      * Fired when data is retrieved from the local cache.
      *
-     * @event getCachedResponseEvent
+     * @event cacheResponseEvent
      * @param oArgs.request {Object} The request object.
      * @param oArgs.response {Object} The response object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      * @param oArgs.tId {Number} Transaction ID.
      */
     this.createEvent("cacheResponseEvent");
@@ -129,7 +123,7 @@
      * @event requestEvent
      * @param oArgs.request {Object} The request object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      */
     this.createEvent("requestEvent");
 
@@ -140,7 +134,7 @@
      * @param oArgs.request {Object} The request object.
      * @param oArgs.response {Object} The raw response object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      */
     this.createEvent("responseEvent");
 
@@ -151,7 +145,7 @@
      * @param oArgs.request {Object} The request object.
      * @param oArgs.response {Object} The parsed response object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      */
     this.createEvent("responseParseEvent");
 
@@ -162,7 +156,7 @@
      * @param oArgs.request {Object} The request object.
      * @param oArgs.response {Object} The parsed response object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      */
     this.createEvent("responseCacheEvent");
     /**
@@ -171,7 +165,7 @@
      * @event dataErrorEvent
      * @param oArgs.request {Object} The request object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      * @param oArgs.message {String} The error message.
      */
     this.createEvent("dataErrorEvent");
@@ -419,6 +413,8 @@
  * <dt>fieldDelim</dt> <dd>Field delimiter (text data only)</dd>
  * <dt>fields</dt> <dd>Array of field names (aka keys), or array of object literals
  * such as: {key:"fieldname",parser:YAHOO.util.DataSource.parseDate}</dd>
+ * <dt>metaFields</dt> <dd>Object literal of keys to include in the oParsedResponse.meta collection</dd>
+ * <dt>metaNode</dt> <dd>Name of the node under which to search for meta information in XML response data</dd>
  * </dl>
  *
  * @property responseSchema
@@ -427,8 +423,7 @@
 YAHOO.util.DataSource.prototype.responseSchema = null;
 
  /**
- * Alias to YUI Connection Manager. Allows implementers to specify their own
- * subclasses of the YUI Connection Manager utility.
+ * Alias to YUI Connection Manager, to allow implementers to customize the utility.
  *
  * @property connMgr
  * @type Object
@@ -614,34 +609,55 @@
  */
 YAHOO.util.DataSource.prototype.getCachedResponse = function(oRequest, oCallback, oCaller) {
     var aCache = this._aCache;
-    var nCacheLength = (aCache) ? aCache.length : 0;
-    var oResponse = null;
 
     // If cache is enabled...
-    if((this.maxCacheEntries > 0) && aCache && (nCacheLength > 0)) {
-        this.fireEvent("cacheRequestEvent", {request:oRequest,callback:oCallback,caller:oCaller});
-
-        // Loop through each cached element
-        for(var i = nCacheLength-1; i >= 0; i--) {
-            var oCacheElem = aCache[i];
-
-            // Defer cache hit logic to a public overridable method
-            if(this.isCacheHit(oRequest,oCacheElem.request)) {
-                // Grab the cached response
-                oResponse = oCacheElem.response;
-                // The cache returned a hit!
-                // Remove element from its original location
-                aCache.splice(i,1);
-                // Add as newest
-                this.addToCache(oRequest, oResponse);
-                this.fireEvent("cacheResponseEvent", {request:oRequest,response:oResponse,callback:oCallback,caller:oCaller});
-                break;
+    if(this.maxCacheEntries > 0) {        
+        // Initialize local cache
+        if(!aCache) {
+            this._aCache = [];
+            YAHOO.log("Cache initialized", "info", this.toString());
+        }
+        // Look in local cache
+        else {
+            var nCacheLength = aCache.length;
+            if(nCacheLength > 0) {
+                var oResponse = null;
+                this.fireEvent("cacheRequestEvent", {request:oRequest,callback:oCallback,caller:oCaller});
+        
+                // Loop through each cached element
+                for(var i = nCacheLength-1; i >= 0; i--) {
+                    var oCacheElem = aCache[i];
+        
+                    // Defer cache hit logic to a public overridable method
+                    if(this.isCacheHit(oRequest,oCacheElem.request)) {
+                        // The cache returned a hit!
+                        // Grab the cached response
+                        oResponse = oCacheElem.response;
+                        this.fireEvent("cacheResponseEvent", {request:oRequest,response:oResponse,callback:oCallback,caller:oCaller});
+                        
+                        // Refresh the position of the cache hit
+                        if(i < nCacheLength-1) {
+                            YAHOO.log("Refreshing cache position of the response for \"" +  oRequest + "\"", "info", this.toString());
+                            // Remove element from its original location
+                            aCache.splice(i,1);
+                            YAHOO.log("Cleared from cache the response for \"" +  oRequest + "\"", "info", this.toString());
+                            // Add as newest
+                            this.addToCache(oRequest, oResponse);
+                        }
+                        break;
+                    }
+                }
+                YAHOO.log("The cached response for \"" + YAHOO.lang.dump(oRequest) +
+                        "\" is " + YAHOO.lang.dump(oResponse), "info", this.toString());
+                return oResponse;
             }
         }
     }
-    YAHOO.log("The cached response for \"" + YAHOO.lang.dump(oRequest) +
-            "\" is " + YAHOO.lang.dump(oResponse), "info", this.toString());
-    return oResponse;
+    else if(aCache) {
+        this._aCache = null;
+        YAHOO.log("Cache destroyed", "info", this.toString());
+    }
+    return null;
 };
 
 /**
@@ -672,8 +688,6 @@
         return;
     }
 
-    //TODO: check for duplicate entries
-
     // If the cache is full, make room by removing stalest element (index=0)
     while(aCache.length >= this.maxCacheEntries) {
         aCache.shift();
@@ -681,7 +695,7 @@
 
     // Add to cache in the newest position, at the end of the array
     var oCacheElem = {request:oRequest,response:oResponse};
-    aCache.push(oCacheElem);
+    aCache[aCache.length] = oCacheElem;
     this.fireEvent("responseCacheEvent", {request:oRequest,response:oResponse});
     YAHOO.log("Cached the response for \"" +  oRequest + "\"", "info", this.toString());
 };
@@ -707,12 +721,11 @@
  * @param nMsec {Number} Length of interval in milliseconds.
  * @param oRequest {Object} Request object.
  * @param oCallback {Function} Handler function to receive the response.
- * @param oCaller {Object} The Calling object that is making the request.
+ * @param oCaller {Object} (deprecated) Use oCallback.scope.
  * @return {Number} Interval ID.
  */
 YAHOO.util.DataSource.prototype.setInterval = function(nMsec, oRequest, oCallback, oCaller) {
-    //TODO: management and cleanup of interval IDs
-    try {
+    if(YAHOO.lang.isNumber(nMsec) && (nMsec >= 0)) {
         YAHOO.log("Enabling polling to live data for \"" + oRequest + "\" at interval " + nMsec, "info", this.toString());
         var oSelf = this;
         var nId = setInterval(function() {
@@ -721,7 +734,7 @@
         this._aIntervals.push(nId);
         return nId;
     }
-    catch(e) {
+    else {
         YAHOO.log("Could not enable polling to live data for \"" + oRequest + "\" at interval " + nMsec, "info", this.toString());
     }
 };
@@ -757,19 +770,54 @@
 };
 
 /**
+ * Executes a configured callback.  For object literal callbacks, the third
+ * param determines whether to execute the success handler or failure handler.
+ * @method issueCallback
+ * @param callback {Function|Object} the callback to execute
+ * @param params {Array} params to be passed to the callback method
+ * @param error {Boolean} whether an error occurred
+ * @param scope {Object} the scope from which to execute the callback
+ * (deprecated - use an object literal callback)
+ */
+YAHOO.util.DataSource.issueCallback = function (callback,params,error,scope) {
+    if (YAHOO.lang.isFunction(callback)) {
+        callback.apply(scope, params);
+    } else if (YAHOO.lang.isObject(callback)) {
+        scope = callback.scope || scope || window;
+        var callbackFunc = callback.success;
+        if (error) {
+            callbackFunc = callback.failure;
+        }
+        if (callbackFunc) {
+            callbackFunc.apply(scope, params.concat([callback.argument]));
+        }
+    }
+};
+
+/**
  * First looks for cached response, then sends request to live data.
  *
  * @method sendRequest
  * @param oRequest {Object} Request object.
- * @param oCallback {Function} Handler function to receive the response.
- * @param oCaller {Object} The Calling object that is making the request.
+ * @param oCallback {Object} An object literal with the following properties:
+ *     <dl>
+ *     <dt><code>success</code></dt>
+ *     <dd>The function to call when the data is ready.</dd>
+ *     <dt><code>failure</code></dt>
+ *     <dd>The function to call upon a response failure condition.</dd>
+ *     <dt><code>scope</code></dt>
+ *     <dd>The object to serve as the scope for the success and failure handlers.</dd>
+ *     <dt><code>argument</code></dt>
+ *     <dd>Arbitrary data that will be passed back to the success and failure handlers.</dd>
+ *     </dl> 
+ * @param oCaller {Object} (deprecated) Use oCallback.scope.
  * @return {Number} Transaction ID, or null if response found in cache.
  */
 YAHOO.util.DataSource.prototype.sendRequest = function(oRequest, oCallback, oCaller) {
     // First look in cache
     var oCachedResponse = this.getCachedResponse(oRequest, oCallback, oCaller);
     if(oCachedResponse) {
-        oCallback.call(oCaller, oRequest, oCachedResponse);
+        YAHOO.util.DataSource.issueCallback(oCallback,[oRequest,oCachedResponse],false,oCaller);
         return null;
     }
 
@@ -786,8 +834,8 @@
  *
  * @method makeConnection
  * @param oRequest {Object} Request object.
- * @param oCallback {Function} Handler function to receive the response.
- * @param oCaller {Object} The Calling object that is making the request.
+ * @param oCallback {Object} Callback object literal.
+ * @param oCaller {Object} (deprecated) Use oCallback.scope.
  * @return {Number} Transaction ID.
  */
 YAHOO.util.DataSource.prototype.makeConnection = function(oRequest, oCallback, oCaller) {
@@ -836,7 +884,8 @@
                     YAHOO.log(YAHOO.util.DataSource.ERROR_DATANULL, "error", this.toString());
 
                     // Send error response back to the caller with the error flag on
-                    oCallback.call(oCaller, oRequest, oResponse, true);
+                    // TODO: should this send oResponse, considering the fork?
+                    YAHOO.util.DataSource.issueCallback(oCallback,[oRequest, {error:true}], true, oCaller);
 
                     return null;
                 }
@@ -869,7 +918,10 @@
                 }
 
                 // Send failure response back to the caller with the error flag on
-                oCallback.call(oCaller, oRequest, oResponse, true);
+                oResponse = oResponse || {};
+                oResponse.error = true;
+                YAHOO.util.DataSource.issueCallback(oCallback,[oRequest,oResponse],true, oCaller);
+
                 return null;
             };
 
@@ -960,7 +1012,7 @@
             else {
                 YAHOO.log("Could not find Connection Manager asyncRequest() function", "error", this.toString());
                 // Send null response back to the caller with the error flag on
-                oCallback.call(oCaller, oRequest, null, true);
+                YAHOO.util.DataSource.issueCallback(oCallback,[oRequest,{error:true}],true,oCaller);
             }
 
             break;
@@ -981,23 +1033,24 @@
 };
 
 /**
- * Handles raw data response from live data source. Sends a parsed response object
- * to the callback function in this format:
+ * Receives raw data response and type converts to XML, JSON, etc as necessary.
+ * Forwards oFullResponse to appropriate parsing function to get turned into
+ * oParsedResponse. Calls doBeforeCallback() and adds oParsedResponse to 
+ * the cache when appropriate before calling issueCallback().
+ * 
+ * The oParsedResponse object literal has the following properties:
+ * <dl>
+ *     <dd><dt>tId {Number}</dt> Unique transaction ID</dd>
+ *     <dd><dt>results {Array}</dt> Array of parsed data results</dd>
+ *     <dd><dt>error {Boolean}</dt> True if there was an error</dd>
+ *     <dd><dt>totalRecords {Number}</dt> Total number of records (if available)</dd> 
+ * </dl>
  *
- * fnCallback(oRequest, oParsedResponse)
- *
- * where the oParsedResponse object literal with the following properties:
- * <ul>
- *     <li>tId {Number} Unique transaction ID</li>
- *     <li>results {Array} Array of parsed data results</li>
- *     <li>error {Boolean} True if there was an error</li>
- * </ul>
- *
  * @method handleResponse
  * @param oRequest {Object} Request object
  * @param oRawResponse {Object} The raw response from the live database.
- * @param oCallback {Function} Handler function to receive the response.
- * @param oCaller {Object} The calling object that is making the request.
+ * @param oCallback {Object} Callback object literal.
+ * @param oCaller {Object} (deprecated) Use oCallback.scope.
  * @param tId {Number} Transaction ID.
  */
 YAHOO.util.DataSource.prototype.handleResponse = function(oRequest, oRawResponse, oCallback, oCaller, tId) {
@@ -1006,88 +1059,131 @@
     YAHOO.log("Received live data response for \"" + oRequest + "\"", "info", this.toString());
     var xhr = (this.dataType == YAHOO.util.DataSource.TYPE_XHR) ? true : false;
     var oParsedResponse = null;
-    var bError = false;
+    var oFullResponse = oRawResponse;
 
-    // Access to the raw response before it gets parsed
-    oRawResponse = this.doBeforeParseData(oRequest, oRawResponse);
-
     switch(this.responseType) {
         case YAHOO.util.DataSource.TYPE_JSARRAY:
             if(xhr && oRawResponse.responseText) {
-                oRawResponse = oRawResponse.responseText;
+                oFullResponse = oRawResponse.responseText; 
             }
-            oParsedResponse = this.parseArrayData(oRequest, oRawResponse);
+            oFullResponse = this.doBeforeParseData(oRequest, oFullResponse);
+            oParsedResponse = this.parseArrayData(oRequest, oFullResponse);
             break;
         case YAHOO.util.DataSource.TYPE_JSON:
             if(xhr && oRawResponse.responseText) {
-                oRawResponse = oRawResponse.responseText;
+                oFullResponse = oRawResponse.responseText;
             }
-            oParsedResponse = this.parseJSONData(oRequest, oRawResponse);
+            try {
+                // Convert to JSON object if it's a string
+                if(YAHOO.lang.isString(oFullResponse)) {
+                    // Check for YUI JSON Util
+                    if(YAHOO.lang.JSON) {
+                        oFullResponse = YAHOO.lang.JSON.parse(oFullResponse);
+                    }
+                    // Look for JSON parsers using an API similar to json2.js
+                    else if(window.JSON && JSON.parse) {
+                        oFullResponse = JSON.parse(oFullResponse);
+                    }
+                    // Look for JSON parsers using an API similar to json.js
+                    else if(oFullResponse.parseJSON) {
+                        oFullResponse = oFullResponse.parseJSON();
+                    }
+                    // No JSON lib found so parse the string
+                    else {
+                        // Trim leading spaces
+                        while (oFullResponse.length > 0 &&
+                                (oFullResponse.charAt(0) != "{") &&
+                                (oFullResponse.charAt(0) != "[")) {
+                            oFullResponse = oFullResponse.substring(1, oFullResponse.length);
+                        }
+    
+                        if(oFullResponse.length > 0) {
+                            // Strip extraneous stuff at the end
+                            var objEnd = Math.max(oFullResponse.lastIndexOf("]"),oFullResponse.lastIndexOf("}"));
+                            oFullResponse = oFullResponse.substring(0,objEnd+1);
+    
+                            // Turn the string into an object literal...
+                            // ...eval is necessary here
+                            oFullResponse = eval("(" + oFullResponse + ")");
+    
+                        }
+                    }
+                }
+            }
+            catch(e) {
+            }
+
+            oFullResponse = this.doBeforeParseData(oRequest, oFullResponse);
+            oParsedResponse = this.parseJSONData(oRequest, oFullResponse);
             break;
         case YAHOO.util.DataSource.TYPE_HTMLTABLE:
             if(xhr && oRawResponse.responseText) {
-                oRawResponse = oRawResponse.responseText;
+                oFullResponse = oRawResponse.responseText;
             }
-            oParsedResponse = this.parseHTMLTableData(oRequest, oRawResponse);
+            oFullResponse = this.doBeforeParseData(oRequest, oFullResponse);
+            oParsedResponse = this.parseHTMLTableData(oRequest, oFullResponse);
             break;
         case YAHOO.util.DataSource.TYPE_XML:
             if(xhr && oRawResponse.responseXML) {
-                oRawResponse = oRawResponse.responseXML;
+                oFullResponse = oRawResponse.responseXML;
             }
-            oParsedResponse = this.parseXMLData(oRequest, oRawResponse);
+            oFullResponse = this.doBeforeParseData(oRequest, oFullResponse);
+            oParsedResponse = this.parseXMLData(oRequest, oFullResponse);
             break;
         case YAHOO.util.DataSource.TYPE_TEXT:
             if(xhr && oRawResponse.responseText) {
-                oRawResponse = oRawResponse.responseText;
+                oFullResponse = oRawResponse.responseText;
             }
-            oParsedResponse = this.parseTextData(oRequest, oRawResponse);
+            oFullResponse = this.doBeforeParseData(oRequest, oFullResponse);
+            oParsedResponse = this.parseTextData(oRequest, oFullResponse);
             break;
         default:
             //var contentType = oRawResponse.getResponseHeader["Content-Type"];
-            YAHOO.log("Could not parse data for request \"" + oRequest +
-                    "\" due to unknown response type", "error", this.toString());
+            YAHOO.log("Passing along unknown response type", "warn", this.toString());
+            oFullResponse = this.doBeforeParseData(oRequest, oFullResponse);
+            oParsedResponse = this.doBeforeParseData(oRequest, oFullResponse);
             break;
     }
 
-
-    if(oParsedResponse) {
+    if(oParsedResponse && !oParsedResponse.error) {
         // Last chance to touch the raw response or the parsed response
-        oParsedResponse.tId = tId;
-        oParsedResponse = this.doBeforeCallback(oRequest, oRawResponse, oParsedResponse);
+        oParsedResponse = this.doBeforeCallback(oRequest, oFullResponse, oParsedResponse);
         this.fireEvent("responseParseEvent", {request:oRequest,
                 response:oParsedResponse, callback:oCallback, caller:oCaller});
         // Cache the response
         this.addToCache(oRequest, oParsedResponse);
     }
     else {
-        this.fireEvent("dataErrorEvent", {request:oRequest, callback:oCallback,
+        this.fireEvent("dataErrorEvent", {request:oRequest, response: oRawResponse, callback:oCallback, 
                 caller:oCaller, message:YAHOO.util.DataSource.ERROR_DATANULL});
         YAHOO.log(YAHOO.util.DataSource.ERROR_DATANULL, "error", this.toString());
         
-        // Send response back to the caller with the error flag on
-        oParsedResponse = {error:true};
+        // Be sure the error flag is on
+        oParsedResponse = oParsedResponse || {};
+        oParsedResponse.error = true;
     }
-    
+
     // Send the response back to the caller
-    oCallback.call(oCaller, oRequest, oParsedResponse);
+    oParsedResponse.tId = tId;
+    YAHOO.util.DataSource.issueCallback(oCallback,[oRequest,oParsedResponse],oParsedResponse.error,oCaller);
 };
 
 /**
- * Overridable method gives implementers access to the original raw response
+ * Overridable method gives implementers access to the original full response
  * before the data gets parsed. Implementers should take care not to return an
- * unparsable or otherwise invalid raw response.
+ * unparsable or otherwise invalid response.
  *
  * @method doBeforeParseData
  * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
- * @return {Object} Raw response for parsing.
+ * @param oFullResponse {Object} The full response from the live database.
+ * @return {Object} Full response for parsing.
  */
-YAHOO.util.DataSource.prototype.doBeforeParseData = function(oRequest, oRawResponse) {
-    return oRawResponse;
+YAHOO.util.DataSource.prototype.doBeforeParseData = function(oRequest, oFullResponse) {
+    return oFullResponse;
 };
 
 /**
- * Overridable method gives implementers access to the original raw response and
+ * Overridable method gives implementers access to the original full response and
  * the parsed response (parsed against the given schema) before the data
  * is added to the cache (if applicable) and then sent back to callback function.
  * This is your chance to access the raw response and/or populate the parsed
@@ -1095,340 +1191,261 @@
  *
  * @method doBeforeCallback
  * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
+ * @param oFullResponse {Object} The full response from the live database.
  * @param oParsedResponse {Object} The parsed response to return to calling object.
  * @return {Object} Parsed response object.
  */
-YAHOO.util.DataSource.prototype.doBeforeCallback = function(oRequest, oRawResponse, oParsedResponse) {
+YAHOO.util.DataSource.prototype.doBeforeCallback = function(oRequest, oFullResponse, oParsedResponse) {
     return oParsedResponse;
 };
 
 /**
- * Overridable method parses raw array data into a response object.
+ * Overridable method parses Array data into a response object.
  *
  * @method parseArrayData
  * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
- * @return {Object} Parsed response object.
+ * @param oFullResponse {Object} The full Array from the live database.
+ * @return {Object} Parsed response object with the following properties:<br>
+ *     - results (Array) Array of parsed data results<br>
+ *     - error (Boolean) True if there was an error<br>
+ *     - totalRecords (Number) Total number of records (if available)
  */
-YAHOO.util.DataSource.prototype.parseArrayData = function(oRequest, oRawResponse) {
-    if(YAHOO.lang.isArray(oRawResponse) && YAHOO.lang.isArray(this.responseSchema.fields)) {
-        var oParsedResponse = {results:[]};
-        var fields = this.responseSchema.fields;
-        for(var i=oRawResponse.length-1; i>-1; i--) {
-            var oResult = {};
-            for(var j=fields.length-1; j>-1; j--) {
-                var field = fields[j];
-                var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
-                var data = (YAHOO.lang.isValue(oRawResponse[i][j])) ? oRawResponse[i][j] : oRawResponse[i][key];
-                // Backward compatibility
-                if(!field.parser && field.converter) {
-                    field.parser = field.converter;
-                    YAHOO.log("The field property converter has been deprecated" +
-                            " in favor of parser", "warn", this.toString());
+YAHOO.util.DataSource.prototype.parseArrayData = function(oRequest, oFullResponse) {
+    if(YAHOO.lang.isArray(oFullResponse)) {
+        if(YAHOO.lang.isArray(this.responseSchema.fields)) {
+            var results = [],
+                fields = this.responseSchema.fields,
+                i;
+            for (i = fields.length - 1; i >= 0; --i) {
+                if (typeof fields[i] !== 'object') {
+                    fields[i] = { key : fields[i] };
                 }
-                if(field.parser) {
-                    data = field.parser.call(this, data);
+            }
+
+            var parsers = {};
+            for (i = fields.length - 1; i >= 0; --i) {
+                var p = fields[i].parser || fields[i].converter;
+                if (p) {
+                    parsers[fields[i].key] = p;
                 }
-                // Safety measure
-                if(data === undefined) {
-                    data = null;
-                }
-                oResult[key] = data;
             }
-            oParsedResponse.results.unshift(oResult);
-        }
-        YAHOO.log("Parsed array data is " +
-                YAHOO.lang.dump(oParsedResponse), "info", this.toString());
-        return oParsedResponse;
-    }
-    else {
-        YAHOO.log("Array data could not be parsed: " +
-                YAHOO.lang.dump(oRawResponse), "error", this.toString());
-        return null;
-    }
-};
 
-/**
- * Overridable method parses raw plain text data into a response object.
- *
- * @method parseTextData
- * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
- * @return {Object} Parsed response object.
- */
-YAHOO.util.DataSource.prototype.parseTextData = function(oRequest, oRawResponse) {
-    var oParsedResponse = {};
-    if(YAHOO.lang.isString(oRawResponse) &&
-            YAHOO.lang.isArray(this.responseSchema.fields) &&
-            YAHOO.lang.isString(this.responseSchema.recordDelim) &&
-            YAHOO.lang.isString(this.responseSchema.fieldDelim)) {
-        oParsedResponse.results = [];
-        var recDelim = this.responseSchema.recordDelim;
-        var fieldDelim = this.responseSchema.fieldDelim;
-        var fields = this.responseSchema.fields;
-        if(oRawResponse.length > 0) {
-            // Delete the last line delimiter at the end of the data if it exists
-            var newLength = oRawResponse.length-recDelim.length;
-            if(oRawResponse.substr(newLength) == recDelim) {
-                oRawResponse = oRawResponse.substr(0, newLength);
-            }
-            // Split along record delimiter to get an array of strings
-            var recordsarray = oRawResponse.split(recDelim);
-            // Cycle through each record, except the first which contains header info
-            for(var i = recordsarray.length-1; i>-1; i--) {
+            var arrType = YAHOO.lang.isArray(oFullResponse[0]);
+            for(i=oFullResponse.length-1; i>-1; i--) {
                 var oResult = {};
-                var bError = false;
-                for(var j=fields.length-1; j>-1; j--) {
-                    try {
-                        // Split along field delimiter to get each data value
-                        var fielddataarray = recordsarray[i].split(fieldDelim);
+                var rec = oFullResponse[i];
+                if (typeof rec === 'object') {
+                    for(var j=fields.length-1; j>-1; j--) {
+                        var field = fields[j];
+                        var data = arrType ? rec[j] : rec[field.key];
 
-                        // Remove quotation marks from edges, if applicable
-                        var data = fielddataarray[j];
-                        if(data.charAt(0) == "\"") {
-                            data = data.substr(1);
+                        if (parsers[field.key]) {
+                            data = parsers[field.key].call(this,data);
                         }
-                        if(data.charAt(data.length-1) == "\"") {
-                            data = data.substr(0,data.length-1);
-                        }
-                        var field = fields[j];
-                        var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
-                        // Backward compatibility
-                        if(!field.parser && field.converter) {
-                            field.parser = field.converter;
-                            YAHOO.log("The field property converter has been deprecated" +
-                                    " in favor of parser", "warn", this.toString());
-                        }
-                        if(field.parser) {
-                            data = field.parser.call(this, data);
-                        }
+
                         // Safety measure
                         if(data === undefined) {
                             data = null;
                         }
-                        oResult[key] = data;
+
+                        oResult[field.key] = data;
                     }
-                    catch(e) {
-                        bError = true;
-                    }
                 }
-                if(!bError) {
-                    oParsedResponse.results.unshift(oResult);
-                }
+                results[i] = oResult;
             }
+
+            var oParsedResponse = {results:results};
+            YAHOO.log("Parsed array data is " +
+                    YAHOO.lang.dump(oParsedResponse), "info", this.toString());
+            return oParsedResponse;
         }
-        YAHOO.log("Parsed text data is " +
-                YAHOO.lang.dump(oParsedResponse), "info", this.toString());
     }
-    else {
-        YAHOO.log("Text data could not be parsed: " +
-                YAHOO.lang.dump(oRawResponse), "error", this.toString());
-        oParsedResponse.error = true;
-    }
-    return oParsedResponse;
+    YAHOO.log("Array data could not be parsed: " + YAHOO.lang.dump(oFullResponse), 
+            "error", this.toString());
+    return null;
 };
 
 /**
- * Overridable method parses raw XML data into a response object.
+ * Overridable method parses plain text data into a response object.
  *
- * @method parseXMLData
+ * @method parseTextData
  * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
- * @return {Object} Parsed response object.
+ * @param oFullResponse {Object} The full text response from the live database.
+ * @return {Object} Parsed response object with the following properties:<br>
+ *     - results (Array) Array of parsed data results<br>
+ *     - error (Boolean) True if there was an error<br>
+ *     - totalRecords (Number) Total number of records (if available)
  */
-YAHOO.util.DataSource.prototype.parseXMLData = function(oRequest, oRawResponse) {
-        var bError = false;
-        var oParsedResponse = {};
-        var xmlList = null;
-        // In case oRawResponse is something funky
-        try {
-            xmlList = (this.responseSchema.resultNode) ?
-                oRawResponse.getElementsByTagName(this.responseSchema.resultNode) :
-                null;
-        }
-        catch(e) {
-        }
-        if(!xmlList || !YAHOO.lang.isArray(this.responseSchema.fields)) {
-            bError = true;
-        }
-        // Loop through each result
-        else {
-            oParsedResponse.results = [];
-            for(var k = xmlList.length-1; k >= 0 ; k--) {
-                var result = xmlList.item(k);
-                var oResult = {};
-                // Loop through each data field in each result using the schema
-                for(var m = this.responseSchema.fields.length-1; m >= 0 ; m--) {
-                    var field = this.responseSchema.fields[m];
-                    var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
-                    var data = null;
-                    // Values may be held in an attribute...
-                    var xmlAttr = result.attributes.getNamedItem(key);
-                    if(xmlAttr) {
-                        data = xmlAttr.value;
-                    }
-                    // ...or in a node
-                    else {
-                        var xmlNode = result.getElementsByTagName(key);
-                        if(xmlNode && xmlNode.item(0) && xmlNode.item(0).firstChild) {
-                            data = xmlNode.item(0).firstChild.nodeValue;
+YAHOO.util.DataSource.prototype.parseTextData = function(oRequest, oFullResponse) {
+    if(YAHOO.lang.isString(oFullResponse)) {
+        if(YAHOO.lang.isArray(this.responseSchema.fields) &&
+                YAHOO.lang.isString(this.responseSchema.recordDelim) &&
+                YAHOO.lang.isString(this.responseSchema.fieldDelim)) {
+            var oParsedResponse = {results:[]};
+            var recDelim = this.responseSchema.recordDelim;
+            var fieldDelim = this.responseSchema.fieldDelim;
+            var fields = this.responseSchema.fields;
+            if(oFullResponse.length > 0) {
+                // Delete the last line delimiter at the end of the data if it exists
+                var newLength = oFullResponse.length-recDelim.length;
+                if(oFullResponse.substr(newLength) == recDelim) {
+                    oFullResponse = oFullResponse.substr(0, newLength);
+                }
+                // Split along record delimiter to get an array of strings
+                var recordsarray = oFullResponse.split(recDelim);
+                // Cycle through each record
+                for(var i = 0, len = recordsarray.length, recIdx = 0; i < len; ++i) {
+                    var oResult = {};
+                    var bError = false;
+                    if (YAHOO.lang.isString(recordsarray[i])) {
+                        // Split each record along field delimiter to get data array
+                        var fielddataarray = recordsarray[i].split(fieldDelim);
+                        for(var j=fields.length-1; j>-1; j--) {
+                            try {
+                                // Remove quotation marks from edges, if applicable
+                                var data = fielddataarray[j];
+                                if (YAHOO.lang.isString(data)) {
+                                    if(data.charAt(0) == "\"") {
+                                        data = data.substr(1);
+                                    }
+                                    if(data.charAt(data.length-1) == "\"") {
+                                        data = data.substr(0,data.length-1);
+                                    }
+                                    var field = fields[j];
+                                    var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
+                                    // Backward compatibility
+                                    if(!field.parser && field.converter) {
+                                        field.parser = field.converter;
+                                        YAHOO.log("The field property converter has been deprecated" +
+                                                " in favor of parser", "warn", this.toString());
+                                    }
+                                    if(field.parser) {
+                                        data = field.parser.call(this, data);
+                                    }
+                                    // Safety measure
+                                    if(data === undefined) {
+                                        data = null;
+                                    }
+                                    oResult[key] = data;
+                                }
+                                else {
+                                    bError = true;
+                                }
+                            }
+                            catch(e) {
+                                bError = true;
+                            }
                         }
-                        else {
-                               data = "";
+                        if(!bError) {
+                            oParsedResponse.results[recIdx++] = oResult;
                         }
                     }
-                    // Backward compatibility
-                    if(!field.parser && field.converter) {
-                        field.parser = field.converter;
-                        YAHOO.log("The field property converter has been deprecated" +
-                                " in favor of parser", "warn", this.toString());
-                    }
-                    if(field.parser) {
-                        data = field.parser.call(this, data);
-                    }
-                    // Safety measure
-                    if(data === undefined) {
-                        data = null;
-                    }
-                    oResult[key] = data;
                 }
-                // Capture each array of values into an array of results
-                oParsedResponse.results.unshift(oResult);
             }
-        }
-        if(bError) {
-            YAHOO.log("XML data could not be parsed: " +
-                    YAHOO.lang.dump(oRawResponse), "error", this.toString());
-            oParsedResponse.error = true;
-        }
-        else {
-            YAHOO.log("Parsed XML data is " +
+            YAHOO.log("Parsed text data is " +
                     YAHOO.lang.dump(oParsedResponse), "info", this.toString());
+            return oParsedResponse;
         }
-        return oParsedResponse;
+    }
+    YAHOO.log("Text data could not be parsed: " + YAHOO.lang.dump(oFullResponse), 
+            "error", this.toString());
+    return null;
+            
 };
 
 /**
- * Overridable method parses raw JSON data into a response object.
+ * Overridable method parses XML data into a response object.
  *
- * @method parseJSONData
+ * @method parseXMLData
  * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
- * @return {Object} Parsed response object.
+ * @param oFullResponse {Object} The full XML response from the live database.
+ * @return {Object} Parsed response object with the following properties<br>
+ *     - results (Array) Array of parsed data results<br>
+ *     - error (Boolean) True if there was an error<br>
+ *     - totalRecords (Number) Total number of records (if available)
  */
-YAHOO.util.DataSource.prototype.parseJSONData = function(oRequest, oRawResponse) {
-    var oParsedResponse = {};
-    if(oRawResponse && YAHOO.lang.isArray(this.responseSchema.fields)) {
-        var fields = this.responseSchema.fields;
-        var bError = false;
-        oParsedResponse.results = [];
-        var jsonObj,jsonList;
+YAHOO.util.DataSource.prototype.parseXMLData = function(oRequest, oFullResponse) {
+    var bError = false,
+        schema = this.responseSchema,
+        oParsedResponse = {meta:{}},
+        xmlList = null,
+        metaNode      = schema.metaNode,
+        metaLocators  = schema.metaFields || {},
+        totRecLocator = schema.totalRecords, // Back compat
+        i,k,loc,v;
 
-        // Parse JSON object out if it's a string
-        if(YAHOO.lang.isString(oRawResponse)) {
-            // Check for latest JSON lib but divert KHTML clients
-            var isNotMac = (navigator.userAgent.toLowerCase().indexOf('khtml')== -1);
-            if(oRawResponse.parseJSON && isNotMac) {
-                // Use the new JSON utility if available
-                jsonObj = oRawResponse.parseJSON();
-                if(!jsonObj) {
-                    bError = true;
-                }
-            }
-            // Check for YUI JSON lib but divert KHTML clients
-            else if(YAHOO.lang.JSON && isNotMac) {
-                // Use the JSON utility if available
-                jsonObj = YAHOO.lang.JSON.parse(oRawResponse);
-                if(!jsonObj) {
-                    bError = true;
-                }
-            }
-            // Check for older JSON lib but divert KHTML clients
-            else if(window.JSON && JSON.parse && isNotMac) {
-                // Use the JSON utility if available
-                jsonObj = JSON.parse(oRawResponse);
-                if(!jsonObj) {
-                    bError = true;
-                }
-            }
-            // No JSON lib found so parse the string
-            else {
-                try {
-                    // Trim leading spaces
-                    while (oRawResponse.length > 0 &&
-                            (oRawResponse.charAt(0) != "{") &&
-                            (oRawResponse.charAt(0) != "[")) {
-                        oRawResponse = oRawResponse.substring(1, oRawResponse.length);
-                    }
+    if (totRecLocator && !metaLocators.totalRecords) {
+        metaLocators.totalRecords = totRecLocator;
+    }
 
-                    if(oRawResponse.length > 0) {
-                        // Strip extraneous stuff at the end
-                        var objEnd = Math.max(oRawResponse.lastIndexOf("]"),oRawResponse.lastIndexOf("}"));
-                        oRawResponse = oRawResponse.substring(0,objEnd+1);
+    // In case oFullResponse is something funky
+    try {
+        xmlList = (schema.resultNode) ?
+            oFullResponse.getElementsByTagName(schema.resultNode) :
+            null;
 
-                        // Turn the string into an object literal...
-                        // ...eval is necessary here
-                        jsonObj = eval("(" + oRawResponse + ")");
-                        if(!jsonObj) {
-                            bError = true;
+        // Pull any meta identified
+        metaNode = metaNode ? oFullResponse.getElementsByTagName(metaNode)[0] :
+                   oFullResponse;
+
+        if (metaNode) {
+            for (k in metaLocators) {
+                if (YAHOO.lang.hasOwnProperty(metaLocators, k)) {
+                    loc = metaLocators[k];
+                    // Look for a node
+                    v = metaNode.getElementsByTagName(loc)[0];
+
+                    if (v) {
+                        v = v.firstChild.nodeValue;
+                    } else {
+                        // Look for an attribute
+                        v = metaNode.attributes.getNamedItem(loc);
+                        if (v) {
+                            v = v.value;
                         }
+                    }
 
+                    if (YAHOO.lang.isValue(v)) {
+                        oParsedResponse.meta[k] = v;
                     }
-                    else {
-                        jsonObj = null;
-                        bError = true;
-                    }
                 }
-                catch(e) {
-                    bError = true;
-               }
+                
             }
         }
-        // Response must already be a JSON object
-        else if(oRawResponse.constructor == Object) {
-            jsonObj = oRawResponse;
-        }
-        // Not a string or an object
-        else {
-            bError = true;
-        }
-        // Now that we have a JSON object, parse a jsonList out of it
-        if(jsonObj && jsonObj.constructor == Object) {
-            try {
-                // eval is necessary here since schema can be of unknown depth
-                jsonList = eval("jsonObj." + this.responseSchema.resultsList);
-            }
-            catch(e) {
-                bError = true;
-            }
-        }
+    }
+    catch(e) {
+        YAHOO.log("Error while parsing XML data: " + e.message);
+    }
+    if(!xmlList || !YAHOO.lang.isArray(schema.fields)) {
+        bError = true;
+    }
+    // Loop through each result
+    else {
 
-        if(bError || !jsonList) {
-            YAHOO.log("JSON data could not be parsed: " +
-                    YAHOO.lang.dump(oRawResponse), "error", this.toString());
-            oParsedResponse.error = true;
-        }
-        if(jsonList && !YAHOO.lang.isArray(jsonList)) {
-            jsonList = [jsonList];
-        }
-        else if(!jsonList) {
-            jsonList = [];
-        }
-
-        // Loop through the array of all responses...
-        for(var i = jsonList.length-1; i >= 0 ; i--) {
+        oParsedResponse.results = [];
+        for(i = xmlList.length-1; i >= 0 ; --i) {
+            var result = xmlList.item(i);
             var oResult = {};
-            var jsonResult = jsonList[i];
-            // ...and loop through each data field value of each response
-            for(var j = fields.length-1; j >= 0 ; j--) {
-                var field = fields[j];
+            // Loop through each data field in each result using the schema
+            for(var m = schema.fields.length-1; m >= 0 ; m--) {
+                var field = schema.fields[m];
                 var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
-                // ...and capture data into an array mapped according to the schema...
-                // eval is necessary here since schema can be of unknown depth
-                var data = eval("jsonResult." + key);
-                //YAHOO.log("data: " + i + " value:" +j+" = "+dataFieldValue,"debug",this.toString());
-                
+                var data = null;
+                // Values may be held in an attribute...
+                var xmlAttr = result.attributes.getNamedItem(key);
+                if(xmlAttr) {
+                    data = xmlAttr.value;
+                }
+                // ...or in a node
+                else {
+                    var xmlNode = result.getElementsByTagName(key);
+                    if(xmlNode && xmlNode.item(0) && xmlNode.item(0).firstChild) {
+                        data = xmlNode.item(0).firstChild.nodeValue;
+                    }
+                    else {
+                           data = "";
+                    }
+                }
                 // Backward compatibility
                 if(!field.parser && field.converter) {
                     field.parser = field.converter;
@@ -1444,90 +1461,249 @@
                 }
                 oResult[key] = data;
             }
-            // Capture the array of data field values in an array of results
-            oParsedResponse.results.unshift(oResult);
+            // Capture each array of values into an array of results
+            oParsedResponse.results[i] = oResult;
         }
-        YAHOO.log("Parsed JSON data is " +
-                YAHOO.lang.dump(oParsedResponse), "info", this.toString());
     }
-    else {
-        YAHOO.log("JSON data could not be parsed: " +
-                YAHOO.lang.dump(oRawResponse), "error", this.toString());
+    if(bError) {
+        YAHOO.log("XML data could not be parsed: " +
+                YAHOO.lang.dump(oFullResponse), "error", this.toString());
         oParsedResponse.error = true;
     }
+    else {
+        YAHOO.log("Parsed XML data is " +
+                YAHOO.lang.dump(oParsedResponse), "info", this.toString());
+    }
     return oParsedResponse;
 };
 
 /**
- * Overridable method parses raw HTML TABLE element data into a response object.
+ * Overridable method parses JSON data into a response object.
  *
- * @method parseHTMLTableData
+ * @method parseJSONData
  * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
- * @return {Object} Parsed response object.
+ * @param oFullResponse {Object} The full JSON from the live database.
+ * @return {Object} Parsed response object with the following properties<br>
+ *     - results (Array) Array of parsed data results<br>
+ *     - error (Boolean) True if there was an error<br>
+ *     - totalRecords (Number) Total number of records (if available)
  */
-YAHOO.util.DataSource.prototype.parseHTMLTableData = function(oRequest, oRawResponse) {
-        var bError = false;
-        var elTable = oRawResponse;
-        var fields = this.responseSchema.fields;
-        var oParsedResponse = {};
-        oParsedResponse.results = [];
+YAHOO.util.DataSource.prototype.parseJSONData = function(oRequest, oFullResponse) {
+    var oParsedResponse = {results:[],meta:{}},
+        schema          = this.responseSchema;
 
-        // Iterate through each TBODY
-        for(var i=0; i<elTable.tBodies.length; i++) {
-            var elTbody = elTable.tBodies[i];
+    if(YAHOO.lang.isObject(oFullResponse)) {
+        if(YAHOO.lang.isArray(schema.fields)) {
+            var fields          = schema.fields,
+                resultsList     = oFullResponse,
+                results         = [],
+                metaFields      = schema.metaFields || {},
+                fieldParsers    = [],
+                fieldPaths      = [],
+                simpleFields    = [],
+                bError          = false,
+                i,len,j,v,key,parser,path;
 
-            // Iterate through each TR
-            for(var j=elTbody.rows.length-1; j>-1; j--) {
-                var elRow = elTbody.rows[j];
-                var oResult = {};
-                
-                for(var k=fields.length-1; k>-1; k--) {
-                    var field = fields[k];
-                    var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
-                    var data = elRow.cells[k].innerHTML;
+            // Function to parse the schema's locator keys into walk paths
+            var buildPath = function (needle) {
+                var path = null, keys = [], i = 0;
+                if (needle) {
+                    // Strip the ["string keys"] and [1] array indexes
+                    needle = needle.
+                        replace(/\[(['"])(.*?)\1\]/g,
+                        function (x,$1,$2) {keys[i]=$2;return '.@'+(i++);}).
+                        replace(/\[(\d+)\]/g,
+                        function (x,$1) {keys[i]=parseInt($1,10)|0;return '.@'+(i++);}).
+                        replace(/^\./,''); // remove leading dot
 
-                    // Backward compatibility
-                    if(!field.parser && field.converter) {
-                        field.parser = field.converter;
-                        YAHOO.log("The field property converter has been deprecated" +
-                                " in favor of parser", "warn", this.toString());
+                    // If the cleaned needle contains invalid characters, the
+                    // path is invalid
+                    if (!/[^\w\.\$@]/.test(needle)) {
+                        path = needle.split('.');
+                        for (i=path.length-1; i >= 0; --i) {
+                            if (path[i].charAt(0) === '@') {
+                                path[i] = keys[parseInt(path[i].substr(1),10)];
+                            }
+                        }
                     }
-                    if(field.parser) {
-                        data = field.parser.call(this, data);
+                }
+                return path;
+            };
+
+            // build function to walk a path and return the pot of gold
+            var walkPath = function (path, origin) {
+                var v=origin,i=0,len=path.length;
+                for (;i<len && v;++i) {
+                    v = v[path[i]];
+                }
+                return v;
+            };
+
+            // Build the parser map and location paths
+            for (i = fields.length - 1; i >= 0; --i) {
+                key    = fields[i].key || fields[i];
+                parser = fields[i].parser || fields[i].converter;
+                path   = buildPath(key);
+
+                if (parser) {
+                    fieldParsers[fieldParsers.length] = {key:key,parser:parser};
+                }
+
+                if (path) {
+                    if (path.length > 1) {
+                        fieldPaths[fieldPaths.length] = {key:key,path:path};
+                    } else {
+                        simpleFields[simpleFields.length] = key;
                     }
-                    // Safety measure
-                    if(data === undefined) {
-                        data = null;
+                } else {
+                    YAHOO.log("Invalid key syntax: " + key,"warn",this.toString());
+                }
+            }
+
+            // Parse the response
+            // Step 1. Pull the resultsList from oFullResponse (default assumes
+            // oFullResponse IS the resultsList)
+            if (schema.resultsList) {
+                path = buildPath(schema.resultsList);
+                if (path) {
+                    resultsList = walkPath(path, oFullResponse);
+                    if (resultsList === undefined) {
+                        bError = true;
                     }
-                    oResult[key] = data;
+                } else {
+                    bError = true;
                 }
-                oParsedResponse.results.unshift(oResult);
             }
+            if (!resultsList) {
+                resultsList = [];
+            }
+
+            if (!YAHOO.lang.isArray(resultsList)) {
+                resultsList = [resultsList];
+            }
+
+            if (!bError) {
+                // Step 2. Process the results, flattening the records and/or
+                // applying parsers if needed
+                //if (fieldParsers.length || fieldPaths.length) {
+                    for (i = resultsList.length - 1; i >= 0; --i) {
+                        var r = resultsList[i], rec = {};
+                        for (j = simpleFields.length - 1; j >= 0; --j) {
+                            rec[simpleFields[j]] = r[simpleFields[j]];
+                        }
+
+                        for (j = fieldPaths.length - 1; j >= 0; --j) {
+                            rec[fieldPaths[j].key] = walkPath(fieldPaths[j].path,r);
+                        }
+
+                        for (j = fieldParsers.length - 1; j >= 0; --j) {
+                            var p = fieldParsers[j].key;
+                            rec[p] = fieldParsers[j].parser(rec[p]);
+                            if (rec[p] === undefined) {
+                                rec[p] = null;
+                            }
+                        }
+                        results[i] = rec;
+                    }
+                //}
+
+                // Step 3. Pull meta fields from oFullResponse if identified
+                if (schema.totalRecords && !metaFields.totalRecords) {
+                    // for backward compatibility
+                    metaFields.totalRecords = schema.totalRecords;
+                }
+
+                for (key in metaFields) {
+                    if (YAHOO.lang.hasOwnProperty(metaFields,key)) {
+                        path = buildPath(metaFields[key]);
+                        if (path) {
+                            v = walkPath(path, oFullResponse);
+                            oParsedResponse.meta[key] = v;
+                        }
+                    }
+                }
+
+            } else {
+                YAHOO.log("JSON data could not be parsed: " +
+                        YAHOO.lang.dump(oFullResponse), "error", this.toString());
+
+                oParsedResponse.error = true;
+            }
+
+            oParsedResponse.results = results;
         }
+    }
+    else {
+        YAHOO.log("JSON data could not be parsed: " +
+                YAHOO.lang.dump(oFullResponse), "error", this.toString());
+        oParsedResponse.error = true;
+    }
 
-        if(bError) {
-            YAHOO.log("HTML TABLE data could not be parsed: " +
-                    YAHOO.lang.dump(oRawResponse), "error", this.toString());
-            oParsedResponse.error = true;
-        }
-        else {
-            YAHOO.log("Parsed HTML TABLE data is " +
-                    YAHOO.lang.dump(oParsedResponse), "info", this.toString());
-        }
-        return oParsedResponse;
+    return oParsedResponse;
 };
 
 /**
- * The Number utility provides helper functions to deal with data of type Number.
+ * Overridable method parses an HTML TABLE element reference into a response object.
  *
- * @namespace YAHOO.util
- * @module number
- * @requires datasource
- * @title Number Utility
- * @beta
+ * @method parseHTMLTableData
+ * @param oRequest {Object} Request object.
+ * @param oFullResponse {Object} The full HTML element reference from the live database.
+ * @return {Object} Parsed response object with the following properties<br>
+ *     - results (Array) Array of parsed data results<br>
+ *     - error (Boolean) True if there was an error<br>
+ *     - totalRecords (Number) Total number of records (if available)
  */
+YAHOO.util.DataSource.prototype.parseHTMLTableData = function(oRequest, oFullResponse) {
+    var bError = false;
+    var elTable = oFullResponse;
+    var fields = this.responseSchema.fields;
+    var oParsedResponse = {results:[]};
 
+    // Iterate through each TBODY
+    for(var i=0; i<elTable.tBodies.length; i++) {
+        var elTbody = elTable.tBodies[i];
+
+        // Iterate through each TR
+        for(var j=elTbody.rows.length-1; j>-1; j--) {
+            var elRow = elTbody.rows[j];
+            var oResult = {};
+            
+            for(var k=fields.length-1; k>-1; k--) {
+                var field = fields[k];
+                var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
+                var data = elRow.cells[k].innerHTML;
+
+                // Backward compatibility
+                if(!field.parser && field.converter) {
+                    field.parser = field.converter;
+                    YAHOO.log("The field property converter has been deprecated" +
+                            " in favor of parser", "warn", this.toString());
+                }
+                if(field.parser) {
+                    data = field.parser.call(this, data);
+                }
+                // Safety measure
+                if(data === undefined) {
+                    data = null;
+                }
+                oResult[key] = data;
+            }
+            oParsedResponse.results[j] = oResult;
+        }
+    }
+
+    if(bError) {
+        YAHOO.log("HTML TABLE data could not be parsed: " +
+                YAHOO.lang.dump(oFullResponse), "error", this.toString());
+        oParsedResponse.error = true;
+    }
+    else {
+        YAHOO.log("Parsed HTML TABLE data is " +
+                YAHOO.lang.dump(oParsedResponse), "info", this.toString());
+    }
+    return oParsedResponse;
+};
+
 /****************************************************************************/
 /****************************************************************************/
 /****************************************************************************/
@@ -1536,6 +1712,8 @@
  * The static Number class provides helper functions to deal with data of type
  * Number.
  *
+ * @namespace YAHOO.util
+ * @requires datasource
  * @class Number
  * @static
  */
@@ -1632,16 +1810,6 @@
 
 
 
-/**
- * The Date utility provides helper functions to deal with data of type Date.
- *
- * @namespace YAHOO.util
- * @module date
- * @requires datasource
- * @title Date Utility
- * @beta
- */
-
 /****************************************************************************/
 /****************************************************************************/
 /****************************************************************************/
@@ -1650,6 +1818,8 @@
  * The static Date class provides helper functions to deal with data of type
  * Number.
  *
+ * @namespace YAHOO.util
+ * @requires datasource
  * @class Date
  * @static
  */
@@ -1690,6 +1860,5 @@
         }
     }
  };
-
-
-YAHOO.register("datasource", YAHOO.util.DataSource, {version: "2.4.1", build: "742"});
+ 
+YAHOO.register("datasource", YAHOO.util.DataSource, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/datasource/datasource-beta-min.js
===================================================================
--- trunk/root/static/yui/datasource/datasource-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/datasource/datasource-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +1,9 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-YAHOO.util.DataSource=function(B,D){if(D&&(D.constructor==Object)){for(var C in D){if(C){this[C]=D[C];}}}if(!B){return ;}if(B.nodeType&&B.nodeType==9){this.dataType=YAHOO.util.DataSource.TYPE_XML;}else{if(YAHOO.lang.isArray(B)){this.dataType=YAHOO.util.DataSource.TYPE_JSARRAY;}else{if(YAHOO.lang.isString(B)){this.dataType=YAHOO.util.DataSource.TYPE_XHR;}else{if(YAHOO.lang.isFunction(B)){this.dataType=YAHOO.util.DataSource.TYPE_JSFUNCTION;}else{if(B.nodeName&&(B.nodeName.toLowerCase()=="table")){this.dataType=YAHOO.util.DataSource.TYPE_HTMLTABLE;}else{if(YAHOO.lang.isObject(B)){this.dataType=YAHOO.util.DataSource.TYPE_JSON;}else{this.dataType=YAHOO.util.DataSource.TYPE_UNKNOWN;}}}}}}this.liveData=B;this._oQueue={interval:null,conn:null,requests:[]};var A=this.maxCacheEntries;if(!YAHOO.lang.isNumber(A)||(A<0)){A=0;}if(A>0&&!this._aCache){this._aCache=[];}this._aIntervals=[];this._sName="DataSource instance"+YAHOO.util.DataSource._nIndex;YAHOO.util.DataSource._nIndex++;this.cr!
 eateEvent("cacheRequestEvent");this.createEvent("cacheResponseEvent");this.createEvent("requestEvent");this.createEvent("responseEvent");this.createEvent("responseParseEvent");this.createEvent("responseCacheEvent");this.createEvent("dataErrorEvent");this.createEvent("cacheFlushEvent");};YAHOO.augment(YAHOO.util.DataSource,YAHOO.util.EventProvider);YAHOO.util.DataSource.TYPE_UNKNOWN=-1;YAHOO.util.DataSource.TYPE_JSARRAY=0;YAHOO.util.DataSource.TYPE_JSFUNCTION=1;YAHOO.util.DataSource.TYPE_XHR=2;YAHOO.util.DataSource.TYPE_JSON=3;YAHOO.util.DataSource.TYPE_XML=4;YAHOO.util.DataSource.TYPE_TEXT=5;YAHOO.util.DataSource.TYPE_HTMLTABLE=6;YAHOO.util.DataSource.ERROR_DATAINVALID="Invalid data";YAHOO.util.DataSource.ERROR_DATANULL="Null data";YAHOO.util.DataSource._nIndex=0;YAHOO.util.DataSource._nTransactionId=0;YAHOO.util.DataSource.prototype._sName=null;YAHOO.util.DataSource.prototype._aCache=null;YAHOO.util.DataSource.prototype._oQueue=null;YAHOO.util.DataSource.prototype._aInterv!
 als=null;YAHOO.util.DataSource.prototype.maxCacheEntries=0;YAH!
 OO.util.
DataSource.prototype.liveData=null;YAHOO.util.DataSource.prototype.dataType=YAHOO.util.DataSource.TYPE_UNKNOWN;YAHOO.util.DataSource.prototype.responseType=YAHOO.util.DataSource.TYPE_UNKNOWN;YAHOO.util.DataSource.prototype.responseSchema=null;YAHOO.util.DataSource.prototype.connMgr=null;YAHOO.util.DataSource.prototype.connXhrMode="allowAll";YAHOO.util.DataSource.prototype.connMethodPost=false;YAHOO.util.DataSource.prototype.connTimeout=0;YAHOO.util.DataSource.parseString=function(B){if(!YAHOO.lang.isValue(B)){return null;}var A=B+"";if(YAHOO.lang.isString(A)){return A;}else{return null;}};YAHOO.util.DataSource.parseNumber=function(B){var A=B*1;if(YAHOO.lang.isNumber(A)){return A;}else{return null;}};YAHOO.util.DataSource.convertNumber=function(A){return YAHOO.util.DataSource.parseNumber(A);};YAHOO.util.DataSource.parseDate=function(B){var A=null;if(!(B instanceof Date)){A=new Date(B);}else{return B;}if(A instanceof Date){return A;}else{return null;}};YAHOO.util.DataSource.co!
 nvertDate=function(A){return YAHOO.util.DataSource.parseDate(A);};YAHOO.util.DataSource.prototype.toString=function(){return this._sName;};YAHOO.util.DataSource.prototype.getCachedResponse=function(H,B,G){var A=this._aCache;var D=(A)?A.length:0;var F=null;if((this.maxCacheEntries>0)&&A&&(D>0)){this.fireEvent("cacheRequestEvent",{request:H,callback:B,caller:G});for(var E=D-1;E>=0;E--){var C=A[E];if(this.isCacheHit(H,C.request)){F=C.response;A.splice(E,1);this.addToCache(H,F);this.fireEvent("cacheResponseEvent",{request:H,response:F,callback:B,caller:G});break;}}}return F;};YAHOO.util.DataSource.prototype.isCacheHit=function(A,B){return(A===B);};YAHOO.util.DataSource.prototype.addToCache=function(D,C){var A=this._aCache;if(!A){return ;}while(A.length>=this.maxCacheEntries){A.shift();}var B={request:D,response:C};A.push(B);this.fireEvent("responseCacheEvent",{request:D,response:C});};YAHOO.util.DataSource.prototype.flushCache=function(){if(this._aCache){this._aCache=[];this.fi!
 reEvent("cacheFlushEvent");}};YAHOO.util.DataSource.prototype.!
 setInter
val=function(D,F,B,E){try{var C=this;var A=setInterval(function(){C.makeConnection(F,B,E);},D);this._aIntervals.push(A);return A;}catch(G){}};YAHOO.util.DataSource.prototype.clearInterval=function(A){var C=this._aIntervals||[];for(var B=C.length-1;B>-1;B--){if(C[B]===A){C.splice(B,1);clearInterval(A);}}};YAHOO.util.DataSource.prototype.clearAllIntervals=function(A){var C=this._aIntervals||[];for(var B=C.length-1;B>-1;B--){C.splice(B,1);clearInterval(A);}};YAHOO.util.DataSource.prototype.sendRequest=function(D,A,C){var B=this.getCachedResponse(D,A,C);if(B){A.call(C,D,B);return null;}return this.makeConnection(D,A,C);};YAHOO.util.DataSource.prototype.makeConnection=function(A,P,K){this.fireEvent("requestEvent",{request:A,callback:P,caller:K});var D=null;var L=YAHOO.util.DataSource._nTransactionId++;switch(this.dataType){case YAHOO.util.DataSource.TYPE_JSFUNCTION:D=this.liveData(A);this.handleResponse(A,D,P,K,L);break;case YAHOO.util.DataSource.TYPE_XHR:var N=this;var C=this.co!
 nnMgr||YAHOO.util.Connect;var G=this._oQueue;var J=function(Q){if(Q&&(this.connXhrMode=="ignoreStaleResponses")&&(Q.tId!=G.conn.tId)){return null;}else{if(!Q){this.fireEvent("dataErrorEvent",{request:A,callback:P,caller:K,message:YAHOO.util.DataSource.ERROR_DATANULL});P.call(K,A,Q,true);return null;}else{this.handleResponse(A,Q,P,K,L);}}};var O=function(Q){this.fireEvent("dataErrorEvent",{request:A,callback:P,caller:K,message:YAHOO.util.DataSource.ERROR_DATAINVALID});if((this.liveData.lastIndexOf("?")!==this.liveData.length-1)&&(A.indexOf("?")!==0)){}P.call(K,A,Q,true);return null;};var I={success:J,failure:O,scope:this};if(YAHOO.lang.isNumber(this.connTimeout)){I.timeout=this.connTimeout;}if(this.connXhrMode=="cancelStaleRequests"){if(G.conn){if(C.abort){C.abort(G.conn);G.conn=null;}else{}}}if(C&&C.asyncRequest){var B=this.liveData;var H=this.connMethodPost;var M=(H)?"POST":"GET";var E=(H)?B:B+A;var F=(H)?A:null;
-if(this.connXhrMode!="queueRequests"){G.conn=C.asyncRequest(M,E,I,F);}else{if(G.conn){G.requests.push({request:A,callback:I});if(!G.interval){G.interval=setInterval(function(){if(C.isCallInProgress(G.conn)){return ;}else{if(G.requests.length>0){E=(H)?B:B+G.requests[0].request;F=(H)?G.requests[0].request:null;G.conn=C.asyncRequest(M,E,G.requests[0].callback,F);G.requests.shift();}else{clearInterval(G.interval);G.interval=null;}}},50);}}else{G.conn=C.asyncRequest(M,E,I,F);}}}else{P.call(K,A,null,true);}break;default:D=this.liveData;this.handleResponse(A,D,P,K,L);break;}return L;};YAHOO.util.DataSource.prototype.handleResponse=function(E,C,B,D,H){this.fireEvent("responseEvent",{request:E,response:C,callback:B,caller:D,tId:H});var G=(this.dataType==YAHOO.util.DataSource.TYPE_XHR)?true:false;var F=null;var A=false;C=this.doBeforeParseData(E,C);switch(this.responseType){case YAHOO.util.DataSource.TYPE_JSARRAY:if(G&&C.responseText){C=C.responseText;}F=this.parseArrayData(E,C);brea!
 k;case YAHOO.util.DataSource.TYPE_JSON:if(G&&C.responseText){C=C.responseText;}F=this.parseJSONData(E,C);break;case YAHOO.util.DataSource.TYPE_HTMLTABLE:if(G&&C.responseText){C=C.responseText;}F=this.parseHTMLTableData(E,C);break;case YAHOO.util.DataSource.TYPE_XML:if(G&&C.responseXML){C=C.responseXML;}F=this.parseXMLData(E,C);break;case YAHOO.util.DataSource.TYPE_TEXT:if(G&&C.responseText){C=C.responseText;}F=this.parseTextData(E,C);break;default:break;}if(F){F.tId=H;F=this.doBeforeCallback(E,C,F);this.fireEvent("responseParseEvent",{request:E,response:F,callback:B,caller:D});this.addToCache(E,F);}else{this.fireEvent("dataErrorEvent",{request:E,callback:B,caller:D,message:YAHOO.util.DataSource.ERROR_DATANULL});F={error:true};}B.call(D,E,F);};YAHOO.util.DataSource.prototype.doBeforeParseData=function(B,A){return A;};YAHOO.util.DataSource.prototype.doBeforeCallback=function(B,A,C){return C;};YAHOO.util.DataSource.prototype.parseArrayData=function(A,B){if(YAHOO.lang.isArray(B!
 )&&YAHOO.lang.isArray(this.responseSchema.fields)){var J={resu!
 lts:[]};
var G=this.responseSchema.fields;for(var E=B.length-1;E>-1;E--){var F={};for(var C=G.length-1;C>-1;C--){var H=G[C];var I=(YAHOO.lang.isValue(H.key))?H.key:H;var D=(YAHOO.lang.isValue(B[E][C]))?B[E][C]:B[E][I];if(!H.parser&&H.converter){H.parser=H.converter;}if(H.parser){D=H.parser.call(this,D);}if(D===undefined){D=null;}F[I]=D;}J.results.unshift(F);}return J;}else{return null;}};YAHOO.util.DataSource.prototype.parseTextData=function(A,B){var P={};if(YAHOO.lang.isString(B)&&YAHOO.lang.isArray(this.responseSchema.fields)&&YAHOO.lang.isString(this.responseSchema.recordDelim)&&YAHOO.lang.isString(this.responseSchema.fieldDelim)){P.results=[];var M=this.responseSchema.recordDelim;var G=this.responseSchema.fieldDelim;var J=this.responseSchema.fields;if(B.length>0){var C=B.length-M.length;if(B.substr(C)==M){B=B.substr(0,C);}var Q=B.split(M);for(var F=Q.length-1;F>-1;F--){var I={};var K=false;for(var D=J.length-1;D>-1;D--){try{var H=Q[F].split(G);var E=H[D];if(E.charAt(0)=="\""){E=E!
 .substr(1);}if(E.charAt(E.length-1)=="\""){E=E.substr(0,E.length-1);}var N=J[D];var O=(YAHOO.lang.isValue(N.key))?N.key:N;if(!N.parser&&N.converter){N.parser=N.converter;}if(N.parser){E=N.parser.call(this,E);}if(E===undefined){E=null;}I[O]=E;}catch(L){K=true;}}if(!K){P.results.unshift(I);}}}}else{P.error=true;}return P;};YAHOO.util.DataSource.prototype.parseXMLData=function(A,C){var I=false;var N={};var D=null;try{D=(this.responseSchema.resultNode)?C.getElementsByTagName(this.responseSchema.resultNode):null;}catch(J){}if(!D||!YAHOO.lang.isArray(this.responseSchema.fields)){I=true;}else{N.results=[];for(var F=D.length-1;F>=0;F--){var O=D.item(F);var H={};for(var E=this.responseSchema.fields.length-1;E>=0;E--){var K=this.responseSchema.fields[E];var M=(YAHOO.lang.isValue(K.key))?K.key:K;var G=null;var B=O.attributes.getNamedItem(M);if(B){G=B.value;}else{var L=O.getElementsByTagName(M);if(L&&L.item(0)&&L.item(0).firstChild){G=L.item(0).firstChild.nodeValue;}else{G="";}}if(!K.p!
 arser&&K.converter){K.parser=K.converter;}if(K.parser){G=K.par!
 ser.call
(this,G);}if(G===undefined){G=null;}H[M]=G;}N.results.unshift(H);}}if(I){N.error=true;}else{}return N;};YAHOO.util.DataSource.prototype.parseJSONData=function(oRequest,oRawResponse){var oParsedResponse={};if(oRawResponse&&YAHOO.lang.isArray(this.responseSchema.fields)){var fields=this.responseSchema.fields;var bError=false;oParsedResponse.results=[];var jsonObj,jsonList;if(YAHOO.lang.isString(oRawResponse)){var isNotMac=(navigator.userAgent.toLowerCase().indexOf("khtml")==-1);if(oRawResponse.parseJSON&&isNotMac){jsonObj=oRawResponse.parseJSON();if(!jsonObj){bError=true;}}else{if(YAHOO.lang.JSON&&isNotMac){jsonObj=YAHOO.lang.JSON.parse(oRawResponse);if(!jsonObj){bError=true;}}else{if(window.JSON&&JSON.parse&&isNotMac){jsonObj=JSON.parse(oRawResponse);if(!jsonObj){bError=true;}}else{try{while(oRawResponse.length>0&&(oRawResponse.charAt(0)!="{")&&(oRawResponse.charAt(0)!="[")){oRawResponse=oRawResponse.substring(1,oRawResponse.length);}if(oRawResponse.length>0){var objEnd=Math.!
 max(oRawResponse.lastIndexOf("]"),oRawResponse.lastIndexOf("}"));oRawResponse=oRawResponse.substring(0,objEnd+1);jsonObj=eval("("+oRawResponse+")");if(!jsonObj){bError=true;}}else{jsonObj=null;bError=true;}}catch(e){bError=true;}}}}}else{if(oRawResponse.constructor==Object){jsonObj=oRawResponse;}else{bError=true;}}if(jsonObj&&jsonObj.constructor==Object){try{jsonList=eval("jsonObj."+this.responseSchema.resultsList);}catch(e){bError=true;}}if(bError||!jsonList){oParsedResponse.error=true;}if(jsonList&&!YAHOO.lang.isArray(jsonList)){jsonList=[jsonList];}else{if(!jsonList){jsonList=[];}}for(var i=jsonList.length-1;i>=0;i--){var oResult={};var jsonResult=jsonList[i];for(var j=fields.length-1;j>=0;j--){var field=fields[j];var key=(YAHOO.lang.isValue(field.key))?field.key:field;var data=eval("jsonResult."+key);if(!field.parser&&field.converter){field.parser=field.converter;}if(field.parser){data=field.parser.call(this,data);
-}if(data===undefined){data=null;}oResult[key]=data;}oParsedResponse.results.unshift(oResult);}}else{oParsedResponse.error=true;}return oParsedResponse;};YAHOO.util.DataSource.prototype.parseHTMLTableData=function(B,C){var K=false;var L=C;var J=this.responseSchema.fields;var O={};O.results=[];for(var H=0;H<L.tBodies.length;H++){var D=L.tBodies[H];for(var F=D.rows.length-1;F>-1;F--){var A=D.rows[F];var I={};for(var E=J.length-1;E>-1;E--){var M=J[E];var N=(YAHOO.lang.isValue(M.key))?M.key:M;var G=A.cells[E].innerHTML;if(!M.parser&&M.converter){M.parser=M.converter;}if(M.parser){G=M.parser.call(this,G);}if(G===undefined){G=null;}I[N]=G;}O.results.unshift(I);}}if(K){O.error=true;}else{}return O;};YAHOO.util.Number={format:function(B,E){E=E||{};if(!YAHOO.lang.isNumber(B)){B*=1;}if(YAHOO.lang.isNumber(B)){var I=B+"";var F=(E.decimalSeparator)?E.decimalSeparator:".";var G;if(YAHOO.lang.isNumber(E.decimalPlaces)){var H=E.decimalPlaces;var C=Math.pow(10,H);I=Math.round(B*C)/C+"";G=I.!
 lastIndexOf(".");if(H>0){if(G<0){I+=F;G=I.length-1;}else{if(F!=="."){I=I.replace(".",F);}}while((I.length-1-G)<H){I+="0";}}}if(E.thousandsSeparator){var K=E.thousandsSeparator;G=I.lastIndexOf(F);G=(G>-1)?G:I.length;var J=I.substring(G);var A=-1;for(var D=G;D>0;D--){A++;if((A%3===0)&&(D!==G)){J=K+J;}J=I.charAt(D-1)+J;}I=J;}I=(E.prefix)?E.prefix+I:I;I=(E.suffix)?I+E.suffix:I;return I;}else{return B;}}};YAHOO.util.Date={format:function(C,B){B=B||{};if(C instanceof Date){var D=B.format||"MM/DD/YYYY";var E=C.getMonth()+1;var A=C.getDate();var F=C.getFullYear();switch(D){case"YYYY/MM/DD":return F+"/"+E+"/"+A;case"DD/MM/YYYY":return A+"/"+E+"/"+F;default:return E+"/"+A+"/"+F;}}else{return YAHOO.lang.isValue(C)?C:"";}}};YAHOO.register("datasource",YAHOO.util.DataSource,{version:"2.4.1",build:"742"});
\ No newline at end of file
+YAHOO.util.DataSource=function(B,D){if(!B){return ;}this.liveData=B;this._oQueue={interval:null,conn:null,requests:[]};if(B.nodeType&&B.nodeType==9){this.dataType=YAHOO.util.DataSource.TYPE_XML;}else{if(YAHOO.lang.isArray(B)){this.dataType=YAHOO.util.DataSource.TYPE_JSARRAY;}else{if(YAHOO.lang.isString(B)){this.dataType=YAHOO.util.DataSource.TYPE_XHR;}else{if(YAHOO.lang.isFunction(B)){this.dataType=YAHOO.util.DataSource.TYPE_JSFUNCTION;}else{if(B.nodeName&&(B.nodeName.toLowerCase()=="table")){this.dataType=YAHOO.util.DataSource.TYPE_HTMLTABLE;this.liveData=B.cloneNode(true);}else{if(YAHOO.lang.isObject(B)){this.dataType=YAHOO.util.DataSource.TYPE_JSON;}else{this.dataType=YAHOO.util.DataSource.TYPE_UNKNOWN;}}}}}}if(D&&(D.constructor==Object)){for(var C in D){if(C){this[C]=D[C];}}}var A=this.maxCacheEntries;if(!YAHOO.lang.isNumber(A)||(A<0)){A=0;}this._aIntervals=[];this._sName="DataSource instance"+YAHOO.util.DataSource._nIndex;YAHOO.util.DataSource._nIndex++;this.createEven!
 t("cacheRequestEvent");this.createEvent("cacheResponseEvent");this.createEvent("requestEvent");this.createEvent("responseEvent");this.createEvent("responseParseEvent");this.createEvent("responseCacheEvent");this.createEvent("dataErrorEvent");this.createEvent("cacheFlushEvent");};YAHOO.augment(YAHOO.util.DataSource,YAHOO.util.EventProvider);YAHOO.util.DataSource.TYPE_UNKNOWN=-1;YAHOO.util.DataSource.TYPE_JSARRAY=0;YAHOO.util.DataSource.TYPE_JSFUNCTION=1;YAHOO.util.DataSource.TYPE_XHR=2;YAHOO.util.DataSource.TYPE_JSON=3;YAHOO.util.DataSource.TYPE_XML=4;YAHOO.util.DataSource.TYPE_TEXT=5;YAHOO.util.DataSource.TYPE_HTMLTABLE=6;YAHOO.util.DataSource.ERROR_DATAINVALID="Invalid data";YAHOO.util.DataSource.ERROR_DATANULL="Null data";YAHOO.util.DataSource._nIndex=0;YAHOO.util.DataSource._nTransactionId=0;YAHOO.util.DataSource.prototype._sName=null;YAHOO.util.DataSource.prototype._aCache=null;YAHOO.util.DataSource.prototype._oQueue=null;YAHOO.util.DataSource.prototype._aIntervals=null!
 ;YAHOO.util.DataSource.prototype.maxCacheEntries=0;YAHOO.util.!
 DataSour
ce.prototype.liveData=null;YAHOO.util.DataSource.prototype.dataType=YAHOO.util.DataSource.TYPE_UNKNOWN;YAHOO.util.DataSource.prototype.responseType=YAHOO.util.DataSource.TYPE_UNKNOWN;YAHOO.util.DataSource.prototype.responseSchema=null;YAHOO.util.DataSource.prototype.connMgr=null;YAHOO.util.DataSource.prototype.connXhrMode="allowAll";YAHOO.util.DataSource.prototype.connMethodPost=false;YAHOO.util.DataSource.prototype.connTimeout=0;YAHOO.util.DataSource.parseString=function(B){if(!YAHOO.lang.isValue(B)){return null;}var A=B+"";if(YAHOO.lang.isString(A)){return A;}else{return null;}};YAHOO.util.DataSource.parseNumber=function(B){var A=B*1;if(YAHOO.lang.isNumber(A)){return A;}else{return null;}};YAHOO.util.DataSource.convertNumber=function(A){return YAHOO.util.DataSource.parseNumber(A);};YAHOO.util.DataSource.parseDate=function(B){var A=null;if(!(B instanceof Date)){A=new Date(B);}else{return B;}if(A instanceof Date){return A;}else{return null;}};YAHOO.util.DataSource.convertDat!
 e=function(A){return YAHOO.util.DataSource.parseDate(A);};YAHOO.util.DataSource.prototype.toString=function(){return this._sName;};YAHOO.util.DataSource.prototype.getCachedResponse=function(H,B,G){var A=this._aCache;if(this.maxCacheEntries>0){if(!A){this._aCache=[];}else{var D=A.length;if(D>0){var F=null;this.fireEvent("cacheRequestEvent",{request:H,callback:B,caller:G});for(var E=D-1;E>=0;E--){var C=A[E];if(this.isCacheHit(H,C.request)){F=C.response;this.fireEvent("cacheResponseEvent",{request:H,response:F,callback:B,caller:G});if(E<D-1){A.splice(E,1);this.addToCache(H,F);}break;}}return F;}}}else{if(A){this._aCache=null;}}return null;};YAHOO.util.DataSource.prototype.isCacheHit=function(A,B){return(A===B);};YAHOO.util.DataSource.prototype.addToCache=function(D,C){var A=this._aCache;if(!A){return ;}while(A.length>=this.maxCacheEntries){A.shift();}var B={request:D,response:C};A[A.length]=B;this.fireEvent("responseCacheEvent",{request:D,response:C});};YAHOO.util.DataSource.p!
 rototype.flushCache=function(){if(this._aCache){this._aCache=[!
 ];this.f
ireEvent("cacheFlushEvent");}};YAHOO.util.DataSource.prototype.setInterval=function(D,F,B,E){if(YAHOO.lang.isNumber(D)&&(D>=0)){var C=this;var A=setInterval(function(){C.makeConnection(F,B,E);},D);this._aIntervals.push(A);return A;}else{}};YAHOO.util.DataSource.prototype.clearInterval=function(A){var C=this._aIntervals||[];for(var B=C.length-1;B>-1;B--){if(C[B]===A){C.splice(B,1);clearInterval(A);}}};YAHOO.util.DataSource.prototype.clearAllIntervals=function(A){var C=this._aIntervals||[];for(var B=C.length-1;B>-1;B--){C.splice(B,1);clearInterval(A);}};YAHOO.util.DataSource.issueCallback=function(E,D,B,C){if(YAHOO.lang.isFunction(E)){E.apply(C,D);}else{if(YAHOO.lang.isObject(E)){C=E.scope||C||window;var A=E.success;if(B){A=E.failure;}if(A){A.apply(C,D.concat([E.argument]));}}}};YAHOO.util.DataSource.prototype.sendRequest=function(D,A,C){var B=this.getCachedResponse(D,A,C);if(B){YAHOO.util.DataSource.issueCallback(A,[D,B],false,C);return null;}return this.makeConnection(D,A,C)!
 ;};YAHOO.util.DataSource.prototype.makeConnection=function(A,P,K){this.fireEvent("requestEvent",{request:A,callback:P,caller:K});var D=null;var L=YAHOO.util.DataSource._nTransactionId++;switch(this.dataType){case YAHOO.util.DataSource.TYPE_JSFUNCTION:D=this.liveData(A);this.handleResponse(A,D,P,K,L);break;case YAHOO.util.DataSource.TYPE_XHR:var N=this;var C=this.connMgr||YAHOO.util.Connect;var G=this._oQueue;var J=function(Q){if(Q&&(this.connXhrMode=="ignoreStaleResponses")&&(Q.tId!=G.conn.tId)){return null;}else{if(!Q){this.fireEvent("dataErrorEvent",{request:A,callback:P,caller:K,message:YAHOO.util.DataSource.ERROR_DATANULL});YAHOO.util.DataSource.issueCallback(P,[A,{error:true}],true,K);return null;}else{this.handleResponse(A,Q,P,K,L);}}};var O=function(Q){this.fireEvent("dataErrorEvent",{request:A,callback:P,caller:K,message:YAHOO.util.DataSource.ERROR_DATAINVALID});if((this.liveData.lastIndexOf("?")!==this.liveData.length-1)&&(A.indexOf("?")!==0)){}Q=Q||{};
+Q.error=true;YAHOO.util.DataSource.issueCallback(P,[A,Q],true,K);return null;};var I={success:J,failure:O,scope:this};if(YAHOO.lang.isNumber(this.connTimeout)){I.timeout=this.connTimeout;}if(this.connXhrMode=="cancelStaleRequests"){if(G.conn){if(C.abort){C.abort(G.conn);G.conn=null;}else{}}}if(C&&C.asyncRequest){var B=this.liveData;var H=this.connMethodPost;var M=(H)?"POST":"GET";var E=(H)?B:B+A;var F=(H)?A:null;if(this.connXhrMode!="queueRequests"){G.conn=C.asyncRequest(M,E,I,F);}else{if(G.conn){G.requests.push({request:A,callback:I});if(!G.interval){G.interval=setInterval(function(){if(C.isCallInProgress(G.conn)){return ;}else{if(G.requests.length>0){E=(H)?B:B+G.requests[0].request;F=(H)?G.requests[0].request:null;G.conn=C.asyncRequest(M,E,G.requests[0].callback,F);G.requests.shift();}else{clearInterval(G.interval);G.interval=null;}}},50);}}else{G.conn=C.asyncRequest(M,E,I,F);}}}else{YAHOO.util.DataSource.issueCallback(P,[A,{error:true}],true,K);}break;default:D=this.live!
 Data;this.handleResponse(A,D,P,K,L);break;}return L;};YAHOO.util.DataSource.prototype.handleResponse=function(oRequest,oRawResponse,oCallback,oCaller,tId){this.fireEvent("responseEvent",{request:oRequest,response:oRawResponse,callback:oCallback,caller:oCaller,tId:tId});var xhr=(this.dataType==YAHOO.util.DataSource.TYPE_XHR)?true:false;var oParsedResponse=null;var oFullResponse=oRawResponse;switch(this.responseType){case YAHOO.util.DataSource.TYPE_JSARRAY:if(xhr&&oRawResponse.responseText){oFullResponse=oRawResponse.responseText;}oFullResponse=this.doBeforeParseData(oRequest,oFullResponse);oParsedResponse=this.parseArrayData(oRequest,oFullResponse);break;case YAHOO.util.DataSource.TYPE_JSON:if(xhr&&oRawResponse.responseText){oFullResponse=oRawResponse.responseText;}try{if(YAHOO.lang.isString(oFullResponse)){if(YAHOO.lang.JSON){oFullResponse=YAHOO.lang.JSON.parse(oFullResponse);}else{if(window.JSON&&JSON.parse){oFullResponse=JSON.parse(oFullResponse);}else{if(oFullResponse.pa!
 rseJSON){oFullResponse=oFullResponse.parseJSON();}else{while(o!
 FullResp
onse.length>0&&(oFullResponse.charAt(0)!="{")&&(oFullResponse.charAt(0)!="[")){oFullResponse=oFullResponse.substring(1,oFullResponse.length);}if(oFullResponse.length>0){var objEnd=Math.max(oFullResponse.lastIndexOf("]"),oFullResponse.lastIndexOf("}"));oFullResponse=oFullResponse.substring(0,objEnd+1);oFullResponse=eval("("+oFullResponse+")");}}}}}}catch(e){}oFullResponse=this.doBeforeParseData(oRequest,oFullResponse);oParsedResponse=this.parseJSONData(oRequest,oFullResponse);break;case YAHOO.util.DataSource.TYPE_HTMLTABLE:if(xhr&&oRawResponse.responseText){oFullResponse=oRawResponse.responseText;}oFullResponse=this.doBeforeParseData(oRequest,oFullResponse);oParsedResponse=this.parseHTMLTableData(oRequest,oFullResponse);break;case YAHOO.util.DataSource.TYPE_XML:if(xhr&&oRawResponse.responseXML){oFullResponse=oRawResponse.responseXML;}oFullResponse=this.doBeforeParseData(oRequest,oFullResponse);oParsedResponse=this.parseXMLData(oRequest,oFullResponse);break;case YAHOO.util.Dat!
 aSource.TYPE_TEXT:if(xhr&&oRawResponse.responseText){oFullResponse=oRawResponse.responseText;}oFullResponse=this.doBeforeParseData(oRequest,oFullResponse);oParsedResponse=this.parseTextData(oRequest,oFullResponse);break;default:oFullResponse=this.doBeforeParseData(oRequest,oFullResponse);oParsedResponse=this.doBeforeParseData(oRequest,oFullResponse);break;}if(oParsedResponse&&!oParsedResponse.error){oParsedResponse=this.doBeforeCallback(oRequest,oFullResponse,oParsedResponse);this.fireEvent("responseParseEvent",{request:oRequest,response:oParsedResponse,callback:oCallback,caller:oCaller});this.addToCache(oRequest,oParsedResponse);}else{this.fireEvent("dataErrorEvent",{request:oRequest,response:oRawResponse,callback:oCallback,caller:oCaller,message:YAHOO.util.DataSource.ERROR_DATANULL});oParsedResponse=oParsedResponse||{};oParsedResponse.error=true;}oParsedResponse.tId=tId;YAHOO.util.DataSource.issueCallback(oCallback,[oRequest,oParsedResponse],oParsedResponse.error,oCaller)!
 ;};YAHOO.util.DataSource.prototype.doBeforeParseData=function(!
 B,A){ret
urn A;};YAHOO.util.DataSource.prototype.doBeforeCallback=function(B,A,C){return C;};YAHOO.util.DataSource.prototype.parseArrayData=function(B,L){if(YAHOO.lang.isArray(L)){if(YAHOO.lang.isArray(this.responseSchema.fields)){var F=[],I=this.responseSchema.fields,G;for(G=I.length-1;G>=0;--G){if(typeof I[G]!=="object"){I[G]={key:I[G]};}}var M={};for(G=I.length-1;G>=0;--G){var A=I[G].parser||I[G].converter;if(A){M[I[G].key]=A;}}var J=YAHOO.lang.isArray(L[0]);for(G=L.length-1;G>-1;G--){var H={};var C=L[G];if(typeof C==="object"){for(var D=I.length-1;D>-1;D--){var K=I[D];var E=J?C[D]:C[K.key];if(M[K.key]){E=M[K.key].call(this,E);}if(E===undefined){E=null;}H[K.key]=E;}}F[G]=H;}var N={results:F};return N;}}return null;};YAHOO.util.DataSource.prototype.parseTextData=function(I,O){if(YAHOO.lang.isString(O)){if(YAHOO.lang.isArray(this.responseSchema.fields)&&YAHOO.lang.isString(this.responseSchema.recordDelim)&&YAHOO.lang.isString(this.responseSchema.fieldDelim)){var N={results:[]};var H!
 =this.responseSchema.recordDelim;var F=this.responseSchema.fieldDelim;var G=this.responseSchema.fields;if(O.length>0){var C=O.length-H.length;if(O.substr(C)==H){O=O.substr(0,C);}var D=O.split(H);for(var K=0,L=D.length,Q=0;K<L;++K){var B={};var P=false;if(YAHOO.lang.isString(D[K])){var E=D[K].split(F);for(var J=G.length-1;J>-1;J--){try{var R=E[J];if(YAHOO.lang.isString(R)){if(R.charAt(0)=='"'){R=R.substr(1);}if(R.charAt(R.length-1)=='"'){R=R.substr(0,R.length-1);}var A=G[J];var S=(YAHOO.lang.isValue(A.key))?A.key:A;if(!A.parser&&A.converter){A.parser=A.converter;}if(A.parser){R=A.parser.call(this,R);}if(R===undefined){R=null;}B[S]=R;}else{P=true;}}catch(M){P=true;}}if(!P){N.results[Q++]=B;}}}}return N;}}return null;};YAHOO.util.DataSource.prototype.parseXMLData=function(N,S){var T=false,L=this.responseSchema,R={meta:{}},G=null,I=L.metaNode,A=L.metaFields||{},E=L.totalRecords,P,O,H,K;if(E&&!A.totalRecords){A.totalRecords=E;
+}try{G=(L.resultNode)?S.getElementsByTagName(L.resultNode):null;I=I?S.getElementsByTagName(I)[0]:S;if(I){for(O in A){if(YAHOO.lang.hasOwnProperty(A,O)){H=A[O];K=I.getElementsByTagName(H)[0];if(K){K=K.firstChild.nodeValue;}else{K=I.attributes.getNamedItem(H);if(K){K=K.value;}}if(YAHOO.lang.isValue(K)){R.meta[O]=K;}}}}}catch(Q){}if(!G||!YAHOO.lang.isArray(L.fields)){T=true;}else{R.results=[];for(P=G.length-1;P>=0;--P){var J=G.item(P);var F={};for(var M=L.fields.length-1;M>=0;M--){var B=L.fields[M];var V=(YAHOO.lang.isValue(B.key))?B.key:B;var U=null;var D=J.attributes.getNamedItem(V);if(D){U=D.value;}else{var C=J.getElementsByTagName(V);if(C&&C.item(0)&&C.item(0).firstChild){U=C.item(0).firstChild.nodeValue;}else{U="";}}if(!B.parser&&B.converter){B.parser=B.converter;}if(B.parser){U=B.parser.call(this,U);}if(U===undefined){U=null;}F[V]=U;}R.results[P]=F;}}if(T){R.error=true;}else{}return R;};YAHOO.util.DataSource.prototype.parseJSONData=function(Q,V){var U={results:[],meta:{}!
 },N=this.responseSchema;if(YAHOO.lang.isObject(V)){if(YAHOO.lang.isArray(N.fields)){var O=N.fields,C=V,P=[],I=N.metaFields||{},E=[],H=[],G=[],W=false,S,T,R,J,X,B,M;var A=function(b){var a=null,Z=[],Y=0;if(b){b=b.replace(/\[(['"])(.*?)\1\]/g,function(d,c,e){Z[Y]=e;return".@"+(Y++);}).replace(/\[(\d+)\]/g,function(d,c){Z[Y]=parseInt(c,10)|0;return".@"+(Y++);}).replace(/^\./,"");if(!/[^\w\.\$@]/.test(b)){a=b.split(".");for(Y=a.length-1;Y>=0;--Y){if(a[Y].charAt(0)==="@"){a[Y]=Z[parseInt(a[Y].substr(1),10)];}}}}return a;};var D=function(c,a){var Z=a,b=0,Y=c.length;for(;b<Y&&Z;++b){Z=Z[c[b]];}return Z;};for(S=O.length-1;S>=0;--S){X=O[S].key||O[S];B=O[S].parser||O[S].converter;M=A(X);if(B){E[E.length]={key:X,parser:B};}if(M){if(M.length>1){H[H.length]={key:X,path:M};}else{G[G.length]=X;}}else{}}if(N.resultsList){M=A(N.resultsList);if(M){C=D(M,V);if(C===undefined){W=true;}}else{W=true;}}if(!C){C=[];}if(!YAHOO.lang.isArray(C)){C=[C];}if(!W){for(S=C.length-1;S>=0;--S){var K=C[S],F={}!
 ;for(R=G.length-1;R>=0;--R){F[G[R]]=K[G[R]];}for(R=H.length-1;!
 R>=0;--R
){F[H[R].key]=D(H[R].path,K);}for(R=E.length-1;R>=0;--R){var L=E[R].key;F[L]=E[R].parser(F[L]);if(F[L]===undefined){F[L]=null;}}P[S]=F;}if(N.totalRecords&&!I.totalRecords){I.totalRecords=N.totalRecords;}for(X in I){if(YAHOO.lang.hasOwnProperty(I,X)){M=A(I[X]);if(M){J=D(M,V);U.meta[X]=J;}}}}else{U.error=true;}U.results=P;}}else{U.error=true;}return U;};YAHOO.util.DataSource.prototype.parseHTMLTableData=function(B,M){var J=false;var K=M;var I=this.responseSchema.fields;var O={results:[]};for(var G=0;G<K.tBodies.length;G++){var C=K.tBodies[G];for(var E=C.rows.length-1;E>-1;E--){var A=C.rows[E];var H={};for(var D=I.length-1;D>-1;D--){var L=I[D];var N=(YAHOO.lang.isValue(L.key))?L.key:L;var F=A.cells[D].innerHTML;if(!L.parser&&L.converter){L.parser=L.converter;}if(L.parser){F=L.parser.call(this,F);}if(F===undefined){F=null;}H[N]=F;}O.results[E]=H;}}if(J){O.error=true;}else{}return O;};YAHOO.util.Number={format:function(B,E){E=E||{};if(!YAHOO.lang.isNumber(B)){B*=1;}if(YAHOO.lang.!
 isNumber(B)){var I=B+"";var F=(E.decimalSeparator)?E.decimalSeparator:".";var G;if(YAHOO.lang.isNumber(E.decimalPlaces)){var H=E.decimalPlaces;var C=Math.pow(10,H);I=Math.round(B*C)/C+"";G=I.lastIndexOf(".");if(H>0){if(G<0){I+=F;G=I.length-1;}else{if(F!=="."){I=I.replace(".",F);}}while((I.length-1-G)<H){I+="0";}}}if(E.thousandsSeparator){var K=E.thousandsSeparator;G=I.lastIndexOf(F);G=(G>-1)?G:I.length;var J=I.substring(G);var A=-1;for(var D=G;D>0;D--){A++;if((A%3===0)&&(D!==G)){J=K+J;}J=I.charAt(D-1)+J;}I=J;}I=(E.prefix)?E.prefix+I:I;I=(E.suffix)?I+E.suffix:I;return I;}else{return B;}}};YAHOO.util.Date={format:function(C,B){B=B||{};if(C instanceof Date){var D=B.format||"MM/DD/YYYY";var E=C.getMonth()+1;var A=C.getDate();var F=C.getFullYear();switch(D){case"YYYY/MM/DD":return F+"/"+E+"/"+A;case"DD/MM/YYYY":return A+"/"+E+"/"+F;default:return E+"/"+A+"/"+F;}}else{return YAHOO.lang.isValue(C)?C:"";}}};YAHOO.register("datasource",YAHOO.util.DataSource,{version:"2.5.1",build:"9!
 84"});
\ No newline at end of file

Modified: trunk/root/static/yui/datasource/datasource-beta.js
===================================================================
--- trunk/root/static/yui/datasource/datasource-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/datasource/datasource-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The DataSource utility provides a common configurable interface for widgets
@@ -34,18 +34,12 @@
  * @param oConfigs {Object} (optional) Object literal of configuration values.
  */
 YAHOO.util.DataSource = function(oLiveData, oConfigs) {
-    // Set any config params passed in to override defaults
-    if(oConfigs && (oConfigs.constructor == Object)) {
-        for(var sConfig in oConfigs) {
-            if(sConfig) {
-                this[sConfig] = oConfigs[sConfig];
-            }
-        }
-    }
-    
     if(!oLiveData) {
         return;
     }
+    
+    this.liveData = oLiveData;
+    this._oQueue = {interval:null, conn:null, requests:[]};
 
     if(oLiveData.nodeType && oLiveData.nodeType == 9) {
         this.dataType = YAHOO.util.DataSource.TYPE_XML;
@@ -61,6 +55,7 @@
     }
     else if(oLiveData.nodeName && (oLiveData.nodeName.toLowerCase() == "table")) {
         this.dataType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
+        this.liveData = oLiveData.cloneNode(true);
     }
     else if(YAHOO.lang.isObject(oLiveData)) {
         this.dataType = YAHOO.util.DataSource.TYPE_JSON;
@@ -69,21 +64,21 @@
         this.dataType = YAHOO.util.DataSource.TYPE_UNKNOWN;
     }
 
-    this.liveData = oLiveData;
-    this._oQueue = {interval:null, conn:null, requests:[]};
-
-
+    // Set any config params passed in to override defaults
+    if(oConfigs && (oConfigs.constructor == Object)) {
+        for(var sConfig in oConfigs) {
+            if(sConfig) {
+                this[sConfig] = oConfigs[sConfig];
+            }
+        }
+    }
+    
     // Validate and initialize public configs
     var maxCacheEntries = this.maxCacheEntries;
     if(!YAHOO.lang.isNumber(maxCacheEntries) || (maxCacheEntries < 0)) {
         maxCacheEntries = 0;
     }
 
-    // Initialize local cache
-    if(maxCacheEntries > 0 && !this._aCache) {
-        this._aCache = [];
-    }
-    
     // Initialize interval tracker
     this._aIntervals = [];
 
@@ -103,18 +98,18 @@
      * @event cacheRequestEvent
      * @param oArgs.request {Object} The request object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      */
     this.createEvent("cacheRequestEvent");
 
     /**
      * Fired when data is retrieved from the local cache.
      *
-     * @event getCachedResponseEvent
+     * @event cacheResponseEvent
      * @param oArgs.request {Object} The request object.
      * @param oArgs.response {Object} The response object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      * @param oArgs.tId {Number} Transaction ID.
      */
     this.createEvent("cacheResponseEvent");
@@ -125,7 +120,7 @@
      * @event requestEvent
      * @param oArgs.request {Object} The request object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      */
     this.createEvent("requestEvent");
 
@@ -136,7 +131,7 @@
      * @param oArgs.request {Object} The request object.
      * @param oArgs.response {Object} The raw response object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      */
     this.createEvent("responseEvent");
 
@@ -147,7 +142,7 @@
      * @param oArgs.request {Object} The request object.
      * @param oArgs.response {Object} The parsed response object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      */
     this.createEvent("responseParseEvent");
 
@@ -158,7 +153,7 @@
      * @param oArgs.request {Object} The request object.
      * @param oArgs.response {Object} The parsed response object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      */
     this.createEvent("responseCacheEvent");
     /**
@@ -167,7 +162,7 @@
      * @event dataErrorEvent
      * @param oArgs.request {Object} The request object.
      * @param oArgs.callback {Function} The callback function.
-     * @param oArgs.caller {Object} The parent object of the callback function.
+     * @param oArgs.caller {Object} (deprecated) Use callback.scope.
      * @param oArgs.message {String} The error message.
      */
     this.createEvent("dataErrorEvent");
@@ -415,6 +410,8 @@
  * <dt>fieldDelim</dt> <dd>Field delimiter (text data only)</dd>
  * <dt>fields</dt> <dd>Array of field names (aka keys), or array of object literals
  * such as: {key:"fieldname",parser:YAHOO.util.DataSource.parseDate}</dd>
+ * <dt>metaFields</dt> <dd>Object literal of keys to include in the oParsedResponse.meta collection</dd>
+ * <dt>metaNode</dt> <dd>Name of the node under which to search for meta information in XML response data</dd>
  * </dl>
  *
  * @property responseSchema
@@ -423,8 +420,7 @@
 YAHOO.util.DataSource.prototype.responseSchema = null;
 
  /**
- * Alias to YUI Connection Manager. Allows implementers to specify their own
- * subclasses of the YUI Connection Manager utility.
+ * Alias to YUI Connection Manager, to allow implementers to customize the utility.
  *
  * @property connMgr
  * @type Object
@@ -601,32 +597,49 @@
  */
 YAHOO.util.DataSource.prototype.getCachedResponse = function(oRequest, oCallback, oCaller) {
     var aCache = this._aCache;
-    var nCacheLength = (aCache) ? aCache.length : 0;
-    var oResponse = null;
 
     // If cache is enabled...
-    if((this.maxCacheEntries > 0) && aCache && (nCacheLength > 0)) {
-        this.fireEvent("cacheRequestEvent", {request:oRequest,callback:oCallback,caller:oCaller});
-
-        // Loop through each cached element
-        for(var i = nCacheLength-1; i >= 0; i--) {
-            var oCacheElem = aCache[i];
-
-            // Defer cache hit logic to a public overridable method
-            if(this.isCacheHit(oRequest,oCacheElem.request)) {
-                // Grab the cached response
-                oResponse = oCacheElem.response;
-                // The cache returned a hit!
-                // Remove element from its original location
-                aCache.splice(i,1);
-                // Add as newest
-                this.addToCache(oRequest, oResponse);
-                this.fireEvent("cacheResponseEvent", {request:oRequest,response:oResponse,callback:oCallback,caller:oCaller});
-                break;
+    if(this.maxCacheEntries > 0) {        
+        // Initialize local cache
+        if(!aCache) {
+            this._aCache = [];
+        }
+        // Look in local cache
+        else {
+            var nCacheLength = aCache.length;
+            if(nCacheLength > 0) {
+                var oResponse = null;
+                this.fireEvent("cacheRequestEvent", {request:oRequest,callback:oCallback,caller:oCaller});
+        
+                // Loop through each cached element
+                for(var i = nCacheLength-1; i >= 0; i--) {
+                    var oCacheElem = aCache[i];
+        
+                    // Defer cache hit logic to a public overridable method
+                    if(this.isCacheHit(oRequest,oCacheElem.request)) {
+                        // The cache returned a hit!
+                        // Grab the cached response
+                        oResponse = oCacheElem.response;
+                        this.fireEvent("cacheResponseEvent", {request:oRequest,response:oResponse,callback:oCallback,caller:oCaller});
+                        
+                        // Refresh the position of the cache hit
+                        if(i < nCacheLength-1) {
+                            // Remove element from its original location
+                            aCache.splice(i,1);
+                            // Add as newest
+                            this.addToCache(oRequest, oResponse);
+                        }
+                        break;
+                    }
+                }
+                return oResponse;
             }
         }
     }
-    return oResponse;
+    else if(aCache) {
+        this._aCache = null;
+    }
+    return null;
 };
 
 /**
@@ -657,8 +670,6 @@
         return;
     }
 
-    //TODO: check for duplicate entries
-
     // If the cache is full, make room by removing stalest element (index=0)
     while(aCache.length >= this.maxCacheEntries) {
         aCache.shift();
@@ -666,7 +677,7 @@
 
     // Add to cache in the newest position, at the end of the array
     var oCacheElem = {request:oRequest,response:oResponse};
-    aCache.push(oCacheElem);
+    aCache[aCache.length] = oCacheElem;
     this.fireEvent("responseCacheEvent", {request:oRequest,response:oResponse});
 };
 
@@ -690,12 +701,11 @@
  * @param nMsec {Number} Length of interval in milliseconds.
  * @param oRequest {Object} Request object.
  * @param oCallback {Function} Handler function to receive the response.
- * @param oCaller {Object} The Calling object that is making the request.
+ * @param oCaller {Object} (deprecated) Use oCallback.scope.
  * @return {Number} Interval ID.
  */
 YAHOO.util.DataSource.prototype.setInterval = function(nMsec, oRequest, oCallback, oCaller) {
-    //TODO: management and cleanup of interval IDs
-    try {
+    if(YAHOO.lang.isNumber(nMsec) && (nMsec >= 0)) {
         var oSelf = this;
         var nId = setInterval(function() {
             oSelf.makeConnection(oRequest, oCallback, oCaller);
@@ -703,7 +713,7 @@
         this._aIntervals.push(nId);
         return nId;
     }
-    catch(e) {
+    else {
     }
 };
 
@@ -738,19 +748,54 @@
 };
 
 /**
+ * Executes a configured callback.  For object literal callbacks, the third
+ * param determines whether to execute the success handler or failure handler.
+ * @method issueCallback
+ * @param callback {Function|Object} the callback to execute
+ * @param params {Array} params to be passed to the callback method
+ * @param error {Boolean} whether an error occurred
+ * @param scope {Object} the scope from which to execute the callback
+ * (deprecated - use an object literal callback)
+ */
+YAHOO.util.DataSource.issueCallback = function (callback,params,error,scope) {
+    if (YAHOO.lang.isFunction(callback)) {
+        callback.apply(scope, params);
+    } else if (YAHOO.lang.isObject(callback)) {
+        scope = callback.scope || scope || window;
+        var callbackFunc = callback.success;
+        if (error) {
+            callbackFunc = callback.failure;
+        }
+        if (callbackFunc) {
+            callbackFunc.apply(scope, params.concat([callback.argument]));
+        }
+    }
+};
+
+/**
  * First looks for cached response, then sends request to live data.
  *
  * @method sendRequest
  * @param oRequest {Object} Request object.
- * @param oCallback {Function} Handler function to receive the response.
- * @param oCaller {Object} The Calling object that is making the request.
+ * @param oCallback {Object} An object literal with the following properties:
+ *     <dl>
+ *     <dt><code>success</code></dt>
+ *     <dd>The function to call when the data is ready.</dd>
+ *     <dt><code>failure</code></dt>
+ *     <dd>The function to call upon a response failure condition.</dd>
+ *     <dt><code>scope</code></dt>
+ *     <dd>The object to serve as the scope for the success and failure handlers.</dd>
+ *     <dt><code>argument</code></dt>
+ *     <dd>Arbitrary data that will be passed back to the success and failure handlers.</dd>
+ *     </dl> 
+ * @param oCaller {Object} (deprecated) Use oCallback.scope.
  * @return {Number} Transaction ID, or null if response found in cache.
  */
 YAHOO.util.DataSource.prototype.sendRequest = function(oRequest, oCallback, oCaller) {
     // First look in cache
     var oCachedResponse = this.getCachedResponse(oRequest, oCallback, oCaller);
     if(oCachedResponse) {
-        oCallback.call(oCaller, oRequest, oCachedResponse);
+        YAHOO.util.DataSource.issueCallback(oCallback,[oRequest,oCachedResponse],false,oCaller);
         return null;
     }
 
@@ -766,8 +811,8 @@
  *
  * @method makeConnection
  * @param oRequest {Object} Request object.
- * @param oCallback {Function} Handler function to receive the response.
- * @param oCaller {Object} The Calling object that is making the request.
+ * @param oCallback {Object} Callback object literal.
+ * @param oCaller {Object} (deprecated) Use oCallback.scope.
  * @return {Number} Transaction ID.
  */
 YAHOO.util.DataSource.prototype.makeConnection = function(oRequest, oCallback, oCaller) {
@@ -814,7 +859,8 @@
                             message:YAHOO.util.DataSource.ERROR_DATANULL});
 
                     // Send error response back to the caller with the error flag on
-                    oCallback.call(oCaller, oRequest, oResponse, true);
+                    // TODO: should this send oResponse, considering the fork?
+                    YAHOO.util.DataSource.issueCallback(oCallback,[oRequest, {error:true}], true, oCaller);
 
                     return null;
                 }
@@ -842,7 +888,10 @@
                 }
 
                 // Send failure response back to the caller with the error flag on
-                oCallback.call(oCaller, oRequest, oResponse, true);
+                oResponse = oResponse || {};
+                oResponse.error = true;
+                YAHOO.util.DataSource.issueCallback(oCallback,[oRequest,oResponse],true, oCaller);
+
                 return null;
             };
 
@@ -930,7 +979,7 @@
             }
             else {
                 // Send null response back to the caller with the error flag on
-                oCallback.call(oCaller, oRequest, null, true);
+                YAHOO.util.DataSource.issueCallback(oCallback,[oRequest,{error:true}],true,oCaller);
             }
 
             break;
@@ -951,23 +1000,24 @@
 };
 
 /**
- * Handles raw data response from live data source. Sends a parsed response object
- * to the callback function in this format:
+ * Receives raw data response and type converts to XML, JSON, etc as necessary.
+ * Forwards oFullResponse to appropriate parsing function to get turned into
+ * oParsedResponse. Calls doBeforeCallback() and adds oParsedResponse to 
+ * the cache when appropriate before calling issueCallback().
+ * 
+ * The oParsedResponse object literal has the following properties:
+ * <dl>
+ *     <dd><dt>tId {Number}</dt> Unique transaction ID</dd>
+ *     <dd><dt>results {Array}</dt> Array of parsed data results</dd>
+ *     <dd><dt>error {Boolean}</dt> True if there was an error</dd>
+ *     <dd><dt>totalRecords {Number}</dt> Total number of records (if available)</dd> 
+ * </dl>
  *
- * fnCallback(oRequest, oParsedResponse)
- *
- * where the oParsedResponse object literal with the following properties:
- * <ul>
- *     <li>tId {Number} Unique transaction ID</li>
- *     <li>results {Array} Array of parsed data results</li>
- *     <li>error {Boolean} True if there was an error</li>
- * </ul>
- *
  * @method handleResponse
  * @param oRequest {Object} Request object
  * @param oRawResponse {Object} The raw response from the live database.
- * @param oCallback {Function} Handler function to receive the response.
- * @param oCaller {Object} The calling object that is making the request.
+ * @param oCallback {Object} Callback object literal.
+ * @param oCaller {Object} (deprecated) Use oCallback.scope.
  * @param tId {Number} Transaction ID.
  */
 YAHOO.util.DataSource.prototype.handleResponse = function(oRequest, oRawResponse, oCallback, oCaller, tId) {
@@ -975,85 +1025,129 @@
             callback:oCallback, caller:oCaller, tId: tId});
     var xhr = (this.dataType == YAHOO.util.DataSource.TYPE_XHR) ? true : false;
     var oParsedResponse = null;
-    var bError = false;
+    var oFullResponse = oRawResponse;
 
-    // Access to the raw response before it gets parsed
-    oRawResponse = this.doBeforeParseData(oRequest, oRawResponse);
-
     switch(this.responseType) {
         case YAHOO.util.DataSource.TYPE_JSARRAY:
             if(xhr && oRawResponse.responseText) {
-                oRawResponse = oRawResponse.responseText;
+                oFullResponse = oRawResponse.responseText; 
             }
-            oParsedResponse = this.parseArrayData(oRequest, oRawResponse);
+            oFullResponse = this.doBeforeParseData(oRequest, oFullResponse);
+            oParsedResponse = this.parseArrayData(oRequest, oFullResponse);
             break;
         case YAHOO.util.DataSource.TYPE_JSON:
             if(xhr && oRawResponse.responseText) {
-                oRawResponse = oRawResponse.responseText;
+                oFullResponse = oRawResponse.responseText;
             }
-            oParsedResponse = this.parseJSONData(oRequest, oRawResponse);
+            try {
+                // Convert to JSON object if it's a string
+                if(YAHOO.lang.isString(oFullResponse)) {
+                    // Check for YUI JSON Util
+                    if(YAHOO.lang.JSON) {
+                        oFullResponse = YAHOO.lang.JSON.parse(oFullResponse);
+                    }
+                    // Look for JSON parsers using an API similar to json2.js
+                    else if(window.JSON && JSON.parse) {
+                        oFullResponse = JSON.parse(oFullResponse);
+                    }
+                    // Look for JSON parsers using an API similar to json.js
+                    else if(oFullResponse.parseJSON) {
+                        oFullResponse = oFullResponse.parseJSON();
+                    }
+                    // No JSON lib found so parse the string
+                    else {
+                        // Trim leading spaces
+                        while (oFullResponse.length > 0 &&
+                                (oFullResponse.charAt(0) != "{") &&
+                                (oFullResponse.charAt(0) != "[")) {
+                            oFullResponse = oFullResponse.substring(1, oFullResponse.length);
+                        }
+    
+                        if(oFullResponse.length > 0) {
+                            // Strip extraneous stuff at the end
+                            var objEnd = Math.max(oFullResponse.lastIndexOf("]"),oFullResponse.lastIndexOf("}"));
+                            oFullResponse = oFullResponse.substring(0,objEnd+1);
+    
+                            // Turn the string into an object literal...
+                            // ...eval is necessary here
+                            oFullResponse = eval("(" + oFullResponse + ")");
+    
+                        }
+                    }
+                }
+            }
+            catch(e) {
+            }
+
+            oFullResponse = this.doBeforeParseData(oRequest, oFullResponse);
+            oParsedResponse = this.parseJSONData(oRequest, oFullResponse);
             break;
         case YAHOO.util.DataSource.TYPE_HTMLTABLE:
             if(xhr && oRawResponse.responseText) {
-                oRawResponse = oRawResponse.responseText;
+                oFullResponse = oRawResponse.responseText;
             }
-            oParsedResponse = this.parseHTMLTableData(oRequest, oRawResponse);
+            oFullResponse = this.doBeforeParseData(oRequest, oFullResponse);
+            oParsedResponse = this.parseHTMLTableData(oRequest, oFullResponse);
             break;
         case YAHOO.util.DataSource.TYPE_XML:
             if(xhr && oRawResponse.responseXML) {
-                oRawResponse = oRawResponse.responseXML;
+                oFullResponse = oRawResponse.responseXML;
             }
-            oParsedResponse = this.parseXMLData(oRequest, oRawResponse);
+            oFullResponse = this.doBeforeParseData(oRequest, oFullResponse);
+            oParsedResponse = this.parseXMLData(oRequest, oFullResponse);
             break;
         case YAHOO.util.DataSource.TYPE_TEXT:
             if(xhr && oRawResponse.responseText) {
-                oRawResponse = oRawResponse.responseText;
+                oFullResponse = oRawResponse.responseText;
             }
-            oParsedResponse = this.parseTextData(oRequest, oRawResponse);
+            oFullResponse = this.doBeforeParseData(oRequest, oFullResponse);
+            oParsedResponse = this.parseTextData(oRequest, oFullResponse);
             break;
         default:
             //var contentType = oRawResponse.getResponseHeader["Content-Type"];
+            oFullResponse = this.doBeforeParseData(oRequest, oFullResponse);
+            oParsedResponse = this.doBeforeParseData(oRequest, oFullResponse);
             break;
     }
 
-
-    if(oParsedResponse) {
+    if(oParsedResponse && !oParsedResponse.error) {
         // Last chance to touch the raw response or the parsed response
-        oParsedResponse.tId = tId;
-        oParsedResponse = this.doBeforeCallback(oRequest, oRawResponse, oParsedResponse);
+        oParsedResponse = this.doBeforeCallback(oRequest, oFullResponse, oParsedResponse);
         this.fireEvent("responseParseEvent", {request:oRequest,
                 response:oParsedResponse, callback:oCallback, caller:oCaller});
         // Cache the response
         this.addToCache(oRequest, oParsedResponse);
     }
     else {
-        this.fireEvent("dataErrorEvent", {request:oRequest, callback:oCallback,
+        this.fireEvent("dataErrorEvent", {request:oRequest, response: oRawResponse, callback:oCallback, 
                 caller:oCaller, message:YAHOO.util.DataSource.ERROR_DATANULL});
         
-        // Send response back to the caller with the error flag on
-        oParsedResponse = {error:true};
+        // Be sure the error flag is on
+        oParsedResponse = oParsedResponse || {};
+        oParsedResponse.error = true;
     }
-    
+
     // Send the response back to the caller
-    oCallback.call(oCaller, oRequest, oParsedResponse);
+    oParsedResponse.tId = tId;
+    YAHOO.util.DataSource.issueCallback(oCallback,[oRequest,oParsedResponse],oParsedResponse.error,oCaller);
 };
 
 /**
- * Overridable method gives implementers access to the original raw response
+ * Overridable method gives implementers access to the original full response
  * before the data gets parsed. Implementers should take care not to return an
- * unparsable or otherwise invalid raw response.
+ * unparsable or otherwise invalid response.
  *
  * @method doBeforeParseData
  * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
- * @return {Object} Raw response for parsing.
+ * @param oFullResponse {Object} The full response from the live database.
+ * @return {Object} Full response for parsing.
  */
-YAHOO.util.DataSource.prototype.doBeforeParseData = function(oRequest, oRawResponse) {
-    return oRawResponse;
+YAHOO.util.DataSource.prototype.doBeforeParseData = function(oRequest, oFullResponse) {
+    return oFullResponse;
 };
 
 /**
- * Overridable method gives implementers access to the original raw response and
+ * Overridable method gives implementers access to the original full response and
  * the parsed response (parsed against the given schema) before the data
  * is added to the cache (if applicable) and then sent back to callback function.
  * This is your chance to access the raw response and/or populate the parsed
@@ -1061,319 +1155,250 @@
  *
  * @method doBeforeCallback
  * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
+ * @param oFullResponse {Object} The full response from the live database.
  * @param oParsedResponse {Object} The parsed response to return to calling object.
  * @return {Object} Parsed response object.
  */
-YAHOO.util.DataSource.prototype.doBeforeCallback = function(oRequest, oRawResponse, oParsedResponse) {
+YAHOO.util.DataSource.prototype.doBeforeCallback = function(oRequest, oFullResponse, oParsedResponse) {
     return oParsedResponse;
 };
 
 /**
- * Overridable method parses raw array data into a response object.
+ * Overridable method parses Array data into a response object.
  *
  * @method parseArrayData
  * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
- * @return {Object} Parsed response object.
+ * @param oFullResponse {Object} The full Array from the live database.
+ * @return {Object} Parsed response object with the following properties:<br>
+ *     - results (Array) Array of parsed data results<br>
+ *     - error (Boolean) True if there was an error<br>
+ *     - totalRecords (Number) Total number of records (if available)
  */
-YAHOO.util.DataSource.prototype.parseArrayData = function(oRequest, oRawResponse) {
-    if(YAHOO.lang.isArray(oRawResponse) && YAHOO.lang.isArray(this.responseSchema.fields)) {
-        var oParsedResponse = {results:[]};
-        var fields = this.responseSchema.fields;
-        for(var i=oRawResponse.length-1; i>-1; i--) {
-            var oResult = {};
-            for(var j=fields.length-1; j>-1; j--) {
-                var field = fields[j];
-                var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
-                var data = (YAHOO.lang.isValue(oRawResponse[i][j])) ? oRawResponse[i][j] : oRawResponse[i][key];
-                // Backward compatibility
-                if(!field.parser && field.converter) {
-                    field.parser = field.converter;
+YAHOO.util.DataSource.prototype.parseArrayData = function(oRequest, oFullResponse) {
+    if(YAHOO.lang.isArray(oFullResponse)) {
+        if(YAHOO.lang.isArray(this.responseSchema.fields)) {
+            var results = [],
+                fields = this.responseSchema.fields,
+                i;
+            for (i = fields.length - 1; i >= 0; --i) {
+                if (typeof fields[i] !== 'object') {
+                    fields[i] = { key : fields[i] };
                 }
-                if(field.parser) {
-                    data = field.parser.call(this, data);
+            }
+
+            var parsers = {};
+            for (i = fields.length - 1; i >= 0; --i) {
+                var p = fields[i].parser || fields[i].converter;
+                if (p) {
+                    parsers[fields[i].key] = p;
                 }
-                // Safety measure
-                if(data === undefined) {
-                    data = null;
-                }
-                oResult[key] = data;
             }
-            oParsedResponse.results.unshift(oResult);
-        }
-        return oParsedResponse;
-    }
-    else {
-        return null;
-    }
-};
 
-/**
- * Overridable method parses raw plain text data into a response object.
- *
- * @method parseTextData
- * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
- * @return {Object} Parsed response object.
- */
-YAHOO.util.DataSource.prototype.parseTextData = function(oRequest, oRawResponse) {
-    var oParsedResponse = {};
-    if(YAHOO.lang.isString(oRawResponse) &&
-            YAHOO.lang.isArray(this.responseSchema.fields) &&
-            YAHOO.lang.isString(this.responseSchema.recordDelim) &&
-            YAHOO.lang.isString(this.responseSchema.fieldDelim)) {
-        oParsedResponse.results = [];
-        var recDelim = this.responseSchema.recordDelim;
-        var fieldDelim = this.responseSchema.fieldDelim;
-        var fields = this.responseSchema.fields;
-        if(oRawResponse.length > 0) {
-            // Delete the last line delimiter at the end of the data if it exists
-            var newLength = oRawResponse.length-recDelim.length;
-            if(oRawResponse.substr(newLength) == recDelim) {
-                oRawResponse = oRawResponse.substr(0, newLength);
-            }
-            // Split along record delimiter to get an array of strings
-            var recordsarray = oRawResponse.split(recDelim);
-            // Cycle through each record, except the first which contains header info
-            for(var i = recordsarray.length-1; i>-1; i--) {
+            var arrType = YAHOO.lang.isArray(oFullResponse[0]);
+            for(i=oFullResponse.length-1; i>-1; i--) {
                 var oResult = {};
-                var bError = false;
-                for(var j=fields.length-1; j>-1; j--) {
-                    try {
-                        // Split along field delimiter to get each data value
-                        var fielddataarray = recordsarray[i].split(fieldDelim);
+                var rec = oFullResponse[i];
+                if (typeof rec === 'object') {
+                    for(var j=fields.length-1; j>-1; j--) {
+                        var field = fields[j];
+                        var data = arrType ? rec[j] : rec[field.key];
 
-                        // Remove quotation marks from edges, if applicable
-                        var data = fielddataarray[j];
-                        if(data.charAt(0) == "\"") {
-                            data = data.substr(1);
+                        if (parsers[field.key]) {
+                            data = parsers[field.key].call(this,data);
                         }
-                        if(data.charAt(data.length-1) == "\"") {
-                            data = data.substr(0,data.length-1);
-                        }
-                        var field = fields[j];
-                        var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
-                        // Backward compatibility
-                        if(!field.parser && field.converter) {
-                            field.parser = field.converter;
-                        }
-                        if(field.parser) {
-                            data = field.parser.call(this, data);
-                        }
+
                         // Safety measure
                         if(data === undefined) {
                             data = null;
                         }
-                        oResult[key] = data;
+
+                        oResult[field.key] = data;
                     }
-                    catch(e) {
-                        bError = true;
-                    }
                 }
-                if(!bError) {
-                    oParsedResponse.results.unshift(oResult);
-                }
+                results[i] = oResult;
             }
+
+            var oParsedResponse = {results:results};
+            return oParsedResponse;
         }
     }
-    else {
-        oParsedResponse.error = true;
-    }
-    return oParsedResponse;
+    return null;
 };
 
 /**
- * Overridable method parses raw XML data into a response object.
+ * Overridable method parses plain text data into a response object.
  *
- * @method parseXMLData
+ * @method parseTextData
  * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
- * @return {Object} Parsed response object.
+ * @param oFullResponse {Object} The full text response from the live database.
+ * @return {Object} Parsed response object with the following properties:<br>
+ *     - results (Array) Array of parsed data results<br>
+ *     - error (Boolean) True if there was an error<br>
+ *     - totalRecords (Number) Total number of records (if available)
  */
-YAHOO.util.DataSource.prototype.parseXMLData = function(oRequest, oRawResponse) {
-        var bError = false;
-        var oParsedResponse = {};
-        var xmlList = null;
-        // In case oRawResponse is something funky
-        try {
-            xmlList = (this.responseSchema.resultNode) ?
-                oRawResponse.getElementsByTagName(this.responseSchema.resultNode) :
-                null;
-        }
-        catch(e) {
-        }
-        if(!xmlList || !YAHOO.lang.isArray(this.responseSchema.fields)) {
-            bError = true;
-        }
-        // Loop through each result
-        else {
-            oParsedResponse.results = [];
-            for(var k = xmlList.length-1; k >= 0 ; k--) {
-                var result = xmlList.item(k);
-                var oResult = {};
-                // Loop through each data field in each result using the schema
-                for(var m = this.responseSchema.fields.length-1; m >= 0 ; m--) {
-                    var field = this.responseSchema.fields[m];
-                    var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
-                    var data = null;
-                    // Values may be held in an attribute...
-                    var xmlAttr = result.attributes.getNamedItem(key);
-                    if(xmlAttr) {
-                        data = xmlAttr.value;
-                    }
-                    // ...or in a node
-                    else {
-                        var xmlNode = result.getElementsByTagName(key);
-                        if(xmlNode && xmlNode.item(0) && xmlNode.item(0).firstChild) {
-                            data = xmlNode.item(0).firstChild.nodeValue;
+YAHOO.util.DataSource.prototype.parseTextData = function(oRequest, oFullResponse) {
+    if(YAHOO.lang.isString(oFullResponse)) {
+        if(YAHOO.lang.isArray(this.responseSchema.fields) &&
+                YAHOO.lang.isString(this.responseSchema.recordDelim) &&
+                YAHOO.lang.isString(this.responseSchema.fieldDelim)) {
+            var oParsedResponse = {results:[]};
+            var recDelim = this.responseSchema.recordDelim;
+            var fieldDelim = this.responseSchema.fieldDelim;
+            var fields = this.responseSchema.fields;
+            if(oFullResponse.length > 0) {
+                // Delete the last line delimiter at the end of the data if it exists
+                var newLength = oFullResponse.length-recDelim.length;
+                if(oFullResponse.substr(newLength) == recDelim) {
+                    oFullResponse = oFullResponse.substr(0, newLength);
+                }
+                // Split along record delimiter to get an array of strings
+                var recordsarray = oFullResponse.split(recDelim);
+                // Cycle through each record
+                for(var i = 0, len = recordsarray.length, recIdx = 0; i < len; ++i) {
+                    var oResult = {};
+                    var bError = false;
+                    if (YAHOO.lang.isString(recordsarray[i])) {
+                        // Split each record along field delimiter to get data array
+                        var fielddataarray = recordsarray[i].split(fieldDelim);
+                        for(var j=fields.length-1; j>-1; j--) {
+                            try {
+                                // Remove quotation marks from edges, if applicable
+                                var data = fielddataarray[j];
+                                if (YAHOO.lang.isString(data)) {
+                                    if(data.charAt(0) == "\"") {
+                                        data = data.substr(1);
+                                    }
+                                    if(data.charAt(data.length-1) == "\"") {
+                                        data = data.substr(0,data.length-1);
+                                    }
+                                    var field = fields[j];
+                                    var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
+                                    // Backward compatibility
+                                    if(!field.parser && field.converter) {
+                                        field.parser = field.converter;
+                                    }
+                                    if(field.parser) {
+                                        data = field.parser.call(this, data);
+                                    }
+                                    // Safety measure
+                                    if(data === undefined) {
+                                        data = null;
+                                    }
+                                    oResult[key] = data;
+                                }
+                                else {
+                                    bError = true;
+                                }
+                            }
+                            catch(e) {
+                                bError = true;
+                            }
                         }
-                        else {
-                               data = "";
+                        if(!bError) {
+                            oParsedResponse.results[recIdx++] = oResult;
                         }
                     }
-                    // Backward compatibility
-                    if(!field.parser && field.converter) {
-                        field.parser = field.converter;
-                    }
-                    if(field.parser) {
-                        data = field.parser.call(this, data);
-                    }
-                    // Safety measure
-                    if(data === undefined) {
-                        data = null;
-                    }
-                    oResult[key] = data;
                 }
-                // Capture each array of values into an array of results
-                oParsedResponse.results.unshift(oResult);
             }
+            return oParsedResponse;
         }
-        if(bError) {
-            oParsedResponse.error = true;
-        }
-        else {
-        }
-        return oParsedResponse;
+    }
+    return null;
+            
 };
 
 /**
- * Overridable method parses raw JSON data into a response object.
+ * Overridable method parses XML data into a response object.
  *
- * @method parseJSONData
+ * @method parseXMLData
  * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
- * @return {Object} Parsed response object.
+ * @param oFullResponse {Object} The full XML response from the live database.
+ * @return {Object} Parsed response object with the following properties<br>
+ *     - results (Array) Array of parsed data results<br>
+ *     - error (Boolean) True if there was an error<br>
+ *     - totalRecords (Number) Total number of records (if available)
  */
-YAHOO.util.DataSource.prototype.parseJSONData = function(oRequest, oRawResponse) {
-    var oParsedResponse = {};
-    if(oRawResponse && YAHOO.lang.isArray(this.responseSchema.fields)) {
-        var fields = this.responseSchema.fields;
-        var bError = false;
-        oParsedResponse.results = [];
-        var jsonObj,jsonList;
+YAHOO.util.DataSource.prototype.parseXMLData = function(oRequest, oFullResponse) {
+    var bError = false,
+        schema = this.responseSchema,
+        oParsedResponse = {meta:{}},
+        xmlList = null,
+        metaNode      = schema.metaNode,
+        metaLocators  = schema.metaFields || {},
+        totRecLocator = schema.totalRecords, // Back compat
+        i,k,loc,v;
 
-        // Parse JSON object out if it's a string
-        if(YAHOO.lang.isString(oRawResponse)) {
-            // Check for latest JSON lib but divert KHTML clients
-            var isNotMac = (navigator.userAgent.toLowerCase().indexOf('khtml')== -1);
-            if(oRawResponse.parseJSON && isNotMac) {
-                // Use the new JSON utility if available
-                jsonObj = oRawResponse.parseJSON();
-                if(!jsonObj) {
-                    bError = true;
-                }
-            }
-            // Check for YUI JSON lib but divert KHTML clients
-            else if(YAHOO.lang.JSON && isNotMac) {
-                // Use the JSON utility if available
-                jsonObj = YAHOO.lang.JSON.parse(oRawResponse);
-                if(!jsonObj) {
-                    bError = true;
-                }
-            }
-            // Check for older JSON lib but divert KHTML clients
-            else if(window.JSON && JSON.parse && isNotMac) {
-                // Use the JSON utility if available
-                jsonObj = JSON.parse(oRawResponse);
-                if(!jsonObj) {
-                    bError = true;
-                }
-            }
-            // No JSON lib found so parse the string
-            else {
-                try {
-                    // Trim leading spaces
-                    while (oRawResponse.length > 0 &&
-                            (oRawResponse.charAt(0) != "{") &&
-                            (oRawResponse.charAt(0) != "[")) {
-                        oRawResponse = oRawResponse.substring(1, oRawResponse.length);
-                    }
+    if (totRecLocator && !metaLocators.totalRecords) {
+        metaLocators.totalRecords = totRecLocator;
+    }
 
-                    if(oRawResponse.length > 0) {
-                        // Strip extraneous stuff at the end
-                        var objEnd = Math.max(oRawResponse.lastIndexOf("]"),oRawResponse.lastIndexOf("}"));
-                        oRawResponse = oRawResponse.substring(0,objEnd+1);
+    // In case oFullResponse is something funky
+    try {
+        xmlList = (schema.resultNode) ?
+            oFullResponse.getElementsByTagName(schema.resultNode) :
+            null;
 
-                        // Turn the string into an object literal...
-                        // ...eval is necessary here
-                        jsonObj = eval("(" + oRawResponse + ")");
-                        if(!jsonObj) {
-                            bError = true;
+        // Pull any meta identified
+        metaNode = metaNode ? oFullResponse.getElementsByTagName(metaNode)[0] :
+                   oFullResponse;
+
+        if (metaNode) {
+            for (k in metaLocators) {
+                if (YAHOO.lang.hasOwnProperty(metaLocators, k)) {
+                    loc = metaLocators[k];
+                    // Look for a node
+                    v = metaNode.getElementsByTagName(loc)[0];
+
+                    if (v) {
+                        v = v.firstChild.nodeValue;
+                    } else {
+                        // Look for an attribute
+                        v = metaNode.attributes.getNamedItem(loc);
+                        if (v) {
+                            v = v.value;
                         }
+                    }
 
+                    if (YAHOO.lang.isValue(v)) {
+                        oParsedResponse.meta[k] = v;
                     }
-                    else {
-                        jsonObj = null;
-                        bError = true;
-                    }
                 }
-                catch(e) {
-                    bError = true;
-               }
+                
             }
         }
-        // Response must already be a JSON object
-        else if(oRawResponse.constructor == Object) {
-            jsonObj = oRawResponse;
-        }
-        // Not a string or an object
-        else {
-            bError = true;
-        }
-        // Now that we have a JSON object, parse a jsonList out of it
-        if(jsonObj && jsonObj.constructor == Object) {
-            try {
-                // eval is necessary here since schema can be of unknown depth
-                jsonList = eval("jsonObj." + this.responseSchema.resultsList);
-            }
-            catch(e) {
-                bError = true;
-            }
-        }
+    }
+    catch(e) {
+    }
+    if(!xmlList || !YAHOO.lang.isArray(schema.fields)) {
+        bError = true;
+    }
+    // Loop through each result
+    else {
 
-        if(bError || !jsonList) {
-            oParsedResponse.error = true;
-        }
-        if(jsonList && !YAHOO.lang.isArray(jsonList)) {
-            jsonList = [jsonList];
-        }
-        else if(!jsonList) {
-            jsonList = [];
-        }
-
-        // Loop through the array of all responses...
-        for(var i = jsonList.length-1; i >= 0 ; i--) {
+        oParsedResponse.results = [];
+        for(i = xmlList.length-1; i >= 0 ; --i) {
+            var result = xmlList.item(i);
             var oResult = {};
-            var jsonResult = jsonList[i];
-            // ...and loop through each data field value of each response
-            for(var j = fields.length-1; j >= 0 ; j--) {
-                var field = fields[j];
+            // Loop through each data field in each result using the schema
+            for(var m = schema.fields.length-1; m >= 0 ; m--) {
+                var field = schema.fields[m];
                 var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
-                // ...and capture data into an array mapped according to the schema...
-                // eval is necessary here since schema can be of unknown depth
-                var data = eval("jsonResult." + key);
-                
+                var data = null;
+                // Values may be held in an attribute...
+                var xmlAttr = result.attributes.getNamedItem(key);
+                if(xmlAttr) {
+                    data = xmlAttr.value;
+                }
+                // ...or in a node
+                else {
+                    var xmlNode = result.getElementsByTagName(key);
+                    if(xmlNode && xmlNode.item(0) && xmlNode.item(0).firstChild) {
+                        data = xmlNode.item(0).firstChild.nodeValue;
+                    }
+                    else {
+                           data = "";
+                    }
+                }
                 // Backward compatibility
                 if(!field.parser && field.converter) {
                     field.parser = field.converter;
@@ -1387,80 +1412,234 @@
                 }
                 oResult[key] = data;
             }
-            // Capture the array of data field values in an array of results
-            oParsedResponse.results.unshift(oResult);
+            // Capture each array of values into an array of results
+            oParsedResponse.results[i] = oResult;
         }
     }
-    else {
+    if(bError) {
         oParsedResponse.error = true;
     }
+    else {
+    }
     return oParsedResponse;
 };
 
 /**
- * Overridable method parses raw HTML TABLE element data into a response object.
+ * Overridable method parses JSON data into a response object.
  *
- * @method parseHTMLTableData
+ * @method parseJSONData
  * @param oRequest {Object} Request object.
- * @param oRawResponse {Object} The raw response from the live database.
- * @return {Object} Parsed response object.
+ * @param oFullResponse {Object} The full JSON from the live database.
+ * @return {Object} Parsed response object with the following properties<br>
+ *     - results (Array) Array of parsed data results<br>
+ *     - error (Boolean) True if there was an error<br>
+ *     - totalRecords (Number) Total number of records (if available)
  */
-YAHOO.util.DataSource.prototype.parseHTMLTableData = function(oRequest, oRawResponse) {
-        var bError = false;
-        var elTable = oRawResponse;
-        var fields = this.responseSchema.fields;
-        var oParsedResponse = {};
-        oParsedResponse.results = [];
+YAHOO.util.DataSource.prototype.parseJSONData = function(oRequest, oFullResponse) {
+    var oParsedResponse = {results:[],meta:{}},
+        schema          = this.responseSchema;
 
-        // Iterate through each TBODY
-        for(var i=0; i<elTable.tBodies.length; i++) {
-            var elTbody = elTable.tBodies[i];
+    if(YAHOO.lang.isObject(oFullResponse)) {
+        if(YAHOO.lang.isArray(schema.fields)) {
+            var fields          = schema.fields,
+                resultsList     = oFullResponse,
+                results         = [],
+                metaFields      = schema.metaFields || {},
+                fieldParsers    = [],
+                fieldPaths      = [],
+                simpleFields    = [],
+                bError          = false,
+                i,len,j,v,key,parser,path;
 
-            // Iterate through each TR
-            for(var j=elTbody.rows.length-1; j>-1; j--) {
-                var elRow = elTbody.rows[j];
-                var oResult = {};
-                
-                for(var k=fields.length-1; k>-1; k--) {
-                    var field = fields[k];
-                    var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
-                    var data = elRow.cells[k].innerHTML;
+            // Function to parse the schema's locator keys into walk paths
+            var buildPath = function (needle) {
+                var path = null, keys = [], i = 0;
+                if (needle) {
+                    // Strip the ["string keys"] and [1] array indexes
+                    needle = needle.
+                        replace(/\[(['"])(.*?)\1\]/g,
+                        function (x,$1,$2) {keys[i]=$2;return '.@'+(i++);}).
+                        replace(/\[(\d+)\]/g,
+                        function (x,$1) {keys[i]=parseInt($1,10)|0;return '.@'+(i++);}).
+                        replace(/^\./,''); // remove leading dot
 
-                    // Backward compatibility
-                    if(!field.parser && field.converter) {
-                        field.parser = field.converter;
+                    // If the cleaned needle contains invalid characters, the
+                    // path is invalid
+                    if (!/[^\w\.\$@]/.test(needle)) {
+                        path = needle.split('.');
+                        for (i=path.length-1; i >= 0; --i) {
+                            if (path[i].charAt(0) === '@') {
+                                path[i] = keys[parseInt(path[i].substr(1),10)];
+                            }
+                        }
                     }
-                    if(field.parser) {
-                        data = field.parser.call(this, data);
+                }
+                return path;
+            };
+
+            // build function to walk a path and return the pot of gold
+            var walkPath = function (path, origin) {
+                var v=origin,i=0,len=path.length;
+                for (;i<len && v;++i) {
+                    v = v[path[i]];
+                }
+                return v;
+            };
+
+            // Build the parser map and location paths
+            for (i = fields.length - 1; i >= 0; --i) {
+                key    = fields[i].key || fields[i];
+                parser = fields[i].parser || fields[i].converter;
+                path   = buildPath(key);
+
+                if (parser) {
+                    fieldParsers[fieldParsers.length] = {key:key,parser:parser};
+                }
+
+                if (path) {
+                    if (path.length > 1) {
+                        fieldPaths[fieldPaths.length] = {key:key,path:path};
+                    } else {
+                        simpleFields[simpleFields.length] = key;
                     }
-                    // Safety measure
-                    if(data === undefined) {
-                        data = null;
+                } else {
+                }
+            }
+
+            // Parse the response
+            // Step 1. Pull the resultsList from oFullResponse (default assumes
+            // oFullResponse IS the resultsList)
+            if (schema.resultsList) {
+                path = buildPath(schema.resultsList);
+                if (path) {
+                    resultsList = walkPath(path, oFullResponse);
+                    if (resultsList === undefined) {
+                        bError = true;
                     }
-                    oResult[key] = data;
+                } else {
+                    bError = true;
                 }
-                oParsedResponse.results.unshift(oResult);
             }
+            if (!resultsList) {
+                resultsList = [];
+            }
+
+            if (!YAHOO.lang.isArray(resultsList)) {
+                resultsList = [resultsList];
+            }
+
+            if (!bError) {
+                // Step 2. Process the results, flattening the records and/or
+                // applying parsers if needed
+                //if (fieldParsers.length || fieldPaths.length) {
+                    for (i = resultsList.length - 1; i >= 0; --i) {
+                        var r = resultsList[i], rec = {};
+                        for (j = simpleFields.length - 1; j >= 0; --j) {
+                            rec[simpleFields[j]] = r[simpleFields[j]];
+                        }
+
+                        for (j = fieldPaths.length - 1; j >= 0; --j) {
+                            rec[fieldPaths[j].key] = walkPath(fieldPaths[j].path,r);
+                        }
+
+                        for (j = fieldParsers.length - 1; j >= 0; --j) {
+                            var p = fieldParsers[j].key;
+                            rec[p] = fieldParsers[j].parser(rec[p]);
+                            if (rec[p] === undefined) {
+                                rec[p] = null;
+                            }
+                        }
+                        results[i] = rec;
+                    }
+                //}
+
+                // Step 3. Pull meta fields from oFullResponse if identified
+                if (schema.totalRecords && !metaFields.totalRecords) {
+                    // for backward compatibility
+                    metaFields.totalRecords = schema.totalRecords;
+                }
+
+                for (key in metaFields) {
+                    if (YAHOO.lang.hasOwnProperty(metaFields,key)) {
+                        path = buildPath(metaFields[key]);
+                        if (path) {
+                            v = walkPath(path, oFullResponse);
+                            oParsedResponse.meta[key] = v;
+                        }
+                    }
+                }
+
+            } else {
+
+                oParsedResponse.error = true;
+            }
+
+            oParsedResponse.results = results;
         }
+    }
+    else {
+        oParsedResponse.error = true;
+    }
 
-        if(bError) {
-            oParsedResponse.error = true;
-        }
-        else {
-        }
-        return oParsedResponse;
+    return oParsedResponse;
 };
 
 /**
- * The Number utility provides helper functions to deal with data of type Number.
+ * Overridable method parses an HTML TABLE element reference into a response object.
  *
- * @namespace YAHOO.util
- * @module number
- * @requires datasource
- * @title Number Utility
- * @beta
+ * @method parseHTMLTableData
+ * @param oRequest {Object} Request object.
+ * @param oFullResponse {Object} The full HTML element reference from the live database.
+ * @return {Object} Parsed response object with the following properties<br>
+ *     - results (Array) Array of parsed data results<br>
+ *     - error (Boolean) True if there was an error<br>
+ *     - totalRecords (Number) Total number of records (if available)
  */
+YAHOO.util.DataSource.prototype.parseHTMLTableData = function(oRequest, oFullResponse) {
+    var bError = false;
+    var elTable = oFullResponse;
+    var fields = this.responseSchema.fields;
+    var oParsedResponse = {results:[]};
 
+    // Iterate through each TBODY
+    for(var i=0; i<elTable.tBodies.length; i++) {
+        var elTbody = elTable.tBodies[i];
+
+        // Iterate through each TR
+        for(var j=elTbody.rows.length-1; j>-1; j--) {
+            var elRow = elTbody.rows[j];
+            var oResult = {};
+            
+            for(var k=fields.length-1; k>-1; k--) {
+                var field = fields[k];
+                var key = (YAHOO.lang.isValue(field.key)) ? field.key : field;
+                var data = elRow.cells[k].innerHTML;
+
+                // Backward compatibility
+                if(!field.parser && field.converter) {
+                    field.parser = field.converter;
+                }
+                if(field.parser) {
+                    data = field.parser.call(this, data);
+                }
+                // Safety measure
+                if(data === undefined) {
+                    data = null;
+                }
+                oResult[key] = data;
+            }
+            oParsedResponse.results[j] = oResult;
+        }
+    }
+
+    if(bError) {
+        oParsedResponse.error = true;
+    }
+    else {
+    }
+    return oParsedResponse;
+};
+
 /****************************************************************************/
 /****************************************************************************/
 /****************************************************************************/
@@ -1469,6 +1648,8 @@
  * The static Number class provides helper functions to deal with data of type
  * Number.
  *
+ * @namespace YAHOO.util
+ * @requires datasource
  * @class Number
  * @static
  */
@@ -1565,16 +1746,6 @@
 
 
 
-/**
- * The Date utility provides helper functions to deal with data of type Date.
- *
- * @namespace YAHOO.util
- * @module date
- * @requires datasource
- * @title Date Utility
- * @beta
- */
-
 /****************************************************************************/
 /****************************************************************************/
 /****************************************************************************/
@@ -1583,6 +1754,8 @@
  * The static Date class provides helper functions to deal with data of type
  * Number.
  *
+ * @namespace YAHOO.util
+ * @requires datasource
  * @class Date
  * @static
  */
@@ -1623,6 +1796,5 @@
         }
     }
  };
-
-
-YAHOO.register("datasource", YAHOO.util.DataSource, {version: "2.4.1", build: "742"});
+ 
+YAHOO.register("datasource", YAHOO.util.DataSource, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/datatable/README
===================================================================
--- trunk/root/static/yui/datatable/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/datatable/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,5 +1,74 @@
 DataTable Release Notes
 
+*** version 2.5.1 ***
+
+* Only split THEAD from TBODY markup for scrollable tables.
+* columnResizeEvent sends new width value.
+* Improved performance for adding, deleting, and updating rows dynamically.
+
+
+
+*** version 2.5.0 ***
+
+* Introduced YAHOO.widget.Paginator to manage pagination.
+* Introduced YAHOO.util.Chain to allow for progressive rendering.
+
+Removed APIs
+
+    * CLASS_SCROLLBODY
+    * CLASS_TABLE
+    * getTableEl()
+
+Changed APIs
+
+    * doBeforeLoadData(sRequest, oResponse, oPayload) - oResponse is now the converted full response (typed JSON or XML as appropriate). oPayload is now an optional data payload implementer can pass in to DataSource.sendRequest via the callback object literal.
+    * formatCell() - The first argument, elCell, is now a reference to the cell liner element rather than the TD itself.
+    * onDataReturnAppendRows(sRequest, oResponse, oPayload) - oResponse is now the converted full response (typed JSON or XML as appropriate). oPayload is now an optional data payload implementer can pass in to DataSource.sendRequest via the callback object literal.
+    * onDataReturnInitializeTable(sRequest, oResponse, oPayload) - oResponse is now the converted full response (typed JSON or XML as appropriate). oPayload is now an optional data payload implementer can pass in to DataSource.sendRequest via the callback object literal.
+    * onDataReturnInsertRows(sRequest, oResponse, oPayload) - oResponse is now the converted full response (typed JSON or XML as appropriate). oPayload is now an optional data payload implementer can pass in to DataSource.sendRequest via the callback object literal.
+    * paginator - Should now be an instance of YAHOO.widget.Paginator.
+    * sortedBy.dir - Use CLASS_ASC or CLASS_DESC instead of "asc" and "desc" strings.
+    * Scrolling must be enabled via the configs "scrollable", "width", and "height". CSS should no longer be used to set width or height on scrollable tables.    
+
+Deprecated APIs
+
+    * formatPaginatorDropdown() - Use new Paginator class.
+    * formatPaginatorLinks() - Use new Paginator class.
+    * formatPaginators() - Use new Paginator class.
+    * refreshView() - Use render().
+    * showPage() - Use new Paginator class.
+    * updatePaginator() - Use new Paginator class.
+    * headerCellClickEvent - Use theadCellClickEvent.
+    * headerCellDblclickEvent - Use theadCellDblclickEvent.
+    * headerCellMousedownEvent - Use theadCellMousedownEvent.
+    * headerCellMouseoutEvent - Use theadCellMouseoutEvent.
+    * headerCellMouseoverEvent - Use theadCellMouseoverEvent.
+    * headerLabelClickEvent - Use theadLabelClickEvent.
+    * headerLabelDblclickEvent - Use theadLabelDblclickEvent.
+    * headerLabelMousedownEvent - Use theadLabelMousedownEvent.
+    * headerLabelMouseoutEvent - Use theadLabelMouseoutEvent.
+    * headerLabelMouseoverEvent - Use theadLabelMouseoverEvent.
+    * headerRowClickEvent - Use theadRowClickEvent.
+    * headerRowDblclickEvent - Use theadRowDblclickEvent.
+    * headerRowMousedownEvent - Use theadRowMousedownEvent.
+    * headerRowMouseoutEvent - Use theadRowMouseoutEvent.
+    * headerRowMouseoverEvent - Use theadRowMouseoverEvent.
+    * refreshEvent - Use renderEvent.
+    * paginated - No longer used, as long as "paginator" value is an instance of Paginator class.
+
+
+RecordSet
+
+    * updateKey() - Use updateRecordValue().
+    * keyUpdateEvent - Use recordValueUpdateEvent.
+
+Column
+
+    * width - Must now be a number. Strings will be ignored.
+    * sortOptions.defaultOrder - Use sortOptions.defaultDir, and use CLASS_ASC or CLASS_DESC instead of "asc" and "desc" strings.
+
+
+
 *** version 2.4.0 ***
 
 * No changes.

Modified: trunk/root/static/yui/datatable/assets/datatable-core.css
===================================================================
--- trunk/root/static/yui/datatable/assets/datatable-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/datatable/assets/datatable-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,48 +1,85 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-/*foundational css*/
-table.yui-dt-table {
-    table-layout:fixed;
-}
-
-th .yui-dt-header {
-    position:relative;
-}
-
-th .yui-dt-label {
-    position:relative;
-}
-
-th .yui-dt-resizer {
-    position:absolute;
-    margin-right:-6px;
-    right:0;
-    bottom:0;
-    width:6px;
-    height:100%;
-    cursor:w-resize;
-    cursor:col-resize;
-}
-
-/* foundational scrolling css */
-.yui-dt-scrollable  {
-    *overflow-y:auto; /* for ie */
-}
-.yui-dt-scrollable  thead {
-    display:block; /* for safari and opera */
-}
-.yui-dt-scrollable thead tr {
-    position:relative;  /* for ie */
-}
-.yui-dt-scrollbody {
-    display:block; /* for safari and opera */
-    overflow:auto; /* for gecko */
-}
-
-.yui-dt-editor {
-    position:absolute;z-index:9000;
-}
+/* foundational CSS */
+.yui-dt {
+    border-bottom:1px solid transparent;
+}
+
+.yui-dt-noop {
+    border-bottom:none;
+}
+
+/* a11y headers */
+.yui-dt-hd {
+    display: none;
+}
+
+.yui-dt-scrollable .yui-dt-hd {
+    display: block;
+}
+.yui-dt-scrollable .yui-dt-bd thead tr,
+.yui-dt-scrollable .yui-dt-bd thead th {
+    position:absolute;
+    left:-1500px;
+}
+
+.yui-dt-scrollable tbody {
+    -moz-outline:none;
+}
+
+/* draggable columns */
+.yui-dt-draggable {
+    cursor: move;
+}
+.yui-dt-coltarget {
+    position: absolute;
+    z-index: 999;
+}
+
+/* resizeable columns */
+.yui-dt-hd {
+    zoom:1; 
+}
+th.yui-dt-resizeable .yui-dt-liner {
+    position:relative;
+}
+.yui-dt-resizer {
+    position:absolute;
+    right:0;
+    bottom:0;
+    height:100%;
+    cursor:e-resize;
+    cursor:col-resize;
+}
+.yui-dt-resizerproxy {
+    visibility:hidden;
+    position:absolute;
+    z-index:9000;
+}
+
+/* hidden columns */
+.yui-skin-sam th.yui-dt-hidden .yui-dt-liner, 
+.yui-skin-sam td.yui-dt-hidden .yui-dt-liner {
+    margin:0;
+    padding:0;
+    overflow:hidden;
+    white-space:nowrap;
+}
+
+/* vertical and horizontal scrolling */
+.yui-dt-scrollable .yui-dt-bd {
+    overflow:auto;
+}
+.yui-dt-scrollable .yui-dt-hd {
+    overflow:hidden;
+    position:relative; /* for ie overflow bug http://rowanw.com/bugs/overflow_relative.htm */
+} 
+
+/* editing */
+.yui-dt-editor {
+    position:absolute;z-index:9000;
+}

Modified: trunk/root/static/yui/datatable/assets/datatable.css
===================================================================
--- trunk/root/static/yui/datatable/assets/datatable.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/datatable/assets/datatable.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /*foundational css*/
 .yui-dt-table th, .yui-dt-table td {

Modified: trunk/root/static/yui/datatable/assets/skins/sam/datatable-skin.css
===================================================================
--- trunk/root/static/yui/datatable/assets/skins/sam/datatable-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/datatable/assets/skins/sam/datatable-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,192 +1,257 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-/* basic skin styles */
-.yui-skin-sam .yui-dt-table {margin:0;padding:0;font-family:arial;font-size:inherit;border-collapse:collapse;border:1px solid #7F7F7F;}
-.yui-skin-sam .yui-dt-table caption {padding-bottom:1em;text-align:left;}
-.yui-skin-sam .yui-dt-table th {
-    background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0; /* header gradient */
-}
-.yui-skin-sam .yui-dt-table th,
-.yui-skin-sam .yui-dt-table th a {
-    font-weight:normal;text-decoration:none;color:#000; /* header text */
-    vertical-align:bottom;
-}
-.yui-skin-sam .yui-dt-table th,
-.yui-skin-sam .yui-dt-table td {
-    padding:4px 10px 4px 10px; /* cell padding */
-    border-right:1px solid #CBCBCB; /* inner column border */
-}
-.yui-skin-sam .yui-dt-table td {
-    text-align:left;
-}
-.yui-skin-sam .yui-dt-table th.yui-dt-last,
-.yui-skin-sam .yui-dt-table td.yui-dt-last {
-    border-right:1px solid #7F7F7F; /* outer border */
-}
-.yui-skin-sam .yui-dt-list td {
-    border-right:none; /* disable inner column border in list mode */
-}
-.yui-skin-sam .yui-dt-table thead {
-    border:1px solid #989898; /* outer border */
-}
-.yui-skin-sam .yui-dt-table tbody {
-    border-left:1px solid #7F7F7F;border-right:1px solid #7F7F7F;border-bottom:1px solid #7F7F7F; /* outer border */
-}
-
-/* messaging */
-.yui-skin-sam .yui-dt-loading {
-    background-color:#FFF;
-}
-
-.yui-skin-sam .yui-dt-loading {
-    background-color:#FFF;
-}
-
-/* sortable columns */
-.yui-skin-sam .yui-dt-sortable {
-    cursor:pointer;
-}
-.yui-skin-sam th.yui-dt-sortable {
-    padding-right:5px; /* room for arrow */
-}
-.yui-skin-sam th.yui-dt-sortable .yui-dt-label {
-    margin-right:15px; /* room for arrow */
-}
-.yui-skin-sam th.yui-dt-asc,
-.yui-skin-sam th.yui-dt-desc {
-    background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -100px; /* sorted header gradient */
-}
-.yui-skin-sam th.yui-dt-asc .yui-dt-header {
-    background:url(dt-arrow-up.png) no-repeat right; /* sorted header gradient */
-    /*background-image: url('../img/arrow_up.gif'); background-repeat:no-repeat; background-position:right; sorted header icon */
-}
-.yui-skin-sam th.yui-dt-desc .yui-dt-header {
-    background:url(dt-arrow-dn.png) no-repeat right; /* sorted header gradient */
-    /*background-image: url('../img/arrow_dn.gif'); background-repeat:no-repeat; background-position:right; /*sorted header icon */
-} 
-
-/* editing */
-.yui-dt-editable {
-    cursor:pointer;
-}
-.yui-dt-editor {
-    text-align:left;
-    background-color:#F2F2F2;
-    border:1px solid #808080;
-    padding:6px;
-}
-.yui-dt-editor label {
-    padding-left:4px;padding-right:6px;
-}
-.yui-dt-editor .yui-dt-button {
-    padding-top:6px;text-align:right;
-}
-.yui-dt-editor .yui-dt-button button {
-    background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;
-    border:1px solid #999;
-    width:4em;height:1.8em;
-    margin-left:6px;
-}
-.yui-dt-editor .yui-dt-button button.yui-dt-default {
-    background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1400px;
-    background-color: #5584E0;
-    border:1px solid #304369;
-    color:#FFF
-}
-.yui-dt-editor .yui-dt-button button:hover {
-    background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1300px;
-    color:#000;
-}
-.yui-dt-editor .yui-dt-button button:active {
-    background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1700px;
-    color:#000;
-}
-
-/* striping */
-.yui-skin-sam tr.yui-dt-even { background-color:#FFF; } /* white */
-.yui-skin-sam tr.yui-dt-odd { background-color:#EDF5FF; } /* light blue */
-.yui-skin-sam tr.yui-dt-even td.yui-dt-asc,
-.yui-skin-sam tr.yui-dt-even td.yui-dt-desc { background-color:#EDF5FF; } /* light blue sorted */
-.yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,
-.yui-skin-sam tr.yui-dt-odd td.yui-dt-desc { background-color:#DBEAFF; } /* dark blue sorted */
-
-/* disable striping in list mode */
-.yui-skin-sam .yui-dt-list tr.yui-dt-even { background-color:#FFF; } /* white */
-.yui-skin-sam .yui-dt-list tr.yui-dt-odd { background-color:#FFF; } /* white */
-.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,
-.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc { background-color:#EDF5FF; } /* light blue sorted */
-.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,
-.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc { background-color:#EDF5FF; } /* light blue sorted */
-
-/* highlighting */
-.yui-skin-sam tr.yui-dt-highlighted,
-.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,
-.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,
-.yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,
-.yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted {
-    cursor:pointer;
-    background-color:#B2D2FF; /* med blue hover */
-}
-
-/* enable highlighting in list mode */
-.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,
-.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,
-.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,
-.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,
-.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted {
-    cursor:pointer;
-    background-color:#B2D2FF; /* med blue  hover */
-}
-
-/* selection */
-.yui-skin-sam tr.yui-dt-selected td,
-.yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,
-.yui-skin-sam tr.yui-dt-selected td.yui-dt-desc {
-    background-color:#426FD9; /* bright blue selected row */
-    color:#FFF;
-}
-.yui-skin-sam tr.yui-dt-even td.yui-dt-selected,
-.yui-skin-sam tr.yui-dt-odd td.yui-dt-selected {
-    background-color:#446CD7; /* bright blue selected cell */
-    color:#FFF;
-}
-
-/* enable selection in list mode */
-.yui-skin-sam .yui-dt-list tr.yui-dt-selected td,
-.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,
-.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc {
-    background-color:#426FD9; /* bright blue selected row */
-    color:#FFF;
-}
-.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,
-.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected {
-    background-color:#446CD7; /* bright blue selected cell */
-    color:#FFF;
-}
-
-/* pagination */
-.yui-skin-sam .yui-dt-paginator {
-    display:block;margin:6px 0;white-space:nowrap;
-}
-.yui-skin-sam .yui-dt-paginator .yui-dt-first,
-.yui-skin-sam .yui-dt-paginator .yui-dt-last,
-.yui-skin-sam .yui-dt-paginator .yui-dt-selected {
-    padding:2px 6px;
-}
-.yui-skin-sam .yui-dt-paginator a.yui-dt-first,
-.yui-skin-sam .yui-dt-paginator a.yui-dt-last {
-    text-decoration:none;
-}
-.yui-skin-sam .yui-dt-paginator .yui-dt-previous,
-.yui-skin-sam .yui-dt-paginator .yui-dt-next {
-    display:none;
-}
-.yui-skin-sam a.yui-dt-page {
-    border:1px solid #CBCBCB;
-    padding:2px 6px;
-    text-decoration:none;
-}
+/* basic skin styles */
+.yui-skin-sam .yui-dt table {margin:0;padding:0;font-family:arial;font-size:inherit;border-collapse:collapse;border-spacing:0;}
+.yui-skin-sam .yui-dt thead {border-spacing:0;} /* for safari bug */
+.yui-skin-sam .yui-dt caption {padding-bottom:1em;text-align:left;}
+
+/*outer border */
+.yui-skin-sam .yui-dt-hd table {border-left:1px solid #7F7F7F;border-top:1px solid #7F7F7F;border-right:1px solid #7F7F7F;}
+.yui-skin-sam .yui-dt-bd table {border:1px solid #7F7F7F;}
+
+.yui-skin-sam .yui-dt-scrollable .yui-dt-hd table {border:0px;}
+.yui-skin-sam .yui-dt-scrollable .yui-dt-bd table {border:0px;}
+.yui-skin-sam .yui-dt-scrollable .yui-dt-hd {border-left:1px solid #7F7F7F;border-top:1px solid #7F7F7F;border-right:1px solid #7F7F7F;}
+.yui-skin-sam .yui-dt-scrollable .yui-dt-bd {border-left:1px solid #7F7F7F;border-bottom:1px solid #7F7F7F;border-right:1px solid #7F7F7F;}
+
+.yui-skin-sam .yui-dt th {
+    background:#D8D8DA url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0; /* header gradient */
+}
+.yui-skin-sam .yui-dt th,
+.yui-skin-sam .yui-dt th a {
+    font-weight:normal;text-decoration:none;color:#000; /* header text */
+    vertical-align:bottom;
+}
+.yui-skin-sam .yui-dt th {
+    margin:0;padding:0;
+    border:none;
+    border-right:1px solid #CBCBCB;/*  inner column border */
+}
+.yui-skin-sam .yui-dt-liner {
+    margin:0;padding:0;
+    padding:4px 10px 4px 10px; /* cell padding */
+}
+.yui-skin-sam .yui-dt-coltarget {
+    width: 5px;
+    background-color: red;
+}
+.yui-skin-sam .yui-dt td {
+    margin:0;padding:0;
+    border:none;
+    border-right:1px solid #CBCBCB; /* inner column border */
+    text-align:left;
+}
+.yui-skin-sam .yui-dt-list td {
+    border-right:none; /* disable inner column border in list mode */
+}
+.yui-skin-sam .yui-dt-resizer {
+    width:6px;
+}
+
+/* messaging */
+.yui-skin-sam .yui-dt-loading {
+    background-color:#FFF;
+}
+.yui-skin-sam .yui-dt-empty {
+    background-color:#FFF;
+}
+.yui-skin-sam .yui-dt-error {
+    background-color:#FFF;
+}
+
+/* sortable columns */
+.yui-skin-sam thead .yui-dt-sortable {
+    cursor:pointer;
+}
+.yui-skin-sam th.yui-dt-asc,
+.yui-skin-sam th.yui-dt-desc {
+    background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -100px; /* sorted header gradient */
+}
+.yui-skin-sam th.yui-dt-sortable .yui-dt-label {
+    margin-right:10px;
+}
+.yui-skin-sam th.yui-dt-asc .yui-dt-liner {
+    background:url(dt-arrow-up.png) no-repeat right; /* sorted header gradient */
+}
+.yui-skin-sam th.yui-dt-desc .yui-dt-liner {
+    background:url(dt-arrow-dn.png) no-repeat right; /* sorted header gradient */
+}
+
+/* editing */
+.yui-dt-editable {
+    cursor:pointer;
+}
+.yui-dt-editor {
+    text-align:left;
+    background-color:#F2F2F2;
+    border:1px solid #808080;
+    padding:6px;
+}
+.yui-dt-editor label {
+    padding-left:4px;padding-right:6px;
+}
+.yui-dt-editor .yui-dt-button {
+    padding-top:6px;text-align:right;
+}
+.yui-dt-editor .yui-dt-button button {
+    background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;
+    border:1px solid #999;
+    width:4em;height:1.8em;
+    margin-left:6px;
+}
+.yui-dt-editor .yui-dt-button button.yui-dt-default {
+    background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1400px;
+    background-color: #5584E0;
+    border:1px solid #304369;
+    color:#FFF
+}
+.yui-dt-editor .yui-dt-button button:hover {
+    background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1300px;
+    color:#000;
+}
+.yui-dt-editor .yui-dt-button button:active {
+    background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1700px;
+    color:#000;
+}
+
+/* striping */
+.yui-skin-sam tr.yui-dt-even { background-color:#FFF; } /* white */
+.yui-skin-sam tr.yui-dt-odd { background-color:#EDF5FF; } /* light blue */
+.yui-skin-sam tr.yui-dt-even td.yui-dt-asc,
+.yui-skin-sam tr.yui-dt-even td.yui-dt-desc { background-color:#EDF5FF; } /* light blue sorted */
+.yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,
+.yui-skin-sam tr.yui-dt-odd td.yui-dt-desc { background-color:#DBEAFF; } /* dark blue sorted */
+
+/* disable striping in list mode */
+.yui-skin-sam .yui-dt-list tr.yui-dt-even { background-color:#FFF; } /* white */
+.yui-skin-sam .yui-dt-list tr.yui-dt-odd { background-color:#FFF; } /* white */
+.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,
+.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc { background-color:#EDF5FF; } /* light blue sorted */
+.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,
+.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc { background-color:#EDF5FF; } /* light blue sorted */
+
+/* highlighting */
+.yui-skin-sam th.yui-dt-highlighted,
+.yui-skin-sam th.yui-dt-highlighted a {
+    background-color:#B2D2FF; /* med blue hover */
+}
+.yui-skin-sam tr.yui-dt-highlighted,
+.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,
+.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,
+.yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,
+.yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted {
+    cursor:pointer;
+    background-color:#B2D2FF; /* med blue hover */
+}
+
+/* enable highlighting in list mode */
+.yui-skin-sam .yui-dt-list th.yui-dt-highlighted,
+.yui-skin-sam .yui-dt-list th.yui-dt-highlighted a {
+    background-color:#B2D2FF; /* med blue hover */
+}
+.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,
+.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,
+.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,
+.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,
+.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted {
+    cursor:pointer;
+    background-color:#B2D2FF; /* med blue  hover */
+}
+
+/* selection */
+.yui-skin-sam th.yui-dt-selected,
+.yui-skin-sam th.yui-dt-selected a {
+    background-color:#446CD7; /* bright blue selected cell */
+}
+.yui-skin-sam tr.yui-dt-selected td,
+.yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,
+.yui-skin-sam tr.yui-dt-selected td.yui-dt-desc {
+    background-color:#426FD9; /* bright blue selected row */
+    color:#FFF;
+}
+.yui-skin-sam tr.yui-dt-even td.yui-dt-selected,
+.yui-skin-sam tr.yui-dt-odd td.yui-dt-selected {
+    background-color:#446CD7; /* bright blue selected cell */
+    color:#FFF;
+}
+
+/* enable selection in list mode */
+.yui-skin-sam .yui-dt-list th.yui-dt-selected,
+.yui-skin-sam .yui-dt-list th.yui-dt-selected a {
+    background-color:#446CD7; /* bright blue selected cell */
+}
+.yui-skin-sam .yui-dt-list tr.yui-dt-selected td,
+.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,
+.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc {
+    background-color:#426FD9; /* bright blue selected row */
+    color:#FFF;
+}
+.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,
+.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected {
+    background-color:#446CD7; /* bright blue selected cell */
+    color:#FFF;
+}
+
+/* pagination */
+.yui-skin-sam .yui-pg-container,
+.yui-skin-sam .yui-dt-paginator {
+    display:block;margin:6px 0;white-space:nowrap;
+}
+.yui-skin-sam .yui-pg-first,
+.yui-skin-sam .yui-pg-last,
+.yui-skin-sam .yui-pg-current-page,
+.yui-skin-sam .yui-dt-first,
+.yui-skin-sam .yui-dt-paginator .yui-dt-last,
+.yui-skin-sam .yui-dt-paginator .yui-dt-selected {
+    padding:2px 6px;
+}
+.yui-skin-sam a.yui-pg-first,
+.yui-skin-sam a.yui-pg-previous,
+.yui-skin-sam a.yui-pg-next,
+.yui-skin-sam a.yui-pg-last,
+.yui-skin-sam a.yui-pg-page,
+.yui-skin-sam .yui-dt-paginator a.yui-dt-first,
+.yui-skin-sam .yui-dt-paginator a.yui-dt-last {
+    text-decoration:none;
+}
+.yui-skin-sam .yui-dt-paginator .yui-dt-previous,
+.yui-skin-sam .yui-dt-paginator .yui-dt-next {
+    display:none;
+}
+.yui-skin-sam a.yui-pg-page,
+.yui-skin-sam a.yui-dt-page {
+    border:1px solid #CBCBCB;
+    padding:2px 6px;
+    text-decoration:none;
+    background-color:#fff
+}
+.yui-skin-sam .yui-pg-current-page,
+.yui-skin-sam .yui-dt-selected {
+    border:1px solid #fff;
+    background-color:#fff;
+}
+.yui-skin-sam .yui-pg-pages {
+    margin-left:1ex;
+    margin-right:1ex;
+}
+.yui-skin-sam .yui-pg-page {
+    margin-right:1px;
+    margin-left:1px;
+}
+.yui-skin-sam .yui-pg-first,
+.yui-skin-sam .yui-pg-previous {
+    margin-right:3px;
+}
+.yui-skin-sam .yui-pg-next,
+.yui-skin-sam .yui-pg-last {
+    margin-left:3px;
+}
+.yui-skin-sam .yui-pg-current,
+.yui-skin-sam .yui-pg-rpp-options {
+    margin-right:1em;
+    margin-left:1em;
+}

Modified: trunk/root/static/yui/datatable/assets/skins/sam/datatable.css
===================================================================
--- trunk/root/static/yui/datatable/assets/skins/sam/datatable.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/datatable/assets/skins/sam/datatable.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-table.yui-dt-table{table-layout:fixed;}th .yui-dt-header{position:relative;}th .yui-dt-label{position:relative;}th .yui-dt-resizer{position:absolute;margin-right:-6px;right:0;bottom:0;width:6px;height:100%;cursor:w-resize;cursor:col-resize;}.yui-dt-scrollable{*overflow-y:auto;}.yui-dt-scrollable thead{display:block;}.yui-dt-scrollable thead tr{position:relative;}.yui-dt-scrollbody{display:block;overflow:auto;}.yui-dt-editor{position:absolute;z-index:9000;}.yui-skin-sam .yui-dt-table{margin:0;padding:0;font-family:arial;font-size:inherit;border-collapse:collapse;border:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-table caption{padding-bottom:1em;text-align:left;}.yui-skin-sam .yui-dt-table th{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;}.yui-skin-sam .yui-dt-table th,.yui-skin-sam .yui-dt-table th a{font-weight:normal;text-decoration:none;color:#000;vertical-align:bottom;}.yui-skin-sam .yui-dt-table th,.yui-skin-sam .yui-dt-table td{padding:4px 10px 4px !
 10px;border-right:1px solid #CBCBCB;}.yui-skin-sam .yui-dt-table td{text-align:left;}.yui-skin-sam .yui-dt-table th.yui-dt-last,.yui-skin-sam .yui-dt-table td.yui-dt-last{border-right:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-list td{border-right:none;}.yui-skin-sam .yui-dt-table thead{border:1px solid #989898;}.yui-skin-sam .yui-dt-table tbody{border-left:1px solid #7F7F7F;border-right:1px solid #7F7F7F;border-bottom:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-loading{background-color:#FFF;}.yui-skin-sam .yui-dt-loading{background-color:#FFF;}.yui-skin-sam .yui-dt-sortable{cursor:pointer;}.yui-skin-sam th.yui-dt-sortable{padding-right:5px;}.yui-skin-sam th.yui-dt-sortable .yui-dt-label{margin-right:15px;}.yui-skin-sam th.yui-dt-asc,.yui-skin-sam th.yui-dt-desc{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -100px;}.yui-skin-sam th.yui-dt-asc .yui-dt-header{background:url(dt-arrow-up.png) no-repeat right;}.yui-skin-sam th.yui-dt-desc .yui-dt-header{backgroun!
 d:url(dt-arrow-dn.png) no-repeat right;}.yui-dt-editable{curso!
 r:pointe
r;}.yui-dt-editor{text-align:left;background-color:#F2F2F2;border:1px solid #808080;padding:6px;}.yui-dt-editor label{padding-left:4px;padding-right:6px;}.yui-dt-editor .yui-dt-button{padding-top:6px;text-align:right;}.yui-dt-editor .yui-dt-button button{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;border:1px solid #999;width:4em;height:1.8em;margin-left:6px;}.yui-dt-editor .yui-dt-button button.yui-dt-default{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1400px;background-color:#5584E0;border:1px solid #304369;color:#FFF}.yui-dt-editor .yui-dt-button button:hover{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1300px;color:#000;}.yui-dt-editor .yui-dt-button button:active{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1700px;color:#000;}.yui-skin-sam tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam tr.yui-dt-odd{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-asc,.yui-!
 skin-sam tr.yui-dt-even td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam tr.yui-dt-odd td.yui-dt-desc{background-color:#DBEAFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-odd{background-color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam .y!
 ui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam !
 .yui-dt-
list tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam tr.yui-dt-selected td,.yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam tr.yui-dt-selected td.yui-dt-desc{background-color:#426FD9;color:#FFF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam tr.yui-dt-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-selected td,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-desc{background-color:#426FD9;color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}.yui-skin-sam .yui-dt-paginator{display:block;margin:6px 0;white-space:nowrap;}.yui-skin-sam .yui-dt-paginator .yui-dt-first,.yui-skin-sam .yui-dt-paginator .yui-dt-last,.yui-ski!
 n-sam .yui-dt-paginator .yui-dt-selected{padding:2px 6px;}.yui-skin-sam .yui-dt-paginator a.yui-dt-first,.yui-skin-sam .yui-dt-paginator a.yui-dt-last{text-decoration:none;}.yui-skin-sam .yui-dt-paginator .yui-dt-previous,.yui-skin-sam .yui-dt-paginator .yui-dt-next{display:none;}.yui-skin-sam a.yui-dt-page{border:1px solid #CBCBCB;padding:2px 6px;text-decoration:none;}
+.yui-dt{border-bottom:1px solid transparent;}.yui-dt-noop{border-bottom:none;}.yui-dt-hd{display:none;}.yui-dt-scrollable .yui-dt-hd{display:block;}.yui-dt-scrollable .yui-dt-bd thead tr,.yui-dt-scrollable .yui-dt-bd thead th{position:absolute;left:-1500px;}.yui-dt-scrollable tbody{-moz-outline:none;}.yui-dt-draggable{cursor:move;}.yui-dt-coltarget{position:absolute;z-index:999;}.yui-dt-hd{zoom:1;}th.yui-dt-resizeable .yui-dt-liner{position:relative;}.yui-dt-resizer{position:absolute;right:0;bottom:0;height:100%;cursor:e-resize;cursor:col-resize;}.yui-dt-resizerproxy{visibility:hidden;position:absolute;z-index:9000;}.yui-skin-sam th.yui-dt-hidden .yui-dt-liner,.yui-skin-sam td.yui-dt-hidden .yui-dt-liner{margin:0;padding:0;overflow:hidden;white-space:nowrap;}.yui-dt-scrollable .yui-dt-bd{overflow:auto;}.yui-dt-scrollable .yui-dt-hd{overflow:hidden;position:relative;}.yui-dt-editor{position:absolute;z-index:9000;}.yui-skin-sam .yui-dt table{margin:0;padding:0;font-family:ari!
 al;font-size:inherit;border-collapse:collapse;border-spacing:0;}.yui-skin-sam .yui-dt thead{border-spacing:0;}.yui-skin-sam .yui-dt caption{padding-bottom:1em;text-align:left;}.yui-skin-sam .yui-dt-hd table{border-left:1px solid #7F7F7F;border-top:1px solid #7F7F7F;border-right:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-bd table{border:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-scrollable .yui-dt-hd table{border:0px;}.yui-skin-sam .yui-dt-scrollable .yui-dt-bd table{border:0px;}.yui-skin-sam .yui-dt-scrollable .yui-dt-hd{border-left:1px solid #7F7F7F;border-top:1px solid #7F7F7F;border-right:1px solid #7F7F7F;}.yui-skin-sam .yui-dt-scrollable .yui-dt-bd{border-left:1px solid #7F7F7F;border-bottom:1px solid #7F7F7F;border-right:1px solid #7F7F7F;}.yui-skin-sam .yui-dt th{background:#D8D8DA url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;}.yui-skin-sam .yui-dt th,.yui-skin-sam .yui-dt th a{font-weight:normal;text-decoration:none;color:#000;vertical-align:bottom;}.yui-sk!
 in-sam .yui-dt th{margin:0;padding:0;border:none;border-right:!
 1px soli
d #CBCBCB;}.yui-skin-sam .yui-dt-liner{margin:0;padding:0;padding:4px 10px 4px 10px;}.yui-skin-sam .yui-dt-coltarget{width:5px;background-color:red;}.yui-skin-sam .yui-dt td{margin:0;padding:0;border:none;border-right:1px solid #CBCBCB;text-align:left;}.yui-skin-sam .yui-dt-list td{border-right:none;}.yui-skin-sam .yui-dt-resizer{width:6px;}.yui-skin-sam .yui-dt-loading{background-color:#FFF;}.yui-skin-sam .yui-dt-empty{background-color:#FFF;}.yui-skin-sam .yui-dt-error{background-color:#FFF;}.yui-skin-sam thead .yui-dt-sortable{cursor:pointer;}.yui-skin-sam th.yui-dt-asc,.yui-skin-sam th.yui-dt-desc{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -100px;}.yui-skin-sam th.yui-dt-sortable .yui-dt-label{margin-right:10px;}.yui-skin-sam th.yui-dt-asc .yui-dt-liner{background:url(dt-arrow-up.png) no-repeat right;}.yui-skin-sam th.yui-dt-desc .yui-dt-liner{background:url(dt-arrow-dn.png) no-repeat right;}.yui-dt-editable{cursor:pointer;}.yui-dt-editor{text-alig!
 n:left;background-color:#F2F2F2;border:1px solid #808080;padding:6px;}.yui-dt-editor label{padding-left:4px;padding-right:6px;}.yui-dt-editor .yui-dt-button{padding-top:6px;text-align:right;}.yui-dt-editor .yui-dt-button button{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;border:1px solid #999;width:4em;height:1.8em;margin-left:6px;}.yui-dt-editor .yui-dt-button button.yui-dt-default{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1400px;background-color:#5584E0;border:1px solid #304369;color:#FFF}.yui-dt-editor .yui-dt-button button:hover{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1300px;color:#000;}.yui-dt-editor .yui-dt-button button:active{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1700px;color:#000;}.yui-skin-sam tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam tr.yui-dt-odd{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam tr.yui-dt-even td!
 .yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam tr.yui-dt!
 -odd td.
yui-dt-asc,.yui-skin-sam tr.yui-dt-odd td.yui-dt-desc{background-color:#DBEAFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even{background-color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-odd{background-color:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-desc{background-color:#EDF5FF;}.yui-skin-sam th.yui-dt-highlighted,.yui-skin-sam th.yui-dt-highlighted a{background-color:#B2D2FF;}.yui-skin-sam tr.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam .yui-dt-list th.yui-dt-highlighted,.yui-skin-sam .yui-dt-list th.yui-dt-highlighted a{background-color:#B2D2FF;!
 }.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-asc,.yui-skin-sam .yui-dt-list tr.yui-dt-highlighted td.yui-dt-desc,.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-highlighted,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-highlighted{cursor:pointer;background-color:#B2D2FF;}.yui-skin-sam th.yui-dt-selected,.yui-skin-sam th.yui-dt-selected a{background-color:#446CD7;}.yui-skin-sam tr.yui-dt-selected td,.yui-skin-sam tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam tr.yui-dt-selected td.yui-dt-desc{background-color:#426FD9;color:#FFF;}.yui-skin-sam tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam tr.yui-dt-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}.yui-skin-sam .yui-dt-list th.yui-dt-selected,.yui-skin-sam .yui-dt-list th.yui-dt-selected a{background-color:#446CD7;}.yui-skin-sam .yui-dt-list tr.yui-dt-selected td,.yui-skin-sam .yui-dt-list tr.yui-dt-selected td.yui-dt-asc,.yui-skin-sam .yui-d!
 t-list tr.yui-dt-selected td.yui-dt-desc{background-color:#426!
 FD9;colo
r:#FFF;}.yui-skin-sam .yui-dt-list tr.yui-dt-even td.yui-dt-selected,.yui-skin-sam .yui-dt-list tr.yui-dt-odd td.yui-dt-selected{background-color:#446CD7;color:#FFF;}.yui-skin-sam .yui-pg-container,.yui-skin-sam .yui-dt-paginator{display:block;margin:6px 0;white-space:nowrap;}.yui-skin-sam .yui-pg-first,.yui-skin-sam .yui-pg-last,.yui-skin-sam .yui-pg-current-page,.yui-skin-sam .yui-dt-first,.yui-skin-sam .yui-dt-paginator .yui-dt-last,.yui-skin-sam .yui-dt-paginator .yui-dt-selected{padding:2px 6px;}.yui-skin-sam a.yui-pg-first,.yui-skin-sam a.yui-pg-previous,.yui-skin-sam a.yui-pg-next,.yui-skin-sam a.yui-pg-last,.yui-skin-sam a.yui-pg-page,.yui-skin-sam .yui-dt-paginator a.yui-dt-first,.yui-skin-sam .yui-dt-paginator a.yui-dt-last{text-decoration:none;}.yui-skin-sam .yui-dt-paginator .yui-dt-previous,.yui-skin-sam .yui-dt-paginator .yui-dt-next{display:none;}.yui-skin-sam a.yui-pg-page,.yui-skin-sam a.yui-dt-page{border:1px solid #CBCBCB;padding:2px 6px;text-decoration:no!
 ne;background-color:#fff}.yui-skin-sam .yui-pg-current-page,.yui-skin-sam .yui-dt-selected{border:1px solid #fff;background-color:#fff;}.yui-skin-sam .yui-pg-pages{margin-left:1ex;margin-right:1ex;}.yui-skin-sam .yui-pg-page{margin-right:1px;margin-left:1px;}.yui-skin-sam .yui-pg-first,.yui-skin-sam .yui-pg-previous{margin-right:3px;}.yui-skin-sam .yui-pg-next,.yui-skin-sam .yui-pg-last{margin-left:3px;}.yui-skin-sam .yui-pg-current,.yui-skin-sam .yui-pg-rpp-options{margin-right:1em;margin-left:1em;}

Modified: trunk/root/static/yui/datatable/assets/skins/sam/dt-arrow-dn.png
===================================================================
(Binary files differ)

Modified: trunk/root/static/yui/datatable/assets/skins/sam/dt-arrow-up.png
===================================================================
(Binary files differ)

Modified: trunk/root/static/yui/datatable/datatable-beta-debug.js
===================================================================
--- trunk/root/static/yui/datatable/datatable-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/datatable/datatable-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,16 +1,4352 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
+ * Mechanism to execute a series of callbacks in a non-blocking queue.  Each callback is executed via setTimout unless configured with a negative timeout, in which case it is run in blocking mode in the same execution thread as the previous callback.  Callbacks can be function references or object literals with the following keys:
+ * <ul>
+ *    <li><code>method</code> - {Function} REQUIRED the callback function.</li>
+ *    <li><code>scope</code> - {Object} the scope from which to execute the callback.  Default is the global window scope.</li>
+ *    <li><code>argument</code> - {Array} parameters to be passed to method as individual arguments.</li>
+ *    <li><code>timeout</code> - {number} millisecond delay to wait after previous callback completion before executing this callback.  Negative values cause immediate blocking execution.  Default 0.</li>
+ *    <li><code>until</code> - {Function} boolean function executed before each iteration.  Return true to indicate completion and proceed to the next callback.</li>
+ *    <li><code>iterations</code> - {Number} number of times to execute the callback before proceeding to the next callback in the chain. Incompatible with <code>until</code>.</li>
+ * </ul>
+ *
+ * @namespace YAHOO.util
+ * @class Chain
+ * @constructor
+ * @param callback* {Function|Object} Any number of callbacks to initialize the queue
+*/
+YAHOO.util.Chain = function () {
+    /**
+     * The callback queue
+     * @property q
+     * @type {Array}
+     * @private
+     */
+    this.q = [].slice.call(arguments);
+
+    /**
+     * Event fired when the callback queue is emptied via execution (not via
+     * a call to chain.stop().
+     * @event end
+     */
+    this.createEvent('end');
+};
+
+YAHOO.util.Chain.prototype = {
+    /**
+     * Timeout id used to pause or stop execution and indicate the execution state of the Chain.  0 indicates paused or stopped, -1 indicates blocking execution, and any positive number indicates non-blocking execution.
+     * @property id
+     * @type {number}
+     * @private
+     */
+    id   : 0,
+
+    /**
+     * Begin executing the chain, or resume execution from the last paused position.
+     * @method run
+     * @return {Chain} the Chain instance
+     */
+    run : function () {
+        // Grab the first callback in the queue
+        var c  = this.q[0],
+            fn;
+
+        // If there is no callback in the queue or the Chain is currently
+        // in an execution mode, return
+        if (!c) {
+            this.fireEvent('end');
+            return this;
+        } else if (this.id) {
+            return this;
+        }
+
+        fn = c.method || c;
+
+        if (typeof fn === 'function') {
+            var o    = c.scope || {},
+                args = c.argument || [],
+                ms   = c.timeout || 0,
+                me   = this;
+                
+            if (!(args instanceof Array)) {
+                args = [args];
+            }
+
+            // Execute immediately if the callback timeout is negative.
+            if (ms < 0) {
+                this.id = ms;
+                if (c.until) {
+                    for (;!c.until();) {
+                        // Execute the callback from scope, with argument
+                        fn.apply(o,args);
+                    }
+                } else if (c.iterations) {
+                    for (;c.iterations-- > 0;) {
+                        fn.apply(o,args);
+                    }
+                } else {
+                    fn.apply(o,args);
+                }
+                this.q.shift();
+                this.id = 0;
+                return this.run();
+            } else {
+                // If the until condition is set, check if we're done
+                if (c.until) {
+                    if (c.until()) {
+                        // Shift this callback from the queue and execute the next
+                        // callback
+                        this.q.shift();
+                        return this.run();
+                    }
+                // Otherwise if either iterations is not set or we're
+                // executing the last iteration, shift callback from the queue
+                } else if (!c.iterations || !--c.iterations) {
+                    this.q.shift();
+                }
+
+                // Otherwise set to execute after the configured timeout
+                this.id = setTimeout(function () {
+                    // Execute the callback from scope, with argument
+                    fn.apply(o,args);
+                    // Check if the Chain was not paused from inside the callback
+                    if (me.id) {
+                        // Indicate ready to run state
+                        me.id = 0;
+                        // Start the fun all over again
+                        me.run();
+                    }
+                },ms);
+            }
+        }
+
+        return this;
+    },
+    
+    /**
+     * Add a callback to the end of the queue
+     * @method add
+     * @param c {Function|Object} the callback function ref or object literal
+     * @return {Chain} the Chain instance
+     */
+    add  : function (c) {
+        this.q.push(c);
+        return this;
+    },
+
+    /**
+     * Pause the execution of the Chain after the current execution of the
+     * current callback completes.  If called interstitially, clears the
+     * timeout for the pending callback. Paused Chains can be restarted with
+     * chain.run()
+     * @method pause
+     * @return {Chain} the Chain instance
+     */
+    pause: function () {
+        clearTimeout(this.id);
+        this.id = 0;
+        return this;
+    },
+
+    /**
+     * Stop and clear the Chain's queue after the current execution of the
+     * current callback completes.
+     * @method stop
+     * @return {Chain} the Chain instance
+     */
+    stop : function () { 
+        this.pause();
+        this.q = [];
+        return this;
+    }
+};
+YAHOO.lang.augmentProto(YAHOO.util.Chain,YAHOO.util.EventProvider);
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * The ColumnSet class defines and manages a DataTable's Columns,
+ * including nested hierarchies and access to individual Column instances.
+ *
+ * @namespace YAHOO.widget
+ * @class ColumnSet
+ * @uses YAHOO.util.EventProvider
+ * @constructor
+ * @param aDefinitions {Object[]} Array of object literals that define cells in
+ * the THEAD.
+ */
+YAHOO.widget.ColumnSet = function(aDefinitions) {
+    this._sId = "yui-cs" + YAHOO.widget.ColumnSet._nCount;
+
+    // First clone the defs
+    aDefinitions = YAHOO.widget.DataTable._cloneObject(aDefinitions);
+    this._init(aDefinitions);
+
+    YAHOO.widget.ColumnSet._nCount++;
+    YAHOO.log("ColumnSet initialized", "info", this.toString());
+};
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Private member variables
+//
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Internal class variable to index multiple ColumnSet instances.
+ *
+ * @property ColumnSet._nCount
+ * @type Number
+ * @private
+ * @static
+ */
+YAHOO.widget.ColumnSet._nCount = 0;
+
+YAHOO.widget.ColumnSet.prototype = {
+    /**
+     * Unique instance name.
+     *
+     * @property _sId
+     * @type String
+     * @private
+     */
+    _sId : null,
+
+    /**
+     * Array of object literal Column definitions passed to the constructor.
+     *
+     * @property _aDefinitions
+     * @type Object[]
+     * @private
+     */
+    _aDefinitions : null,
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public member variables
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Top-down tree representation of Column hierarchy.
+     *
+     * @property tree
+     * @type YAHOO.widget.Column[]
+     */
+    tree : null,
+
+    /**
+     * Flattened representation of all Columns.
+     *
+     * @property flat
+     * @type YAHOO.widget.Column[]
+     * @default []
+     */
+    flat : null,
+
+    /**
+     * Array of Columns that map one-to-one to a table column.
+     *
+     * @property keys
+     * @type YAHOO.widget.Column[]
+     * @default []
+     */
+    keys : null,
+
+    /**
+     * ID index of nested parent hierarchies for HEADERS accessibility attribute.
+     *
+     * @property headers
+     * @type String[]
+     * @default []
+     */
+    headers : null,
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Private methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Initializes ColumnSet instance with data from Column definitions.
+     *
+     * @method _init
+     * @param aDefinitions {Object[]} Array of object literals that define cells in
+     * the THEAD .
+     * @private
+     */
+
+    _init : function(aDefinitions) {        
+        // DOM tree representation of all Columns
+        var tree = [];
+        // Flat representation of all Columns
+        var flat = [];
+        // Flat representation of only Columns that are meant to display data
+        var keys = [];
+        // Array of HEADERS attribute values for all keys in the "keys" array
+        var headers = [];
+
+        // Tracks current node list depth being tracked
+        var nodeDepth = -1;
+
+        // Internal recursive function to define Column instances
+        var parseColumns = function(nodeList, parent) {
+            // One level down
+            nodeDepth++;
+
+            // Create corresponding tree node if not already there for this depth
+            if(!tree[nodeDepth]) {
+                tree[nodeDepth] = [];
+            }
+
+
+            // Parse each node at this depth for attributes and any children
+            for(var j=0; j<nodeList.length; j++) {
+                var currentNode = nodeList[j];
+
+                // Instantiate a new Column for each node
+                var oColumn = new YAHOO.widget.Column(currentNode);
+                
+                // Assign unique ID to Column and cross-reference it back to the
+                // original object literal definition
+                currentNode.yuiColumnId = oColumn._sId = YAHOO.widget.Column._nCount + "";
+                
+                // Assign a key if not found
+                if(!YAHOO.lang.isValue(oColumn.key)) {
+                    oColumn.key = "yui-dt-col" + YAHOO.widget.Column._nCount;
+                }
+                // Increment counter
+                YAHOO.widget.Column._nCount++;
+
+                // Add the new Column to the flat list
+                flat.push(oColumn);
+
+                // Assign its parent as an attribute, if applicable
+                if(parent) {
+                    oColumn.parent = parent;
+                }
+
+                // The Column has descendants
+                if(YAHOO.lang.isArray(currentNode.children)) {
+                    oColumn.children = currentNode.children;
+
+                    // Determine COLSPAN value for this Column
+                    var terminalChildNodes = 0;
+                    var countTerminalChildNodes = function(ancestor) {
+                        var descendants = ancestor.children;
+                        // Drill down each branch and count terminal nodes
+                        for(var k=0; k<descendants.length; k++) {
+                            // Keep drilling down
+                            if(YAHOO.lang.isArray(descendants[k].children)) {
+                                countTerminalChildNodes(descendants[k]);
+                            }
+                            // Reached branch terminus
+                            else {
+                                terminalChildNodes++;
+                            }
+                        }
+                    };
+                    countTerminalChildNodes(currentNode);
+                    oColumn._nColspan = terminalChildNodes;
+
+                    // Cascade certain properties to children if not defined on their own
+                    var currentChildren = currentNode.children;
+                    for(var k=0; k<currentChildren.length; k++) {
+                        var child = currentChildren[k];
+                        if(oColumn.className && (child.className === undefined)) {
+                            child.className = oColumn.className;
+                        }
+                        if(oColumn.editor && (child.editor === undefined)) {
+                            child.editor = oColumn.editor;
+                        }
+                        if(oColumn.editorOptions && (child.editorOptions === undefined)) {
+                            child.editorOptions = oColumn.editorOptions;
+                        }
+                        if(oColumn.formatter && (child.formatter === undefined)) {
+                            child.formatter = oColumn.formatter;
+                        }
+                        if(oColumn.resizeable && (child.resizeable === undefined)) {
+                            child.resizeable = oColumn.resizeable;
+                        }
+                        if(oColumn.sortable && (child.sortable === undefined)) {
+                            child.sortable = oColumn.sortable;
+                        }
+                        if(oColumn.width && (child.width === undefined)) {
+                            child.width = oColumn.width;
+                        }
+                        // Backward compatibility
+                        if(oColumn.type && (child.type === undefined)) {
+                            child.type = oColumn.type;
+                        }
+                        if(oColumn.type && !oColumn.formatter) {
+                            YAHOO.log("The property type has been" +
+                            " deprecated in favor of formatter", "warn", oColumn.toString());
+                            oColumn.formatter = oColumn.type;
+                        }
+                        if(oColumn.text && !YAHOO.lang.isValue(oColumn.label)) {
+                            YAHOO.log("The property text has been" +
+                            " deprecated in favor of label", "warn", oColumn.toString());
+                            oColumn.label = oColumn.text;
+                        }
+                        if(oColumn.parser) {
+                            YAHOO.log("The property parser is no longer supported",
+                            "warn", this.toString());
+                        }
+                        if(oColumn.sortOptions && ((oColumn.sortOptions.ascFunction) ||
+                                (oColumn.sortOptions.descFunction))) {
+                            YAHOO.log("The properties sortOptions.ascFunction and " +
+                            " sortOptions.descFunction have been deprecated in favor " +
+                            " of sortOptions.sortFunction", "warn", oColumn.toString());
+                        }
+                    }
+
+                    // The children themselves must also be parsed for Column instances
+                    if(!tree[nodeDepth+1]) {
+                        tree[nodeDepth+1] = [];
+                    }
+                    parseColumns(currentChildren, oColumn);
+                }
+                // This Column does not have any children
+                else {
+                    oColumn._nKeyIndex = keys.length;
+                    oColumn._nColspan = 1;
+                    keys.push(oColumn);
+                }
+
+                // Add the Column to the top-down tree
+                tree[nodeDepth].push(oColumn);
+            }
+            nodeDepth--;
+        };
+
+        // Parse out Column instances from the array of object literals
+        if(YAHOO.lang.isArray(aDefinitions)) {
+            parseColumns(aDefinitions);
+
+            // Store the array
+            this._aDefinitions = aDefinitions;
+        }
+        else {
+            YAHOO.log("Could not initialize ColumnSet due to invalid definitions","error");
+            return null;
+        }
+
+        var i;
+
+        // Determine ROWSPAN value for each Column in the tree
+        var parseTreeForRowspan = function(tree) {
+            var maxRowDepth = 1;
+            var currentRow;
+            var currentColumn;
+
+            // Calculate the max depth of descendants for this row
+            var countMaxRowDepth = function(row, tmpRowDepth) {
+                tmpRowDepth = tmpRowDepth || 1;
+
+                for(var n=0; n<row.length; n++) {
+                    var col = row[n];
+                    // Column has children, so keep counting
+                    if(YAHOO.lang.isArray(col.children)) {
+                        tmpRowDepth++;
+                        countMaxRowDepth(col.children, tmpRowDepth);
+                        tmpRowDepth--;
+                    }
+                    // No children, is it the max depth?
+                    else {
+                        if(tmpRowDepth > maxRowDepth) {
+                            maxRowDepth = tmpRowDepth;
+                        }
+                    }
+
+                }
+            };
+
+            // Count max row depth for each row
+            for(var m=0; m<tree.length; m++) {
+                currentRow = tree[m];
+                countMaxRowDepth(currentRow);
+
+                // Assign the right ROWSPAN values to each Column in the row
+                for(var p=0; p<currentRow.length; p++) {
+                    currentColumn = currentRow[p];
+                    if(!YAHOO.lang.isArray(currentColumn.children)) {
+                        currentColumn._nRowspan = maxRowDepth;
+                    }
+                    else {
+                        currentColumn._nRowspan = 1;
+                    }
+                }
+
+                // Reset counter for next row
+                maxRowDepth = 1;
+            }
+        };
+        parseTreeForRowspan(tree);
+
+        // Store tree index values
+        for(i=0; i<tree[0].length; i++) {
+            tree[0][i]._nTreeIndex = i;
+        }
+
+        // Store header relationships in an array for HEADERS attribute
+        var recurseAncestorsForHeaders = function(i, oColumn) {
+            headers[i].push(oColumn._sId);
+            if(oColumn.parent) {
+                recurseAncestorsForHeaders(i, oColumn.parent);
+            }
+        };
+        for(i=0; i<keys.length; i++) {
+            headers[i] = [];
+            recurseAncestorsForHeaders(i, keys[i]);
+            headers[i] = headers[i].reverse();
+        }
+
+        // Save to the ColumnSet instance
+        this.tree = tree;
+        this.flat = flat;
+        this.keys = keys;
+        this.headers = headers;
+    },
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns unique name of the ColumnSet instance.
+     *
+     * @method getId
+     * @return {String} Unique name of the ColumnSet instance.
+     */
+
+    getId : function() {
+        return this._sId;
+    },
+
+    /**
+     * ColumnSet instance name, for logging.
+     *
+     * @method toString
+     * @return {String} Unique name of the ColumnSet instance.
+     */
+
+    toString : function() {
+        return "ColumnSet instance " + this._sId;
+    },
+
+    /**
+     * Public accessor to the definitions array.
+     *
+     * @method getDefinitions
+     * @return {Object[]} Array of object literal Column definitions.
+     */
+
+    getDefinitions : function() {
+        var aDefinitions = this._aDefinitions;
+        
+        // Internal recursive function to define Column instances
+        var parseColumns = function(nodeList, oSelf) {
+            // Parse each node at this depth for attributes and any children
+            for(var j=0; j<nodeList.length; j++) {
+                var currentNode = nodeList[j];
+                
+                // Get the Column for each node
+                var oColumn = oSelf.getColumnById(currentNode.yuiColumnId);
+                
+                if(oColumn) {    
+                    // Update the definition
+                    currentNode.abbr = oColumn.abbr;
+                    currentNode.className = oColumn.className;
+                    currentNode.editor = oColumn.editor;
+                    currentNode.editorOptions = oColumn.editorOptions;
+                    currentNode.formatter = oColumn.formatter;
+                    currentNode.hidden = oColumn.hidden;
+                    currentNode.key = oColumn.key;
+                    currentNode.label = oColumn.label;
+                    currentNode.minWidth = oColumn.minWidth;
+                    currentNode.resizeable = oColumn.resizeable;
+                    currentNode.selected = oColumn.selected;
+                    currentNode.sortable = oColumn.sortable;
+                    currentNode.sortOptions = oColumn.sortOptions;
+                    currentNode.width = oColumn.width;
+                }
+                            
+                // The Column has descendants
+                if(YAHOO.lang.isArray(currentNode.children)) {
+                    // The children themselves must also be parsed for Column instances
+                    parseColumns(currentNode.children, oSelf);
+                }
+            }
+        };
+
+        parseColumns(aDefinitions, this);
+        this._aDefinitions = aDefinitions;
+        return aDefinitions;
+    },
+
+    /**
+     * Returns Column instance with given ID.
+     *
+     * @method getColumnById
+     * @param column {String} Column ID.
+     * @return {YAHOO.widget.Column} Column instance.
+     */
+
+    getColumnById : function(column) {
+        if(YAHOO.lang.isString(column)) {
+            var allColumns = this.flat;
+            for(var i=allColumns.length-1; i>-1; i--) {
+                if(allColumns[i]._sId === column) {
+                    return allColumns[i];
+                }
+            }
+        }
+        return null;
+    },
+
+    /**
+     * Returns Column instance with given key or ColumnSet key index.
+     *
+     * @method getColumn
+     * @param column {String | Number} Column key or ColumnSet key index.
+     * @return {YAHOO.widget.Column} Column instance.
+     */
+
+    getColumn : function(column) {
+        if(YAHOO.lang.isNumber(column) && this.keys[column]) {
+            return this.keys[column];
+        }
+        else if(YAHOO.lang.isString(column)) {
+            var allColumns = this.flat;
+            var aColumns = [];
+            for(var i=0; i<allColumns.length; i++) {
+                if(allColumns[i].key === column) {
+                    aColumns.push(allColumns[i]);
+                }
+            }
+            if(aColumns.length === 1) {
+                return aColumns[0];
+            }
+            else if(aColumns.length > 1) {
+                return aColumns;
+            }
+        }
+        return null;
+    },
+
+    /**
+     * Public accessor returns array of given Column's desendants (if any), including itself.
+     *
+     * @method getDescendants
+     * @parem {YAHOO.widget.Column} Column instance.
+     * @return {Array} Array including the Column itself and all descendants (if any).
+     */
+    getDescendants : function(oColumn) {
+        var oSelf = this;
+        var allDescendants = [];
+        var i;
+
+        // Recursive function to loop thru all children
+        var parse = function(oParent) {
+            allDescendants.push(oParent);
+            // This Column has children
+            if(oParent.children) {
+                for(i=0; i<oParent.children.length; i++) {
+                    parse(oSelf.getColumn(oParent.children[i].key));
+                }
+            }
+        };
+        parse(oColumn);
+
+        return allDescendants;
+    }
+};
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * The Column class defines and manages attributes of DataTable Columns
+ *
+ * @namespace YAHOO.widget
+ * @class Column
+ * @constructor
+ * @param oConfigs {Object} Object literal of definitions.
+ */
+YAHOO.widget.Column = function(oConfigs) {
+    // Object literal defines Column attributes
+    if(oConfigs && (oConfigs.constructor == Object)) {
+        for(var sConfig in oConfigs) {
+            if(sConfig) {
+                this[sConfig] = oConfigs[sConfig];
+            }
+        }
+   }
+    // Backward compatibility
+    if(this.width && !YAHOO.lang.isNumber(this.width)) {
+        this.width = null;
+        YAHOO.log("The Column property width must be a number", "warn", this.toString());
+    }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Private member variables
+//
+/////////////////////////////////////////////////////////////////////////////
+
+YAHOO.lang.augmentObject(YAHOO.widget.Column, {
+    /**
+     * Internal class variable to index multiple Column instances.
+     *
+     * @property Column._nCount
+     * @type Number
+     * @private
+     * @static
+     */
+    _nCount : 0,
+
+    formatCheckbox : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.log("The method YAHOO.widget.Column.formatCheckbox() has been" +
+        " deprecated in favor of YAHOO.widget.DataTable.formatCheckbox()", "warn",
+        "YAHOO.widget.Column.formatCheckbox");
+        YAHOO.widget.DataTable.formatCheckbox(elCell, oRecord, oColumn, oData);
+    },
+
+    formatCurrency : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.log("The method YAHOO.widget.Column.formatCurrency() has been" +
+        " deprecated in favor of YAHOO.widget.DataTable.formatCurrency()", "warn",
+        "YAHOO.widget.Column.formatCurrency");
+        YAHOO.widget.DataTable.formatCurrency(elCell, oRecord, oColumn, oData);
+    },
+
+    formatDate : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.log("The method YAHOO.widget.Column.formatDate() has been" +
+        " deprecated in favor of YAHOO.widget.DataTable.formatDate()", "warn",
+        "YAHOO.widget.Column.formatDate");
+        YAHOO.widget.DataTable.formatDate(elCell, oRecord, oColumn, oData);
+    },
+
+    formatEmail : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.log("The method YAHOO.widget.Column.formatEmail() has been" +
+        " deprecated in favor of YAHOO.widget.DataTable.formatEmail()", "warn",
+        "YAHOO.widget.Column.formatEmail");
+        YAHOO.widget.DataTable.formatEmail(elCell, oRecord, oColumn, oData);
+    },
+
+    formatLink : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.log("The method YAHOO.widget.Column.formatLink() has been" +
+        " deprecated in favor of YAHOO.widget.DataTable.formatLink()", "warn",
+        "YAHOO.widget.Column.formatLink");
+        YAHOO.widget.DataTable.formatLink(elCell, oRecord, oColumn, oData);
+    },
+
+    formatNumber : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.log("The method YAHOO.widget.Column.formatNumber() has been" +
+        " deprecated in favor of YAHOO.widget.DataTable.formatNumber()", "warn",
+        "YAHOO.widget.Column.formatNumber");
+        YAHOO.widget.DataTable.formatNumber(elCell, oRecord, oColumn, oData);
+    },
+
+    formatSelect : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.log("The method YAHOO.widget.Column.formatSelect() has been" +
+        " deprecated in favor of YAHOO.widget.DataTable.formatDropdown()", "warn",
+        "YAHOO.widget.Column.formatSelect");
+        YAHOO.widget.DataTable.formatDropdown(elCell, oRecord, oColumn, oData);
+    }
+});
+
+YAHOO.widget.Column.prototype = {
+    /**
+     * Unique String identifier assigned at instantiation.
+     *
+     * @property _sId
+     * @type String
+     * @private
+     */
+    _sId : null,
+
+    /**
+     * Object literal definition
+     *
+     * @property _oDefinition
+     * @type Object
+     * @private
+     */
+    _oDefinition : null,
+
+    /**
+     * Reference to Column's current position index within its ColumnSet's keys
+     * array, if applicable. This property only applies to non-nested and bottom-
+     * level child Columns.
+     *
+     * @property _nKeyIndex
+     * @type Number
+     * @private
+     */
+    _nKeyIndex : null,
+
+    /**
+     * Reference to Column's current position index within its ColumnSet's tree
+     * array, if applicable. This property only applies to non-nested and top-
+     * level parent Columns.
+     *
+     * @property _nTreeIndex
+     * @type Number
+     * @private
+     */
+    _nTreeIndex : null,
+
+    /**
+     * Number of table cells the Column spans.
+     *
+     * @property _nColspan
+     * @type Number
+     * @private
+     */
+    _nColspan : 1,
+
+    /**
+     * Number of table rows the Column spans.
+     *
+     * @property _nRowspan
+     * @type Number
+     * @private
+     */
+    _nRowspan : 1,
+
+    /**
+     * Column's parent Column instance, or null.
+     *
+     * @property _oParent
+     * @type YAHOO.widget.Column
+     * @private
+     */
+    _oParent : null,
+
+    /*TODO: remove
+     * The DOM reference the associated COL element.
+     *
+     * @property _elCol
+     * @type HTMLElement
+     * @private
+     */
+    //YAHOO.widget.Column.prototype._elCol = null;
+
+    /**
+     * The DOM reference to the associated TH element.
+     *
+     * @property _elTh
+     * @type HTMLElement
+     * @private
+     */
+    _elTh : null,
+
+    /**
+     * The DOM reference to the associated resizerelement (if any).
+     *
+     * @property _elResizer
+     * @type HTMLElement
+     * @private
+     */
+    _elResizer : null,
+
+    /**
+     * For unreg() purposes, a reference to the Column's DragDrop instance.
+     *
+     * @property _dd
+     * @type YAHOO.util.DragDrop
+     * @private
+     */
+    _dd : null,
+
+    /**
+     * For unreg() purposes, a reference to the Column resizer's DragDrop instance.
+     *
+     * @property _ddResizer
+     * @type YAHOO.util.DragDrop
+     * @private
+     */
+    _ddResizer : null,
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public member variables
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Associated database field, or null.
+     *
+     * @property key
+     * @type String
+     */
+    key : null,
+
+    /**
+     * Text or HTML for display as Column's label in the TH element.
+     *
+     * @property label
+     * @type String
+     */
+    label : null,
+
+    /**
+     * Column head cell ABBR for accessibility.
+     *
+     * @property abbr
+     * @type String
+     */
+    abbr : null,
+
+    /**
+     * Array of object literals that define children (nested headers) of a Column.
+     *
+     * @property children
+     * @type Object[]
+     */
+    children : null,
+
+    /**
+     * Column width (in pixels).
+     *
+     * @property width
+     * @type Number
+     */
+    width : null,
+
+    /**
+     * Minimum Column width (in pixels).
+     *
+     * @property minWidth
+     * @type Number
+     * @default 10
+     */
+    minWidth : 10,
+
+    /**
+     * True if Column is in hidden state.
+     *
+     * @property hidden
+     * @type Boolean
+     * @default false     
+     */
+    hidden : false,
+
+    /**
+     * True if Column is in selected state.
+     *
+     * @property selected
+     * @type Boolean
+     * @default false     
+     */
+    selected : false,
+
+    /**
+     * Custom CSS class or array of classes to be applied to every cell in the Column.
+     *
+     * @property className
+     * @type String || String[]
+     */
+    className : null,
+
+    /**
+     * Defines a format function.
+     *
+     * @property formatter
+     * @type String || HTMLFunction
+     */
+    formatter : null,
+
+    /**
+     * Defines an editor function, otherwise Column is not editable.
+     *
+     * @property editor
+     * @type String || HTMLFunction
+     */
+    editor : null,
+
+    /**
+     * Defines editor options for Column in an object literal of param:value pairs.
+     *
+     * @property editorOptions
+     * @type Object
+     */
+    editorOptions : null,
+
+    /**
+     * True if Column is resizeable, false otherwise. The Drag & Drop Utility is
+     * required to enable this feature. Only bottom-level and non-nested Columns are
+     * resizeble. 
+     *
+     * @property resizeable
+     * @type Boolean
+     * @default false
+     */
+    resizeable : false,
+
+    /**
+     * True if Column is sortable, false otherwise.
+     *
+     * @property sortable
+     * @type Boolean
+     * @default false
+     */
+    sortable : false,
+
+    /**
+     * @property sortOptions.defaultOrder
+     * @deprecated Use sortOptions.defaultDir.
+     */
+    /**
+     * Default sort direction for Column: YAHOO.widget.DataTable.CLASS_ASC or YAHOO.widget.DataTable.CLASS_DESC.
+     *
+     * @property sortOptions.defaultDir
+     * @type String
+     * @default null
+     */
+    /**
+     * Custom sort handler.
+     *
+     * @property sortOptions.sortFunction
+     * @type Function
+     * @default null
+     */
+    sortOptions : null,
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns unique ID string.
+     *
+     * @method getId
+     * @return {String} Unique ID string.
+     */
+    getId : function() {
+        return this._sId;
+    },
+
+    /**
+     * Column instance name, for logging.
+     *
+     * @method toString
+     * @return {String} Column's unique name.
+     */
+    toString : function() {
+        return "Column instance " + this._sId;
+    },
+
+    /**
+     * Returns object literal definition.
+     *
+     * @method getDefinition
+     * @return {Object} Object literal definition.
+     */
+    getDefinition : function() {
+        var oDefinition = this._oDefinition;
+        
+        // Update the definition
+        oDefinition.abbr = this.abbr;
+        oDefinition.className = this.className;
+        oDefinition.editor = this.editor;
+        oDefinition.editorOptions = this.editorOptions;
+        oDefinition.formatter = this.formatter;
+        oDefinition.key = this.key;
+        oDefinition.label = this.label;
+        oDefinition.minWidth = this.minWidth;
+        oDefinition.resizeable = this.resizeable;
+        oDefinition.sortable = this.sortable;
+        oDefinition.sortOptions = this.sortOptions;
+        oDefinition.width = this.width;
+
+        return oDefinition;
+    },
+
+    /**
+     * Returns unique Column key.
+     *
+     * @method getKey
+     * @return {String} Column key.
+     */
+    getKey : function() {
+        return this.key;
+    },
+
+    /**
+     * Public accessor returns Column's current position index within its
+     * ColumnSet's keys array, if applicable. Only non-nested and bottom-level
+     * child Columns will return a value.
+     *
+     * @method getKeyIndex
+     * @return {Number} Position index, or null.
+     */
+    getKeyIndex : function() {
+        return this._nKeyIndex;
+    },
+
+    /**
+     * Public accessor returns Column's current position index within its
+     * ColumnSet's tree array, if applicable. Only non-nested and top-level parent
+     * Columns will return a value;
+     *
+     * @method getTreeIndex
+     * @return {Number} Position index, or null.
+     */
+    getTreeIndex : function() {
+        return this._nTreeIndex;
+    },
+
+    /**
+     * Public accessor returns Column's parent instance if any, or null otherwise.
+     *
+     * @method getParent
+     * @return {YAHOO.widget.Column} Column's parent instance.
+     */
+    getParent : function() {
+        return this._oParent;
+    },
+
+    /**
+     * Public accessor returns Column's calculated COLSPAN value.
+     *
+     * @method getColspan
+     * @return {Number} Column's COLSPAN value.
+     */
+    getColspan : function() {
+        return this._nColspan;
+    },
+    // Backward compatibility
+    getColSpan : function() {
+        YAHOO.log("The method getColSpan() has been" +
+        " deprecated in favor of getColspan()", "warn", this.toString());
+        return this.getColspan();
+    },
+
+    /**
+     * Public accessor returns Column's calculated ROWSPAN value.
+     *
+     * @method getRowspan
+     * @return {Number} Column's ROWSPAN value.
+     */
+    getRowspan : function() {
+        return this._nRowspan;
+    },
+
+    /**
+     * Returns DOM reference to the key TH element.
+     *
+     * @method getThEl
+     * @return {HTMLElement} TH element.
+     */
+    getThEl : function() {
+        return this._elTh;
+    },
+
+    /**
+     * Returns DOM reference to the resizer element, or null.
+     *
+     * @method getResizerEl
+     * @return {HTMLElement} DIV element.
+     */
+    getResizerEl : function() {
+        return this._elResizer;
+    },
+
+    // Backward compatibility
+    /**
+     * @method getColEl
+     * @deprecated Use getThEl
+     */
+    getColEl : function() {
+        YAHOO.log("The method getColEl() has been" +
+        " deprecated in favor of getThEl()", "warn",
+        this.toString());
+        return this.getThEl();
+    },
+    getIndex : function() {
+        YAHOO.log("The method getIndex() has been" +
+        " deprecated in favor of getKeyIndex()", "warn",
+        this.toString());
+        return this.getKeyIndex();
+    },
+    format : function() {
+        YAHOO.log("The method format() has been deprecated in favor of the " +
+        "DataTable method formatCell()", "error", this.toString());
+    }
+};
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * Sort static utility to support Column sorting.
+ *
+ * @namespace YAHOO.util
+ * @class Sort
+ * @static
+ */
+YAHOO.util.Sort = {
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Comparator function for simple case-insensitive string sorting.
+     *
+     * @method compare
+     * @param a {Object} First sort argument.
+     * @param b {Object} Second sort argument.
+     * @param desc {Boolean} True if sort direction is descending, false if
+     * sort direction is ascending.
+     */
+    compare: function(a, b, desc) {
+        if((a === null) || (typeof a == "undefined")) {
+            if((b === null) || (typeof b == "undefined")) {
+                return 0;
+            }
+            else {
+                return 1;
+            }
+        }
+        else if((b === null) || (typeof b == "undefined")) {
+            return -1;
+        }
+
+        if(a.constructor == String) {
+            a = a.toLowerCase();
+        }
+        if(b.constructor == String) {
+            b = b.toLowerCase();
+        }
+        if(a < b) {
+            return (desc) ? 1 : -1;
+        }
+        else if (a > b) {
+            return (desc) ? -1 : 1;
+        }
+        else {
+            return 0;
+        }
+    }
+};
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * ColumnDD subclasses DragDrop to support rearrangeable Columns.
+ *
+ * @namespace YAHOO.util
+ * @class ColumnDD
+ * @extends YAHOO.util.DDProxy
+ * @constructor
+ * @param oDataTable {YAHOO.widget.DataTable} DataTable instance.
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @param elTh {HTMLElement} TH element reference.
+ * @param elTarget {HTMLElement} Drag target element.
+ */
+YAHOO.widget.ColumnDD = function(oDataTable, oColumn, elTh, elTarget) {
+    if(oDataTable && oColumn && elTh && elTarget) {
+        this.datatable = oDataTable;
+        this.table = oDataTable.getTheadEl().parentNode;
+        this.column = oColumn;
+        this.headCell = elTh;
+        this.pointer = elTarget;
+        this.newIndex = null;
+        this.init(elTh);
+        this.initFrame(); // Needed for DDProxy
+        this.invalidHandleTypes = {};
+
+        //Set padding to account for children of nested columns
+        this.setPadding(10, 0, (this.datatable.getTheadEl().offsetHeight + 10) , 0);
+    }
+    else {
+        YAHOO.log("Column dragdrop could not be created","warn",oDataTable.toString());
+    }
+};
+
+if(YAHOO.util.DDProxy) {
+    YAHOO.extend(YAHOO.widget.ColumnDD, YAHOO.util.DDProxy, {
+        initConstraints: function() {
+            //Get the top, right, bottom and left positions
+            var region = YAHOO.util.Dom.getRegion(this.table),
+                //Get the element we are working on
+                el = this.getEl(),
+                //Get the xy position of it
+                xy = YAHOO.util.Dom.getXY(el),
+                //Get the width and height
+                width = parseInt(YAHOO.util.Dom.getStyle(el, 'width'), 10),
+                height = parseInt(YAHOO.util.Dom.getStyle(el, 'height'), 10),
+                //Set left to x minus left
+                left = ((xy[0] - region.left) + 15), //Buffer of 15px
+                //Set right to right minus x minus width
+                right = ((region.right - xy[0] - width) + 15);
+    
+            //Set the constraints based on the above calculations
+            this.setXConstraint(left, right);
+            this.setYConstraint(10, 10);
+            
+            YAHOO.util.Event.on(window, 'resize', function() {
+                this.initConstraints();
+            }, this, true);
+        },
+        _resizeProxy: function() {
+            this.constructor.superclass._resizeProxy.apply(this, arguments);
+            var dragEl = this.getDragEl(),
+                el = this.getEl();
+
+            YAHOO.util.Dom.setStyle(this.pointer, 'height', (this.table.parentNode.offsetHeight + 10) + 'px');
+            YAHOO.util.Dom.setStyle(this.pointer, 'display', 'block');
+            var xy = YAHOO.util.Dom.getXY(el);
+            YAHOO.util.Dom.setXY(this.pointer, [xy[0], (xy[1] - 5)]);
+            
+            YAHOO.util.Dom.setStyle(dragEl, 'height', this.datatable.getContainerEl().offsetHeight + "px");
+            YAHOO.util.Dom.setStyle(dragEl, 'width', (parseInt(YAHOO.util.Dom.getStyle(dragEl, 'width'),10) + 4) + 'px');
+            YAHOO.util.Dom.setXY(this.dragEl, xy);
+        },
+        onMouseDown: function() {
+                this.initConstraints();
+                this.resetConstraints();
+        },
+        clickValidator: function(e) {
+            if(!this.column.hidden) {
+                var target = YAHOO.util.Event.getTarget(e);
+                return ( this.isValidHandleChild(target) &&
+                            (this.id == this.handleElId ||
+                                this.DDM.handleWasClicked(target, this.id)) );
+            }
+        },
+        onDragOver: function(ev, id) {
+            // Validate target
+            var target = this.datatable.getColumn(id);
+            if(target) {
+                var mouseX = YAHOO.util.Event.getPageX(ev),
+                targetX = YAHOO.util.Dom.getX(id),
+                midX = targetX + ((YAHOO.util.Dom.get(id).offsetWidth)/2),
+                currentIndex =  this.column.getTreeIndex(),
+                targetIndex = target.getTreeIndex(),
+                newIndex = targetIndex;
+                
+                
+                if (mouseX < midX) {
+                   YAHOO.util.Dom.setX(this.pointer, targetX);
+                } else {
+                    var thisWidth = parseInt(target.getThEl().offsetWidth, 10);
+                    YAHOO.util.Dom.setX(this.pointer, (targetX + thisWidth));
+                    newIndex++;
+                }
+                if (targetIndex > currentIndex) {
+                    newIndex--;
+                }
+                if(newIndex < 0) {
+                    newIndex = 0;
+                }
+                else if(newIndex > this.datatable.getColumnSet().tree[0].length) {
+                    newIndex = this.datatable.getColumnSet().tree[0].length;
+                }
+                this.newIndex = newIndex;
+            }
+        },
+        onDragDrop: function() {
+            if(YAHOO.lang.isNumber(this.newIndex) && (this.newIndex !== this.column.getTreeIndex())) {
+                var oDataTable = this.datatable;
+                oDataTable._oChainRender.stop();
+                var aColumnDefs = oDataTable._oColumnSet.getDefinitions();
+                var oColumn = aColumnDefs.splice(this.column.getTreeIndex(),1)[0];
+                aColumnDefs.splice(this.newIndex, 0, oColumn);
+                oDataTable._initColumnSet(aColumnDefs);
+                oDataTable._initTheadEls();
+                oDataTable.render();
+                oDataTable.fireEvent("columnReorderEvent");
+            }
+        },
+        endDrag: function() {
+            this.newIndex = null;
+            YAHOO.util.Dom.setStyle(this.pointer, 'display', 'none');
+        }
+    });
+}
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * ColumnResizer subclasses DragDrop to support resizeable Columns.
+ *
+ * @namespace YAHOO.util
+ * @class ColumnResizer
+ * @extends YAHOO.util.DDProxy
+ * @constructor
+ * @param oDataTable {YAHOO.widget.DataTable} DataTable instance.
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @param elTh {HTMLElement} TH element reference.
+ * @param sHandleElId {String} DOM ID of the handle element that causes the resize.
+ * @param elProxy {HTMLElement} Resizer proxy element.
+ */
+YAHOO.util.ColumnResizer = function(oDataTable, oColumn, elTh, sHandleId, elProxy) {
+    if(oDataTable && oColumn && elTh && sHandleId) {
+        this.datatable = oDataTable;
+        this.column = oColumn;
+        this.headCell = elTh;
+        this.headCellLiner = elTh.firstChild;
+        this.init(sHandleId, sHandleId, {dragOnly:true, dragElId: elProxy.id});
+        this.initFrame(); // Needed for proxy
+    }
+    else {
+        YAHOO.log("Column resizer could not be created","warn",oDataTable.toString());
+    }
+};
+
+if(YAHOO.util.DD) {
+    YAHOO.extend(YAHOO.util.ColumnResizer, YAHOO.util.DDProxy, {
+        /////////////////////////////////////////////////////////////////////////////
+        //
+        // Public methods
+        //
+        /////////////////////////////////////////////////////////////////////////////
+        /**
+         * Resets resizer element.
+         *
+         * @method resetResizerEl
+         */
+        resetResizerEl : function() {
+            var resizerStyle = YAHOO.util.Dom.get(this.handleElId).style;
+            resizerStyle.left = "auto";
+            resizerStyle.right = 0;
+            resizerStyle.top = "auto";
+            resizerStyle.bottom = 0;
+        },
+    
+        /////////////////////////////////////////////////////////////////////////////
+        //
+        // Public DOM event handlers
+        //
+        /////////////////////////////////////////////////////////////////////////////
+    
+        /**
+         * Handles mouseup events on the Column resizer.
+         *
+         * @method onMouseUp
+         * @param e {string} The mouseup event
+         */
+        onMouseUp : function(e) {
+            this.resetResizerEl();
+            
+            var el = this.headCell.firstChild;
+            var newWidth = el.offsetWidth -
+                (parseInt(YAHOO.util.Dom.getStyle(el,"paddingLeft"),10)|0) -
+                (parseInt(YAHOO.util.Dom.getStyle(el,"paddingRight"),10)|0);
+
+            this.datatable.fireEvent("columnResizeEvent", {column:this.column,target:this.headCell,width:newWidth});
+        },
+    
+        /**
+         * Handles mousedown events on the Column resizer.
+         *
+         * @method onMouseDown
+         * @param e {string} The mousedown event
+         */
+        onMouseDown : function(e) {
+            this.startWidth = this.headCell.firstChild.offsetWidth;
+            this.startX = YAHOO.util.Event.getXY(e)[0];
+            this.nLinerPadding = (parseInt(YAHOO.util.Dom.getStyle(this.headCellLiner,"paddingLeft"),10)|0) +
+                    (parseInt(YAHOO.util.Dom.getStyle(this.headCellLiner,"paddingRight"),10)|0);
+        },
+    
+        /**
+         * Custom clickValidator to ensure Column is not in hidden state.
+         *
+         * @method clickValidator
+         * @param {Event} e
+         * @private
+         */
+        clickValidator : function(e) {
+            if(!this.column.hidden) {
+                var target = YAHOO.util.Event.getTarget(e);
+                return ( this.isValidHandleChild(target) &&
+                            (this.id == this.handleElId ||
+                                this.DDM.handleWasClicked(target, this.id)) );
+            }
+        },
+    
+        /**
+         * Handles drag events on the Column resizer.
+         *
+         * @method onDrag
+         * @param e {string} The drag event
+         */
+        onDrag : function(e) {
+            var newX = YAHOO.util.Event.getXY(e)[0];
+            if(newX > YAHOO.util.Dom.getX(this.headCellLiner)) {
+                var offsetX = newX - this.startX;
+                var newWidth = this.startWidth + offsetX - this.nLinerPadding;
+                this.datatable.setColumnWidth(this.column, newWidth);
+            }
+        }
+    });
+}
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * A RecordSet defines and manages a set of Records.
+ *
+ * @namespace YAHOO.widget
+ * @class RecordSet
+ * @param data {Object || Object[]} An object literal or an array of data.
+ * @constructor
+ */
+YAHOO.widget.RecordSet = function(data) {
+    // Internal variables
+    this._sId = "yui-rs" + YAHOO.widget.RecordSet._nCount;
+    YAHOO.widget.RecordSet._nCount++;
+    this._records = [];
+    //this._length = 0;
+
+    if(data) {
+        if(YAHOO.lang.isArray(data)) {
+            this.addRecords(data);
+        }
+        else if(data.constructor == Object) {
+            this.addRecord(data);
+        }
+    }
+
+    /**
+     * Fired when a new Record is added to the RecordSet.
+     *
+     * @event recordAddEvent
+     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
+     * @param oArgs.data {Object} Data added.
+     */
+    this.createEvent("recordAddEvent");
+
+    /**
+     * Fired when multiple Records are added to the RecordSet at once.
+     *
+     * @event recordsAddEvent
+     * @param oArgs.records {YAHOO.widget.Record[]} An array of Record instances.
+     * @param oArgs.data {Object[]} Data added.
+     */
+    this.createEvent("recordsAddEvent");
+
+    /**
+     * Fired when a Record is set in the RecordSet.
+     *
+     * @event recordSetEvent
+     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
+     * @param oArgs.data {Object} Data added.
+     */
+    this.createEvent("recordSetEvent");
+
+    /**
+     * Fired when multiple Records are set in the RecordSet at once.
+     *
+     * @event recordsSetEvent
+     * @param oArgs.records {YAHOO.widget.Record[]} An array of Record instances.
+     * @param oArgs.data {Object[]} Data added.
+     */
+    this.createEvent("recordsSetEvent");
+
+    /**
+     * Fired when a Record is updated with new data.
+     *
+     * @event recordUpdateEvent
+     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
+     * @param oArgs.newData {Object} New data.
+     * @param oArgs.oldData {Object} Old data.
+     */
+    this.createEvent("recordUpdateEvent");
+    
+    /**
+     * Fired when a Record is deleted from the RecordSet.
+     *
+     * @event recordDeleteEvent
+     * @param oArgs.data {Object} A copy of the data held by the Record,
+     * or an array of data object literals if multiple Records were deleted at once.
+     * @param oArgs.index {Object} Index of the deleted Record.
+     */
+    this.createEvent("recordDeleteEvent");
+
+    /**
+     * Fired when multiple Records are deleted from the RecordSet at once.
+     *
+     * @event recordsDeleteEvent
+     * @param oArgs.data {Object[]} An array of data object literals copied
+     * from the Records.
+     * @param oArgs.index {Object} Index of the first deleted Record.
+     */
+    this.createEvent("recordsDeleteEvent");
+    
+    /**
+     * Fired when all Records are deleted from the RecordSet at once.
+     *
+     * @event resetEvent
+     */
+    this.createEvent("resetEvent");
+
+    /**
+     * @event keyUpdateEvent    
+     * @deprecated Use recordValueUpdateEvent     
+     */
+    this.createEvent("keyUpdateEvent");
+    /**
+     * Fired when a Record value is updated with new data.
+     *
+     * @event recordValueUpdateEvent
+     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
+     * @param oArgs.key {String} The updated key.
+     * @param oArgs.newData {Object} New data.
+     * @param oArgs.oldData {Object} Old data.
+     *
+     */
+    this.createEvent("recordValueUpdateEvent");
+
+    YAHOO.log("RecordSet initialized", "info", this.toString());
+};
+
+/**
+ * Internal class variable to name multiple Recordset instances.
+ *
+ * @property RecordSet._nCount
+ * @type Number
+ * @private
+ * @static
+ */
+YAHOO.widget.RecordSet._nCount = 0;
+
+YAHOO.widget.RecordSet.prototype = {
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Private member variables
+    //
+    /////////////////////////////////////////////////////////////////////////////
+    /**
+     * Unique String identifier assigned at instantiation.
+     *
+     * @property _sId
+     * @type String
+     * @private
+     */
+    _sId : null,
+
+    /**
+     * Internal counter of how many Records are in the RecordSet.
+     *
+     * @property _length
+     * @type Number
+     * @private
+     * @deprecated No longer used
+     */
+    //_length : null,
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Private methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Adds one Record to the RecordSet at the given index. If index is null,
+     * then adds the Record to the end of the RecordSet.
+     *
+     * @method _addRecord
+     * @param oData {Object} An object literal of data.
+     * @param index {Number} (optional) Position index.
+     * @return {YAHOO.widget.Record} A Record instance.
+     * @private
+     */
+    _addRecord : function(oData, index) {
+        var oRecord = new YAHOO.widget.Record(oData);
+        
+        if(YAHOO.lang.isNumber(index) && (index > -1)) {
+            this._records.splice(index,0,oRecord);
+        }
+        else {
+            //index = this.getLength();
+            //this._records[index] = oRecord;
+            this._records[this._records.length] = oRecord;
+        }
+        //this._length++;
+        return oRecord;
+    },
+
+    /**
+     * Sets/replaces one Record to the RecordSet at the given index.  Existing
+     * Records with higher indexes are not shifted.  If no index specified, the
+     * Record is added to the end of the RecordSet.
+     *
+     * @method _setRecord
+     * @param oData {Object} An object literal of data.
+     * @param index {Number} (optional) Position index.
+     * @return {YAHOO.widget.Record} A Record instance.
+     * @private
+     */
+    _setRecord : function(oData, index) {
+        if (!YAHOO.lang.isNumber(index) || index < 0) {
+            index = this._records.length;
+        }
+        return (this._records[index] = new YAHOO.widget.Record(oData));
+        /*
+        if(YAHOO.lang.isNumber(index) && (index > -1)) {
+            this._records[index] = oRecord;
+            if((index+1) > this.getLength()) {
+                this._length = index+1;
+            }
+        }
+        else {
+            this._records[this.getLength()] = oRecord;
+            this._length++;
+        }
+        return oRecord;
+        */
+    },
+
+    /**
+     * Deletes Records from the RecordSet at the given index. If range is null,
+     * then only one Record is deleted.
+     *
+     * @method _deleteRecord
+     * @param index {Number} Position index.
+     * @param range {Number} (optional) How many Records to delete
+     * @private
+     */
+    _deleteRecord : function(index, range) {
+        if(!YAHOO.lang.isNumber(range) || (range < 0)) {
+            range = 1;
+        }
+        this._records.splice(index, range);
+        //this._length = this._length - range;
+    },
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns unique name of the RecordSet instance.
+     *
+     * @method getId
+     * @return {String} Unique name of the RecordSet instance.
+     */
+    getId : function() {
+        return this._sId;
+    },
+
+    /**
+     * Public accessor to the unique name of the RecordSet instance.
+     *
+     * @method toString
+     * @return {String} Unique name of the RecordSet instance.
+     */
+    toString : function() {
+        return "RecordSet instance " + this._sId;
+    },
+
+    /**
+     * Returns the number of Records held in the RecordSet.
+     *
+     * @method getLength
+     * @return {Number} Number of records in the RecordSet.
+     */
+    getLength : function() {
+            //return this._length;
+            return this._records.length;
+    },
+
+    /**
+     * Returns Record by ID or RecordSet position index.
+     *
+     * @method getRecord
+     * @param record {YAHOO.widget.Record | Number | String} Record instance,
+     * RecordSet position index, or Record ID.
+     * @return {YAHOO.widget.Record} Record object.
+     */
+    getRecord : function(record) {
+        var i;
+        if(record instanceof YAHOO.widget.Record) {
+            for(i=0; i<this._records.length; i++) {
+                if(this._records[i] && (this._records[i]._sId === record._sId)) {
+                    return record;
+                }
+            }
+        }
+        else if(YAHOO.lang.isNumber(record)) {
+            if((record > -1) && (record < this.getLength())) {
+                return this._records[record];
+            }
+        }
+        else if(YAHOO.lang.isString(record)) {
+            for(i=0; i<this._records.length; i++) {
+                if(this._records[i] && (this._records[i]._sId === record)) {
+                    return this._records[i];
+                }
+            }
+        }
+        // Not a valid Record for this RecordSet
+        return null;
+
+    },
+
+    /**
+     * Returns an array of Records from the RecordSet.
+     *
+     * @method getRecords
+     * @param index {Number} (optional) Recordset position index of which Record to
+     * start at.
+     * @param range {Number} (optional) Number of Records to get.
+     * @return {YAHOO.widget.Record[]} Array of Records starting at given index and
+     * length equal to given range. If index is not given, all Records are returned.
+     */
+    getRecords : function(index, range) {
+        if(!YAHOO.lang.isNumber(index)) {
+            return this._records;
+        }
+        if(!YAHOO.lang.isNumber(range)) {
+            return this._records.slice(index);
+        }
+        return this._records.slice(index, index+range);
+    },
+
+    /**
+     * Returns a boolean indicating whether Records exist in the RecordSet at the
+     * specified index range.  Returns true if and only if a Record exists at each
+     * index in the range.
+     * @method hasRecords
+     * @param index
+     * @param range
+     * @return {Boolean} true if all indices are populated in the RecordSet
+     */
+    hasRecords : function (index, range) {
+        var recs = this.getRecords(index,range);
+        for (var i = 0; i < range; ++i) {
+            if (typeof recs[i] === 'undefined') {
+                return false;
+            }
+        }
+        return true;
+    },
+
+    /**
+     * Returns current position index for the given Record.
+     *
+     * @method getRecordIndex
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @return {Number} Record's RecordSet position index.
+     */
+
+    getRecordIndex : function(oRecord) {
+        if(oRecord) {
+            for(var i=this._records.length-1; i>-1; i--) {
+                if(this._records[i] && oRecord.getId() === this._records[i].getId()) {
+                    return i;
+                }
+            }
+        }
+        return null;
+
+    },
+
+    /**
+     * Adds one Record to the RecordSet at the given index. If index is null,
+     * then adds the Record to the end of the RecordSet.
+     *
+     * @method addRecord
+     * @param oData {Object} An object literal of data.
+     * @param index {Number} (optional) Position index.
+     * @return {YAHOO.widget.Record} A Record instance.
+     */
+    addRecord : function(oData, index) {
+        if(oData && (oData.constructor == Object)) {
+            var oRecord = this._addRecord(oData, index);
+            this.fireEvent("recordAddEvent",{record:oRecord,data:oData});
+            YAHOO.log("Added Record at index " + index +
+                    " with data " + YAHOO.lang.dump(oData), "info", this.toString());
+            return oRecord;
+        }
+        else {
+            YAHOO.log("Could not add Record with data" +
+                    YAHOO.lang.dump(oData), "info", this.toString());
+            return null;
+        }
+    },
+
+    /**
+     * Adds multiple Records at once to the RecordSet at the given index with the
+     * given object literal data. If index is null, then the new Records are
+     * added to the end of the RecordSet.
+     *
+     * @method addRecords
+     * @param aData {Object[]} An object literal data or an array of data object literals.
+     * @param index {Number} (optional) Position index.
+     * @return {YAHOO.widget.Record[]} An array of Record instances.
+     */
+    addRecords : function(aData, index) {
+        if(YAHOO.lang.isArray(aData)) {
+            var newRecords = [];
+            // Can't go backwards bc we need to preserve order
+            for(var i=0; i<aData.length; i++) {
+                if(aData[i] && (aData[i].constructor == Object)) {
+                    var record = this._addRecord(aData[i], index);
+                    newRecords.push(record);
+                }
+           }
+            this.fireEvent("recordsAddEvent",{records:newRecords,data:aData});
+            YAHOO.log("Added " + newRecords.length + " Record(s) at index " + index +
+                    " with data " + YAHOO.lang.dump(aData), "info", this.toString());
+           return newRecords;
+        }
+        else if(aData && (aData.constructor == Object)) {
+            var oRecord = this._addRecord(aData);
+            this.fireEvent("recordsAddEvent",{records:[oRecord],data:aData});
+            YAHOO.log("Added 1 Record at index " + index +
+                    " with data " + YAHOO.lang.dump(aData), "info", this.toString());
+            return oRecord;
+        }
+        else {
+            YAHOO.log("Could not add Records with data " +
+                    YAHOO.lang.dump(aData), "info", this.toString());
+            return null;
+        }
+    },
+
+    /**
+     * Sets or replaces one Record to the RecordSet at the given index. Unlike
+     * addRecord, an existing Record at that index is not shifted to preserve it.
+     * If no index is specified, it adds the Record to the end of the RecordSet.
+     *
+     * @method setRecord
+     * @param oData {Object} An object literal of data.
+     * @param index {Number} (optional) Position index.
+     * @return {YAHOO.widget.Record} A Record instance.
+     */
+    setRecord : function(oData, index) {
+        if(oData && (oData.constructor == Object)) {
+            var oRecord = this._setRecord(oData, index);
+            this.fireEvent("recordSetEvent",{record:oRecord,data:oData});
+            YAHOO.log("Set Record at index " + index +
+                    " with data " + YAHOO.lang.dump(oData), "info", this.toString());
+            return oRecord;
+        }
+        else {
+            YAHOO.log("Could not set Record with data" +
+                    YAHOO.lang.dump(oData), "info", this.toString());
+            return null;
+        }
+    },
+
+    /**
+     * Sets or replaces multiple Records at once to the RecordSet with the given
+     * data, starting at the given index. If index is not specified, then the new
+     * Records are added to the end of the RecordSet.
+     *
+     * @method setRecords
+     * @param aData {Object[]} An array of object literal data.
+     * @param index {Number} (optional) Position index.
+     * @return {YAHOO.widget.Record[]} An array of Record instances.
+     */
+    setRecords : function(aData, index) {
+        var Rec   = YAHOO.widget.Record,
+            a     = YAHOO.lang.isArray(aData) ? aData : [aData],
+            added = [],
+            i = 0, l = a.length, j = 0;
+
+        index = parseInt(index,10)|0;
+
+        for(; i < l; ++i) {
+            if (typeof a[i] === 'object' && a[i]) {
+                added[j++] = this._records[index + i] = new Rec(a[i]);
+            }
+        }
+
+        this.fireEvent("recordsSet",{records:added,data:aData});
+        YAHOO.log("Set "+j+" Record(s) at index "+index, "info",
+                  this.toString());
+
+        if (a.length && !added.length) {
+            YAHOO.log("Could not set Records with data " +
+                    YAHOO.lang.dump(aData), "info", this.toString());
+        }
+
+        return added.length > 1 ? added : added[0];
+    },
+
+    /**
+     * Updates given Record with given data.
+     *
+     * @method updateRecord
+     * @param record {YAHOO.widget.Record | Number | String} A Record instance,
+     * a RecordSet position index, or a Record ID.
+     * @param oData {Object} Object literal of new data.
+     * @return {YAHOO.widget.Record} Updated Record, or null.
+     */
+    updateRecord : function(record, oData) {
+        var oRecord = this.getRecord(record);
+        if(oRecord && oData && (oData.constructor == Object)) {
+            // Copy data from the Record for the event that gets fired later
+            var oldData = {};
+            for(var key in oRecord._oData) {
+                oldData[key] = oRecord._oData[key];
+            }
+            oRecord._oData = oData;
+            this.fireEvent("recordUpdateEvent",{record:oRecord,newData:oData,oldData:oldData});
+            YAHOO.log("Record at index " + this.getRecordIndex(oRecord) +
+                    " updated with data " + YAHOO.lang.dump(oData), "info", this.toString());
+            return oRecord;
+        }
+        else {
+            YAHOO.log("Could not update Record " + record, "error", this.toString());
+            return null;
+        }
+    },
+
+    /**
+     * @method updateKey
+     * @deprecated Use updateRecordValue
+     */
+    updateKey : function(record, sKey, oData) {
+        this.updateRecordValue(record, sKey, oData);
+    },
+    /**
+     * Sets given Record at given key to given data.
+     *
+     * @method updateRecordValue
+     * @param record {YAHOO.widget.Record | Number | String} A Record instance,
+     * a RecordSet position index, or a Record ID.
+     * @param sKey {String} Key name.
+     * @param oData {Object} New data.
+     */
+    updateRecordValue : function(record, sKey, oData) {
+        var oRecord = this.getRecord(record);
+        if(oRecord) {
+            var oldData = null;
+            var keyValue = oRecord._oData[sKey];
+            // Copy data from the Record for the event that gets fired later
+            if(keyValue && keyValue.constructor == Object) {
+                oldData = {};
+                for(var key in keyValue) {
+                    oldData[key] = keyValue[key];
+                }
+            }
+            // Copy by value
+            else {
+                oldData = keyValue;
+            }
+
+            oRecord._oData[sKey] = oData;
+            this.fireEvent("keyUpdateEvent",{record:oRecord,key:sKey,newData:oData,oldData:oldData});
+            this.fireEvent("recordValueUpdateEvent",{record:oRecord,key:sKey,newData:oData,oldData:oldData});
+            YAHOO.log("Key \"" + sKey +
+                    "\" for Record at index " + this.getRecordIndex(oRecord) +
+                    " updated to \"" + YAHOO.lang.dump(oData) + "\"", "info", this.toString());
+        }
+        else {
+            YAHOO.log("Could not update key " + sKey + " for Record " + record, "error", this.toString());
+        }
+    },
+
+    /**
+     * Replaces all Records in RecordSet with new object literal data.
+     *
+     * @method replaceRecords
+     * @param data {Object || Object[]} An object literal of data or an array of
+     * data object literals.
+     * @return {YAHOO.widget.Record || YAHOO.widget.Record[]} A Record instance or
+     * an array of Records.
+     */
+    replaceRecords : function(data) {
+        this.reset();
+        return this.addRecords(data);
+    },
+
+    /**
+     * Sorts all Records by given function. Records keep their unique IDs but will
+     * have new RecordSet position indexes.
+     *
+     * @method sortRecords
+     * @param fnSort {Function} Reference to a sort function.
+     * @param desc {Boolean} True if sort direction is descending, false if sort
+     * direction is ascending.
+     * @return {YAHOO.widget.Record[]} Sorted array of Records.
+     */
+    sortRecords : function(fnSort, desc) {
+        return this._records.sort(function(a, b) {return fnSort(a, b, desc);});
+    },
+
+    /**
+     * Reverses all Records, so ["one", "two", "three"] becomes ["three", "two", "one"].
+     *
+     * @method reverseRecords
+     * @return {YAHOO.widget.Record[]} Reverse-sorted array of Records.
+     */
+    reverseRecords : function() {
+        return this._records.reverse();
+    },
+
+    /**
+     * Removes the Record at the given position index from the RecordSet. If a range
+     * is also provided, removes that many Records, starting from the index. Length
+     * of RecordSet is correspondingly shortened.
+     *
+     * @method deleteRecord
+     * @param index {Number} Record's RecordSet position index.
+     * @param range {Number} (optional) How many Records to delete.
+     * @return {Object} A copy of the data held by the deleted Record.
+     */
+    deleteRecord : function(index) {
+        if(YAHOO.lang.isNumber(index) && (index > -1) && (index < this.getLength())) {
+            // Copy data from the Record for the event that gets fired later
+            var oData = YAHOO.widget.DataTable._cloneObject(this.getRecord(index).getData());
+            
+            this._deleteRecord(index);
+            this.fireEvent("recordDeleteEvent",{data:oData,index:index});
+            YAHOO.log("Record deleted at index " + index +
+                    " and containing data " + YAHOO.lang.dump(oData), "info", this.toString());
+            return oData;
+        }
+        else {
+            YAHOO.log("Could not delete Record at index " + index, "error", this.toString());
+            return null;
+        }
+    },
+
+    /**
+     * Removes the Record at the given position index from the RecordSet. If a range
+     * is also provided, removes that many Records, starting from the index. Length
+     * of RecordSet is correspondingly shortened.
+     *
+     * @method deleteRecords
+     * @param index {Number} Record's RecordSet position index.
+     * @param range {Number} (optional) How many Records to delete.
+     * @return {Object[]} An array of copies of the data held by the deleted Records.     
+     */
+    deleteRecords : function(index, range) {
+        if(!YAHOO.lang.isNumber(range)) {
+            range = 1;
+        }
+        if(YAHOO.lang.isNumber(index) && (index > -1) && (index < this.getLength())) {
+            var recordsToDelete = this.getRecords(index, range);
+            // Copy data from each Record for the event that gets fired later
+            var deletedData = [];
+            
+            for(var i=0; i<recordsToDelete.length; i++) {
+                deletedData[deletedData.length] = YAHOO.widget.DataTable._cloneObject(recordsToDelete[i]);
+            }
+            this._deleteRecord(index, range);
+
+            this.fireEvent("recordsDeleteEvent",{data:deletedData,index:index});
+            YAHOO.log(range + "Record(s) deleted at index " + index +
+                    " and containing data " + YAHOO.lang.dump(deletedData), "info", this.toString());
+
+            return deletedData;
+        }
+        else {
+            YAHOO.log("Could not delete Records at index " + index, "error", this.toString());
+            return null;
+        }
+    },
+
+    /**
+     * Deletes all Records from the RecordSet.
+     *
+     * @method reset
+     */
+    reset : function() {
+        this._records = [];
+        //this._length = 0;
+        this.fireEvent("resetEvent");
+        YAHOO.log("All Records deleted from RecordSet", "info", this.toString());
+    }
+};
+
+YAHOO.augment(YAHOO.widget.RecordSet, YAHOO.util.EventProvider);
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * The Record class defines a DataTable record.
+ *
+ * @namespace YAHOO.widget
+ * @class Record
+ * @constructor
+ * @param oConfigs {Object} (optional) Object literal of key/value pairs.
+ */
+YAHOO.widget.Record = function(oLiteral) {
+    this._sId = "yui-rec" + YAHOO.widget.Record._nCount;
+    YAHOO.widget.Record._nCount++;
+    this._oData = {};
+    if(oLiteral && (oLiteral.constructor == Object)) {
+        for(var sKey in oLiteral) {
+            this._oData[sKey] = oLiteral[sKey];
+        }
+    }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Private member variables
+//
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Internal class variable to give unique IDs to Record instances.
+ *
+ * @property Record._nCount
+ * @type Number
+ * @private
+ */
+YAHOO.widget.Record._nCount = 0;
+
+YAHOO.widget.Record.prototype = {
+    /**
+     * Immutable unique ID assigned at instantiation. Remains constant while a
+     * Record's position index can change from sorting.
+     *
+     * @property _sId
+     * @type String
+     * @private
+     */
+    _sId : null,
+
+    /**
+     * Holds data for the Record in an object literal.
+     *
+     * @property _oData
+     * @type Object
+     * @private
+     */
+    _oData : null,
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public member variables
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns unique ID assigned at instantiation.
+     *
+     * @method getId
+     * @return String
+     */
+    getId : function() {
+        return this._sId;
+    },
+
+    /**
+     * Returns data for the Record for a key if given, or the entire object
+     * literal otherwise.
+     *
+     * @method getData
+     * @param sKey {String} (Optional) The key to retrieve a single data value.
+     * @return Object
+     */
+    getData : function(sKey) {
+        if(YAHOO.lang.isString(sKey)) {
+            return this._oData[sKey];
+        }
+        else {
+            return this._oData;
+        }
+    },
+
+    /**
+     * Sets given data at the given key. Use the RecordSet method setValue to trigger
+     * events. 
+     *
+     * @method setData
+     * @param sKey {String} The key of the new value.
+     * @param oData {MIXED} The new value.
+     */
+    setData : function(sKey, oData) {
+        this._oData[sKey] = oData;
+    }
+};
+/**
+ * The Paginator widget provides a set of controls to navigate through paged
+ * data.
+ *
+ * @namespace YAHOO.widget
+ * @class Paginator
+ * @uses YAHOO.util.EventProvider
+ * @uses YAHOO.util.AttributeProvider
+ *
+ * @constructor
+ * @param config {Object} Object literal to set instance and ui component
+ * configuration.
+ */
+YAHOO.widget.Paginator = function (config) {
+    var UNLIMITED = YAHOO.widget.Paginator.VALUE_UNLIMITED,
+        lang      = YAHOO.lang,
+        attrib, initialPage, records, perPage;
+
+    config = lang.isObject(config) ? config : {};
+
+    this.initConfig();
+
+    this.initEvents();
+
+    // Set the basic config keys first
+    this.set('rowsPerPage',config.rowsPerPage,true);
+    if (lang.isNumber(config.totalRecords)) {
+        this.set('totalRecords',config.totalRecords,true);
+    }
+    
+    this.initUIComponents();
+
+    // Update the other config values
+    for (attrib in config) {
+        if (lang.hasOwnProperty(config,attrib)) {
+            this.set(attrib,config[attrib],true);
+        }
+    }
+
+    // Calculate the initial record offset
+    initialPage = this.get('initialPage');
+    records     = this.get('totalRecords');
+    perPage     = this.get('rowsPerPage');
+    if (initialPage > 1 && perPage !== UNLIMITED) {
+        var startIndex = (initialPage - 1) * perPage;
+        if (records === UNLIMITED || startIndex < records) {
+            this.set('recordOffset',startIndex,true);
+        }
+    }
+};
+
+
+// Static members
+YAHOO.lang.augmentObject(YAHOO.widget.Paginator, {
+    /**
+     * Incrementing index used to give instances unique ids.
+     * @static
+     * @property id
+     * @type number
+     * @private
+     */
+    id : 0,
+
+    /**
+     * Base of id strings used for ui components.
+     * @static
+     * @property ID_BASE
+     * @type string
+     * @private
+     */
+    ID_BASE : 'yui-pg',
+
+    /**
+     * Used to identify unset, optional configurations, or used explicitly in
+     * the case of totalRecords to indicate unlimited pagination.
+     * @static
+     * @property VALUE_UNLIMITED
+     * @type number
+     * @final
+     */
+    VALUE_UNLIMITED : -1,
+
+    /**
+     * Default template used by Paginator instances.  Update this if you want
+     * all new Paginators to use a different default template.
+     * @static
+     * @property TEMPLATE_DEFAULT
+     * @type string
+     */
+    TEMPLATE_DEFAULT : "{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}",
+
+    /**
+     * Common alternate pagination format, including page links, links for
+     * previous, next, first and last pages as well as a rows-per-page
+     * dropdown.  Offered as a convenience.
+     * @static
+     * @property TEMPLATE_ROWS_PER_PAGE
+     * @type string
+     */
+    TEMPLATE_ROWS_PER_PAGE : "{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
+
+},true);
+
+
+// Instance members and methods
+YAHOO.widget.Paginator.prototype = {
+
+    // Instance members
+
+    /**
+     * Array of nodes in which to render pagination controls.  This is set via
+     * the "containers" attribute.
+     * @property _containers
+     * @type Array(HTMLElement)
+     * @private
+     */
+    _containers : [],
+
+
+
+
+    // Instance methods
+
+    /**
+     * Initialize the Paginator's attributes (see YAHOO.util.Element class
+     * AttributeProvider).
+     * @method initConfig
+     * @private
+     */
+    initConfig : function () {
+
+        var UNLIMITED = YAHOO.widget.Paginator.VALUE_UNLIMITED,
+            l         = YAHOO.lang;
+
+        /**
+         * REQUIRED. Number of records constituting a "page"
+         * @attribute rowsPerPage
+         * @type integer
+         */
+        this.setAttributeConfig('rowsPerPage', {
+            value     : 0,
+            validator : l.isNumber
+        });
+
+        /**
+         * REQUIRED. Node references or ids of nodes in which to render the
+         * pagination controls.
+         * @attribute containers
+         * @type {string|HTMLElement|Array(string|HTMLElement)}
+         */
+        this.setAttributeConfig('containers', {
+            value     : null,
+            writeOnce : true,
+            validator : function (val) {
+                if (!l.isArray(val)) {
+                    val = [val];
+                }
+                for (var i = 0, len = val.length; i < len; ++i) {
+                    if (l.isString(val[i]) || 
+                        (l.isObject(val[i]) && val[i].nodeType === 1)) {
+                        continue;
+                    }
+                    return false;
+                }
+                return true;
+            },
+            method : function (val) {
+                val = YAHOO.util.Dom.get(val);
+                if (!l.isArray(val)) {
+                    val = [val];
+                }
+                this._containers = val;
+            }
+        });
+
+        /**
+         * Total number of records to paginate through
+         * @attribute totalRecords
+         * @type integer
+         * @default 0
+         */
+        this.setAttributeConfig('totalRecords', {
+            value     : 0,
+            validator : l.isNumber
+        });
+
+        /**
+         * Zero based index of the record considered first on the current page.
+         * For page based interactions, don't modify this attribute directly;
+         * use setPage(n).
+         * @attribute recordOffset
+         * @type integer
+         * @default 0
+         */
+        this.setAttributeConfig('recordOffset', {
+            value     : 0,
+            validator : function (val) {
+                var total = this.get('totalRecords');
+                if (l.isNumber(val)) {
+                    return total === UNLIMITED || total > val;
+                }
+
+                return false;
+            }
+        });
+
+        /**
+         * Page to display on initial paint
+         * @attribute initialPage
+         * @type integer
+         * @default 1
+         */
+        this.setAttributeConfig('initialPage', {
+            value     : 1,
+            validator : l.isNumber
+        });
+
+        /**
+         * Template used to render controls.  The string will be used as
+         * innerHTML on all specified container nodes.  Bracketed keys
+         * (e.g. {pageLinks}) in the string will be replaced with an instance
+         * of the so named ui component.
+         * @see Paginator.TEMPLATE_DEFAULT
+         * @see Paginator.TEMPLATE_ROWS_PER_PAGE
+         * @attribute template
+         * @type string
+         */
+        this.setAttributeConfig('template', {
+            value : YAHOO.widget.Paginator.TEMPLATE_DEFAULT,
+            validator : l.isString
+        });
+
+        /**
+         * Class assigned to the element(s) containing pagination controls.
+         * @attribute containerClass
+         * @type string
+         * @default 'yui-pg-container'
+         */
+        this.setAttributeConfig('containerClass', {
+            value : 'yui-pg-container',
+            validator : l.isString
+        });
+
+        /**
+         * Display pagination controls even when there is only one page.  Set
+         * to false to forgo rendering and/or hide the containers when there
+         * is only one page of data.  Note if you are using the rowsPerPage
+         * dropdown ui component, visibility will be maintained as long as the
+         * number of records exceeds the smallest page size.
+         * @attribute alwaysVisible
+         * @type boolean
+         * @default true
+         */
+        this.setAttributeConfig('alwaysVisible', {
+            value : true,
+            validator : l.isBoolean
+        });
+
+        /**
+         * Update the UI immediately upon interaction.  If false, changeRequest
+         * subscribers or other external code will need to explicitly set the
+         * new values in the paginator to trigger repaint.
+         * @attribute updateOnChange
+         * @type boolean
+         * @default false
+         */
+        this.setAttributeConfig('updateOnChange', {
+            value     : false,
+            validator : l.isBoolean
+        });
+
+
+
+        // Read only attributes
+
+        /**
+         * Unique id assigned to this instance
+         * @attribute id
+         * @type integer
+         * @final
+         */
+        this.setAttributeConfig('id', {
+            value    : YAHOO.widget.Paginator.id++,
+            readOnly : true
+        });
+
+        /**
+         * Indicator of whether the DOM nodes have been initially created
+         * @attribute rendered
+         * @type boolean
+         * @final
+         */
+        this.setAttributeConfig('rendered', {
+            value    : false,
+            readOnly : true
+        });
+
+    },
+
+    /**
+     * Initialize registered ui components onto this instance.
+     * @method initUIComponents
+     * @private
+     */
+    initUIComponents : function () {
+        var ui = YAHOO.widget.Paginator.ui;
+        for (var name in ui) {
+            var UIComp = ui[name];
+            if (YAHOO.lang.isObject(UIComp) &&
+                YAHOO.lang.isFunction(UIComp.init)) {
+                UIComp.init(this);
+            }
+        }
+    },
+
+    /**
+     * Initialize this instance's CustomEvents.
+     * @method initEvents
+     * @private
+     */
+    initEvents : function () {
+        this.createEvent('recordOffsetChange');
+        this.createEvent('totalRecordsChange');
+        this.createEvent('rowsPerPageChange');
+        this.createEvent('alwaysVisibleChange');
+
+        this.createEvent('rendered');
+        this.createEvent('changeRequest');
+        this.createEvent('beforeDestroy');
+
+        // Listen for changes to totalRecords and alwaysVisible 
+        this.subscribe('totalRecordsChange',this.updateVisibility,this,true);
+        this.subscribe('alwaysVisibleChange',this.updateVisibility,this,true);
+    },
+
+    /**
+     * Render the pagination controls per the format attribute into the
+     * specified container nodes.
+     * @method render
+     */
+    render : function () {
+        if (this.get('rendered')) {
+            return;
+        }
+
+        // Forgo rendering if only one page and alwaysVisible is off
+        var totalRecords = this.get('totalRecords');
+        if (totalRecords !== YAHOO.widget.Paginator.VALUE_UNLIMITED &&
+            totalRecords < this.get('rowsPerPage') &&
+            !this.get('alwaysVisible')) {
+            return;
+        }
+
+        var Dom            = YAHOO.util.Dom,
+            template       = this.get('template'),
+            containerClass = this.get('containerClass');
+
+        // add marker spans to the template html to indicate drop zones
+        // for ui components
+        template = template.replace(/\{([a-z0-9_ \-]+)\}/gi,
+            '<span class="yui-pg-ui $1"></span>');
+        for (var i = 0, len = this._containers.length; i < len; ++i) {
+            var c       = this._containers[i],
+                // ex. yui-pg0-1 (first paginator, second container)
+                id_base = YAHOO.widget.Paginator.ID_BASE + this.get('id') +
+                          '-' + i;
+
+            if (!c) {
+                continue;
+            }
+            // Hide the container while its contents are rendered
+            c.style.display = 'none';
+
+            Dom.addClass(c,containerClass);
+
+            // Place the template innerHTML
+            c.innerHTML = template;
+
+            // Replace each marker with the ui component's render() output
+            var markers = Dom.getElementsByClassName('yui-pg-ui','span',c);
+
+            for (var j = 0, jlen = markers.length; j < jlen; ++j) {
+                var m      = markers[j],
+                    mp     = m.parentNode,
+                    name   = m.className.replace(/\s*yui-pg-ui\s+/g,''),
+                    UIComp = YAHOO.widget.Paginator.ui[name];
+
+                if (YAHOO.lang.isFunction(UIComp)) {
+                    var comp = new UIComp(this);
+                    if (YAHOO.lang.isFunction(comp.render)) {
+                        mp.replaceChild(comp.render(id_base),m);
+                    }
+                }
+            }
+
+            // Show the container allowing page reflow
+            c.style.display = '';
+        }
+
+        // Set render attribute manually to support its readOnly contract
+        if (this._containers.length) {
+            this.setAttributeConfig('rendered',{value:true});
+
+            this.fireEvent('rendered',this.getState());
+        }
+    },
+
+    /**
+     * Removes controls from the page and unhooks events.
+     * @method destroy
+     */
+    destroy : function () {
+        this.fireEvent('beforeDestroy');
+        for (var i = 0, len = this._containers.length; i < len; ++i) {
+            this._containers[i].innerHTML = '';
+        }
+        this.setAttributeConfig('rendered',{value:false});
+    },
+
+    /**
+     * Hides the containers if there is only one page of data and attribute
+     * alwaysVisible is false.  Conversely, it displays the containers if either
+     * there is more than one page worth of data or alwaysVisible is turned on.
+     * @method updateVisibility
+     */
+    updateVisibility : function (e) {
+        var alwaysVisible = this.get('alwaysVisible');
+        if (e.type === 'alwaysVisibleChange' || !alwaysVisible) {
+            var totalRecords = this.get('totalRecords'),
+                visible = true,
+                rpp = this.get('rowsPerPage'),
+                rppOptions = this.get('rowsPerPageOptions'),
+                i,len;
+
+            if (YAHOO.lang.isArray(rppOptions)) {
+                for (i = 0, len = rppOptions.length; i < len; ++i) {
+                    rpp = Math.min(rpp,rppOptions[i]);
+                }
+            }
+
+            if (totalRecords !== YAHOO.widget.Paginator.VALUE_UNLIMITED &&
+                totalRecords <= rpp) {
+                visible = false;
+            }
+
+            visible = visible || alwaysVisible;
+
+            for (i = 0, len = this._containers.length; i < len; ++i) {
+                YAHOO.util.Dom.setStyle(this._containers[i],'display',
+                    visible ? '' : 'none');
+            }
+        }
+    },
+
+
+
+
+    /**
+     * Get the configured container nodes
+     * @method getContainerNodes
+     * @return {Array} array of HTMLElement nodes
+     */
+    getContainerNodes : function () {
+        return this._containers;
+    },
+
+    /**
+     * Get the total number of pages in the data set according to the current
+     * rowsPerPage and totalRecords values.  If totalRecords is not set, or
+     * set to YAHOO.widget.Paginator.VALUE_UNLIMITED, returns
+     * YAHOO.widget.Paginator.VALUE_UNLIMITED.
+     * @method getTotalPages
+     * @return {number}
+     */
+    getTotalPages : function () {
+        var records = this.get('totalRecords');
+        var perPage = this.get('rowsPerPage');
+
+        // rowsPerPage not set.  Can't calculate
+        if (!perPage) {
+            return null;
+        }
+
+        if (records === YAHOO.widget.Paginator.VALUE_UNLIMITED) {
+            return YAHOO.widget.Paginator.VALUE_UNLIMITED;
+        }
+
+        return Math.ceil(records/perPage);
+    },
+
+    /**
+     * Does the requested page have any records?
+     * @method hasPage
+     * @param page {number} the page in question
+     * @return {boolean}
+     */
+    hasPage : function (page) {
+        if (!YAHOO.lang.isNumber(page) || page < 1) {
+            return false;
+        }
+
+        var totalPages = this.getTotalPages();
+
+        return (totalPages === YAHOO.widget.Paginator.VALUE_UNLIMITED || totalPages >= page);
+    },
+
+    /**
+     * Get the page number corresponding to the current record offset.
+     * @method getCurrentPage
+     * @return {number}
+     */
+    getCurrentPage : function () {
+        var perPage = this.get('rowsPerPage');
+        if (!perPage || !this.get('totalRecords')) {
+            return 0;
+        }
+        return Math.floor(this.get('recordOffset') / perPage) + 1;
+    },
+
+    /**
+     * Are there records on the next page?
+     * @method hasNextPage
+     * @return {boolean}
+     */
+    hasNextPage : function () {
+        var currentPage = this.getCurrentPage(),
+            totalPages  = this.getTotalPages();
+
+        return currentPage && (totalPages === YAHOO.widget.Paginator.VALUE_UNLIMITED || currentPage < totalPages);
+    },
+
+    /**
+     * Get the page number of the next page, or null if the current page is the
+     * last page.
+     * @method getNextPage
+     * @return {number}
+     */
+    getNextPage : function () {
+        return this.hasNextPage() ? this.getCurrentPage() + 1 : null;
+    },
+
+    /**
+     * Is there a page before the current page?
+     * @method hasPreviousPage
+     * @return {boolean}
+     */
+    hasPreviousPage : function () {
+        return (this.getCurrentPage() > 1);
+    },
+
+    /**
+     * Get the page number of the previous page, or null if the current page
+     * is the first page.
+     * @method getPreviousPage
+     * @return {number}
+     */
+    getPreviousPage : function () {
+        return (this.hasPreviousPage() ? this.getCurrentPage() - 1 : 1);
+    },
+
+    /**
+     * Get the start and end record indexes of the specified page.
+     * @method getPageRecords
+     * @param page {number} (optional) The page (current page if not specified)
+     * @return {Array} [start_index, end_index]
+     */
+    getPageRecords : function (page) {
+        if (!YAHOO.lang.isNumber(page)) {
+            page = this.getCurrentPage();
+        }
+
+        var perPage = this.get('rowsPerPage'),
+            records = this.get('totalRecords'),
+            start, end;
+
+        if (!page || !perPage) {
+            return null;
+        }
+
+        start = (page - 1) * perPage;
+        if (records !== YAHOO.widget.Paginator.VALUE_UNLIMITED) {
+            if (start >= records) {
+                return null;
+            }
+            end = Math.min(start + perPage, records) - 1;
+        } else {
+            end = start + perPage - 1;
+        }
+
+        return [start,end];
+    },
+
+    /**
+     * Set the current page to the provided page number if possible.
+     * @method setPage
+     * @param newPage {number} the new page number
+     * @param silent {boolean} whether to forcibly avoid firing the
+     * changeRequest event
+     */
+    setPage : function (page,silent) {
+        if (this.hasPage(page) && page !== this.getCurrentPage()) {
+            if (this.get('updateOnChange') || silent) {
+                this.set('recordOffset', (page - 1) * this.get('rowsPerPage'));
+            } else {
+                this.fireEvent('changeRequest',this.getState({'page':page}));
+            }
+        }
+    },
+
+    /**
+     * Get the number of rows per page.
+     * @method getRowsPerPage
+     * @return {number} the current setting of the rowsPerPage attribute
+     */
+    getRowsPerPage : function () {
+        return this.get('rowsPerPage');
+    },
+
+    /**
+     * Set the number of rows per page.
+     * @method setRowsPerPage
+     * @param rpp {number} the new number of rows per page
+     * @param silent {boolean} whether to forcibly avoid firing the
+     * changeRequest event
+     */
+    setRowsPerPage : function (rpp,silent) {
+        if (YAHOO.lang.isNumber(rpp) && rpp > 0 &&
+            rpp !== this.get('rowsPerPage')) {
+            if (this.get('updateOnChange') || silent) {
+                this.set('rowsPerPage',rpp);
+            } else {
+                this.fireEvent('changeRequest',
+                    this.getState({'rowsPerPage':rpp}));
+            }
+        }
+    },
+
+    /**
+     * Get the total number of records.
+     * @method getTotalRecords
+     * @return {number} the current setting of totalRecords attribute
+     */
+    getTotalRecords : function () {
+        return this.get('totalRecords');
+    },
+
+    /**
+     * Set the total number of records.
+     * @method setTotalRecords
+     * @param total {number} the new total number of records
+     * @param silent {boolean} whether to forcibly avoid firing the changeRequest event
+     */
+    setTotalRecords : function (total,silent) {
+        if (YAHOO.lang.isNumber(total) && total >= 0 &&
+            total !== this.get('totalRecords')) {
+            if (this.get('updateOnChange') || silent) {
+                this.set('totalRecords',total);
+            } else {
+                this.fireEvent('changeRequest',
+                    this.getState({'totalRecords':total}));
+            }
+        }
+    },
+
+    /**
+     * Get the index of the first record on the current page
+     * @method getStartIndex
+     * @return {number} the index of the first record on the current page
+     */
+    getStartIndex : function () {
+        return this.get('recordOffset');
+    },
+
+    /**
+     * Move the record offset to a new starting index.  This will likely cause
+     * the calculated current page to change.  You should probably use setPage.
+     * @method setStartIndex
+     * @param offset {number} the new record offset
+     * @param silent {boolean} whether to forcibly avoid firing the changeRequest event
+     */
+    setStartIndex : function (offset,silent) {
+        if (YAHOO.lang.isNumber(offset) && offset >= 0 &&
+            offset !== this.get('recordOffset')) {
+            if (this.get('updateOnChange') || silent) {
+                this.set('recordOffset',offset);
+            } else {
+                this.fireEvent('changeRequest',
+                    this.getState({'recordOffset':offset}));
+            }
+        }
+    },
+
+    /**
+     * Get an object literal describing the current state of the paginator.  If
+     * an object literal of proposed values is passed, the proposed state will
+     * be returned as an object literal with the following keys:
+     * <ul>
+     * <li>paginator - instance of the Paginator</li>
+     * <li>page - number</li>
+     * <li>totalRecords - number</li>
+     * <li>recordOffset - number</li>
+     * <li>rowsPerPage - number</li>
+     * <li>records - [ start_index, end_index ]</li>
+     * <li>before - (OPTIONAL) { state object literal for current state }</li>
+     * </ul>
+     * @method getState
+     * @return {object}
+     * @param changes {object} OPTIONAL object literal with proposed values
+     * Supported change keys include:
+     * <ul>
+     * <li>rowsPerPage</li>
+     * <li>totalRecords</li>
+     * <li>recordOffset OR</li>
+     * <li>page</li>
+     * </ul>
+     */
+    getState : function (changes) {
+        var UNLIMITED = YAHOO.widget.Paginator.VALUE_UNLIMITED,
+            L         = YAHOO.lang;
+
+        var currentState = {
+            paginator    : this,
+            page         : this.getCurrentPage(),
+            totalRecords : this.get('totalRecords'),
+            recordOffset : this.get('recordOffset'),
+            rowsPerPage  : this.get('rowsPerPage'),
+            records      : this.getPageRecords()
+        };
+
+        if (!changes) {
+            return currentState;
+        }
+
+        var newOffset = currentState.recordOffset;
+        var state = {
+            paginator    : this,
+            before       : currentState,
+
+            rowsPerPage  : changes.rowsPerPage || currentState.rowsPerPage,
+            totalRecords : (L.isNumber(changes.totalRecords) ?
+                                Math.max(changes.totalRecords,UNLIMITED) :
+                                currentState.totalRecords)
+        };
+
+        if (state.totalRecords === 0) {
+            newOffset  = 0;
+            state.page = 0;
+        } else {
+            if (!L.isNumber(changes.recordOffset) &&
+                 L.isNumber(changes.page)) {
+                newOffset = (changes.page - 1) * state.rowsPerPage;
+                if (state.totalRecords === UNLIMITED) {
+                    state.page = changes.page;
+                } else {
+                    // Limit values by totalRecords and rowsPerPage
+                    state.page = Math.min(
+                                    changes.page,
+                                    Math.ceil(state.totalRecords / state.rowsPerPage));
+                    newOffset  = Math.min(newOffset, state.totalRecords - 1);
+                }
+            } else {
+                newOffset  = Math.min(newOffset,state.totalRecords - 1);
+                state.page = Math.floor(newOffset/state.rowsPerPage) + 1;
+            }
+        }
+
+        // Jump offset to top of page
+        state.recordOffset = state.recordOffset ||
+                             newOffset - (newOffset % state.rowsPerPage);
+
+        state.records = [ state.recordOffset,
+                          state.recordOffset + state.rowsPerPage - 1 ];
+
+        if (state.totalRecords !== UNLIMITED &&
+            state.recordOffset < state.totalRecords &&
+            state.records[1] > state.totalRecords - 1) {
+            // limit upper index to totalRecords - 1
+            state.records[1] = state.totalRecords - 1;
+        }
+
+        return state;
+    }
+};
+
+YAHOO.lang.augmentProto(YAHOO.widget.Paginator, YAHOO.util.AttributeProvider);
+
+
+
+
+
+
+// UI Components
+
+(function () {
+
+// UI Component namespace
+YAHOO.widget.Paginator.ui = {};
+
+var Paginator = YAHOO.widget.Paginator,
+    ui        = Paginator.ui,
+    l         = YAHOO.lang;
+
+/**
+ * ui Component to generate the link to jump to the first page.
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class FirstPageLink
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.FirstPageLink = function (p) {
+    this.paginator = p;
+
+    p.createEvent('firstPageLinkLabelChange');
+    p.createEvent('firstPageLinkClassChange');
+
+    p.subscribe('recordOffsetChange',this.update,this,true);
+    p.subscribe('beforeDestroy',this.destroy,this,true);
+
+    // TODO: make this work
+    p.subscribe('firstPageLinkLabelChange',this.update,this,true);
+    p.subscribe('firstPageLinkClassChange',this.update,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param p {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.FirstPageLink.init = function (p) {
+
+    /**
+     * Used as innerHTML for the first page link/span.
+     * @attribute firstPageLinkLabel
+     * @default '<< first'
+     */
+    p.setAttributeConfig('firstPageLinkLabel', {
+        value : '<< first',
+        validator : l.isString
+    });
+
+    /**
+     * CSS class assigned to the link/span
+     * @attribute firstPageLinkClass
+     * @default 'yui-pg-first'
+     */
+    p.setAttributeConfig('firstPageLinkClass', {
+        value : 'yui-pg-first',
+        validator : l.isString
+    });
+};
+
+// Instance members and methods
+ui.FirstPageLink.prototype = {
+
+    /**
+     * The currently placed HTMLElement node
+     * @property current
+     * @type HTMLElement
+     * @private
+     */
+    current   : null,
+
+    /**
+     * Link node
+     * @property link
+     * @type HTMLElement
+     * @private
+     */
+    link      : null,
+
+    /**
+     * Span node (inactive link)
+     * @property span
+     * @type HTMLElement
+     * @private
+     */
+    span      : null,
+
+    /**
+     * Generate the nodes and return the appropriate node given the current
+     * pagination state.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        var p     = this.paginator,
+            c     = p.get('firstPageLinkClass'),
+            label = p.get('firstPageLinkLabel');
+
+        this.link     = document.createElement('a');
+        this.span     = document.createElement('span');
+
+        this.link.id        = id_base + '-first-link';
+        this.link.href      = '#';
+        this.link.className = c;
+        this.link.innerHTML = label;
+        YAHOO.util.Event.on(this.link,'click',this.onClick,this,true);
+
+        this.span.id        = id_base + '-first-span';
+        this.span.className = c;
+        this.span.innerHTML = label;
+
+        this.current = p.get('recordOffset') < 1 ? this.span : this.link;
+        return this.current;
+    },
+
+    /**
+     * Swap the link and span nodes if appropriate.
+     * @method update
+     * @param e {CustomEvent} The calling change event
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+        var par = this.current ? this.current.parentNode : null;
+        if (this.paginator.get('recordOffset') < 1) {
+            if (par && this.current === this.link) {
+                par.replaceChild(this.span,this.current);
+                this.current = this.span;
+            }
+        } else {
+            if (par && this.current === this.span) {
+                par.replaceChild(this.link,this.current);
+                this.current = this.link;
+            }
+        }
+    },
+
+    /**
+     * Removes the onClick listener from the link in preparation for content
+     * removal.
+     * @method destroy
+     * @private
+     */
+    destroy : function () {
+        YAHOO.util.Event.purgeElement(this.link);
+    },
+
+    /**
+     * Listener for the link's onclick event.  Pass new value to setPage method.
+     * @method onClick
+     * @param e {DOMEvent} The click event
+     */
+    onClick : function (e) {
+        YAHOO.util.Event.stopEvent(e);
+        this.paginator.setPage(1);
+    }
+};
+
+
+
+/**
+ * ui Component to generate the link to jump to the last page.
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class LastPageLink
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.LastPageLink = function (p) {
+    this.paginator = p;
+
+    p.createEvent('lastPageLinkLabelChange');
+    p.createEvent('lastPageLinkClassChange');
+
+    p.subscribe('recordOffsetChange',this.update,this,true);
+    p.subscribe('totalRecordsChange',this.update,this,true);
+    p.subscribe('rowsPerPageChange', this.update,this,true);
+    p.subscribe('beforeDestroy',this.destroy,this,true);
+
+    // TODO: make this work
+    p.subscribe('lastPageLinkLabelChange',this.update,this,true);
+    p.subscribe('lastPageLinkClassChange', this.update,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param paginator {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.LastPageLink.init = function (p) {
+
+    /**
+     * Used as innerHTML for the last page link/span.
+     * @attribute lastPageLinkLabel
+     * @default 'last >>'
+     */
+    p.setAttributeConfig('lastPageLinkLabel', {
+        value : 'last >>',
+        validator : l.isString
+    });
+
+    /**
+     * CSS class assigned to the link/span
+     * @attribute lastPageLinkClass
+     * @default 'yui-pg-last'
+     */
+    p.setAttributeConfig('lastPageLinkClass', {
+        value : 'yui-pg-last',
+        validator : l.isString
+    });
+};
+
+ui.LastPageLink.prototype = {
+
+    /**
+     * Currently placed HTMLElement node
+     * @property current
+     * @type HTMLElement
+     * @private
+     */
+    current   : null,
+
+    /**
+     * Link HTMLElement node
+     * @property link
+     * @type HTMLElement
+     * @private
+     */
+    link      : null,
+
+    /**
+     * Span node (inactive link)
+     * @property span
+     * @type HTMLElement
+     * @private
+     */
+    span      : null,
+
+    /**
+     * Empty place holder node for when the last page link is inappropriate to
+     * display in any form (unlimited paging).
+     * @property na
+     * @type HTMLElement
+     * @private
+     */
+    na        : null,
+
+
+    /**
+     * Generate the nodes and return the appropriate node given the current
+     * pagination state.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        var p     = this.paginator,
+            c     = p.get('lastPageLinkClass'),
+            label = p.get('lastPageLinkLabel'),
+            last  = p.getTotalPages();
+
+        this.link = document.createElement('a');
+        this.span = document.createElement('span');
+        this.na   = this.span.cloneNode(false);
+
+        this.link.id        = id_base + '-last-link';
+        this.link.href      = '#';
+        this.link.className = c;
+        this.link.innerHTML = label;
+        YAHOO.util.Event.on(this.link,'click',this.onClick,this,true);
+
+        this.span.id        = id_base + '-last-span';
+        this.span.className = c;
+        this.span.innerHTML = label;
+
+        this.na.id = id_base + '-last-na';
+
+        switch (last) {
+            case Paginator.VALUE_UNLIMITED :
+                    this.current = this.na; break;
+            case p.getCurrentPage() :
+                    this.current = this.span; break;
+            default :
+                    this.current = this.link;
+        }
+
+        return this.current;
+    },
+
+    /**
+     * Swap the link, span, and na nodes if appropriate.
+     * @method update
+     * @param e {CustomEvent} The calling change event (ignored)
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+        var par   = this.current ? this.current.parentNode : null,
+            after = this.link;
+
+        if (par) {
+            switch (this.paginator.getTotalPages()) {
+                case Paginator.VALUE_UNLIMITED :
+                        after = this.na; break;
+                case this.paginator.getCurrentPage() :
+                        after = this.span; break;
+            }
+
+            if (this.current !== after) {
+                par.replaceChild(after,this.current);
+                this.current = after;
+            }
+        }
+    },
+
+    /**
+     * Removes the onClick listener from the link in preparation for content
+     * removal.
+     * @method destroy
+     * @private
+     */
+    destroy : function () {
+        YAHOO.util.Event.purgeElement(this.link);
+    },
+
+    /**
+     * Listener for the link's onclick event.  Passes to setPage method.
+     * @method onClick
+     * @param e {DOMEvent} The click event
+     */
+    onClick : function (e) {
+        YAHOO.util.Event.stopEvent(e);
+        this.paginator.setPage(this.paginator.getTotalPages());
+    }
+};
+
+
+/**
+ * ui Component to generate the link to jump to the previous page.
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class PreviousPageLink
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.PreviousPageLink = function (p) {
+    this.paginator = p;
+
+    p.createEvent('previousPageLinkLabelChange');
+    p.createEvent('previousPageLinkClassChange');
+
+    p.subscribe('recordOffsetChange',this.update,this,true);
+    p.subscribe('beforeDestroy',this.destroy,this,true);
+
+    // TODO: make this work
+    p.subscribe('previousPageLinkLabelChange',this.update,this,true);
+    p.subscribe('previousPageLinkClassChange',this.update,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param p {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.PreviousPageLink.init = function (p) {
+
+    /**
+     * Used as innerHTML for the previous page link/span.
+     * @attribute previousPageLinkLabel
+     * @default '< prev'
+     */
+    p.setAttributeConfig('previousPageLinkLabel', {
+        value : '< prev',
+        validator : l.isString
+    });
+
+    /**
+     * CSS class assigned to the link/span
+     * @attribute previousPageLinkClass
+     * @default 'yui-pg-previous'
+     */
+    p.setAttributeConfig('previousPageLinkClass', {
+        value : 'yui-pg-previous',
+        validator : l.isString
+    });
+};
+
+ui.PreviousPageLink.prototype = {
+
+    /**
+     * Currently placed HTMLElement node
+     * @property current
+     * @type HTMLElement
+     * @private
+     */
+    current   : null,
+
+    /**
+     * Link node
+     * @property link
+     * @type HTMLElement
+     * @private
+     */
+    link      : null,
+
+    /**
+     * Span node (inactive link)
+     * @property span
+     * @type HTMLElement
+     * @private
+     */
+    span      : null,
+
+
+    /**
+     * Generate the nodes and return the appropriate node given the current
+     * pagination state.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        var p     = this.paginator,
+            c     = p.get('previousPageLinkClass'),
+            label = p.get('previousPageLinkLabel');
+
+        this.link     = document.createElement('a');
+        this.span     = document.createElement('span');
+
+        this.link.id        = id_base + '-prev-link';
+        this.link.href      = '#';
+        this.link.className = c;
+        this.link.innerHTML = label;
+        YAHOO.util.Event.on(this.link,'click',this.onClick,this,true);
+
+        this.span.id        = id_base + '-prev-span';
+        this.span.className = c;
+        this.span.innerHTML = label;
+
+        this.current = p.get('recordOffset') < 1 ? this.span : this.link;
+        return this.current;
+    },
+
+    /**
+     * Swap the link and span nodes if appropriate.
+     * @method update
+     * @param e {CustomEvent} The calling change event
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+        var par = this.current ? this.current.parentNode : null;
+        if (this.paginator.get('recordOffset') < 1) {
+            if (par && this.current === this.link) {
+                par.replaceChild(this.span,this.current);
+                this.current = this.span;
+            }
+        } else {
+            if (par && this.current === this.span) {
+                par.replaceChild(this.link,this.current);
+                this.current = this.link;
+            }
+        }
+    },
+
+    /**
+     * Removes the onClick listener from the link in preparation for content
+     * removal.
+     * @method destroy
+     * @private
+     */
+    destroy : function () {
+        YAHOO.util.Event.purgeElement(this.link);
+    },
+
+    /**
+     * Listener for the link's onclick event.  Passes to setPage method.
+     * @method onClick
+     * @param e {DOMEvent} The click event
+     */
+    onClick : function (e) {
+        YAHOO.util.Event.stopEvent(e);
+        this.paginator.setPage(this.paginator.getPreviousPage());
+    }
+};
+
+
+
+/**
+ * ui Component to generate the link to jump to the next page.
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class NextPageLink
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.NextPageLink = function (p) {
+    this.paginator = p;
+
+    p.createEvent('nextPageLinkLabelChange');
+    p.createEvent('nextPageLinkClassChange');
+
+    p.subscribe('recordOffsetChange',this.update,this,true);
+    p.subscribe('totalRecordsChange',this.update,this,true);
+    p.subscribe('rowsPerPageChange', this.update,this,true);
+    p.subscribe('beforeDestroy',this.destroy,this,true);
+
+    // TODO: make this work
+    p.subscribe('nextPageLinkLabelChange', this.update,this,true);
+    p.subscribe('nextPageLinkClassChange', this.update,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param p {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.NextPageLink.init = function (p) {
+
+    /**
+     * Used as innerHTML for the next page link/span.
+     * @attribute nextPageLinkLabel
+     * @default 'next >'
+     */
+    p.setAttributeConfig('nextPageLinkLabel', {
+        value : 'next >',
+        validator : l.isString
+    });
+
+    /**
+     * CSS class assigned to the link/span
+     * @attribute nextPageLinkClass
+     * @default 'yui-pg-next'
+     */
+    p.setAttributeConfig('nextPageLinkClass', {
+        value : 'yui-pg-next',
+        validator : l.isString
+    });
+};
+
+ui.NextPageLink.prototype = {
+
+    /**
+     * Currently placed HTMLElement node
+     * @property current
+     * @type HTMLElement
+     * @private
+     */
+    current   : null,
+
+    /**
+     * Link node
+     * @property link
+     * @type HTMLElement
+     * @private
+     */
+    link      : null,
+
+    /**
+     * Span node (inactive link)
+     * @property span
+     * @type HTMLElement
+     * @private
+     */
+    span      : null,
+
+
+    /**
+     * Generate the nodes and return the appropriate node given the current
+     * pagination state.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        var p     = this.paginator,
+            c     = p.get('nextPageLinkClass'),
+            label = p.get('nextPageLinkLabel'),
+            last  = p.getTotalPages();
+
+        this.link     = document.createElement('a');
+        this.span     = document.createElement('span');
+
+        this.link.id        = id_base + '-next-link';
+        this.link.href      = '#';
+        this.link.className = c;
+        this.link.innerHTML = label;
+        YAHOO.util.Event.on(this.link,'click',this.onClick,this,true);
+
+        this.span.id        = id_base + '-next-span';
+        this.span.className = c;
+        this.span.innerHTML = label;
+
+        this.current = p.getCurrentPage() === last ? this.span : this.link;
+
+        return this.current;
+    },
+
+    /**
+     * Swap the link and span nodes if appropriate.
+     * @method update
+     * @param e {CustomEvent} The calling change event
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+        var last = this.paginator.getTotalPages(),
+            par  = this.current ? this.current.parentNode : null;
+
+        if (this.paginator.getCurrentPage() !== last) {
+            if (par && this.current === this.span) {
+                par.replaceChild(this.link,this.current);
+                this.current = this.link;
+            }
+        } else if (this.current === this.link) {
+            if (par) {
+                par.replaceChild(this.span,this.current);
+                this.current = this.span;
+            }
+        }
+    },
+
+    /**
+     * Removes the onClick listener from the link in preparation for content
+     * removal.
+     * @method destroy
+     * @private
+     */
+    destroy : function () {
+        YAHOO.util.Event.purgeElement(this.link);
+    },
+
+    /**
+     * Listener for the link's onclick event.  Passes to setPage method.
+     * @method onClick
+     * @param e {DOMEvent} The click event
+     */
+    onClick : function (e) {
+        YAHOO.util.Event.stopEvent(e);
+        this.paginator.setPage(this.paginator.getNextPage());
+    }
+};
+
+
+/**
+ * ui Component to generate the page links
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class PageLinks
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.PageLinks = function (p) {
+    this.paginator = p;
+
+    p.createEvent('pageLinkClassChange');
+    p.createEvent('currentPageClassChange');
+    p.createEvent('pageLinksContainerClassChange');
+    p.createEvent('pageLinksChange');
+
+    p.subscribe('recordOffsetChange',this.update,this,true);
+    p.subscribe('pageLinksChange',   this.rebuild,this,true);
+    p.subscribe('totalRecordsChange',this.rebuild,this,true);
+    p.subscribe('rowsPerPageChange', this.rebuild,this,true);
+    p.subscribe('pageLinkClassChange', this.rebuild,this,true);
+    p.subscribe('currentPageClassChange', this.rebuild,this,true);
+    p.subscribe('beforeDestroy',this.destroy,this,true);
+
+    //TODO: Make this work
+    p.subscribe('pageLinksContainerClassChange', this.rebuild,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param p {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.PageLinks.init = function (p) {
+
+    /**
+     * CSS class assigned to each page link/span.
+     * @attribute pageLinkClass
+     * @default 'yui-pg-page'
+     */
+    p.setAttributeConfig('pageLinkClass', {
+        value : 'yui-pg-page',
+        validator : l.isString
+    });
+
+    /**
+     * CSS class assigned to the current page span.
+     * @attribute currentPageClass
+     * @default 'yui-pg-current-page'
+     */
+    p.setAttributeConfig('currentPageClass', {
+        value : 'yui-pg-current-page',
+        validator : l.isString
+    });
+
+    /**
+     * CSS class assigned to the span containing the page links.
+     * @attribute pageLinksContainerClass
+     * @default 'yui-pg-pages'
+     */
+    p.setAttributeConfig('pageLinksContainerClass', {
+        value : 'yui-pg-pages',
+        validator : l.isString
+    });
+
+    /**
+     * Maximum number of page links to display at one time.
+     * @attribute pageLinks
+     * @default 10
+     */
+    p.setAttributeConfig('pageLinks', {
+        value : 10,
+        validator : l.isNumber
+    });
+
+    /**
+     * Function used generate the innerHTML for each page link/span.  The
+     * function receives as parameters the page number and a reference to the
+     * paginator object.
+     * @attribute pageLabelBuilder
+     * @default function (page, paginator) { return page; }
+     */
+    p.setAttributeConfig('pageLabelBuilder', {
+        value : function (page, paginator) { return page; },
+        validator : l.isFunction
+    });
+};
+
+/**
+ * Calculates start and end page numbers given a current page, attempting
+ * to keep the current page in the middle
+ * @static
+ * @method calculateRange
+ * @param {int} currentPage  The current page
+ * @param {int} totalPages   (optional) Maximum number of pages
+ * @param {int} numPages     (optional) Preferred number of pages in range
+ * @return {Array} [start_page_number, end_page_number]
+ */
+ui.PageLinks.calculateRange = function (currentPage,totalPages,numPages) {
+    var UNLIMITED = Paginator.VALUE_UNLIMITED,
+        start, end, delta;
+
+    // Either has no pages, or unlimited pages.  Show none.
+    if (!currentPage || numPages === 0 || totalPages === 0 ||
+        (totalPages === UNLIMITED && numPages === UNLIMITED)) {
+        return [0,-1];
+    }
+
+    // Limit requested pageLinks if there are fewer totalPages
+    if (totalPages !== UNLIMITED) {
+        numPages = numPages === UNLIMITED ?
+                    totalPages :
+                    Math.min(numPages,totalPages);
+    }
+
+    // Determine start and end, trying to keep current in the middle
+    start = Math.max(1,Math.ceil(currentPage - (numPages/2)));
+    if (totalPages === UNLIMITED) {
+        end = start + numPages - 1;
+    } else {
+        end = Math.min(totalPages, start + numPages - 1);
+    }
+
+    // Adjust the start index when approaching the last page
+    delta = numPages - (end - start + 1);
+    start = Math.max(1, start - delta);
+
+    return [start,end];
+};
+
+
+ui.PageLinks.prototype = {
+
+    /**
+     * Current page
+     * @property current
+     * @type number
+     * @private
+     */
+    current     : 0,
+
+    /**
+     * Span node containing the page links
+     * @property container
+     * @type HTMLElement
+     * @private
+     */
+    container   : null,
+
+
+    /**
+     * Generate the nodes and return the container node containing page links
+     * appropriate to the current pagination state.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        var p = this.paginator;
+
+        // Set up container
+        this.container = document.createElement('span');
+        this.container.id        = id_base + '-pages';
+        this.container.className = p.get('pageLinksContainerClass');
+        YAHOO.util.Event.on(this.container,'click',this.onClick,this,true);
+
+        // Call update, flagging a need to rebuild
+        this.update({newValue : null, rebuild : true});
+
+        return this.container;
+    },
+
+    /**
+     * Update the links if appropriate
+     * @method update
+     * @param e {CustomEvent} The calling change event
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+        var p           = this.paginator,
+            currentPage = p.getCurrentPage();
+
+        // Replace content if there's been a change
+        if (this.current !== currentPage || e.rebuild) {
+            var labelBuilder = p.get('pageLabelBuilder'),
+                range        = ui.PageLinks.calculateRange(
+                                currentPage,
+                                p.getTotalPages(),
+                                p.get('pageLinks')),
+                start        = range[0],
+                end          = range[1],
+                content      = '',
+                linkTemplate,i;
+
+            linkTemplate = '<a href="#" class="' + p.get('pageLinkClass') +
+                           '" page="';
+            for (i = start; i <= end; ++i) {
+                if (i === currentPage) {
+                    content +=
+                        '<span class="' + p.get('currentPageClass') + ' ' +
+                                          p.get('pageLinkClass') + '">' +
+                        labelBuilder(i,p) + '</span>';
+                } else {
+                    content +=
+                        linkTemplate + i + '">' + labelBuilder(i,p) + '</a>';
+                }
+            }
+
+            this.container.innerHTML = content;
+        }
+    },
+
+    /**
+     * Force a rebuild of the page links.
+     * @method rebuild
+     * @param e {CustomEvent} The calling change event
+     */
+    rebuild     : function (e) {
+        e.rebuild = true;
+        this.update(e);
+    },
+
+    /**
+     * Removes the onClick listener from the container in preparation for
+     * content removal.
+     * @method destroy
+     * @private
+     */
+    destroy : function () {
+        YAHOO.util.Event.purgeElement(this.container,true);
+    },
+
+    /**
+     * Listener for the container's onclick event.  Looks for qualifying link
+     * clicks, and pulls the page number from the link's page attribute.
+     * Sends link's page attribute to the Paginator's setPage method.
+     * @method onClick
+     * @param e {DOMEvent} The click event
+     */
+    onClick : function (e) {
+        var t = YAHOO.util.Event.getTarget(e);
+        if (t && YAHOO.util.Dom.hasClass(t,
+                        this.paginator.get('pageLinkClass'))) {
+
+            YAHOO.util.Event.stopEvent(e);
+
+            this.paginator.setPage(parseInt(t.getAttribute('page'),10));
+        }
+    }
+
+};
+
+
+/**
+ * ui Component to generate the rows-per-page dropdown
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class RowsPerPageDropdown
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.RowsPerPageDropdown = function (p) {
+    this.paginator = p;
+
+    p.createEvent('rowsPerPageOptionsChange');
+    p.createEvent('rowsPerPageDropdownClassChange');
+
+    p.subscribe('rowsPerPageChange',this.update,this,true);
+    p.subscribe('rowsPerPageOptionsChange',this.rebuild,this,true);
+    p.subscribe('beforeDestroy',this.destroy,this,true);
+
+    // TODO: make this work
+    p.subscribe('rowsPerPageDropdownClassChange',this.rebuild,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param p {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.RowsPerPageDropdown.init = function (p) {
+
+    /**
+     * Array of available rows-per-page sizes.  Converted into select options.
+     * Array values may be positive integers or object literals in the form<br>
+     * { value : NUMBER, text : STRING }
+     * @attribute rowsPerPageOptions
+     * @default []
+     */
+    p.setAttributeConfig('rowsPerPageOptions', {
+        value : [],
+        validator : l.isArray
+    });
+
+    /**
+     * CSS class assigned to the select node
+     * @attribute rowsPerPageDropdownClass
+     * @default 'yui-pg-rpp-options'
+     */
+    p.setAttributeConfig('rowsPerPageDropdownClass', {
+        value : 'yui-pg-rpp-options',
+        validator : l.isString
+    });
+};
+
+ui.RowsPerPageDropdown.prototype = {
+
+    /**
+     * select node
+     * @property select
+     * @type HTMLElement
+     * @private
+     */
+    select  : null,
+
+
+    /**
+     * Generate the select and option nodes and returns the select node.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        this.select = document.createElement('select');
+        this.select.id        = id_base + '-rpp';
+        this.select.className = this.paginator.get('rowsPerPageDropdownClass');
+        this.select.title = 'Rows per page';
+
+        YAHOO.util.Event.on(this.select,'change',this.onChange,this,true);
+
+        this.rebuild();
+
+        return this.select;
+    },
+
+    /**
+     * Select the appropriate option if changed.
+     * @method update
+     * @param e {CustomEvent} The calling change event
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+        var rpp     = this.paginator.get('rowsPerPage'),
+            options = this.select.options,
+            i,len;
+
+        for (i = 0, len = options.length; i < len; ++i) {
+            if (parseInt(options[i].value,10) === rpp) {
+                options[i].selected = true;
+            }
+        }
+    },
+
+
+    /**
+     * (Re)generate the select options.
+     * @method rebuild
+     */
+    rebuild : function (e) {
+        var p       = this.paginator,
+            sel     = this.select,
+            options = p.get('rowsPerPageOptions'),
+            opt_tem = document.createElement('option'),
+            i,len;
+
+        while (sel.firstChild) {
+            sel.removeChild(sel.firstChild);
+        }
+
+        for (i = 0, len = options.length; i < len; ++i) {
+            var node = opt_tem.cloneNode(false),
+                opt  = options[i];
+            node.value = l.isValue(opt.value) ? opt.value : opt;
+            node.innerHTML = l.isValue(opt.text) ? opt.text : opt;
+            sel.appendChild(node);
+        }
+
+        this.update();
+    },
+
+    /**
+     * Removes the onChange listener from the select in preparation for content
+     * removal.
+     * @method destroy
+     * @private
+     */
+    destroy : function () {
+        YAHOO.util.Event.purgeElement(this.select);
+    },
+
+    /**
+     * Listener for the select's onchange event.  Sent to setRowsPerPage method.
+     * @method onChange
+     * @param e {DOMEvent} The change event
+     */
+    onChange : function (e) {
+        this.paginator.setRowsPerPage(
+                parseInt(this.select.options[this.select.selectedIndex].value,10));
+    }
+};
+
+
+
+/**
+ * ui Component to generate the textual report of current pagination status.
+ * E.g. "Now viewing page 1 of 13".
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class CurrentPageReport
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.CurrentPageReport = function (p) {
+    this.paginator = p;
+
+    p.createEvent('pageReportClassChange');
+    p.createEvent('pageReportTemplateChange');
+
+    p.subscribe('recordOffsetChange',this.update,this,true);
+    p.subscribe('totalRecordsChange',this.update,this,true);
+    p.subscribe('rowsPerPageChange', this.update,this,true);
+    p.subscribe('pageReportTemplateChange', this.update,this,true);
+
+    //TODO: make this work
+    p.subscribe('pageReportClassChange', this.update,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param p {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.CurrentPageReport.init = function (p) {
+
+    /**
+     * CSS class assigned to the span containing the info.
+     * @attribute pageReportClass
+     * @default 'yui-pg-current'
+     */
+    p.setAttributeConfig('pageReportClass', {
+        value : 'yui-pg-current',
+        validator : l.isString
+    });
+
+    /**
+     * Used as innerHTML for the span.  Place holders in the form of {name}
+     * will be replaced with the so named value from the key:value map
+     * generated by the function held in the pageReportValueGenerator attribute.
+     * @attribute pageReportTemplate
+     * @default '({currentPage} of {totalPages})'
+     * @see pageReportValueGenerator attribute
+     */
+    p.setAttributeConfig('pageReportTemplate', {
+        value : '({currentPage} of {totalPages})',
+        validator : l.isString
+    });
+
+    /**
+     * Function to generate the value map used to populate the
+     * pageReportTemplate.  The function is passed the Paginator instance as a
+     * parameter.  The default function returns a map with the following keys:
+     * <ul>
+     * <li>currentPage</li>
+     * <li>totalPages</li>
+     * <li>startIndex</li>
+     * <li>endIndex</li>
+     * <li>startRecord</li>
+     * <li>endRecord</li>
+     * <li>totalRecords</li>
+     * </ul>
+     * @attribute pageReportValueGenarator
+     */
+    p.setAttributeConfig('pageReportValueGenerator', {
+        value : function (paginator) {
+            var curPage = paginator.getCurrentPage(),
+                records = paginator.getPageRecords();
+
+            return {
+                'currentPage' : records ? curPage : 0,
+                'totalPages'  : paginator.getTotalPages(),
+                'startIndex'  : records ? records[0] : 0,
+                'endIndex'    : records ? records[1] : 0,
+                'startRecord' : records ? records[0] + 1 : 0,
+                'endRecord'   : records ? records[1] + 1 : 0,
+                'totalRecords': paginator.get('totalRecords')
+            };
+        },
+        validator : l.isFunction
+    });
+};
+
+/**
+ * Replace place holders in a string with the named values found in an
+ * object literal.
+ * @static
+ * @method sprintf
+ * @param template {string} The content string containing place holders
+ * @param values {object} The key:value pairs used to replace the place holders
+ * @return {string}
+ */
+ui.CurrentPageReport.sprintf = function (template, values) {
+    return template.replace(/{([\w\s\-]+)}/g, function (x,key) {
+            return (key in values) ? values[key] : '';
+        });
+};
+
+ui.CurrentPageReport.prototype = {
+
+    /**
+     * Span node containing the formatted info
+     * @property span
+     * @type HTMLElement
+     * @private
+     */
+    span : null,
+
+
+    /**
+     * Generate the span containing info formatted per the pageReportTemplate
+     * attribute.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        this.span = document.createElement('span');
+        this.span.id        = id_base + '-page-report';
+        this.span.className = this.paginator.get('pageReportClass');
+        this.update();
+        
+        return this.span;
+    },
+    
+    /**
+     * Regenerate the content of the span if appropriate. Calls
+     * CurrentPageReport.sprintf with the value of the pageReportTemplate
+     * attribute and the value map returned from pageReportValueGenerator
+     * function.
+     * @method update
+     * @param e {CustomEvent} The calling change event
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+
+        this.span.innerHTML = ui.CurrentPageReport.sprintf(
+            this.paginator.get('pageReportTemplate'),
+            this.paginator.get('pageReportValueGenerator')(this.paginator));
+    }
+};
+
+})();
+/**
  * The DataTable widget provides a progressively enhanced DHTML control for
  * displaying tabular data across A-grade browsers.
  *
  * @module datatable
- * @requires yahoo, dom, event, datasource
- * @optional dragdrop
+ * @requires yahoo, dom, event, element, datasource
+ * @optional connection, dragdrop
  * @title DataTable Widget
  * @beta
  */
@@ -32,28 +4368,33 @@
  * @param oConfigs {object} (optional) Object literal of configuration values.
  */
 YAHOO.widget.DataTable = function(elContainer,aColumnDefs,oDataSource,oConfigs) {
+    var DT = YAHOO.widget.DataTable,
+        DS = YAHOO.util.DataSource;
+
     // Internal vars
-    this._nIndex = YAHOO.widget.DataTable._nCount;
-    this._sName = "instance" + this._nIndex;
-    this.id = "yui-dt"+this._nIndex;
+    this._nIndex = DT._nCount;
+    this._sId = "yui-dt"+this._nIndex;
+    this._oChainRender = new YAHOO.util.Chain();
+    this._oChainSync = new YAHOO.util.Chain();
+    this._oChainRender.subscribe("end",this._sync, this, true);
 
-    // Initialize container element
-    this._initContainerEl(elContainer);
-    if(!this._elContainer) {
-        YAHOO.log("Could not instantiate DataTable due to an invalid container element", "error", this.toString());
+    // Initialize configs
+    this._initConfigs(oConfigs);
+
+    // Initialize DataSource
+    this._initDataSource(oDataSource);
+    if(!this._oDataSource) {
+        YAHOO.log("Could not instantiate DataTable due to an invalid DataSource", "error", this.toString());
         return;
     }
 
-    // Initialize configs
-    this._initConfigs(oConfigs);
-
     // Initialize ColumnSet
     this._initColumnSet(aColumnDefs);
     if(!this._oColumnSet) {
         YAHOO.log("Could not instantiate DataTable due to an invalid ColumnSet", "error", this.toString());
         return;
     }
-    
+
     // Initialize RecordSet
     this._initRecordSet();
     if(!this._oRecordSet) {
@@ -61,58 +4402,1411 @@
         return;
     }
 
-    // Initialize DataSource
-    this._initDataSource(oDataSource);
-    if(!this._oDataSource) {
-        YAHOO.log("Could not instantiate DataTable due to an invalid DataSource", "error", this.toString());
+    // Initialize node templates
+    this._initNodeTemplates();
+
+    // Initialize container element
+    this._initContainerEl(elContainer);
+    if(!this._elContainer) {
+        YAHOO.log("Could not instantiate DataTable due to an invalid container element", "error", this.toString());
         return;
     }
 
-    // Progressive enhancement special case
-    if(this._oDataSource.dataType == YAHOO.util.DataSource.TYPE_HTMLTABLE) {
-        this._oDataSource.sendRequest(this.get("initialRequest"), this._onDataReturnEnhanceTable, this);
+    // Initialize the rest of the DOM elements
+    this._initTableEl();
+    if(!this._elContainer || !this._elThead || !this._elTbody) {
+        YAHOO.log("Could not instantiate DataTable due to an invalid DOM elements", "error", this.toString());
+        return;
     }
-    else {
-        // Initialize DOM elements
-        this._initTableEl();
-        if(!this._elTable || !this._elThead || !this._elTbody) {
-            YAHOO.log("Could not instantiate DataTable due to an invalid DOM elements", "error", this.toString());
-            return;
-        }
 
-        // Call Element's constructor after DOM elements are created
-        // but *before* table is populated with data
-        YAHOO.widget.DataTable.superclass.constructor.call(this, this._elContainer, this._oConfigs);
-        
-        //HACK: Set the Paginator values here via updatePaginator
-        if(this._oConfigs && this._oConfigs.paginator) {
-            this.updatePaginator(this._oConfigs.paginator);
+    // Call Element's constructor after DOM elements are created
+    // but *before* table is populated with data
+    DT.superclass.constructor.call(this, this._elContainer, this._oConfigs);
+
+    // HACK: Set sortedBy values for backward compatibility
+    var oSortedBy = this.get("sortedBy");
+    if(oSortedBy) {
+        if(oSortedBy.dir == "desc") {
+            this._configs.sortedBy.value.dir = DT.CLASS_DESC;
         }
+        else if(oSortedBy.dir == "asc") {
+            this._configs.sortedBy.value.dir = DT.CLASS_ASC;
+        }
+    }
 
-        // Send out for data in an asynchronous request
-        this._oDataSource.sendRequest(this.get("initialRequest"), this.onDataReturnInitializeTable, this);
+    //HACK: Set the paginator values.  Attribute doesn't afford for merging
+    // obj value's keys.  It's all or nothing.  Merge in provided keys.
+    if(this._oConfigs.paginator && !(this._oConfigs.paginator instanceof YAHOO.widget.Paginator)) {
+        // Backward compatibility
+        this.updatePaginator(this._oConfigs.paginator);
     }
 
     // Initialize inline Cell editing
     this._initCellEditorEl();
-
+    
     // Initialize Column sort
     this._initColumnSort();
 
-    // Initialize DOM event listeners
-    this._initDomEvents();
+    // Once per instance
+    YAHOO.util.Event.addListener(document, "click", this._onDocumentClick, this);
 
-    YAHOO.widget.DataTable._nCount++;
-    YAHOO.log("DataTable initialized", "info", this.toString());
+    DT._nCount++;
+    DT._nCurrentCount++;
+    
+    // Send a simple initial request
+    var oCallback = {
+        success : this.onDataReturnSetRows,
+        failure : this.onDataReturnSetRows,
+        scope   : this,
+        argument: {}
+    };
+    if(this.get("initialLoad") === true) {
+        this._oDataSource.sendRequest(this.get("initialRequest"), oCallback);
+    }
+    // Do not send an initial request at all
+    else if(this.get("initialLoad") === false) {
+        this.showTableMessage(DT.MSG_EMPTY, DT.CLASS_EMPTY);
+        this._oChainRender.add({
+            method: function() {
+                if((this instanceof DT) && this._sId && this._bInit) {
+                    this._bInit = false;
+                    this.fireEvent("initEvent");
+                    YAHOO.log("DataTable initialized with no rows", "info", this.toString());
+                }
+            },
+            scope: this
+        });
+        this._oChainRender.run();
+    }
+    // Send an initial request with a custom payload
+    else {
+        var oCustom = this.get("initialLoad");
+        oCallback.argument = oCustom.argument;
+        this._oDataSource.sendRequest(oCustom.request, oCallback);
+    }
 };
 
-if(YAHOO.util.Element) {
-    YAHOO.lang.extend(YAHOO.widget.DataTable, YAHOO.util.Element);
-}
-else {
-    YAHOO.log("Missing dependency: YAHOO.util.Element","error",this.toString());
-}
+/////////////////////////////////////////////////////////////////////////////
+//
+// Public constants
+//
+/////////////////////////////////////////////////////////////////////////////
+(function () {
 
+var lang   = YAHOO.lang,
+    util   = YAHOO.util,
+    widget = YAHOO.widget,
+    ua     = YAHOO.env.ua,
+    
+    Dom    = util.Dom,
+    Ev     = util.Event,
+    DS     = util.DataSource,
+    DT     = widget.DataTable,
+    Pag    = widget.Paginator;
+    
+
+    
+
+lang.augmentObject(DT, {
+
+    /**
+     * Class name assigned to liner DIV elements.
+     *
+     * @property DataTable.CLASS_LINER
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-liner"
+     */
+    CLASS_LINER : "yui-dt-liner",
+
+    /**
+     * Class name assigned to display label elements.
+     *
+     * @property DataTable.CLASS_LABEL
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-label"
+     */
+    CLASS_LABEL : "yui-dt-label",
+
+    /**
+     * Class name assigned to Column drag target.
+     *
+     * @property DataTable.CLASS_COLTARGET
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-coltarget"
+     */
+    CLASS_COLTARGET : "yui-dt-coltarget",
+
+    /**
+     * Class name assigned to resizer handle elements.
+     *
+     * @property DataTable.CLASS_RESIZER
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-resizer"
+     */
+    CLASS_RESIZER : "yui-dt-resizer",
+
+    /**
+     * Class name assigned to resizer proxy elements.
+     *
+     * @property DataTable.CLASS_RESIZERPROXY
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-resizerproxy"
+     */
+    CLASS_RESIZERPROXY : "yui-dt-resizerproxy",
+
+    /**
+     * Class name assigned to Editor container elements.
+     *
+     * @property DataTable.CLASS_EDITOR
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-editor"
+     */
+    CLASS_EDITOR : "yui-dt-editor",
+
+    /**
+     * Class name assigned to paginator container elements.
+     *
+     * @property DataTable.CLASS_PAGINATOR
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-paginator"
+     */
+    CLASS_PAGINATOR : "yui-dt-paginator",
+
+    /**
+     * Class name assigned to page number indicators.
+     *
+     * @property DataTable.CLASS_PAGE
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-page"
+     */
+    CLASS_PAGE : "yui-dt-page",
+
+    /**
+     * Class name assigned to default indicators.
+     *
+     * @property DataTable.CLASS_DEFAULT
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-default"
+     */
+    CLASS_DEFAULT : "yui-dt-default",
+
+    /**
+     * Class name assigned to previous indicators.
+     *
+     * @property DataTable.CLASS_PREVIOUS
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-previous"
+     */
+    CLASS_PREVIOUS : "yui-dt-previous",
+
+    /**
+     * Class name assigned next indicators.
+     *
+     * @property DataTable.CLASS_NEXT
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-next"
+     */
+    CLASS_NEXT : "yui-dt-next",
+
+    /**
+     * Class name assigned to first elements.
+     *
+     * @property DataTable.CLASS_FIRST
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-first"
+     */
+    CLASS_FIRST : "yui-dt-first",
+
+    /**
+     * Class name assigned to last elements.
+     *
+     * @property DataTable.CLASS_LAST
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-last"
+     */
+    CLASS_LAST : "yui-dt-last",
+
+    /**
+     * Class name assigned to even elements.
+     *
+     * @property DataTable.CLASS_EVEN
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-even"
+     */
+    CLASS_EVEN : "yui-dt-even",
+
+    /**
+     * Class name assigned to odd elements.
+     *
+     * @property DataTable.CLASS_ODD
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-odd"
+     */
+    CLASS_ODD : "yui-dt-odd",
+
+    /**
+     * Class name assigned to selected elements.
+     *
+     * @property DataTable.CLASS_SELECTED
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-selected"
+     */
+    CLASS_SELECTED : "yui-dt-selected",
+
+    /**
+     * Class name assigned to highlighted elements.
+     *
+     * @property DataTable.CLASS_HIGHLIGHTED
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-highlighted"
+     */
+    CLASS_HIGHLIGHTED : "yui-dt-highlighted",
+
+    /**
+     * Class name assigned to hidden elements.
+     *
+     * @property DataTable.CLASS_HIDDEN
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-hidden"
+     */
+    CLASS_HIDDEN : "yui-dt-hidden",
+
+    /**
+     * Class name assigned to disabled elements.
+     *
+     * @property DataTable.CLASS_DISABLED
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-disabled"
+     */
+    CLASS_DISABLED : "yui-dt-disabled",
+
+    /**
+     * Class name assigned to empty indicators.
+     *
+     * @property DataTable.CLASS_EMPTY
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-empty"
+     */
+    CLASS_EMPTY : "yui-dt-empty",
+
+    /**
+     * Class name assigned to loading indicatorx.
+     *
+     * @property DataTable.CLASS_LOADING
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-loading"
+     */
+    CLASS_LOADING : "yui-dt-loading",
+
+    /**
+     * Class name assigned to error indicators.
+     *
+     * @property DataTable.CLASS_ERROR
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-error"
+     */
+    CLASS_ERROR : "yui-dt-error",
+
+    /**
+     * Class name assigned to editable elements.
+     *
+     * @property DataTable.CLASS_EDITABLE
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-editable"
+     */
+    CLASS_EDITABLE : "yui-dt-editable",
+
+    /**
+     * Class name assigned to draggable elements.
+     *
+     * @property DataTable.CLASS_DRAGGABLE
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-draggable"
+     */
+    CLASS_DRAGGABLE : "yui-dt-draggable",
+
+    /**
+     * Class name assigned to resizeable elements.
+     *
+     * @property DataTable.CLASS_RESIZEABLE
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-resizeable"
+     */
+    CLASS_RESIZEABLE : "yui-dt-resizeable",
+
+    /**
+     * Class name assigned to scrollable elements.
+     *
+     * @property DataTable.CLASS_SCROLLABLE
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-scrollable"
+     */
+    CLASS_SCROLLABLE : "yui-dt-scrollable",
+
+    /**
+     * Class name assigned to sortable elements.
+     *
+     * @property DataTable.CLASS_SORTABLE
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-sortable"
+     */
+    CLASS_SORTABLE : "yui-dt-sortable",
+
+    /**
+     * Class name assigned to ascending elements.
+     *
+     * @property DataTable.CLASS_ASC
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-asc"
+     */
+    CLASS_ASC : "yui-dt-asc",
+
+    /**
+     * Class name assigned to descending elements.
+     *
+     * @property DataTable.CLASS_DESC
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-desc"
+     */
+    CLASS_DESC : "yui-dt-desc",
+
+    /**
+     * Class name assigned to BUTTON elements and/or container elements.
+     *
+     * @property DataTable.CLASS_BUTTON
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-button"
+     */
+    CLASS_BUTTON : "yui-dt-button",
+
+    /**
+     * Class name assigned to INPUT TYPE=CHECKBOX elements and/or container elements.
+     *
+     * @property DataTable.CLASS_CHECKBOX
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-checkbox"
+     */
+    CLASS_CHECKBOX : "yui-dt-checkbox",
+
+    /**
+     * Class name assigned to SELECT elements and/or container elements.
+     *
+     * @property DataTable.CLASS_DROPDOWN
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-dropdown"
+     */
+    CLASS_DROPDOWN : "yui-dt-dropdown",
+
+    /**
+     * Class name assigned to INPUT TYPE=RADIO elements and/or container elements.
+     *
+     * @property DataTable.CLASS_RADIO
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-radio"
+     */
+    CLASS_RADIO : "yui-dt-radio",
+
+    /**
+     * Message to display if DataTable has no data.
+     *
+     * @property DataTable.MSG_EMPTY
+     * @type String
+     * @static
+     * @final
+     * @default "No records found."
+     */
+    MSG_EMPTY : "No records found.",
+
+    /**
+     * Message to display while DataTable is loading data.
+     *
+     * @property DataTable.MSG_LOADING
+     * @type String
+     * @static
+     * @final
+     * @default "Loading data..."
+     */
+    MSG_LOADING : "Loading data...",
+
+    /**
+     * Message to display while DataTable has data error.
+     *
+     * @property DataTable.MSG_ERROR
+     * @type String
+     * @static
+     * @final
+     * @default "Data error."
+     */
+    MSG_ERROR : "Data error.",
+
+    /////////////////////////////////////////////////////////////////////////
+    //
+    // Private static variables
+    //
+    /////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Internal class variable for indexing multiple DataTable instances.
+     *
+     * @property DataTable._nCount
+     * @type Number
+     * @private
+     * @static
+     */
+    _nCount : 0,
+
+    /**
+     * Internal class variable tracking current number of DataTable instances,
+     * so that certain class values can be reset when all instances are destroyed.          
+     *
+     * @property DataTable._nCurrentCount
+     * @type Number
+     * @private
+     * @static
+     */
+    _nCurrentCount : 0,
+
+    /**
+     * Reference to STYLE node that is dynamically created and written to
+     * in order to manage Column widths.
+     *
+     * @property DataTable._elStylesheet
+     * @type HTMLElement
+     * @private
+     * @static     
+     */
+    _elStylesheet : null,
+
+    /**
+     * Set to true if _elStylesheet cannot be populated due to browser incompatibility.
+     *
+     * @property DataTable._bStylesheetFallback
+     * @type boolean
+     * @private
+     * @static     
+     */
+    _bStylesheetFallback : (ua.ie && (ua.ie<7)) ? true : false,
+
+    /**
+     * Object literal hash of Columns and their dynamically create style rules.
+     *
+     * @property DataTable._oStylesheetRules
+     * @type Object
+     * @private
+     * @static     
+     */
+    _oStylesheetRules : {},
+
+    /**
+     * Element reference to shared Column drag target.
+     *
+     * @property DataTable._elColumnDragTarget
+     * @type HTMLElement
+     * @private
+     * @static 
+     */
+    _elColumnDragTarget : null,
+
+    /**
+     * Element reference to shared Column resizer proxy.
+     *
+     * @property DataTable._elColumnResizerProxy
+     * @type HTMLElement
+     * @private
+     * @static 
+     */
+    _elColumnResizerProxy : null,
+
+    /**
+     * Clones object literal or array of object literals.
+     *
+     * @method DataTable._cloneObject
+     * @param o {Object} Object.
+     * @private
+     * @static     
+     */
+    _cloneObject : function(o) {
+        if(!lang.isValue(o)) {
+            return o;
+        }
+        
+        var copy = {};
+        
+        if(lang.isArray(o)) {
+            var array = [];
+            for(var i=0,len=o.length;i<len;i++) {
+                array[i] = DT._cloneObject(o[i]);
+            }
+            copy = array;
+        }
+        else if(o.constructor && (o.constructor == Object)) { 
+            for (var x in o){
+                if(lang.hasOwnProperty(o, x)) {
+                    if(lang.isValue(o[x]) && (o[x].constructor == Object) || lang.isArray(o[x])) {
+                        copy[x] = DT._cloneObject(o[x]);
+                    }
+                    else {
+                        copy[x] = o[x];
+                    }
+                }
+            }
+        }
+        else {
+            copy = o;
+        }
+    
+        return copy;
+    },
+
+    /**
+     * Creates HTML markup for shared Column drag target.
+     *
+     * @method DataTable._initColumnDragTargetEl
+     * @return {HTMLElement} Reference to Column drag target. 
+     * @private
+     * @static 
+     */
+    _initColumnDragTargetEl : function() {
+        if(!DT._elColumnDragTarget) {
+            // Attach Column drag target element as first child of body
+            var elColumnDragTarget = document.createElement('div');
+            elColumnDragTarget.id = "yui-dt-coltarget";
+            elColumnDragTarget.className = DT.CLASS_COLTARGET;
+            elColumnDragTarget.style.display = "none";
+            document.body.insertBefore(elColumnDragTarget, document.body.firstChild);
+
+            // Internal tracker of Column drag target
+            DT._elColumnDragTarget = elColumnDragTarget;
+            
+        }
+        return DT._elColumnDragTarget;
+    },
+
+    /**
+     * Creates HTML markup for shared Column resizer proxy.
+     *
+     * @method DataTable._initColumnResizerProxyEl
+     * @return {HTMLElement} Reference to Column resizer proxy.
+     * @private 
+     * @static 
+     */
+    _initColumnResizerProxyEl : function() {
+        if(!DT._elColumnResizerProxy) {
+
+            // Attach Column resizer element as first child of body
+            var elColumnResizerProxy = document.createElement("div");
+            elColumnResizerProxy.id = "yui-dt-colresizerproxy";
+            Dom.addClass(elColumnResizerProxy, DT.CLASS_RESIZERPROXY);
+            document.body.insertBefore(elColumnResizerProxy, document.body.firstChild);
+
+            // Internal tracker of Column resizer proxy
+            DT._elColumnResizerProxy = elColumnResizerProxy;
+        }
+        return DT._elColumnResizerProxy;
+    },
+
+    /**
+     * Outputs markup into the given TH based on given Column.
+     *
+     * @method DataTable.formatTheadCell
+     * @param elCellLabel {HTMLElement} The label DIV element within the TH liner.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oSelf {DT} DataTable instance.
+     * @static
+     */
+    formatTheadCell : function(elCellLabel, oColumn, oSelf) {
+        var sKey = oColumn.getKey();
+        var sLabel = lang.isValue(oColumn.label) ? oColumn.label : sKey;
+
+        // Add accessibility link for sortable Columns
+        if(oColumn.sortable) {
+            // Calculate the direction
+            var sSortClass = oSelf.getColumnSortDir(oColumn);
+            var sSortDir = (sSortClass === DT.CLASS_DESC) ? "descending" : "ascending";
+
+            // Generate a unique HREF for visited status
+            var sHref = oSelf.getId() + "-sort" + oColumn.getId() + "-" + sSortDir;
+            
+            // Generate a dynamic TITLE for sort status
+            var sTitle = "Click to sort " + sSortDir;
+            
+            // Format the element
+            elCellLabel.innerHTML = "<a href=\"" + sHref + "\" title=\"" + sTitle + "\" class=\"" + DT.CLASS_SORTABLE + "\">" + sLabel + "</a>";
+        }
+        // Just display the label for non-sortable Columns
+        else {
+            elCellLabel.innerHTML = sLabel;
+        }
+    },
+
+    /**
+     * Formats a BUTTON element.
+     *
+     * @method DataTable.formatButton
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object | Boolean} Data value for the cell. By default, the value
+     * is what gets written to the BUTTON.
+     * @static
+     */
+    formatButton : function(el, oRecord, oColumn, oData) {
+        var sValue = lang.isValue(oData) ? oData : "Click";
+        //TODO: support YAHOO.widget.Button
+        //if(YAHOO.widget.Button) {
+
+        //}
+        //else {
+            el.innerHTML = "<button type=\"button\" class=\""+
+                    DT.CLASS_BUTTON + "\">" + sValue + "</button>";
+        //}
+    },
+
+    /**
+     * Formats a CHECKBOX element.
+     *
+     * @method DataTable.formatCheckbox
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object | Boolean} Data value for the cell. Can be a simple
+     * Boolean to indicate whether checkbox is checked or not. Can be object literal
+     * {checked:bBoolean, label:sLabel}. Other forms of oData require a custom
+     * formatter.
+     * @static
+     */
+    formatCheckbox : function(el, oRecord, oColumn, oData) {
+        var bChecked = oData;
+        bChecked = (bChecked) ? " checked" : "";
+        el.innerHTML = "<input type=\"checkbox\"" + bChecked +
+                " class=\"" + DT.CLASS_CHECKBOX + "\">";
+    },
+
+    /**
+     * Formats currency. Default unit is USD.
+     *
+     * @method DataTable.formatCurrency
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Number} Data value for the cell.
+     * @static
+     */
+    formatCurrency : function(el, oRecord, oColumn, oData) {
+        el.innerHTML = util.Number.format(oData, {
+                prefix:"$",
+                decimalPlaces:2,
+                decimalSeparator:".",
+                thousandsSeparator:","
+            });
+    },
+
+    /**
+     * Formats JavaScript Dates.
+     *
+     * @method DataTable.formatDate
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} Data value for the cell, or null.
+     * @static
+     */
+    formatDate : function(el, oRecord, oColumn, oData) {
+        el.innerHTML = util.Date.format(oData, {format:"MM/DD/YYYY"});
+    },
+
+    /**
+     * Formats SELECT elements.
+     *
+     * @method DataTable.formatDropdown
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} Data value for the cell, or null.
+     * @static
+     */
+    formatDropdown : function(el, oRecord, oColumn, oData) {
+        var selectedValue = (lang.isValue(oData)) ? oData : oRecord.getData(oColumn.key);
+        var options = (lang.isArray(oColumn.dropdownOptions)) ?
+                oColumn.dropdownOptions : null;
+
+        var selectEl;
+        var collection = el.getElementsByTagName("select");
+
+        // Create the form element only once, so we can attach the onChange listener
+        if(collection.length === 0) {
+            // Create SELECT element
+            selectEl = document.createElement("select");
+            Dom.addClass(selectEl, DT.CLASS_DROPDOWN);
+            selectEl = el.appendChild(selectEl);
+
+            // Add event listener
+            Ev.addListener(selectEl,"change",this._onDropdownChange,this);
+        }
+
+        selectEl = collection[0];
+
+        // Update the form element
+        if(selectEl) {
+            // Clear out previous options
+            selectEl.innerHTML = "";
+
+            // We have options to populate
+            if(options) {
+                // Create OPTION elements
+                for(var i=0; i<options.length; i++) {
+                    var option = options[i];
+                    var optionEl = document.createElement("option");
+                    optionEl.value = (lang.isValue(option.value)) ?
+                            option.value : option;
+                    optionEl.innerHTML = (lang.isValue(option.text)) ?
+                            option.text : option;
+                    optionEl = selectEl.appendChild(optionEl);
+                    if (optionEl.value == selectedValue) {
+                        optionEl.selected = true;
+                    }
+                }
+            }
+            // Selected value is our only option
+            else {
+                selectEl.innerHTML = "<option selected value=\"" + selectedValue + "\">" + selectedValue + "</option>";
+            }
+        }
+        else {
+            el.innerHTML = lang.isValue(oData) ? oData : "";
+        }
+    },
+
+    /**
+     * Formats emails.
+     *
+     * @method DataTable.formatEmail
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} Data value for the cell, or null.
+     * @static
+     */
+    formatEmail : function(el, oRecord, oColumn, oData) {
+        if(lang.isString(oData)) {
+            el.innerHTML = "<a href=\"mailto:" + oData + "\">" + oData + "</a>";
+        }
+        else {
+            el.innerHTML = lang.isValue(oData) ? oData : "";
+        }
+    },
+
+    /**
+     * Formats links.
+     *
+     * @method DataTable.formatLink
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} Data value for the cell, or null.
+     * @static
+     */
+    formatLink : function(el, oRecord, oColumn, oData) {
+        if(lang.isString(oData)) {
+            el.innerHTML = "<a href=\"" + oData + "\">" + oData + "</a>";
+        }
+        else {
+            el.innerHTML = lang.isValue(oData) ? oData : "";
+        }
+    },
+
+    /**
+     * Formats numbers.
+     *
+     * @method DataTable.formatNumber
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} Data value for the cell, or null.
+     * @static
+     */
+    formatNumber : function(el, oRecord, oColumn, oData) {
+        if(lang.isNumber(oData)) {
+            el.innerHTML = oData;
+        }
+        else {
+            el.innerHTML = lang.isValue(oData) ? oData : "";
+        }
+    },
+
+    /**
+     * Formats INPUT TYPE=RADIO elements.
+     *
+     * @method DataTable.formatRadio
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} (Optional) Data value for the cell.
+     * @static
+     */
+    formatRadio : function(el, oRecord, oColumn, oData) {
+        var bChecked = oData;
+        bChecked = (bChecked) ? " checked" : "";
+        el.innerHTML = "<input type=\"radio\"" + bChecked +
+                " name=\"col" + oColumn.getId() + "-radio\"" +
+                " class=\"" + DT.CLASS_RADIO+ "\">";
+    },
+
+    /**
+     * Formats text strings.
+     *
+     * @method DataTable.formatText
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} (Optional) Data value for the cell.
+     * @static
+     */
+    formatText : function(el, oRecord, oColumn, oData) {
+        var value = (lang.isValue(oRecord.getData(oColumn.key))) ?
+                oRecord.getData(oColumn.key) : "";
+        //TODO: move to util function
+        el.innerHTML = value.toString().replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
+    },
+
+    /**
+     * Formats TEXTAREA elements.
+     *
+     * @method DataTable.formatTextarea
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} (Optional) Data value for the cell.
+     * @static
+     */
+    formatTextarea : function(el, oRecord, oColumn, oData) {
+        var value = (lang.isValue(oRecord.getData(oColumn.key))) ?
+                oRecord.getData(oColumn.key) : "";
+        var markup = "<textarea>" + value + "</textarea>";
+        el.innerHTML = markup;
+    },
+
+    /**
+     * Formats INPUT TYPE=TEXT elements.
+     *
+     * @method DataTable.formatTextbox
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} (Optional) Data value for the cell.
+     * @static
+     */
+    formatTextbox : function(el, oRecord, oColumn, oData) {
+        var value = (lang.isValue(oRecord.getData(oColumn.key))) ?
+                oRecord.getData(oColumn.key) : "";
+        var markup = "<input type=\"text\" value=\"" + value + "\">";
+        el.innerHTML = markup;
+    },
+
+    /**
+     * Handles Pag changeRequest events for static DataSources
+     * (i.e. DataSources that return all data immediately)
+     * @method DataTable.handleSimplePagination
+     * @param {object} the requested state of the pagination
+     * @param {DataTable} the DataTable instance
+     * @static     
+     */
+    handleSimplePagination : function (oState,self) {
+        // Set the core pagination values silently (the second param)
+        // to avoid looping back through the changeRequest mechanism
+        oState.paginator.setTotalRecords(oState.totalRecords,true);
+        oState.paginator.setStartIndex(oState.recordOffset,true);
+        oState.paginator.setRowsPerPage(oState.rowsPerPage,true);
+
+        self.render();
+    },
+
+    /**
+     * Handles Pag changeRequest events for dynamic DataSources
+     * such as DataSource.TYPE_XHR or DataSource.TYPE_JSFUNCTION.
+     * @method DataTable.handleDataSourcePagination
+     * @param {object} the requested state of the pagination
+     * @param {DataTable} the DataTable instance
+     * @static     
+     */
+    handleDataSourcePagination : function (oState,self) {
+        var requestedRecords = oState.records[1] - oState.recordOffset;
+
+        // Translate the proposed page state into a DataSource request param
+        var generateRequest = self.get('generateRequest');
+        var request = generateRequest({ pagination : oState }, self);
+
+        var callback = {
+            success : self.onDataReturnSetRows,
+            failure : self.onDataReturnSetRows,
+            argument : {
+                startIndex : oState.recordOffset,
+                pagination : oState
+            },
+            scope : self
+        };
+
+        self._oDataSource.sendRequest(request, callback);
+    },
+
+    /**
+     * Enables CHECKBOX Editor.
+     *
+     * @method DataTable.editCheckbox
+     * @param oEditor {Object} Object literal representation of Editor values.
+     * @param oSelf {DT} Reference back to DataTable instance.
+     * @static
+     */
+    //DT.editCheckbox = function(elContainer, oRecord, oColumn, oEditor, oSelf) 
+    editCheckbox : function(oEditor, oSelf) {
+        var elCell = oEditor.cell;
+        var oRecord = oEditor.record;
+        var oColumn = oEditor.column;
+        var elContainer = oEditor.container;
+        var aCheckedValues = oEditor.value;
+        if(!lang.isArray(aCheckedValues)) {
+            aCheckedValues = [aCheckedValues];
+        }
+
+        // Checkboxes
+        if(oColumn.editorOptions && lang.isArray(oColumn.editorOptions.checkboxOptions)) {
+            var checkboxOptions = oColumn.editorOptions.checkboxOptions;
+            var checkboxValue, checkboxId, elLabel, j, k;
+            // First create the checkbox buttons in an IE-friendly way
+            for(j=0; j<checkboxOptions.length; j++) {
+                checkboxValue = lang.isValue(checkboxOptions[j].label) ?
+                        checkboxOptions[j].label : checkboxOptions[j];
+                checkboxId =  oSelf.getId() + "-editor-checkbox" + j;
+                elContainer.innerHTML += "<input type=\"checkbox\"" +
+                        " name=\"" + oSelf.getId() + "-editor-checkbox\"" +
+                        " value=\"" + checkboxValue + "\"" +
+                        " id=\"" +  checkboxId + "\">";
+                // Then create the labels in an IE-friendly way
+                elLabel = elContainer.appendChild(document.createElement("label"));
+                elLabel.htmlFor = checkboxId;
+                elLabel.innerHTML = checkboxValue;
+            }
+            var aCheckboxEls = [];
+            var checkboxEl;
+            // Loop through checkboxes to check them
+            for(j=0; j<checkboxOptions.length; j++) {
+                checkboxEl = Dom.get(oSelf.getId() + "-editor-checkbox" + j);
+                aCheckboxEls.push(checkboxEl);
+                for(k=0; k<aCheckedValues.length; k++) {
+                    if(checkboxEl.value === aCheckedValues[k]) {
+                        checkboxEl.checked = true;
+                    }
+                }
+                // Focus the first checkbox
+                if(j===0) {
+                    oSelf._focusEl(checkboxEl);
+                }
+            }
+            // Loop through checkboxes to assign click handlers
+            for(j=0; j<checkboxOptions.length; j++) {
+                checkboxEl = Dom.get(oSelf.getId() + "-editor-checkbox" + j);
+                Ev.addListener(checkboxEl, "click", function(){
+                    var aNewValues = [];
+                    for(var m=0; m<aCheckboxEls.length; m++) {
+                        if(aCheckboxEls[m].checked) {
+                            aNewValues.push(aCheckboxEls[m].value);
+                        }
+                    }
+                    oSelf._oCellEditor.value = aNewValues;
+                    oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
+                });
+            }
+        }
+    },
+
+    /**
+     * Enables Date Editor.
+     *
+     * @method DataTable.editDate
+     * @param oEditor {Object} Object literal representation of Editor values.
+     * @param oSelf {DT} Reference back to DataTable instance.
+     * @static
+     */
+    editDate : function(oEditor, oSelf) {
+        var elCell = oEditor.cell;
+        var oRecord = oEditor.record;
+        var oColumn = oEditor.column;
+        var elContainer = oEditor.container;
+        var value = oEditor.value;
+        
+        // Set a default
+        if(!(value instanceof Date)) {
+            value = oEditor.defaultValue || new Date();
+        }
+
+        // Calendar widget
+        if(YAHOO.widget.Calendar) {
+            var selectedValue = (value.getMonth()+1)+"/"+value.getDate()+"/"+value.getFullYear();
+            var calContainer = elContainer.appendChild(document.createElement("div"));
+            var calPrefix = oColumn.getColEl();
+            calContainer.id = calPrefix + "-dateContainer";
+            var calendar =
+                    new YAHOO.widget.Calendar(calPrefix + "-date",
+                    calContainer.id,
+                    {selected:selectedValue, pagedate:value});
+            calendar.render();
+            calContainer.style.cssFloat = "none";
+
+            if(ua.ie) {
+                var calFloatClearer = elContainer.appendChild(document.createElement("br"));
+                calFloatClearer.style.clear = "both";
+            }
+
+            calendar.selectEvent.subscribe(function(type, args, obj) {
+                oSelf._oCellEditor.value = new Date(args[0][0][0], args[0][0][1]-1, args[0][0][2]);
+                oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
+            });
+        }
+        else {
+            //TODO;
+        }
+    },
+
+    /**
+     * Enables SELECT Editor.
+     *
+     * @method DataTable.editDropdown
+     * @param oEditor {Object} Object literal representation of Editor values.
+     * @param oSelf {DT} Reference back to DataTable instance.
+     * @static
+     */
+    editDropdown : function(oEditor, oSelf) {
+        var elCell = oEditor.cell;
+        var oRecord = oEditor.record;
+        var oColumn = oEditor.column;
+        var elContainer = oEditor.container;
+        var value = oEditor.value;
+        
+        // Set a default
+        if(!lang.isValue(value)) {
+            value = oEditor.defaultValue;
+        }
+
+
+        // Textbox
+        var elDropdown = elContainer.appendChild(document.createElement("select"));
+        var dropdownOptions = (oColumn.editorOptions && lang.isArray(oColumn.editorOptions.dropdownOptions)) ?
+                oColumn.editorOptions.dropdownOptions : [];
+        for(var j=0; j<dropdownOptions.length; j++) {
+            var dropdownOption = dropdownOptions[j];
+            var elOption = document.createElement("option");
+            elOption.value = (lang.isValue(dropdownOption.value)) ?
+                    dropdownOption.value : dropdownOption;
+            elOption.innerHTML = (lang.isValue(dropdownOption.text)) ?
+                    dropdownOption.text : dropdownOption;
+            elOption = elDropdown.appendChild(elOption);
+            if(value === elDropdown.options[j].value) {
+                elDropdown.options[j].selected = true;
+            }
+        }
+
+        // Set up a listener on each check box to track the input value
+        Ev.addListener(elDropdown, "change",
+            function(){
+                oSelf._oCellEditor.value = elDropdown[elDropdown.selectedIndex].value;
+                oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
+        });
+
+        // Focus the dropdown
+        oSelf._focusEl(elDropdown);
+    },
+
+    /**
+     * Enables INPUT TYPE=RADIO Editor.
+     *
+     * @method DataTable.editRadio
+     * @param oEditor {Object} Object literal representation of Editor values.
+     * @param oSelf {DT} Reference back to DataTable instance.
+     * @static
+     */
+    editRadio : function(oEditor, oSelf) {
+        var elCell = oEditor.cell;
+        var oRecord = oEditor.record;
+        var oColumn = oEditor.column;
+        var elContainer = oEditor.container;
+        var value = oEditor.value;
+
+        // Set a default
+        if(!lang.isValue(value)) {
+            value = oEditor.defaultValue;
+        }
+
+        // Radios
+        if(oColumn.editorOptions && lang.isArray(oColumn.editorOptions.radioOptions)) {
+            var radioOptions = oColumn.editorOptions.radioOptions;
+            var radioValue, radioId, elLabel, j;
+            // First create the radio buttons in an IE-friendly way
+            for(j=0; j<radioOptions.length; j++) {
+                radioValue = lang.isValue(radioOptions[j].label) ?
+                        radioOptions[j].label : radioOptions[j];
+                radioId =  oSelf.getId() + "-col" + oColumn.getId() + "-radioeditor" + j;
+                elContainer.innerHTML += "<input type=\"radio\"" +
+                        " name=\"" + oSelf.getId() + "-editor-radio\"" +
+                        " value=\"" + radioValue + "\"" +
+                        " id=\"" +  radioId + "\">";
+                // Then create the labels in an IE-friendly way
+                elLabel = elContainer.appendChild(document.createElement("label"));
+                elLabel.htmlFor = radioId;
+                elLabel.innerHTML = radioValue;
+            }
+            // Then check one, and assign click handlers
+            for(j=0; j<radioOptions.length; j++) {
+                var radioEl = Dom.get(oSelf.getId() + "-col" + oColumn.getId() + "-radioeditor" + j);
+                if(value === radioEl.value) {
+                    radioEl.checked = true;
+                    oSelf._focusEl(radioEl);
+                }
+                Ev.addListener(radioEl, "click",
+                    function(){
+                        oSelf._oCellEditor.value = this.value;
+                        oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
+                });
+            }
+        }
+    },
+
+    /**
+     * Enables TEXTAREA Editor.
+     *
+     * @method DataTable.editTextarea
+     * @param oEditor {Object} Object literal representation of Editor values.
+     * @param oSelf {DT} Reference back to DataTable instance.
+     * @static
+     */
+    editTextarea : function(oEditor, oSelf) {
+       var elCell = oEditor.cell;
+       var oRecord = oEditor.record;
+       var oColumn = oEditor.column;
+       var elContainer = oEditor.container;
+       var value = oEditor.value;
+
+        // Set a default
+        if(!lang.isValue(value)) {
+            value = oEditor.defaultValue || "";
+        }
+
+        // Textarea
+        var elTextarea = elContainer.appendChild(document.createElement("textarea"));
+        elTextarea.style.width = elCell.offsetWidth + "px"; //(parseInt(elCell.offsetWidth,10)) + "px";
+        elTextarea.style.height = "3em"; //(parseInt(elCell.offsetHeight,10)) + "px";
+        elTextarea.value = value;
+
+        // Set up a listener on each check box to track the input value
+        Ev.addListener(elTextarea, "keyup", function(){
+            //TODO: set on a timeout
+            oSelf._oCellEditor.value = elTextarea.value;
+            oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
+        });
+
+        // Select the text
+        elTextarea.focus();
+        elTextarea.select();
+    },
+
+    /**
+     * Enables INPUT TYPE=TEXT Editor.
+     *
+     * @method DataTable.editTextbox
+     * @param oEditor {Object} Object literal representation of Editor values.
+     * @param oSelf {DT} Reference back to DataTable instance.
+     * @static
+     */
+    editTextbox : function(oEditor, oSelf) {
+       var elCell = oEditor.cell;
+       var oRecord = oEditor.record;
+       var oColumn = oEditor.column;
+       var elContainer = oEditor.container;
+       var value = oEditor.value;
+
+        // Set a default
+        if(!lang.isValue(value)) {
+            value = oEditor.defaultValue || "";
+        }
+
+        // Textbox
+        var elTextbox;
+        // Bug 1802582: SF3/Mac needs a form element wrapping the input
+        if(ua.webkit>420) {
+            elTextbox = elContainer.appendChild(document.createElement("form")).appendChild(document.createElement("input"));
+        }
+        else {
+            elTextbox = elContainer.appendChild(document.createElement("input"));
+        }
+        elTextbox.type = "text";
+        elTextbox.style.width = elCell.offsetWidth + "px"; //(parseInt(elCell.offsetWidth,10)) + "px";
+        //elTextbox.style.height = "1em"; //(parseInt(elCell.offsetHeight,10)) + "px";
+        elTextbox.value = value;
+
+        // Bug: 1802582 Set up a listener on each textbox to track on keypress
+        // since SF/OP can't preventDefault on keydown
+        Ev.addListener(elTextbox, "keypress", function(v){
+            // Prevent form submit
+            // Save on "enter"
+            if((v.keyCode === 13)) {
+                YAHOO.util.Event.preventDefault(v);
+                oSelf.saveCellEditor();
+            }
+        });
+
+        // Set up a listener on each textbox to track the input value
+        Ev.addListener(elTextbox, "keyup", function(v){
+            // Update the tracker value
+            oSelf._oCellEditor.value = elTextbox.value;
+            oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
+        });
+
+        // Select the text
+        elTextbox.focus();
+        elTextbox.select();
+    },
+
+    /**
+     * Validates Editor input value to type Number, doing type conversion as
+     * necessary. A valid Number value is return, else the previous value is returned
+     * if input value does not validate.
+     *
+     *
+     * @method DataTable.validateNumber
+     * @param oData {Object} Data to validate.
+     * @static
+    */
+    validateNumber : function(oData) {
+        //Convert to number
+        var number = oData * 1;
+
+        // Validate
+        if(lang.isNumber(number)) {
+            return number;
+        }
+        else {
+            YAHOO.log("Could not validate data " + lang.dump(oData) + " to type Number", "warn", this.toString());
+            return null;
+        }
+    },
+
+    /**
+     * Translates (proposed) DataTable state data into a form consumable by
+     * DataSource sendRequest as the request parameter.  Use
+     * set('generateRequest', yourFunc) to use a custom function rather than this
+     * one.
+     * @method DataTable._generateRequest
+     * @param oData {Object} Object literal defining the current or proposed state
+     * @param oDataTable {DataTable} Reference to the DataTable instance
+     * @returns {MIXED} Returns appropriate value based on DataSource type
+     * @private
+     * @static     
+     */
+    _generateRequest : function (oData, oDataTable) {
+        var request = oData;
+
+        if (oData.pagination) {
+            if (oDataTable._oDataSource.dataType === DS.TYPE_XHR) {
+                request = '?page=' +         oData.pagination.page +
+                          '&recordOffset=' + oData.pagination.recordOffset +
+                          '&rowsPerPage=' +  oData.pagination.rowsPerPage;
+            }
+        }
+        
+        return request;
+    }
+});
+
+// Do in separate step so referenced properties are available
+// TODO: editor shortcuts
+/**
+ * Cell formatting functions.
+ * @property DataTable.Formatter
+ * @type Object
+ * @static
+ */
+DT.Formatter = {
+    button   : DT.formatButton,
+    checkbox : DT.formatCheckbox,
+    currency : DT.formatCurrency,
+    "date"   : DT.formatDate,
+    dropdown : DT.formatDropdown,
+    email    : DT.formatEmail,
+    link     : DT.formatLink,
+    "number" : DT.formatNumber,
+    radio    : DT.formatRadio,
+    text     : DT.formatText,
+    textarea : DT.formatTextarea,
+    textbox  : DT.formatTextbox
+};
+
+lang.extend(DT, util.Element, {
+
 /////////////////////////////////////////////////////////////////////////////
 //
 // Superclass methods
@@ -127,9 +5821,9 @@
  * @private
  */
 
-YAHOO.widget.DataTable.prototype.initAttributes = function(oConfigs) {
+initAttributes : function(oConfigs) {
     oConfigs = oConfigs || {};
-    YAHOO.widget.DataTable.superclass.initAttributes.call(this, oConfigs);
+    DT.superclass.initAttributes.call(this, oConfigs);
 
     /**
     * @attribute summary
@@ -138,9 +5832,9 @@
     */
     this.setAttributeConfig("summary", {
         value: null,
-        validator: YAHOO.lang.isString,
+        validator: lang.isString,
         method: function(sSummary) {
-            this._elTable.summary = sSummary;
+            this._elThead.parentNode.summary = sSummary;
         }
     });
 
@@ -174,20 +5868,62 @@
     */
     this.setAttributeConfig("selectionMode", {
         value: "standard",
-        validator: YAHOO.lang.isString
+        validator: lang.isString
     });
 
     /**
     * @attribute initialRequest
-    * @description Defines the initial request that gets sent to the DataSource.
-    * @type String
+    * @description Defines the initial request that gets sent to the DataSource
+    * during initialization. Value is ignored if initialLoad is set to any value
+    * other than true.    
+    * @type MIXED
+    * @default null
     */
     this.setAttributeConfig("initialRequest", {
-        value: "",
-        validator: YAHOO.lang.isString
+        value: null
     });
 
     /**
+    * @attribute initialLoad
+    * @description Determines whether or not to load data at instantiation. By
+    * default, will trigger a sendRequest() to the DataSource and pass in the
+    * request defined by initialRequest. If set to false, data will not load
+    * at instantiation. Alternatively, implementers who wish to work with a 
+    * custom payload may pass in an object literal with the following values:
+    *     
+    *    <dl>
+    *      <dt>request (MIXED)</dt>
+    *      <dd>Request value.</dd>
+    *
+    *      <dt>argument (MIXED)</dt>
+    *      <dd>Custom data that will be passed through to the callback function.</dd>
+    *    </dl>
+    *
+    *                    
+    * @type Boolean | Object
+    * @default true
+    */
+    this.setAttributeConfig("initialLoad", {
+        value: true
+    });
+
+    /**
+     * @attribute generateRequest
+     * @description A function used to translate proposed DataTable state info
+     * into a value which is then passed to the DataSource's sendRequest method.
+     * This function is called to get the DataTable's initial data as well as
+     * any data changes or requests such as pagination or sorting.  The method
+     * is passed two params, an object literal with the state data and a
+     * reference to the DataTable.
+     * @type function
+     * @default DT._generateRequest
+     */
+    this.setAttributeConfig("generateRequest", {
+        value: DT._generateRequest,
+        validator: lang.isFunction
+    });
+
+    /**
     * @attribute sortedBy
     * @description Object literal provides metadata for initial sort values if
     * data will arrive pre-sorted:
@@ -195,15 +5931,20 @@
     *     <dt>sortedBy.key</dt>
     *     <dd>{String} Key of sorted Column</dd>
     *     <dt>sortedBy.dir</dt>
-    *     <dd>{String} Initial sort direction, either "asc" or "desc"</dd>
+    *     <dd>{String} Initial sort direction, either DT.CLASS_ASC or DT.CLASS_DESC</dd>
     * </dl>
-    * @type Object
+    * @type Object | null
     */
     this.setAttributeConfig("sortedBy", {
         value: null,
         // TODO: accepted array for nested sorts
         validator: function(oNewSortedBy) {
-            return (oNewSortedBy && (oNewSortedBy.constructor == Object) && oNewSortedBy.key);
+            if(oNewSortedBy) {
+                return ((oNewSortedBy.constructor == Object) && oNewSortedBy.key);
+            }
+            else {
+                return (oNewSortedBy === null);
+            }
         },
         method: function(oNewSortedBy) {
             // Remove ASC/DESC from TH
@@ -211,25 +5952,35 @@
             if(oOldSortedBy && (oOldSortedBy.constructor == Object) && oOldSortedBy.key) {
                 var oldColumn = this._oColumnSet.getColumn(oOldSortedBy.key);
                 var oldThEl = this.getThEl(oldColumn);
-                YAHOO.util.Dom.removeClass(oldThEl, YAHOO.widget.DataTable.CLASS_ASC);
-                YAHOO.util.Dom.removeClass(oldThEl, YAHOO.widget.DataTable.CLASS_DESC);
+                Dom.removeClass(oldThEl, DT.CLASS_ASC);
+                Dom.removeClass(oldThEl, DT.CLASS_DESC);
             }
-            
+
             // Set ASC/DESC on TH
-            var column = (oNewSortedBy.column) ? oNewSortedBy.column : this._oColumnSet.getColumn(oNewSortedBy.key);
-            if(column) {
-                var newClass = (oNewSortedBy.dir && (oNewSortedBy.dir != "asc")) ?
-                        YAHOO.widget.DataTable.CLASS_DESC :
-                        YAHOO.widget.DataTable.CLASS_ASC;
-                YAHOO.util.Dom.addClass(this.id + "-col" + column.getId(), newClass);
+            if(oNewSortedBy) {
+                var column = (oNewSortedBy.column) ? oNewSortedBy.column : this._oColumnSet.getColumn(oNewSortedBy.key);
+                if(column) {
+                    // Backward compatibility
+                    if(oNewSortedBy.dir && ((oNewSortedBy.dir == "asc") ||  (oNewSortedBy.dir == "desc"))) {
+                        var newClass = (oNewSortedBy.dir == "desc") ?
+                                DT.CLASS_DESC :
+                                DT.CLASS_ASC;
+                        Dom.addClass(column.getThEl(), newClass);
+                    }
+                    else {
+                         var sortClass = oNewSortedBy.dir || DT.CLASS_ASC;
+                         Dom.addClass(column.getThEl(), sortClass);
+                    }
+                }
             }
         }
     });
-
+    
     /**
     * @attribute paginator
-    * @description Object literal of pagination values.
-    * @default <br>
+    * @description Stores an instance of Pag, or (for
+    * backward compatibility), an object literal of pagination values in the
+    * following form:<br>
     *   { containers:[], // UI container elements <br>
     *   rowsPerPage:500, // 500 rows <br>
     *   currentPage:1,  // page one <br>
@@ -238,11 +5989,12 @@
     *   dropdownOptions:null, // no dropdown <br>
     *   links: [], // links elements <br>
     *   dropdowns: [] } //dropdown elements
-    * 
-    * @type Object
+    *
+    * @default null
+    * @type {Object|YAHOO.widget.Paginator}
     */
     this.setAttributeConfig("paginator", {
-        value: {
+        value : { // Backward compatibility
             rowsPerPage:500, // 500 rows per page
             currentPage:1,  // show page one
             startRecordIndex:0, // start with first Record
@@ -256,177 +6008,249 @@
             dropdowns: [], //dropdown element references,
             links: [] // links elements
         },
-        validator: function(oNewPaginator) {
-            if(oNewPaginator && (oNewPaginator.constructor == Object)) {
-                // Check for incomplete set of values
-                if((oNewPaginator.rowsPerPage !== undefined) &&
-                        (oNewPaginator.currentPage !== undefined) &&
-                        (oNewPaginator.startRecordIndex !== undefined) &&
-                        (oNewPaginator.totalRecords !== undefined) &&
-                        (oNewPaginator.totalPages !== undefined) &&
-                        (oNewPaginator.rowsThisPage !== undefined) &&
-                        (oNewPaginator.pageLinks !== undefined) &&
-                        (oNewPaginator.pageLinksStart !== undefined) &&
-                        (oNewPaginator.dropdownOptions !== undefined) &&
-                        (oNewPaginator.containers !== undefined) &&
-                        (oNewPaginator.dropdowns !== undefined) &&
-                        (oNewPaginator.links !== undefined)) {
+        validator : function (oNewPaginator) {
+            if (typeof oNewPaginator === 'object' && oNewPaginator) {
+                if (oNewPaginator instanceof Pag) {
+                    return true;
+                }
+                else {
+                    // Backward compatibility
+                    if(oNewPaginator && (oNewPaginator.constructor == Object)) {
+                        // Check for incomplete set of values
+                        if((oNewPaginator.rowsPerPage !== undefined) &&
+                                (oNewPaginator.currentPage !== undefined) &&
+                                (oNewPaginator.startRecordIndex !== undefined) &&
+                                (oNewPaginator.totalRecords !== undefined) &&
+                                (oNewPaginator.totalPages !== undefined) &&
+                                (oNewPaginator.rowsThisPage !== undefined) &&
+                                (oNewPaginator.pageLinks !== undefined) &&
+                                (oNewPaginator.pageLinksStart !== undefined) &&
+                                (oNewPaginator.dropdownOptions !== undefined) &&
+                                (oNewPaginator.containers !== undefined) &&
+                                (oNewPaginator.dropdowns !== undefined) &&
+                                (oNewPaginator.links !== undefined)) {
 
-                    // Validate each value
-                    if(YAHOO.lang.isNumber(oNewPaginator.rowsPerPage) &&
-                            YAHOO.lang.isNumber(oNewPaginator.currentPage) &&
-                            YAHOO.lang.isNumber(oNewPaginator.startRecordIndex) &&
-                            YAHOO.lang.isNumber(oNewPaginator.totalRecords) &&
-                            YAHOO.lang.isNumber(oNewPaginator.totalPages) &&
-                            YAHOO.lang.isNumber(oNewPaginator.rowsThisPage) &&
-                            YAHOO.lang.isNumber(oNewPaginator.pageLinks) &&
-                            YAHOO.lang.isNumber(oNewPaginator.pageLinksStart) &&
-                            YAHOO.lang.isArray(oNewPaginator.dropdownOptions) &&
-                            YAHOO.lang.isArray(oNewPaginator.containers) &&
-                            YAHOO.lang.isArray(oNewPaginator.dropdowns) &&
-                            YAHOO.lang.isArray(oNewPaginator.links)) {
-                        return true;
+                            // Validate each value
+                            if(lang.isNumber(oNewPaginator.rowsPerPage) &&
+                                    lang.isNumber(oNewPaginator.currentPage) &&
+                                    lang.isNumber(oNewPaginator.startRecordIndex) &&
+                                    lang.isNumber(oNewPaginator.totalRecords) &&
+                                    lang.isNumber(oNewPaginator.totalPages) &&
+                                    lang.isNumber(oNewPaginator.rowsThisPage) &&
+                                    lang.isNumber(oNewPaginator.pageLinks) &&
+                                    lang.isNumber(oNewPaginator.pageLinksStart) &&
+                                    (lang.isArray(oNewPaginator.dropdownOptions) || lang.isNull(oNewPaginator.dropdownOptions)) &&
+                                    lang.isArray(oNewPaginator.containers) &&
+                                    lang.isArray(oNewPaginator.dropdowns) &&
+                                    lang.isArray(oNewPaginator.links)) {
+                                return true;
+                            }
+                        }
                     }
                 }
             }
             return false;
+        },
+        method : function (oNewPaginator) {
+            // Hook into the pagintor's change event
+            if (oNewPaginator instanceof Pag) {
+                oNewPaginator.subscribe('changeRequest', this.onPaginatorChange, this, true);
+
+                // If the paginator has no configured containers, add some
+                var containers = oNewPaginator.getContainerNodes();
+                if (!containers.length) {
+                    // Build the container nodes
+                    var c_above = document.createElement('div');
+                    c_above.id = this._sId + "-paginator0";
+                    this._elContainer.insertBefore(c_above,this._elContainer.firstChild);
+
+                    // ...and one below the table
+                    var c_below = document.createElement('div');
+                    c_below.id = this._sId + "-paginator1";
+                    this._elContainer.appendChild(c_below);
+
+                    containers = [c_above, c_below];
+                    Dom.addClass(containers,
+                                DT.CLASS_PAGINATOR);
+
+                    oNewPaginator.set('containers',containers);
+                }
+            }
         }
     });
 
     /**
     * @attribute paginated
-    * @description True if built-in client-side pagination is enabled
-    * @default false
-    * @type Boolean
+    * @deprecated No longer used, as long as "paginator" value is an instance of
+    * Paginator class.  
     */
     this.setAttributeConfig("paginated", {
         value: false,
-        validator: YAHOO.lang.isBoolean,
-        method: function(oParam) {
-            var oPaginator = this.get("paginator");
-            var aContainerEls = oPaginator.containers;
-            var i;
-            
-            // Paginator is enabled
-            if(oParam) {
-                // No containers found, create two from scratch
-                if(aContainerEls.length === 0) {
-                    // One before TABLE
-                    var pag0 = document.createElement("span");
-                    pag0.id = this.id + "-paginator0";
-                    YAHOO.util.Dom.addClass(pag0, YAHOO.widget.DataTable.CLASS_PAGINATOR);
-                    pag0 = this._elContainer.insertBefore(pag0, this._elTable);
-                    aContainerEls.push(pag0);
+        validator: lang.isBoolean,
+        method : function (on) {
+            var curVal = this.get('paginated');
+            var i,len;
+            if (on == curVal) {
+                return;
+            }
 
-                    // One after TABLE
-                    var pag1 = document.createElement("span");
-                    pag1.id = this.id + "-paginator1";
-                    YAHOO.util.Dom.addClass(pag1, YAHOO.widget.DataTable.CLASS_PAGINATOR);
-                    pag1 = this._elContainer.insertBefore(pag1, this._elTable.nextSibling);
-                    aContainerEls.push(pag1);
+            var oPaginator  = this.get('paginator');
+            if (!(oPaginator instanceof Pag)) {
+                // Backward compatibility--pagination generated here
+                oPaginator = oPaginator || {
+                    rowsPerPage     : 500,  // 500 rows per page
+                    currentPage     : 1,    // show page one
+                    startRecordIndex: 0,    // start with first Record
+                    totalRecords    : 0,    // how many Records total
+                    totalPages      : 0,    // how many pages total
+                    rowsThisPage    : 0,    // how many rows this page
+                    pageLinks       : 0,    // show all links
+                    pageLinksStart  : 1,    // first link is page 1
+                    dropdownOptions : null, // no dropdown
+                    containers      : [],   // Paginator container element references
+                    dropdowns       : [],   // dropdown element references,
+                    links           : []    // links elements
+                };
+                var aContainerEls = oPaginator.containers;
 
-                    // Add containers directly to tracker
-                    this._configs.paginator.value.containers = [pag0, pag1];
+                // Paginator is enabled
+                if(on) {
+                    // No containers found, create two from scratch
+                    if(aContainerEls.length === 0) {
+                        // One before TABLE
+                        var pag0 = document.createElement("span");
+                        pag0.id = this._sId + "-paginator0";
+                        Dom.addClass(pag0, DT.CLASS_PAGINATOR);
+                        pag0 = this._elContainer.insertBefore(pag0, this._elContainer.firstChild);
+                        aContainerEls.push(pag0);
 
-                }
-                else {
-                    // Show each container
-                    for(i=0; i<aContainerEls.length; i++) {
-                        aContainerEls[i].style.display = "";
+                        // One after TABLE
+                        var pag1 = document.createElement("span");
+                        pag1.id = this._sId + "-paginator1";
+                        Dom.addClass(pag1, DT.CLASS_PAGINATOR);
+                        pag1 = this._elContainer.appendChild(pag1);
+                        aContainerEls.push(pag1);
+
+                        // (re)set the paginator value directly
+                        oPaginator.containers = aContainerEls;
+                        this._configs.paginator.value= oPaginator;
                     }
-                }
-
-                // Links are enabled
-                if(oPaginator.pageLinks > -1) {
-                    var aLinkEls = oPaginator.links;
-                    // No links containers found, create from scratch
-                    if(aLinkEls.length === 0) {
+                    else {
+                        // Show each container
                         for(i=0; i<aContainerEls.length; i++) {
-                            // Create one links container per Paginator container
-                            var linkEl = document.createElement("span");
-                            linkEl.id = "yui-dt-pagselect"+i;
-                            linkEl = aContainerEls[i].appendChild(linkEl);
+                            aContainerEls[i].style.display = "";
+                        }
+                    }
 
-                            // Add event listener
-                            //TODO: anon fnc
-                            YAHOO.util.Event.addListener(linkEl,"click",this._onPaginatorLinkClick,this);
+                    // Links are enabled
+                    if(oPaginator.pageLinks > -1) {
+                        var aLinkEls = oPaginator.links;
+                        // No links containers found, create from scratch
+                        if(aLinkEls.length === 0) {
+                            for(i=0; i<aContainerEls.length; i++) {
+                                // Create one links container per Paginator container
+                                var linkEl = document.createElement("span");
+                                linkEl.id = "yui-dt-pagselect"+i;
+                                linkEl = aContainerEls[i].appendChild(linkEl);
 
-                             // Add directly to tracker
-                            this._configs.paginator.value.links.push(linkEl);
+                                // Add event listener
+                                //TODO: anon fnc
+                                Ev.addListener(linkEl,"click",this._onPaginatorLinkClick,this);
+
+                                 // Add directly to tracker
+                                this._configs.paginator.value.links.push(linkEl);
+                           }
                        }
-                   }
-                }
+                    }
 
-                // Show these options in the dropdown
-                var dropdownOptions = oPaginator.dropdownOptions || [];
+                    for(i=0; i<aContainerEls.length; i++) {
+                        // Create one SELECT element per Paginator container
+                        var selectEl = document.createElement("select");
+                        Dom.addClass(selectEl, DT.CLASS_DROPDOWN);
+                        selectEl = aContainerEls[i].appendChild(selectEl);
+                        selectEl.id = "yui-dt-pagselect"+i;
 
-                for(i=0; i<aContainerEls.length; i++) {
-                    // Create one SELECT element per Paginator container
-                    var selectEl = document.createElement("select");
-                    YAHOO.util.Dom.addClass(selectEl, YAHOO.widget.DataTable.CLASS_DROPDOWN);
-                    selectEl = aContainerEls[i].appendChild(selectEl);
-                    selectEl.id = "yui-dt-pagselect"+i;
+                        // Add event listener
+                        //TODO: anon fnc
+                        Ev.addListener(selectEl,"change",this._onPaginatorDropdownChange,this);
 
-                    // Add event listener
-                    //TODO: anon fnc
-                    YAHOO.util.Event.addListener(selectEl,"change",this._onPaginatorDropdownChange,this);
+                        // Add DOM reference directly to tracker
+                       this._configs.paginator.value.dropdowns.push(selectEl);
 
-                    // Add DOM reference directly to tracker
-                   this._configs.paginator.value.dropdowns.push(selectEl);
+                        // Hide dropdown
+                        if(!oPaginator.dropdownOptions) {
+                            selectEl.style.display = "none";
+                        }
+                    }
 
-                    // Hide dropdown
-                    if(!oPaginator.dropdownOptions) {
-                        selectEl.style.display = "none";
-                    }
+                    //TODO: fire paginatorDisabledEvent & add to api doc
+                    YAHOO.log("Paginator enabled", "info", this.toString());
                 }
+                // Pagination is disabled
+                else {
+                    // Containers found
+                    if(aContainerEls.length > 0) {
+                        // Destroy or just hide?
 
-                //TODO: fire paginatorDisabledEvent & add to api doc
-                YAHOO.log("Paginator enabled", "info", this.toString());
-            }
-            // Pagination is disabled
-            else {
-                // Containers found
-                if(aContainerEls.length > 0) {
-                    // Destroy or just hide?
-                    
-                    // Hide each container
-                    for(i=0; i<aContainerEls.length; i++) {
-                        aContainerEls[i].style.display = "none";
-                    }
+                        // Hide each container
+                        for(i=0; i<aContainerEls.length; i++) {
+                            aContainerEls[i].style.display = "none";
+                        }
 
-                    /*TODO?
-                    // Destroy each container
-                    for(i=0; i<aContainerEls.length; i++) {
-                        YAHOO.util.Event.purgeElement(aContainerEls[i], true);
-                        aContainerEls.innerHTML = null;
-                        //TODO: remove container?
-                        // aContainerEls[i].parentNode.removeChild(aContainerEls[i]);
+                        /*TODO?
+                        // Destroy each container
+                        for(i=0; i<aContainerEls.length; i++) {
+                            Ev.purgeElement(aContainerEls[i], true);
+                            aContainerEls.innerHTML = null;
+                            //TODO: remove container?
+                            // aContainerEls[i].parentNode.removeChild(aContainerEls[i]);
+                        }
+                        */
                     }
-                    */
+                    //TODO: fire paginatorDisabledEvent & add to api doc
+                    YAHOO.log("Paginator disabled", "info", this.toString());
                 }
-                //TODO: fire paginatorDisabledEvent & add to api doc
-                YAHOO.log("Paginator disabled", "info", this.toString());
             }
         }
     });
 
     /**
+     * @attribute paginationEventHandler
+     * @description For use with Pag pagination.  A
+     * handler function that receives the requestChange event from the
+     * configured paginator.  The handler method will be passed these
+     * parameters:
+     * <ol>
+     * <li>oState {Object} - an object literal describing the requested
+     * pagination state</li>
+     * <li>oSelf {DataTable} - The DataTable instance.</li>
+     * </ol>
+     * 
+     * For pagination through dynamic or server side data, assign
+     * DT.handleDataSourcePagination or your own custom
+     * handler.
+     * @type {function|Object}
+     * @default DT.handleSimplePagination
+     */
+    this.setAttributeConfig("paginationEventHandler", {
+        value     : DT.handleSimplePagination,
+        validator : lang.isObject
+    });
+
+    /**
     * @attribute caption
     * @description Value for the CAPTION element.
     * @type String
     */
     this.setAttributeConfig("caption", {
         value: null,
-        validator: YAHOO.lang.isString,
+        validator: lang.isString,
         method: function(sCaption) {
             // Create CAPTION element
             if(!this._elCaption) {
-                if(!this._elTable.firstChild) {
-                    this._elCaption = this._elTable.appendChild(document.createElement("caption"));
-                }
-                else {
-                    this._elCaption = this._elTable.insertBefore(document.createElement("caption"), this._elTable.firstChild);
-                }
+                var bodyTable = this._elTbodyContainer.getElementsByTagName('table')[0];
+                
+                this._elCaption = bodyTable.createCaption();
             }
             // Set CAPTION value
             this._elCaption.innerHTML = sCaption;
@@ -435,467 +6259,237 @@
 
     /**
     * @attribute scrollable
-    * @description True if primary TBODY should scroll while THEAD remains fixed.
-    * When enabling this feature, captions cannot be used, and the following
-    * features are not recommended: inline editing, resizeable columns.
+    * @description True if primary TBODY should scroll.
     * @default false
     * @type Boolean
     */
     this.setAttributeConfig("scrollable", {
         value: false,
         validator: function(oParam) {
-            //TODO: validate agnst resizeable
-            return (YAHOO.lang.isBoolean(oParam) &&
-                    // Not compatible with caption
-                    !YAHOO.lang.isString(this.get("caption")));
+            return (lang.isBoolean(oParam));
         },
         method: function(oParam) {
+            var headTable = this._elTheadContainer.getElementsByTagName('table')[0],
+                bodyTable = this._elTbodyContainer.getElementsByTagName('table')[0],
+                headThead = headTable.getElementsByTagName('thead')[0],
+                bodyThead = bodyTable.getElementsByTagName('thead')[0];
+
             if(oParam) {
-                //TODO: conf height
-                YAHOO.util.Dom.addClass(this._elContainer,YAHOO.widget.DataTable.CLASS_SCROLLABLE);
-                YAHOO.util.Dom.addClass(this._elTbody,YAHOO.widget.DataTable.CLASS_SCROLLBODY);
+                if (headThead) {
+                    headTable.removeChild(headThead);
+                }
+                if (bodyThead) {
+                    bodyTable.removeChild(bodyThead);
+                }
+                headTable.appendChild(this._elThead);
+                bodyTable.insertBefore(this._elA11yThead,bodyTable.firstChild || null);
+
+                // Move the caption from the body table to the head table
+                // if there is a caption
+                if (bodyTable.caption) {
+                    headTable.insertBefore(bodyTable.caption,headTable.firstChild);
+                }
+
+                Dom.addClass(this._elContainer,DT.CLASS_SCROLLABLE);
+
+                // Bug 1716354 - fix gap in Safari 2 and 3 (also seen in
+                // other browsers)
+                bodyTable.style.marginTop = "-"+this._elTbody.offsetTop+"px";
+
+                this._syncColWidths();
+                this._syncScrollPadding();
             }
             else {
-                YAHOO.util.Dom.removeClass(this._elContainer,YAHOO.widget.DataTable.CLASS_SCROLLABLE);
-                YAHOO.util.Dom.removeClass(this._elTbody,YAHOO.widget.DataTable.CLASS_SCROLLBODY);
+                if (headThead) {
+                    headTable.removeChild(headThead);
+                }
+                if (bodyThead) {
+                    bodyTable.removeChild(bodyThead);
+                }
+                headTable.appendChild(this._elA11yThead);
+                bodyTable.insertBefore(this._elThead,bodyTable.firstChild || null);
+                bodyTable.style.marginTop = '';
 
+                // Move the caption from the head table to the body table
+                // if there is a caption
+                if (headTable.caption) {
+                    bodyTable.insertBefore(headTable.caption,bodyTable.firstChild);
+                }
+
+                Dom.removeClass(this._elContainer,DT.CLASS_SCROLLABLE);
             }
         }
     });
-};
 
+    /**
+    * @attribute width
+    * @description Table width for scrollable tables
+    * @type String
+    */
+    this.setAttributeConfig("width", {
+        value: null,
+        validator: lang.isString,
+        method: function(oParam) {
+            if(this.get("scrollable")) {
+                this._elTheadContainer.style.width = oParam;
+                this._elTbodyContainer.style.width = oParam;            
+            }
+        }
+    });
+
+    /**
+    * @attribute height
+    * @description Table height for scrollable tables
+    * @type String
+    */
+    this.setAttributeConfig("height", {
+        value: null,
+        validator: lang.isString,
+        method: function(oParam) {
+            if(this.get("scrollable")) {
+                this._elTbodyContainer.style.height = oParam;  
+            }          
+        }
+    });
+
+    /**
+    * @attribute draggableColumns
+    * @description True if Columns are draggable to reorder, false otherwise.
+    * The Drag & Drop Utility is required to enable this feature. Only top-level
+    * and non-nested Columns are draggable. Write once.
+    * @default false
+    * @type Boolean
+    */
+    this.setAttributeConfig("draggableColumns", {
+        value: false,
+        validator: lang.isBoolean,
+        writeOnce: true
+    });
+
+    /**
+     * @attribute renderLoopSize 	 
+     * @description A value greater than 0 enables DOM rendering of rows to be
+     * executed from a non-blocking timeout queue and sets how many rows to be
+     * rendered per timeout. Recommended for very large data sets.     
+     * @type Number 	 
+     * @default 0 	 
+     */ 	 
+     this.setAttributeConfig("renderLoopSize", { 	 
+         value: 0, 	 
+         validator: lang.isNumber 	 
+     }); 	 
+},
+
 /////////////////////////////////////////////////////////////////////////////
 //
-// Public constants
+// Private member variables
 //
 /////////////////////////////////////////////////////////////////////////////
 
 /**
- * Class name assigned to TABLE element.
+ * True if instance is initialized, so as to fire the initEvent rather than
+ * renderEvent.
  *
- * @property DataTable.CLASS_TABLE
- * @type String
- * @static
- * @final
- * @default "yui-dt-table"
+ * @property _bInit
+ * @type Boolean
+ * @default true
+ * @private
  */
-YAHOO.widget.DataTable.CLASS_TABLE = "yui-dt-table";
+_bInit : true,
 
 /**
- * Class name assigned to header container elements within each TH element.
+ * Index assigned to instance.
  *
- * @property DataTable.CLASS_HEADER
- * @type String
- * @static
- * @final
- * @default "yui-dt-header"
+ * @property _nIndex
+ * @type Number
+ * @private
  */
-YAHOO.widget.DataTable.CLASS_HEADER = "yui-dt-header";
+_nIndex : null,
 
 /**
- * Class name assigned to the primary TBODY element.
+ * Counter for IDs assigned to TR elements.
  *
- * @property DataTable.CLASS_BODY
- * @type String
- * @static
- * @final
- * @default "yui-dt-body"
+ * @property _nTrCount
+ * @type Number
+ * @private
  */
-YAHOO.widget.DataTable.CLASS_BODY = "yui-dt-body";
+_nTrCount : 0,
 
 /**
- * Class name assigned to the scrolling TBODY element of a fixed scrolling DataTable.
+ * Counter for IDs assigned to TD elements.
  *
- * @property DataTable.CLASS_SCROLLBODY
- * @type String
- * @static
- * @final
- * @default "yui-dt-scrollbody"
+ * @property _nTdCount
+ * @type Number
+ * @private
  */
-YAHOO.widget.DataTable.CLASS_SCROLLBODY = "yui-dt-scrollbody";
+_nTdCount : 0,
 
 /**
- * Class name assigned to display label elements.
+ * Unique id assigned to instance "yui-dtN", useful prefix for generating unique
+ * DOM ID strings and log messages.
  *
- * @property DataTable.CLASS_LABEL
+ * @property _sId
  * @type String
- * @static
- * @final
- * @default "yui-dt-label"
+ * @private
  */
-YAHOO.widget.DataTable.CLASS_LABEL = "yui-dt-label";
+_sId : null,
 
 /**
- * Class name assigned to resizer handle elements.
+ * Render chain.
  *
- * @property DataTable.CLASS_RESIZER
- * @type String
- * @static
- * @final
- * @default "yui-dt-resizer"
+ * @property _oChainRender
+ * @type YAHOO.util.Chain
+ * @private
  */
-YAHOO.widget.DataTable.CLASS_RESIZER = "yui-dt-resizer";
+_oChainRender : null,
 
 /**
- * Class name assigned to Editor container elements.
+ * Sync chain.
  *
- * @property DataTable.CLASS_EDITOR
- * @type String
- * @static
- * @final
- * @default "yui-dt-editor"
- */
-YAHOO.widget.DataTable.CLASS_EDITOR = "yui-dt-editor";
-
-/**
- * Class name assigned to paginator container elements.
- *
- * @property DataTable.CLASS_PAGINATOR
- * @type String
- * @static
- * @final
- * @default "yui-dt-paginator"
- */
-YAHOO.widget.DataTable.CLASS_PAGINATOR = "yui-dt-paginator";
-
-/**
- * Class name assigned to page number indicators.
- *
- * @property DataTable.CLASS_PAGE
- * @type String
- * @static
- * @final
- * @default "yui-dt-page"
- */
-YAHOO.widget.DataTable.CLASS_PAGE = "yui-dt-page";
-
-/**
- * Class name assigned to default indicators.
- *
- * @property DataTable.CLASS_DEFAULT
- * @type String
- * @static
- * @final
- * @default "yui-dt-default"
- */
-YAHOO.widget.DataTable.CLASS_DEFAULT = "yui-dt-default";
-
-/**
- * Class name assigned to previous indicators.
- *
- * @property DataTable.CLASS_PREVIOUS
- * @type String
- * @static
- * @final
- * @default "yui-dt-previous"
- */
-YAHOO.widget.DataTable.CLASS_PREVIOUS = "yui-dt-previous";
-
-/**
- * Class name assigned next indicators.
- *
- * @property DataTable.CLASS_NEXT
- * @type String
- * @static
- * @final
- * @default "yui-dt-next"
- */
-YAHOO.widget.DataTable.CLASS_NEXT = "yui-dt-next";
-
-/**
- * Class name assigned to first elements.
- *
- * @property DataTable.CLASS_FIRST
- * @type String
- * @static
- * @final
- * @default "yui-dt-first"
- */
-YAHOO.widget.DataTable.CLASS_FIRST = "yui-dt-first";
-
-/**
- * Class name assigned to last elements.
- *
- * @property DataTable.CLASS_LAST
- * @type String
- * @static
- * @final
- * @default "yui-dt-last"
- */
-YAHOO.widget.DataTable.CLASS_LAST = "yui-dt-last";
-
-/**
- * Class name assigned to even elements.
- *
- * @property DataTable.CLASS_EVEN
- * @type String
- * @static
- * @final
- * @default "yui-dt-even"
- */
-YAHOO.widget.DataTable.CLASS_EVEN = "yui-dt-even";
-
-/**
- * Class name assigned to odd elements.
- *
- * @property DataTable.CLASS_ODD
- * @type String
- * @static
- * @final
- * @default "yui-dt-odd"
- */
-YAHOO.widget.DataTable.CLASS_ODD = "yui-dt-odd";
-
-/**
- * Class name assigned to selected elements.
- *
- * @property DataTable.CLASS_SELECTED
- * @type String
- * @static
- * @final
- * @default "yui-dt-selected"
- */
-YAHOO.widget.DataTable.CLASS_SELECTED = "yui-dt-selected";
-
-/**
- * Class name assigned to highlighted elements.
- *
- * @property DataTable.CLASS_HIGHLIGHTED
- * @type String
- * @static
- * @final
- * @default "yui-dt-highlighted"
- */
-YAHOO.widget.DataTable.CLASS_HIGHLIGHTED = "yui-dt-highlighted";
-
-/**
- * Class name assigned to disabled elements.
- *
- * @property DataTable.CLASS_DISABLED
- * @type String
- * @static
- * @final
- * @default "yui-dt-disabled"
- */
-YAHOO.widget.DataTable.CLASS_DISABLED = "yui-dt-disabled";
-
-/**
- * Class name assigned to empty indicators.
- *
- * @property DataTable.CLASS_EMPTY
- * @type String
- * @static
- * @final
- * @default "yui-dt-empty"
- */
-YAHOO.widget.DataTable.CLASS_EMPTY = "yui-dt-empty";
-
-/**
- * Class name assigned to loading indicatorx.
- *
- * @property DataTable.CLASS_LOADING
- * @type String
- * @static
- * @final
- * @default "yui-dt-loading"
- */
-YAHOO.widget.DataTable.CLASS_LOADING = "yui-dt-loading";
-
-/**
- * Class name assigned to error indicators.
- *
- * @property DataTable.CLASS_ERROR
- * @type String
- * @static
- * @final
- * @default "yui-dt-error"
- */
-YAHOO.widget.DataTable.CLASS_ERROR = "yui-dt-error";
-
-/**
- * Class name assigned to editable elements.
- *
- * @property DataTable.CLASS_EDITABLE
- * @type String
- * @static
- * @final
- * @default "yui-dt-editable"
- */
-YAHOO.widget.DataTable.CLASS_EDITABLE = "yui-dt-editable";
-
-/**
- * Class name assigned to scrollable elements.
- *
- * @property DataTable.CLASS_SCROLLABLE
- * @type String
- * @static
- * @final
- * @default "yui-dt-scrollable"
- */
-YAHOO.widget.DataTable.CLASS_SCROLLABLE = "yui-dt-scrollable";
-
-/**
- * Class name assigned to sortable elements.
- *
- * @property DataTable.CLASS_SORTABLE
- * @type String
- * @static
- * @final
- * @default "yui-dt-sortable"
- */
-YAHOO.widget.DataTable.CLASS_SORTABLE = "yui-dt-sortable";
-
-/**
- * Class name assigned to ascending elements.
- *
- * @property DataTable.CLASS_ASC
- * @type String
- * @static
- * @final
- * @default "yui-dt-asc"
- */
-YAHOO.widget.DataTable.CLASS_ASC = "yui-dt-asc";
-
-/**
- * Class name assigned to descending elements.
- *
- * @property DataTable.CLASS_DESC
- * @type String
- * @static
- * @final
- * @default "yui-dt-desc"
- */
-YAHOO.widget.DataTable.CLASS_DESC = "yui-dt-desc";
-
-/**
- * Class name assigned to BUTTON elements and/or container elements.
- *
- * @property DataTable.CLASS_BUTTON
- * @type String
- * @static
- * @final
- * @default "yui-dt-button"
- */
-YAHOO.widget.DataTable.CLASS_BUTTON = "yui-dt-button";
-
-/**
- * Class name assigned to INPUT TYPE=CHECKBOX elements and/or container elements.
- *
- * @property DataTable.CLASS_CHECKBOX
- * @type String
- * @static
- * @final
- * @default "yui-dt-checkbox"
- */
-YAHOO.widget.DataTable.CLASS_CHECKBOX = "yui-dt-checkbox";
-
-/**
- * Class name assigned to SELECT elements and/or container elements.
- *
- * @property DataTable.CLASS_DROPDOWN
- * @type String
- * @static
- * @final
- * @default "yui-dt-dropdown"
- */
-YAHOO.widget.DataTable.CLASS_DROPDOWN = "yui-dt-dropdown";
-
-/**
- * Class name assigned to INPUT TYPE=RADIO elements and/or container elements.
- *
- * @property DataTable.CLASS_RADIO
- * @type String
- * @static
- * @final
- * @default "yui-dt-radio"
- */
-YAHOO.widget.DataTable.CLASS_RADIO = "yui-dt-radio";
-
-/**
- * Message to display if DataTable has no data.
- *
- * @property DataTable.MSG_EMPTY
- * @type String
- * @static
- * @final
- * @default "No records found."
- */
-YAHOO.widget.DataTable.MSG_EMPTY = "No records found.";
-
-/**
- * Message to display while DataTable is loading data.
- *
- * @property DataTable.MSG_LOADING
- * @type String
- * @static
- * @final
- * @default "Loading data..."
- */
-YAHOO.widget.DataTable.MSG_LOADING = "Loading data...";
-
-/**
- * Message to display while DataTable has data error.
- *
- * @property DataTable.MSG_ERROR
- * @type String
- * @static
- * @final
- * @default "Data error."
- */
-YAHOO.widget.DataTable.MSG_ERROR = "Data error.";
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Private member variables
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Internal class variable for indexing multiple DataTable instances.
- *
- * @property DataTable._nCount
- * @type Number
+ * @property _oChainSync
+ * @type YAHOO.util.Chain
  * @private
- * @static
  */
-YAHOO.widget.DataTable._nCount = 0;
+_oChainSync : null,
 
 /**
- * Index assigned to instance.
+ * Sparse array of custom functions to set column widths for browsers that don't
+ * support dynamic CSS rules.  Functions are added at the index representing
+ * the number of rows they update.
  *
- * @property _nIndex
- * @type Number
+ * @property _aFallbackColResizer
+ * @type Array
  * @private
  */
-YAHOO.widget.DataTable.prototype._nIndex = null;
+_aFallbackColResizer : [],
 
 /**
- * Counter for IDs assigned to TR elements.
+ * DOM reference to the container element for the DataTable instance into which
+ * all other elements get created.
  *
- * @property _nTrCount
- * @type Number
+ * @property _elContainer
+ * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._nTrCount = 0;
+_elContainer : null,
 
 /**
- * Unique name assigned to instance.
+ * DOM reference to the container element for the DataTable's primary THEAD.
  *
- * @property _sName
- * @type String
+ * @property _elTheadContainer
+ * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._sName = null;
+_elTheadContainer : null,
 
 /**
- * DOM reference to the container element for the DataTable instance into which
- * the TABLE element gets created.
+ * DOM reference to the container element for the DataTable's primary TBODY.
  *
- * @property _elContainer
+ * @property _elTbodyContainer
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elContainer = null;
+_elTbodyContainer : null,
 
 /**
  * DOM reference to the CAPTION element for the DataTable instance.
@@ -904,25 +6498,16 @@
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elCaption = null;
+_elCaption : null,
 
 /**
- * DOM reference to the TABLE element for the DataTable instance.
+ * DOM reference to the primary THEAD element for the DataTable instance.
  *
- * @property _elTable
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.DataTable.prototype._elTable = null;
-
-/**
- * DOM reference to the THEAD element for the DataTable instance.
- *
  * @property _elThead
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elThead = null;
+_elThead : null,
 
 /**
  * DOM reference to the primary TBODY element for the DataTable instance.
@@ -931,7 +6516,7 @@
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elTbody = null;
+_elTbody : null,
 
 /**
  * DOM reference to the secondary TBODY element used to display DataTable messages.
@@ -940,7 +6525,7 @@
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elMsgTbody = null;
+_elMsgTbody : null,
 
 /**
  * DOM reference to the secondary TBODY element's single TR element used to display DataTable messages.
@@ -949,7 +6534,7 @@
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elMsgTbodyRow = null;
+_elMsgTbodyRow : null,
 
 /**
  * DOM reference to the secondary TBODY element's single TD element used to display DataTable messages.
@@ -958,7 +6543,7 @@
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elMsgTbodyCell = null;
+_elMsgTbodyCell : null,
 
 /**
  * DataSource instance for the DataTable instance.
@@ -967,7 +6552,7 @@
  * @type YAHOO.util.DataSource
  * @private
  */
-YAHOO.widget.DataTable.prototype._oDataSource = null;
+_oDataSource : null,
 
 /**
  * ColumnSet instance for the DataTable instance.
@@ -976,7 +6561,7 @@
  * @type YAHOO.widget.ColumnSet
  * @private
  */
-YAHOO.widget.DataTable.prototype._oColumnSet = null;
+_oColumnSet : null,
 
 /**
  * RecordSet instance for the DataTable instance.
@@ -985,26 +6570,16 @@
  * @type YAHOO.widget.RecordSet
  * @private
  */
-YAHOO.widget.DataTable.prototype._oRecordSet = null;
+_oRecordSet : null,
 
 /**
- * ID string of first label link element of the current DataTable page, if any.
- * Used for focusing sortable Columns with TAB.
- *
- * @property _sFirstLabelLinkId
- * @type String
- * @private
- */
-YAHOO.widget.DataTable.prototype._sFirstLabelLinkId = null;
-
-/**
  * ID string of first TR element of the current DataTable page.
  *
  * @property _sFirstTrId
  * @type String
  * @private
  */
-YAHOO.widget.DataTable.prototype._sFirstTrId = null;
+_sFirstTrId : null,
 
 /**
  * ID string of the last TR element of the current DataTable page.
@@ -1013,10 +6588,31 @@
  * @type String
  * @private
  */
-YAHOO.widget.DataTable.prototype._sLastTrId = null;
+_sLastTrId : null,
 
+/**
+ * Template cell to create all new cells from.
+ * @property _tdElTemplate
+ * @type {HTMLElement}
+ * @private 
+ */
+_tdElTemplate : null,
 
+/**
+ * Template row to create all new rows from.
+ * @property _trElTemplate
+ * @type {HTMLElement}
+ * @private 
+ */
+_trElTemplate : null,
 
+/**
+ * True if x-scrollbar is currently visible.
+ * @property _bScrollbarX
+ * @type {Boolean}
+ * @private 
+ */
+_bScrollbarX : null,
 
 
 
@@ -1044,8 +6640,6 @@
 
 
 
-
-
 /////////////////////////////////////////////////////////////////////////////
 //
 // Private methods
@@ -1053,40 +6647,348 @@
 /////////////////////////////////////////////////////////////////////////////
 
 /**
+ * Clears browser text selection. Useful to call on rowSelectEvent or
+ * cellSelectEvent to prevent clicks or dblclicks from selecting text in the
+ * browser.
+ *
+ * @method clearTextSelection
+ */
+clearTextSelection : function() {
+    var sel;
+    if(window.getSelection) {
+    	sel = window.getSelection();
+    }
+    else if(document.getSelection) {
+    	sel = document.getSelection();
+    }
+    else if(document.selection) {
+    	sel = document.selection;
+    }
+    if(sel) {
+        if(sel.empty) {
+            sel.empty();
+        }
+        else if (sel.removeAllRanges) {
+            sel.removeAllRanges();
+        }
+        else if(sel.collapse) {
+            sel.collapse();
+        }
+    }
+},
+
+/**
  * Sets focus on the given element.
  *
  * @method _focusEl
  * @param el {HTMLElement} Element.
  * @private
  */
-YAHOO.widget.DataTable.prototype._focusEl = function(el) {
-    el = el || this._elTable;
+_focusEl : function(el) {
+    el = el || this._elTbody;
     // http://developer.mozilla.org/en/docs/index.php?title=Key-navigable_custom_DHTML_widgets
     // The timeout is necessary in both IE and Firefox 1.5, to prevent scripts from doing
     // strange unexpected things as the user clicks on buttons and other controls.
-    setTimeout(function() { el.focus(); },0);
-};
+    setTimeout(function() {
+        try {
+            el.focus();
+        }
+        catch(e) {
+        }
+    },0);
+},
 
+/**
+ * Post render syncing of Column widths and scroll padding
+ *
+ * @method _sync
+ * @private
+ */
+_sync : function() {
+    this._syncColWidths();
+    this._forceGeckoRedraw();
+},
 
+/**
+ * Syncs up widths of THs and TDs across all those Columns without width values.
+ * Actual adjustment is to the liner DIVs so window resizing will not affect cells. 
+ *
+ * @method _syncColWidths
+ * @private
+ */
+_syncColWidths : function() {
+    if(!this.get('scrollable')) {
+        return;
+    }
 
+    if(this._elTbody.rows.length > 0) {
+        // Validate there is at least one row with cells and at least one Column
+        var allKeys = this._oColumnSet.keys,
+            elRow = this.getFirstTrEl();
+    
+        if(allKeys && elRow && (elRow.cells.length === allKeys.length)) {
+            // Temporarily unsnap container since it causes inaccurate calculations
+            var bUnsnap = false;
+            if((YAHOO.env.ua.gecko || YAHOO.env.ua.opera) && this.get("scrollable")) {
+                bUnsnap = true;
+                if(this.get("width")) {
+                    this._elTheadContainer.style.width = "";
+                    this._elTbodyContainer.style.width = "";
+                }
+                else {
+                    this._elContainer.style.width = "";
+                }
+            }
+    
+            var i,
+                oColumn,
+                cellsLen = elRow.cells.length;
+            // First time through, reset the widths to get an accurate measure of the TD
+            for(i=0; i<cellsLen; i++) {
+                oColumn = allKeys[i];
+                // Only for Columns without widths
+                if(!oColumn.width) {
+                    this._setColumnWidth(oColumn, "auto");
+                }
+            }
+    
+            // Calculate width for every Column
+            for(i=0; i<cellsLen; i++) {
+                oColumn = allKeys[i];
+                var newWidth;
+                
+                // Columns without widths
+                if(!oColumn.width) {
+                    var elTh = oColumn.getThEl();
+                    var elTd = elRow.cells[i];
+                    
+                    if(elTh.offsetWidth !== elTd.offsetWidth) {
+                        var elWider = (elTh.offsetWidth > elTd.offsetWidth) ? elTh.firstChild : elTd.firstChild;               
+                        // Calculate the final width by comparing liner widths
+                        newWidth = elWider.offsetWidth -
+                                (parseInt(Dom.getStyle(elWider,"paddingLeft"),10)|0) -
+                                (parseInt(Dom.getStyle(elWider,"paddingRight"),10)|0);
+                        
+                        // Validate against minWidth        
+                        newWidth = (oColumn.minWidth && (oColumn.minWidth > newWidth)) ?
+                                oColumn.minWidth : newWidth;
+                
+                    }
+                }
+                // Columns with widths
+                else {
+                    newWidth = oColumn.width;
+                }
+                
+                // Hidden Columns
+                if(oColumn.hidden) {
+                    oColumn._nLastWidth = newWidth;
+                    newWidth = 1;
+                }
+                
+                // Update to the new width
+                if(newWidth) {
+                    this._setColumnWidth(oColumn, newWidth+"px"); 
+                }
+            }
+            
+            // Resnap unsnapped containers
+            if(bUnsnap) {
+                var sWidth = this.get("width");
+                this._elTheadContainer.style.width = sWidth;
+                this._elTbodyContainer.style.width = sWidth;     
+            } 
+        }
+    }
 
+    this._syncScrollPadding();
+},
 
+/**
+ * Syncs padding around scrollable tables, including Column header right-padding
+ * and container width and height.
+ *
+ * @method _syncScrollPadding
+ * @private
+ */
+_syncScrollPadding : function() {
+    // Proceed only if scrollable is enabled
+    if(this.get("scrollable")) {
+        var elTbody = this._elTbody,
+            elTbodyContainer = this._elTbodyContainer,
+            aLastHeaders, len, prefix, i, elLiner;
+        
+        // IE 6 and 7 only when y-scrolling not enabled
+        if(!this.get("height") && (ua.ie)) {
+            // Snap outer container height to content
+            // but account for x-scrollbar if it is visible
+            if(elTbody.rows.length > 0) {
+                elTbodyContainer.style.height = 
+                        (elTbodyContainer.scrollWidth > elTbodyContainer.offsetWidth) ?
+                        (elTbody.offsetHeight + 19) + "px" : 
+                        elTbody.offsetHeight + "px";
+            }
+            else {
+                elTbodyContainer.style.height = 
+                        (elTbodyContainer.scrollWidth > elTbodyContainer.offsetWidth) ?
+                        (this._elMsgTbody.offsetHeight + 19) + "px" : 
+                        this._elMsgTbody.offsetHeight + "px";
+            }
+        }
+
+        // X-scrolling not enabled
+        if(!this.get("width")) {
+            // Snap outer container width to content
+            // but account for y-scrollbar if it is visible
+            this._elContainer.style.width = 
+                    (elTbodyContainer.scrollHeight > elTbodyContainer.offsetHeight) ?
+                    (elTbody.parentNode.offsetWidth + 19) + "px" :
+                    //TODO: Can we detect left and right border widths instead of hard coding?
+                    (elTbody.parentNode.offsetWidth + 2) + "px";
+        }
+        // X-scrolling is enabled and x-scrollbar is visible
+        else if((elTbodyContainer.scrollWidth > elTbodyContainer.offsetWidth) ||
+            ((elTbodyContainer.scrollHeight > elTbodyContainer.offsetHeight) && (elTbodyContainer.scrollWidth > elTbodyContainer.offsetWidth-16))) {
+            // Perform sync routine
+            if(!this._bScrollbarX) {
+                // Add Column header right-padding
+                aLastHeaders = this._oColumnSet.headers[this._oColumnSet.headers.length-1];
+                len = aLastHeaders.length;
+                prefix = this._sId+"-th";
+                for(i=0; i<len; i++) {
+                    //TODO: A better way to get th cell
+                    elLiner = Dom.get(prefix+aLastHeaders[i]).firstChild;
+                    elLiner.style.marginRight = 
+                            (parseInt(Dom.getStyle(elLiner,"marginRight"),10) + 
+                            16) + "px";
+                }
+                
+                // Save state   
+                this._bScrollbarX = true;
+            }
+        }
+        // X-scrollbar enabled but x-scrollbar is not visible
+        else {
+            // Perform sync routine
+            if(this._bScrollbarX) {                 
+                // Remove Column header right-padding                   
+                aLastHeaders = this._oColumnSet.headers[this._oColumnSet.headers.length-1];
+                len = aLastHeaders.length;
+                prefix = this._sId+"-th";
+                for(i=0; i<len; i++) {
+                    //TODO: A better way to get th cell
+                    elLiner = Dom.get(prefix+aLastHeaders[i]).firstChild;
+                    Dom.setStyle(elLiner,"marginRight","");
+                }
+                                        
+                // Save state
+                this._bScrollbarX = false;
+            }
+        }
+    
+        // Sync message tbody
+        if(this._elTbody.rows.length === 0) {
+            this._elMsgTbody.parentNode.width = this.getTheadEl().parentNode.offsetWidth;
+        }
+        else {
+            this._elMsgTbody.parentNode.width = "";
+        }
+    }
+},
+
+/**
+ * Forces Gecko repaint by removing/adding the no-op class name
+ *
+ * @method _forceGeckoRedraw
+ * @private
+ */
+_forceGeckoRedraw : function() {
+    // Bug 1741322: Needed to force FF to redraw to fix squishy headers on wide tables when new content comes in
+    if(ua.gecko) {
+        var elContainer = this.getContainerEl();
+        setTimeout(function() {
+            Dom.removeClass(elContainer,"yui-dt-noop");
+        },0);
+        setTimeout(function() {
+            Dom.addClass(elContainer,"yui-dt-noop");
+        },0);
+    }
+},
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 // INIT FUNCTIONS
 
 /**
- * Initializes container element.
+ * Initializes the HTMLElement templates used to create various table child
+ * nodes.
+ * @method _initNodeTemplates
+ * @private
+ */
+_initNodeTemplates : function () {
+    var d   = document,
+        tr  = d.createElement('tr'),
+        td  = d.createElement('td'),
+        div = d.createElement('div');
+
+    // Append the liner element
+    td.appendChild(div);
+
+    this._tdElTemplate = td;
+    this._trElTemplate = tr;
+},
+
+/**
+ * Initializes the DataTable container element.
  *
  * @method _initContainerEl
  * @param elContainer {HTMLElement | String} HTML DIV element by reference or ID.
  * @private
  */
-YAHOO.widget.DataTable.prototype._initContainerEl = function(elContainer) {
-    this._elContainer = null;
-    elContainer = YAHOO.util.Dom.get(elContainer);
-    if(elContainer && elContainer.tagName && (elContainer.tagName.toLowerCase() == "div")) {
+_initContainerEl : function(elContainer) {
+    // Clear any previous container
+    if(this._elContainer) {
+        Ev.purgeElement(this._elContainer, true);
+        this._elContainer.innerHTML = "";
+    }
+
+    elContainer = Dom.get(elContainer);
+    if(elContainer && elContainer.nodeName && (elContainer.nodeName.toLowerCase() == "div")) {
+        // Esp for progressive enhancement
+        Ev.purgeElement(elContainer, true);
+        elContainer.innerHTML = "";
+
+        Dom.addClass(elContainer,"yui-dt yui-dt-noop");
+        
+        // Container for header TABLE
+        this._elTheadContainer = elContainer.appendChild(document.createElement("div"));
+        Dom.addClass(this._elTheadContainer, "yui-dt-hd");
+
+        // Container for body TABLE
+        this._elTbodyContainer = elContainer.appendChild(document.createElement("div"));
+        Dom.addClass(this._elTbodyContainer, "yui-dt-bd");
+
         this._elContainer = elContainer;
     }
-};
+},
 
 /**
  * Initializes object literal of config values.
@@ -1095,21 +6997,24 @@
  * @param oConfig {Object} Object literal of config values.
  * @private
  */
-YAHOO.widget.DataTable.prototype._initConfigs = function(oConfigs) {
+_initConfigs : function(oConfigs) {
     if(oConfigs) {
         if(oConfigs.constructor != Object) {
             oConfigs = null;
             YAHOO.log("Invalid configs", "warn", this.toString());
         }
         // Backward compatibility
-        else if(YAHOO.lang.isBoolean(oConfigs.paginator)) {
+        else if(lang.isBoolean(oConfigs.paginator)) {
             YAHOO.log("DataTable's paginator model has been revised" +
             " -- please refer to the documentation for implementation" +
             " details", "warn", this.toString());
         }
         this._oConfigs = oConfigs;
     }
-};
+    else {
+        this._oConfigs = {};
+    }
+},
 
 /**
  * Initializes ColumnSet.
@@ -1118,9 +7023,17 @@
  * @param aColumnDefs {Object[]} Array of object literal Column definitions.
  * @private
  */
-YAHOO.widget.DataTable.prototype._initColumnSet = function(aColumnDefs) {
-    this._oColumnSet = null;
-    if(YAHOO.lang.isArray(aColumnDefs)) {
+_initColumnSet : function(aColumnDefs) {
+    if(this._oColumnSet) {
+        // First clear _oStylesheetRules for existing ColumnSet
+        for(var i=0, l=this._oColumnSet.keys.length; i<l; i++) {
+            DT._oStylesheetRules[".yui-dt-col-"+this._oColumnSet.keys[i].getId()] = undefined;
+        }
+        
+        this._oColumnSet = null;
+    }
+    
+    if(lang.isArray(aColumnDefs)) {
         this._oColumnSet =  new YAHOO.widget.ColumnSet(aColumnDefs);
     }
     // Backward compatibility
@@ -1130,8 +7043,10 @@
         " of object literal Column definitions instead of a ColumnSet instance",
         "warn", this.toString());
     }
-};
 
+
+},
+
 /**
  * Initializes DataSource.
  *
@@ -1139,9 +7054,9 @@
  * @param oDataSource {YAHOO.util.DataSource} DataSource instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._initDataSource = function(oDataSource) {
+_initDataSource : function(oDataSource) {
     this._oDataSource = null;
-    if(oDataSource && (oDataSource instanceof YAHOO.util.DataSource)) {
+    if(oDataSource && (oDataSource instanceof DS)) {
         this._oDataSource = oDataSource;
     }
     // Backward compatibility
@@ -1153,7 +7068,7 @@
         if(tmpContainer.hasChildNodes()) {
             var tmpChildren = tmpContainer.childNodes;
             for(i=0; i<tmpChildren.length; i++) {
-                if(tmpChildren[i].tagName && tmpChildren[i].tagName.toLowerCase() == "table") {
+                if(tmpChildren[i].nodeName && tmpChildren[i].nodeName.toLowerCase() == "table") {
                     tmpTable = tmpChildren[i];
                     break;
                 }
@@ -1164,15 +7079,15 @@
                     tmpFieldsArray.push({key:this._oColumnSet.keys[i].key});
                 }
 
-                this._oDataSource = new YAHOO.util.DataSource(tmpTable);
-                this._oDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
+                this._oDataSource = new DS(tmpTable);
+                this._oDataSource.responseType = DS.TYPE_HTMLTABLE;
                 this._oDataSource.responseSchema = {fields: tmpFieldsArray};
                 YAHOO.log("Null DataSource for progressive enhancement from" +
                 " markup has been deprecated", "warn", this.toString());
             }
         }
     }
-};
+},
 
 /**
  * Initializes RecordSet.
@@ -1180,14 +7095,14 @@
  * @method _initRecordSet
  * @private
  */
-YAHOO.widget.DataTable.prototype._initRecordSet = function() {
+_initRecordSet : function() {
     if(this._oRecordSet) {
         this._oRecordSet.reset();
     }
     else {
         this._oRecordSet = new YAHOO.widget.RecordSet();
     }
-};
+},
 
 /**
  * Creates HTML markup for TABLE, THEAD and TBODY elements.
@@ -1195,205 +7110,369 @@
  * @method _initTableEl
  * @private
  */
-YAHOO.widget.DataTable.prototype._initTableEl = function() {
-    // Clear the container
-    YAHOO.util.Event.purgeElement(this._elContainer, true);
-    this._elContainer.innerHTML = "";
+_initTableEl : function() {
+    var elTable;
 
+    // Destroy existing
+    if(this._elThead) {
+        var i;
+        // Destroy ColumnDDs
+        var aTree = this._oColumnSet.tree[0];
+        for(i=0; i<aTree.length; i++) {
+            if(aTree[i]._dd) {
+                aTree[i]._dd = aTree[i]._dd.unreg();
+            }
+        }
+    
+        // Destroy ColumnResizers
+        var aKeys = this._oColumnSet.keys;
+        for(i=0; i<aKeys.length; i++) {
+            if(aKeys[i]._ddResizer) {
+                aKeys[i]._ddResizer = aKeys[i]._ddResizer.unreg();
+            }
+        }
+        elTable = this._elThead.parentNode;
+        Ev.purgeElement(elTable, true);
+        elTable.parentNode.removeChild(elTable);
+        this._elThead = null;
+    }
+    if(this._elTbody) {
+        elTable = this._elTbody.parentNode;
+        Ev.purgeElement(elTable, true);
+        elTable.parentNode.removeChild(elTable);
+        this._elTbody = null;
+    }
+
+    // Create elements for header
     // Create TABLE
-    this._elTable = this._elContainer.appendChild(document.createElement("table"));
-    var elTable = this._elTable;
-    elTable.tabIndex = 0;
-    elTable.id = this.id + "-table";
-    YAHOO.util.Dom.addClass(elTable, YAHOO.widget.DataTable.CLASS_TABLE);
+    var elHeadTable = document.createElement("table");
+    elHeadTable.id = this._sId + "-headtable";
+    elHeadTable = this._elTheadContainer.appendChild(elHeadTable);
 
-    // Create THEAD
-    this._initTheadEl(elTable, this._oColumnSet);
+    // Create elements for body
+    // Create TABLE
+    var elBodyTable = document.createElement("table");
+    elBodyTable.id = this._sId + "-bodytable";
+    this._elTbodyContainer.appendChild(elBodyTable);
 
+    // Create THEAD for display and for a11y
+    this._initTheadEls();
 
+    // Create TBODY for data
+    this._elTbody = elBodyTable.appendChild(document.createElement("tbody"));
+    this._elTbody.tabIndex = 0;
+    Dom.addClass(this._elTbody,DT.CLASS_BODY);
+
     // Create TBODY for messages
     var elMsgTbody = document.createElement("tbody");
     var elMsgRow = elMsgTbody.appendChild(document.createElement("tr"));
-    YAHOO.util.Dom.addClass(elMsgRow,YAHOO.widget.DataTable.CLASS_FIRST);
-    YAHOO.util.Dom.addClass(elMsgRow,YAHOO.widget.DataTable.CLASS_LAST);
+    Dom.addClass(elMsgRow,DT.CLASS_FIRST);
+    Dom.addClass(elMsgRow,DT.CLASS_LAST);
     this._elMsgRow = elMsgRow;
     var elMsgCell = elMsgRow.appendChild(document.createElement("td"));
     elMsgCell.colSpan = this._oColumnSet.keys.length;
-    YAHOO.util.Dom.addClass(elMsgCell,YAHOO.widget.DataTable.CLASS_FIRST);
-    YAHOO.util.Dom.addClass(elMsgCell,YAHOO.widget.DataTable.CLASS_LAST);
+    Dom.addClass(elMsgCell,DT.CLASS_FIRST);
+    Dom.addClass(elMsgCell,DT.CLASS_LAST);
     this._elMsgTd = elMsgCell;
-    this._elMsgTbody = elTable.appendChild(elMsgTbody);
-    this.showTableMessage(YAHOO.widget.DataTable.MSG_LOADING, YAHOO.widget.DataTable.CLASS_LOADING);
+    this._elMsgTbody = elBodyTable.appendChild(elMsgTbody);
+    var elMsgCellLiner = elMsgCell.appendChild(document.createElement("div"));
+    Dom.addClass(elMsgCellLiner,DT.CLASS_LINER);
+    this.showTableMessage(DT.MSG_LOADING, DT.CLASS_LOADING);
 
-    // Create TBODY for data
-    this._elTbody = elTable.appendChild(document.createElement("tbody"));
-    YAHOO.util.Dom.addClass(this._elTbody,YAHOO.widget.DataTable.CLASS_BODY);
-};
+    var elContainer = this._elContainer;
+    var elThead = this._elThead;
+    var elTbody = this._elTbody;
+    
+    // IE puts focus outline in the wrong place
+    if(ua.ie) {
+        elTbody.hideFocus=true;
+    }
+    var elTbodyContainer = this._elTbodyContainer;
 
+    // Set up DOM events
+    Ev.addListener(elContainer, "focus", this._onTableFocus, this);
+    Ev.addListener(elTbody, "focus", this._onTbodyFocus, this);
+
+    Ev.addListener(elTbody, "mouseover", this._onTableMouseover, this);
+    Ev.addListener(elTbody, "mouseout", this._onTableMouseout, this);
+    Ev.addListener(elTbody, "mousedown", this._onTableMousedown, this);
+
+    Ev.addListener(elTbody, "keydown", this._onTbodyKeydown, this);
+
+    Ev.addListener(elTbody, "keypress", this._onTableKeypress, this);
+
+    // Since we can't listen for click and dblclick on the same element...
+    Ev.addListener(elTbody.parentNode, "dblclick", this._onTableDblclick, this);
+    Ev.addListener(elTbody, "click", this._onTbodyClick, this);
+
+    Ev.addListener(elTbodyContainer, "scroll", this._onScroll, this); // to sync horiz scroll headers
+},
+
 /**
- * Populates THEAD element with TH cells as defined by ColumnSet.
+ * Initializes THEAD elements for display and for screen readers.
  *
- * @method _initTheadEl
+ * @method _initTheadEls
  * @private
  */
-YAHOO.widget.DataTable.prototype._initTheadEl = function() {
-    var i,oColumn, colId;
-    var oColumnSet = this._oColumnSet;
-    this._sFirstLabelLinkId = null;
+_initTheadEls : function() {
+    var i,j, l, elThead, elA11yThead, aTheads;
     
-    // Create THEAD
-    var elThead = document.createElement("thead");
+    // First time through
+    if(!this._elThead) {
+        // Create THEADs
+        elThead     = this._elThead     = document.createElement('thead');
+        elA11yThead = this._elA11yThead = document.createElement('thead');
+        
+        aTheads = [elThead, elA11yThead];
 
-    // Iterate through each row of Column headers...
-    var colTree = oColumnSet.tree;
-    for(i=0; i<colTree.length; i++) {
-        var elTheadRow = elThead.appendChild(document.createElement("tr"));
-        elTheadRow.id = this.id+"-hdrow"+i;
-
-        var elTheadCell;
-        // ...and create THEAD cells
-        for(var j=0; j<colTree[i].length; j++) {
-            oColumn = colTree[i][j];
-            elTheadCell = elTheadRow.appendChild(document.createElement("th"));
-            elTheadCell.id = this.id+"-col" + oColumn.getId();
-            this._initThEl(elTheadCell,oColumn,i,j);
+        Ev.addListener(elThead, "focus", this._onTheadFocus, this);
+        Ev.addListener(elThead, "keydown", this._onTheadKeydown, this);
+        Ev.addListener(elThead, "mouseover", this._onTableMouseover, this);
+        Ev.addListener(elThead, "mouseout", this._onTableMouseout, this);
+        Ev.addListener(elThead, "mousedown", this._onTableMousedown, this);
+        Ev.addListener(elThead, "mouseup", this._onTableMouseup, this);
+        Ev.addListener(elThead, "click", this._onTheadClick, this);
+        Ev.addListener(elThead.parentNode, "dblclick", this._onTableDblclick, this);
+        
+        // Add the accessibility-only thead to the header table by default.
+        // The theads will be swapped for scrollable DataTables, the display
+        // thead fixed in place, and the a11y thead hidden
+        this._elTheadContainer.firstChild.appendChild(elA11yThead);
+        this._elTbodyContainer.firstChild.appendChild(elThead);
+    }
+    // Reinitialization
+    else {
+        // Clear rows from THEADs
+        elThead = this._elThead;
+        elA11yThead = this._elA11yThead;
+        aTheads = [elThead, elA11yThead];
+            
+        for(i=0; i<aTheads.length; i++) {
+            for(j=aTheads[i].rows.length-1; j>-1; j--) {
+                Ev.purgeElement(aTheads[i].rows[j], true);
+                aTheads[i].removeChild(aTheads[i].rows[j]);
+            }     
         }
-
-        // Set FIRST/LAST on THEAD rows
-        if(i === 0) {
-            YAHOO.util.Dom.addClass(elTheadRow, YAHOO.widget.DataTable.CLASS_FIRST);
-        }
-        if(i === (colTree.length-1)) {
-            YAHOO.util.Dom.addClass(elTheadRow, YAHOO.widget.DataTable.CLASS_LAST);
-        }
     }
 
-    this._elThead = this._elTable.appendChild(elThead);
+    
+    var oColumn,
+        oColumnSet = this._oColumnSet;
 
-    // Set FIRST/LAST on THEAD cells using the values in ColumnSet headers array
-    var aFirstHeaders = oColumnSet.headers[0];
-    var aLastHeaders = oColumnSet.headers[oColumnSet.headers.length-1];
-    for(i=0; i<aFirstHeaders.length; i++) {
-        YAHOO.util.Dom.addClass(YAHOO.util.Dom.get(this.id+"-col"+aFirstHeaders[i]), YAHOO.widget.DataTable.CLASS_FIRST);
-    }
-    for(i=0; i<aLastHeaders.length; i++) {
-        YAHOO.util.Dom.addClass(YAHOO.util.Dom.get(this.id+"-col"+aLastHeaders[i]), YAHOO.widget.DataTable.CLASS_LAST);
-    }
+    // Add TRs to the THEADs
+    var colTree = oColumnSet.tree;
+    var elTheadCell, id;
+    for(l=0; l<aTheads.length; l++) {
+        for(i=0; i<colTree.length; i++) {
+            var elTheadRow = aTheads[l].appendChild(document.createElement("tr"));
+            id = (l===1) ? this._sId+"-hdrow" + i + "-a11y": this._sId+"-hdrow" + i;
+            elTheadRow.id = id;
     
-    // Add Resizer only after DOM has been updated
-    var foundDD = (YAHOO.util.DD) ? true : false;
-    var needDD = false;
-    for(i=0; i<this._oColumnSet.keys.length; i++) {
-        oColumn = this._oColumnSet.keys[i];
-        var colKey = oColumn.getKey();
-        var elTheadCellId = YAHOO.util.Dom.get(this.id + "-col" + oColumn.getId());
-        if(oColumn.resizeable) {
-            if(foundDD) {
-                //TODO: fix fixed width tables
-                // Skip the last column for fixed-width tables
-                if(!this.fixedWidth || (this.fixedWidth &&
-                        (oColumn.getKeyIndex() != this._oColumnSet.keys.length-1))) {
-                    // TODO: better way to get elTheadContainer
-                    var elThContainer = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_HEADER,"div",elTheadCellId)[0];
-                    var elThResizer = elThContainer.appendChild(document.createElement("span"));
-                    elThResizer.id = this.id + "-resizer-" + colKey;
-                    YAHOO.util.Dom.addClass(elThResizer,YAHOO.widget.DataTable.CLASS_RESIZER);
-                    oColumn.ddResizer = new YAHOO.util.ColumnResizer(
-                            this, oColumn, elTheadCellId, elThResizer.id, elThResizer.id);
-                    var cancelClick = function(e) {
-                        YAHOO.util.Event.stopPropagation(e);
-                    };
-                    YAHOO.util.Event.addListener(elThResizer,"click",cancelClick);
+            // ...and create TH cells
+            for(j=0; j<colTree[i].length; j++) {
+                oColumn = colTree[i][j];
+                elTheadCell = elTheadRow.appendChild(document.createElement("th"));
+                if(l===0) {
+                    oColumn._elTh = elTheadCell;
                 }
-                if(this.fixedWidth) {
-                    //TODO: fix fixedWidth
-                    //elThContainer.style.overflow = "hidden";
-                    //TODO: better way to get elTheadText
-                    var elThLabel = (YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_LABEL,"span",elTheadCellId))[0];
-                    elThLabel.style.overflow = "hidden";
+                id = (l===1) ? this._sId+"-th" + oColumn.getId() + "-a11y": this._sId+"-th" + oColumn.getId();
+                elTheadCell.id = id;
+                elTheadCell.yuiCellIndex = j;
+                this._initThEl(elTheadCell,oColumn,i,j, (l===1));
+            }
+    
+            if(l===0) {
+                // Set FIRST/LAST on THEAD rows
+                if(i === 0) {
+                    Dom.addClass(elTheadRow, DT.CLASS_FIRST);
                 }
+                if(i === (colTree.length-1)) {
+                    Dom.addClass(elTheadRow, DT.CLASS_LAST);
+                }
             }
-            else {
-                needDD = true;
+        }
+
+        if(l===0) {
+            // Set FIRST/LAST on TH elements using the values in ColumnSet headers array
+            var aFirstHeaders = oColumnSet.headers[0];
+            var aLastHeaders = oColumnSet.headers[oColumnSet.headers.length-1];
+            for(i=0; i<aFirstHeaders.length; i++) {
+                //TODO: A better way to get th cell
+                Dom.addClass(Dom.get(this._sId+"-th"+aFirstHeaders[i]), DT.CLASS_FIRST);
             }
+            for(i=0; i<aLastHeaders.length; i++) {
+                //TODO: A better way to get th cell
+                Dom.addClass(Dom.get(this._sId+"-th"+aLastHeaders[i]), DT.CLASS_LAST);
+            }
+        
+            // Add DD features only after DOM has been updated
+            var foundDD = (util.DD) ? true : false;
+            var needDD = false;
+            // draggable
+            // HACK: Not able to use attribute since this code is run before
+            // attributes are initialized
+            if(this._oConfigs.draggableColumns) {
+                for(i=0; i<this._oColumnSet.tree[0].length; i++) {
+                    oColumn = this._oColumnSet.tree[0][i];
+                    if(foundDD) {
+                        elTheadCell = oColumn.getThEl();
+                        Dom.addClass(elTheadCell, DT.CLASS_DRAGGABLE);
+                        var elDragTarget = DT._initColumnDragTargetEl();
+                        oColumn._dd = new YAHOO.widget.ColumnDD(this, oColumn, elTheadCell, elDragTarget);
+                    }
+                    else {
+                        needDD = true;
+                    }    
+                }
+            }
+            // resizeable
+            for(i=0; i<this._oColumnSet.keys.length; i++) {
+                oColumn = this._oColumnSet.keys[i];
+                if(oColumn.resizeable) {
+                    if(foundDD) {
+                        elTheadCell = oColumn.getThEl();
+                        Dom.addClass(elTheadCell, DT.CLASS_RESIZEABLE);
+                        var elThLiner = elTheadCell.firstChild;
+                        var elThResizer = elThLiner.appendChild(document.createElement("div"));
+                        elThResizer.id = this._sId + "-colresizer" + oColumn.getId();
+                        oColumn._elResizer = elThResizer;
+                        Dom.addClass(elThResizer,DT.CLASS_RESIZER);
+                        var elResizerProxy = DT._initColumnResizerProxyEl();
+                        oColumn._ddResizer = new YAHOO.util.ColumnResizer(
+                                this, oColumn, elTheadCell, elThResizer.id, elResizerProxy);
+                        var cancelClick = function(e) {
+                            Ev.stopPropagation(e);
+                        };
+                        Ev.addListener(elThResizer,"click",cancelClick);
+                    }
+                    else {
+                        needDD = true;
+                    }
+                }
+            }
+            if(needDD) {
+                YAHOO.log("Could not find DragDrop dependancy", "warn", this.toString());
+            }
+            
+            YAHOO.log("TH cells for " + this._oColumnSet.keys.length + " keys created","info",this.toString());
         }
+        else {
+            YAHOO.log("Accessibility TH cells for " + this._oColumnSet.keys.length + " keys created","info",this.toString());
+        }
     }
-    if(needDD) {
-        YAHOO.log("Could not find DragDrop dependancy for resizeable Columns", "warn", this.toString());
+
+
+     // Set widths for hidden Columns
+    for(var g=0, h=this._oColumnSet.keys.length; g<h; g++) {
+        // Hidden Columns
+        if(this._oColumnSet.keys[g].hidden) {
+            var oHiddenColumn = this._oColumnSet.keys[g];
+            var oHiddenThEl = oHiddenColumn.getThEl();
+            oHiddenColumn._nLastWidth = oHiddenThEl.offsetWidth -
+                        (parseInt(Dom.getStyle(oHiddenThEl,"paddingLeft"),10)|0) -
+                        (parseInt(Dom.getStyle(oHiddenThEl,"paddingRight"),10)|0);
+            this._setColumnWidth(oHiddenColumn, "1px"); 
+        }
     }
 
-    YAHOO.log("Column headers for " + this._oColumnSet.keys.length + " keys created","info",this.toString());
-};
 
+    // Bug 1806891
+    if(ua.webkit && ua.webkit < 420) {
+        var oSelf = this;
+        setTimeout(function() {
+            oSelf._elThead.style.display = "";
+        },0);
+        this._elThead.style.display = 'none';
+    }
+},
+
 /**
  * Populates TH cell as defined by Column.
  *
  * @method _initThEl
  * @param elTheadCell {HTMLElement} TH cell element reference.
  * @param oColumn {YAHOO.widget.Column} Column object.
- * @param row {number} Row index.
- * @param col {number} Column index.
+ * @param row {Number} Row index.
+ * @param col {Number} Column index.
+ * @param bA11y {Boolean} True if TH is for accessibility, so as not to
+ * initialize presentation elements.
  * @private
  */
-YAHOO.widget.DataTable.prototype._initThEl = function(elTheadCell,oColumn,row,col) {
+_initThEl : function(elTheadCell,oColumn,row,col, bA11y) {
     // Clear out the cell of prior content
     // TODO: purgeListeners and other validation-related things
-    var index = this._nIndex;
     var colKey = oColumn.getKey();
     var colId = oColumn.getId();
     elTheadCell.yuiColumnKey = colKey;
     elTheadCell.yuiColumnId = colId;
-    if(oColumn.abbr) {
-        elTheadCell.abbr = oColumn.abbr;
-    }
-    if(oColumn.width) {
-        elTheadCell.style.width = oColumn.width;
-    }
-
-    var aCustomClasses;
-    if(YAHOO.lang.isString(oColumn.className)) {
-        aCustomClasses = [oColumn.className];
-    }
-    else if(YAHOO.lang.isArray(oColumn.className)) {
-        aCustomClasses = oColumn.className;
-    }
-    if(aCustomClasses) {
-        for(var i=0; i<aCustomClasses.length; i++) {
-            YAHOO.util.Dom.addClass(elTheadCell,aCustomClasses[i]);
-        }
-    }
-    
-    YAHOO.util.Dom.addClass(elTheadCell, "yui-dt-col-"+colKey);
-    
     elTheadCell.innerHTML = "";
     elTheadCell.rowSpan = oColumn.getRowspan();
     elTheadCell.colSpan = oColumn.getColspan();
 
-    var elTheadContainer = elTheadCell.appendChild(document.createElement("div"));
-    elTheadContainer.id = this.id + "-container" + colId;
-    YAHOO.util.Dom.addClass(elTheadContainer,YAHOO.widget.DataTable.CLASS_HEADER);
-    var elTheadLabel = elTheadContainer.appendChild(document.createElement("span"));
-    elTheadLabel.id = this.id + "-label" + colId;
-    YAHOO.util.Dom.addClass(elTheadLabel,YAHOO.widget.DataTable.CLASS_LABEL);
+    var elTheadCellLiner = elTheadCell.appendChild(document.createElement("div"));
+    var elTheadCellLabel = elTheadCellLiner.appendChild(document.createElement("span"));
 
-    var sLabel = YAHOO.lang.isValue(oColumn.label) ? oColumn.label : colKey;
-    if(oColumn.sortable) {
-        YAHOO.util.Dom.addClass(elTheadCell,YAHOO.widget.DataTable.CLASS_SORTABLE);
-        //TODO: Make sortLink customizeable
-        //TODO: Make title configurable
-        //TODO: Separate label from an accessibility link that says
-        // "Click to sort ascending" and push it offscreen
-        var sLabelLinkId = this.id + "-labellink" + colId;
-        var sortLink = "?key=" + colKey;
-        elTheadLabel.innerHTML = "<a id=\"" + sLabelLinkId + "\" href=\"" + sortLink + "\" title=\"Click to sort\" class=\"" + YAHOO.widget.DataTable.CLASS_SORTABLE + "\">" + sLabel + "</a>";
-        if(!this._sFirstLabelLinkId) {
-            this._sFirstLabelLinkId = sLabelLinkId;
+    // Keep it basic for screen readers
+    if(bA11y) {
+        //TODO: remove IDs and form elements from label
+        if(oColumn.abbr) {
+            elTheadCell.abbr = oColumn.abbr;
         }
+        elTheadCellLabel.innerHTML = lang.isValue(oColumn.label) ? oColumn.label : colKey;
     }
+    // Visually format the elements
     else {
-        elTheadLabel.innerHTML = sLabel;
+        // Needed for resizer
+        elTheadCellLiner.id = elTheadCell.id + "-liner";
+        
+        // Add classes on the liner
+        var aClasses;
+        if(lang.isString(oColumn.className)) {
+            aClasses = [oColumn.className];
+        }
+        else if(lang.isArray(oColumn.className)) {
+            aClasses = oColumn.className;
+        }
+        else {
+            aClasses = [];
+        }
+        
+        //TODO: document special keys will get stripped here
+        aClasses[aClasses.length] = "yui-dt-col-"+colKey.replace(/[^\w\-.:]/g,"");
+        
+        aClasses[aClasses.length] = "yui-dt-col-"+oColumn.getId();
+        
+        aClasses[aClasses.length] = DT.CLASS_LINER;
+
+        Dom.addClass(elTheadCellLiner,aClasses.join(" "));
+
+        // Add classes on the label
+        Dom.addClass(elTheadCellLabel,DT.CLASS_LABEL);
+        
+        // Add classes on the cell
+        aClasses = [];
+        if(oColumn.resizeable) {
+            aClasses[aClasses.length] = DT.CLASS_RESIZEABLE;
+        }
+        if(oColumn.sortable) {
+            aClasses[aClasses.length] = DT.CLASS_SORTABLE;
+        }
+
+        //Set Column hidden
+        if(oColumn.hidden) {
+            aClasses[aClasses.length] = DT.CLASS_HIDDEN;
+        }
+        
+        // Set Column selection on TD
+        if(oColumn.selected) {
+            aClasses[aClasses.length] = DT.CLASS_SELECTED;
+        }
+
+        Dom.addClass(elTheadCell,aClasses.join(" "));
+
+        DT.formatTheadCell(elTheadCellLabel, oColumn, this);
     }
-};
+},
 
 /**
  * Creates HTML markup for Cell Editor.
@@ -1401,73 +7480,48 @@
  * @method _initCellEditorEl
  * @private
  */
-YAHOO.widget.DataTable.prototype._initCellEditorEl = function() {
-    // Attach Cell Editor container element to body
+_initCellEditorEl : function() {
+    // TODO: destroy previous instances
+
+    // Attach Cell Editor container element as first child of body
     var elCellEditor = document.createElement("div");
-    elCellEditor.id = this.id + "-celleditor";
+    elCellEditor.id = this._sId + "-celleditor";
     elCellEditor.style.display = "none";
-    YAHOO.util.Dom.addClass(elCellEditor, YAHOO.widget.DataTable.CLASS_EDITOR);
-    elCellEditor = document.body.appendChild(elCellEditor);
-
+    elCellEditor.tabIndex = 0;
+    Dom.addClass(elCellEditor, DT.CLASS_EDITOR);
+    var elFirstChild = Dom.getFirstChild(document.body);
+    if(elFirstChild) {
+        elCellEditor = Dom.insertBefore(elCellEditor, elFirstChild);
+    }
+    else {
+        elCellEditor = document.body.appendChild(elCellEditor);
+    }
+    
     // Internal tracker of Cell Editor values
     var oCellEditor = {};
     oCellEditor.container = elCellEditor;
     oCellEditor.value = null;
     oCellEditor.isActive = false;
     this._oCellEditor = oCellEditor;
+},
 
-    // Handle ESC key
-    this.subscribe("editorKeydownEvent", function(oArgs) {
-        var e = oArgs.event;
-        var elTarget = YAHOO.util.Event.getTarget(e);
+/** 	 
+  * Initializes Column sorting. 	 
+  * 	 
+  * @method _initColumnSort 	 
+  * @private 	 
+  */ 	 
+_initColumnSort : function() {
+    this.subscribe("theadCellClickEvent", this.onEventSortColumn); 	 
+}, 	 
+ 
 
-        // ESC hides Cell Editor
-        if((e.keyCode == 27)) {
-            this.cancelCellEditor();
-        }
-    });
-};
 
-/**
- * Initializes Column sorting.
- *
- * @method _initColumnSort
- * @private
- */
-YAHOO.widget.DataTable.prototype._initColumnSort = function() {
-    this.subscribe("headerCellClickEvent", this.onEventSortColumn);
-};
 
-/**
- * Initializes DOM event listeners.
- *
- * @method _initDomEvents
- * @private
- */
-YAHOO.widget.DataTable.prototype._initDomEvents = function() {
-    var elTable = this._elTable;
-    var elThead = this._elThead;
-    var elTbody = this._elTbody;
-    var elContainer = this._elContainer;
 
-    YAHOO.util.Event.addListener(document, "click", this._onDocumentClick, this);
-    YAHOO.util.Event.addListener(document, "keydown", this._onDocumentKeydown, this);
 
-    YAHOO.util.Event.addListener(elTable, "focus", this._onTableFocus, this);
-    YAHOO.util.Event.addListener(elTable, "mouseover", this._onTableMouseover, this);
-    YAHOO.util.Event.addListener(elTable, "mouseout", this._onTableMouseout, this);
-    YAHOO.util.Event.addListener(elTable, "mousedown", this._onTableMousedown, this);
-    YAHOO.util.Event.addListener(elTable, "keydown", this._onTableKeydown, this);
-    YAHOO.util.Event.addListener(elTable, "keypress", this._onTableKeypress, this);
 
-    // Since we can't listen for click and dblclick on the same element...
-    YAHOO.util.Event.addListener(elTable, "dblclick", this._onTableDblclick, this);
-    YAHOO.util.Event.addListener(elThead, "click", this._onTheadClick, this);
-    YAHOO.util.Event.addListener(elTbody, "click", this._onTbodyClick, this);
 
-    YAHOO.util.Event.addListener(elContainer, "scroll", this._onScroll, this); // for IE
-    YAHOO.util.Event.addListener(elTbody, "scroll", this._onScroll, this); // for everyone else
-};
 
 
 
@@ -1494,169 +7548,147 @@
 
 
 
+// DOM MUTATION FUNCTIONS
 
 
 
+/**
+ * Create a TR element for a given Record.
+ * @method _createTrEl
+ * @param oRecord {YAHOO.widget.Record} Record instance
+ * @return {HTMLElement} The new TR element.  This must be added to the DOM.
+ * @private 
+ */
+_createTrEl : function (oRecord) {
+    // Clone the empty tr template.  We can't clone an existing row
+    // because of the expandos and td ids that must be set in _addTdEl
+    var elRow     = this._trElTemplate.cloneNode(true);
 
+    elRow.id = this._sId+"-bdrow"+this._nTrCount;
+    this._nTrCount++;
 
+    // Call _updateTrEl to populate and align the row contents
+    return this._updateTrEl(elRow,oRecord);
+},
 
-
-
-
-
-
-// DOM MUTATION FUNCTIONS
-
-
-
-
 /**
- * Adds a TR element to the primary TBODY at the page row index if given, otherwise
- * at the end of the page. Formats TD elements within the TR element using data
- * from the given Record.
+ * Formats all TD elements of given TR element with data from the given Record.
  *
- * @method _addTrEl
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param index {Number} (optional) The page row index at which to add the TR
- * element.
- * @return {String} ID of the added TR element, or null.
+ * @method _updateTrEl
+ * @param elRow {HTMLElement} The TR element to update.
+ * @param oRecord {YAHOO.widget.Record} The associated Record instance.
+ * @return {HTMLElement} DOM reference to the new TR element.
  * @private
  */
-YAHOO.widget.DataTable.prototype._addTrEl = function(oRecord, index) {
-    this.hideTableMessage();
+_updateTrEl : function(elRow, oRecord) {
+    var oColumnSet = this._oColumnSet,
+        sortKey,
+        sortClass,
+        isSortedBy = this.get("sortedBy"),
+        i,j,len,jlen;
 
-    // It's an append if no index provided, or index is negative or too big
-    var append = (!YAHOO.lang.isNumber(index) || (index < 0) ||
-            (index >= (this._elTbody.rows.length))) ? true : false;
-            
-    var oColumnSet = this._oColumnSet;
-    var oRecordSet = this._oRecordSet;
-    var isSortedBy = this.get("sortedBy");
-    var sortedColKeyIndex  = null;
-    var sortedDir, newClass;
     if(isSortedBy) {
-        sortedColKeyIndex = (isSortedBy.column) ?
-                isSortedBy.column.getKeyIndex() :
-                this._oColumnSet.getColumn(isSortedBy.key).getKeyIndex();
-        sortedDir = isSortedBy.dir;
-        newClass = (sortedDir === "desc") ? YAHOO.widget.DataTable.CLASS_DESC :
-                YAHOO.widget.DataTable.CLASS_ASC;
-
+        sortKey = isSortedBy.key;
+        sortClass = isSortedBy.dir;
     }
 
+    // Hide the row to prevent constant reflows
+    elRow.style.display = 'none';
 
-    var elRow = (append) ? this._elTbody.appendChild(document.createElement("tr")) :
-        this._elTbody.insertBefore(document.createElement("tr"),this._elTbody.rows[index]);
+    // Remove extra TD elements
+    while(elRow.childNodes.length > oColumnSet.keys.length) {
+        elRow.removeChild(elRow.firstChild);
+    }
+    // Add more TD elements as needed
+    for (i=elRow.childNodes.length||0, len=oColumnSet.keys.length; i < len; ++i) {
+        this._addTdEl(elRow,oColumnSet.keys[i],i);
+    }
 
-    elRow.id = this.id+"-bdrow"+this._nTrCount;
-    this._nTrCount++;
-    elRow.yuiRecordId = oRecord.getId();
+    // Update TD elements with new data
+    for(i=0,len=oColumnSet.keys.length; i<len; ++i) {
+        var oColumn     = oColumnSet.keys[i],
+            elCell      = elRow.childNodes[i],
+            elCellLiner = elCell.firstChild,
+            cellHeaders = '',
+            headerType  = this.get('scrollable') ? "-a11y " : " ";
 
-    // Create TD cells
-    for(var j=0; j<oColumnSet.keys.length; j++) {
-        var oColumn = oColumnSet.keys[j];
-        var elCell = elRow.appendChild(document.createElement("td"));
-        elCell.id = elRow.id+"-cell"+j;
-        elCell.yuiColumnKey = oColumn.getKey();
-        elCell.yuiColumnId = oColumn.getId();
+        // Set the cell content
+        this.formatCell(elCellLiner, oRecord, oColumn);
 
-        for(var k=0; k<oColumnSet.headers[j].length; k++) {
-            elCell.headers += this.id + "-col" + oColumnSet.headers[j][k] + " ";
+        // Set the cell's accessibility headers
+        for(j=0,jlen=oColumnSet.headers[i].length; j < jlen; ++j) {
+            cellHeaders += this._sId + "-th" + oColumnSet.headers[i][j] + headerType;
         }
-        
-        // For SF2 cellIndex bug: http://www.webreference.com/programming/javascript/ppk2/3.html
-        elCell.yuiCellIndex = j;
+        elCell.headers = cellHeaders;
 
-        // Update UI
-        this.formatCell(elCell, oRecord, oColumn);
-
-        // Set FIRST/LAST on TD
-        if (j === 0) {
-            YAHOO.util.Dom.addClass(elCell, YAHOO.widget.DataTable.CLASS_FIRST);
+        // Set ASC/DESC on TD
+        if(oColumn.key === sortKey) {
+            Dom.replaceClass(elCell, sortClass === DT.CLASS_ASC ?
+                                     DT.CLASS_DESC : DT.CLASS_ASC, sortClass);
+        } else {
+            Dom.removeClass(elCell, DT.CLASS_ASC);
+            Dom.removeClass(elCell, DT.CLASS_DESC);
         }
-        else if (j === this._oColumnSet.keys.length-1) {
-            YAHOO.util.Dom.addClass(elCell, YAHOO.widget.DataTable.CLASS_LAST);
-        }
         
-        // Remove ASC/DESC
-        YAHOO.util.Dom.removeClass(elCell, YAHOO.widget.DataTable.CLASS_ASC);
-        YAHOO.util.Dom.removeClass(elCell, YAHOO.widget.DataTable.CLASS_DESC);
-        
-        // Set ASC/DESC on TD
-        if(j === sortedColKeyIndex) {
-            newClass = (sortedDir === "desc") ?
-                    YAHOO.widget.DataTable.CLASS_DESC :
-                    YAHOO.widget.DataTable.CLASS_ASC;
-            YAHOO.util.Dom.addClass(elCell, newClass);
+        // Set Column hidden if appropriate
+        if(oColumn.hidden) {
+            Dom.addClass(elCell, DT.CLASS_HIDDEN);
         }
+        else {
+            Dom.removeClass(elCell, DT.CLASS_HIDDEN);
+        }
 
+        // Set Column selection on TH
+        if(oColumn.selected) {
+            Dom.addClass(elCell, DT.CLASS_SELECTED);
+        }
+        else {
+            Dom.removeClass(elCell, DT.CLASS_SELECTED);
+        }
+    }
 
-        /*p.abx {word-wrap:break-word;}
-ought to solve the problem for Safari (the long words will wrap in your
-tds, instead of overflowing to the next td.
-(this is supported by IE win as well, so hide it if needed).
+    // Update Record ID
+    elRow.yuiRecordId = oRecord.getId();
+    
+    // Redisplay the row for reflow
+    elRow.style.display = '';
 
-One thing, though: it doesn't work in combination with
-'white-space:nowrap'.*/
+    return elRow;
+},
 
-// need a div wrapper for safari?
-        //TODO: fix fixedWidth
-        if(this.fixedWidth) {
-            elCell.style.overflow = "hidden";
-            //elCell.style.width = "20px";
-        }
-    }
 
-    return elRow.id;
-};
-
 /**
- * Formats all TD elements of given TR element with data from the given Record.
- *
- * @method _updateTrEl
- * @param elRow {HTMLElement} The TR element to update.
- * @param oRecord {YAHOO.widget.Record} The associated Record instance.
- * @return {String} ID of the updated TR element, or null.
+ * Creates a cell within the specified row and column.
+ * @method _addTdEl
+ * @param elRow {HTMLElement} The row to add the cell to
+ * @param oColumn {Column} The column definition to use for the cell
+ * @param index {number} (optional) the index to add the cell at (default null)
+ * @return {HTMLElement} the new cell
  * @private
  */
-YAHOO.widget.DataTable.prototype._updateTrEl = function(elRow, oRecord) {
-    this.hideTableMessage();
+_addTdEl : function (elRow,oColumn,index) {
+    var elCell      = this._tdElTemplate.cloneNode(true),
+        elCellLiner = elCell.firstChild;
 
-    var isSortedBy = this.get("sortedBy");
-    var sortedColKeyIndex  = null;
-    var sortedDir, newClass;
-    if(isSortedBy) {
-        sortedColKeyIndex = (isSortedBy.column) ?
-                isSortedBy.column.getKeyIndex() :
-                this._oColumnSet.getColumn(isSortedBy.key).getKeyIndex();
-        sortedDir = isSortedBy.dir;
-        newClass = (sortedDir === "desc") ? YAHOO.widget.DataTable.CLASS_DESC :
-                YAHOO.widget.DataTable.CLASS_ASC;
-    }
+    index = index || elRow.cells.length;
 
-    // Update TD elements with new data
-    for(var j=0; j<elRow.cells.length; j++) {
-        var oColumn = this._oColumnSet.keys[j];
-        var elCell = elRow.cells[j];
-        this.formatCell(elCell, oRecord, oColumn);
+    elCell.id           = elRow.id+"-cell"+this._nTdCount;
+    this._nTdCount++;
+    elCell.yuiColumnKey = oColumn.getKey();
+    elCell.yuiColumnId  = oColumn.getId();
 
-        // Remove ASC/DESC
-        YAHOO.util.Dom.removeClass(elCell, YAHOO.widget.DataTable.CLASS_ASC);
-        YAHOO.util.Dom.removeClass(elCell, YAHOO.widget.DataTable.CLASS_DESC);
+    // For SF2 cellIndex bug: http://www.webreference.com/programming/javascript/ppk2/3.html
+    elCell.yuiCellIndex = index;
 
-        // Set ASC/DESC on TD
-        if(j === sortedColKeyIndex) {
-            YAHOO.util.Dom.addClass(elCell, newClass);
-        }
+    // Set FIRST/LAST on TD
+    if (!(index % this._oColumnSet.keys.length - 1)) {
+        elCell.className = index ? DT.CLASS_LAST : DT.CLASS_FIRST;
     }
 
-    // Update Record ID
-    elRow.yuiRecordId = oRecord.getId();
-    
-    return elRow.id;
-};
+    var insertBeforeCell = elRow.cells[index] || null;
+    return elRow.insertBefore(elCell,insertBeforeCell);
+},
 
-
 /**
  * Deletes TR element by DOM reference or by DataTable page row index.
  *
@@ -1665,24 +7697,25 @@
  * @return {Boolean} Returns true if successful, else returns false.
  * @private
  */
-YAHOO.widget.DataTable.prototype._deleteTrEl = function(row) {
+_deleteTrEl : function(row) {
     var rowIndex;
-    
+
     // Get page row index for the element
-    if(!YAHOO.lang.isNumber(row)) {
-        rowIndex = YAHOO.util.Dom.get(row).sectionRowIndex;
+    if(!lang.isNumber(row)) {
+        rowIndex = Dom.get(row).sectionRowIndex;
     }
     else {
         rowIndex = row;
     }
-    if(YAHOO.lang.isNumber(rowIndex) && (rowIndex > -2) && (rowIndex < this._elTbody.rows.length)) {
-        this._elTbody.deleteRow(rowIndex);
-        return true;
+    if(lang.isNumber(rowIndex) && (rowIndex > -2) && (rowIndex < this._elTbody.rows.length)) {
+        // Cannot use tbody.deleteRow due to IE6 instability
+        //return this._elTbody.deleteRow(rowIndex);
+        return this._elTbody.removeChild(this.getTrEl(row));
     }
     else {
-        return false;
+        return null;
     }
-};
+},
 
 
 
@@ -1716,54 +7749,54 @@
 
 
 /**
- * Assigns the class YAHOO.widget.DataTable.CLASS_FIRST to the first TR element
+ * Assigns the class DT.CLASS_FIRST to the first TR element
  * of the DataTable page and updates internal tracker.
  *
  * @method _setFirstRow
  * @private
  */
-YAHOO.widget.DataTable.prototype._setFirstRow = function() {
+_setFirstRow : function() {
     var rowEl = this.getFirstTrEl();
     if(rowEl) {
         // Remove FIRST
         if(this._sFirstTrId) {
-            YAHOO.util.Dom.removeClass(this._sFirstTrId, YAHOO.widget.DataTable.CLASS_FIRST);
+            Dom.removeClass(this._sFirstTrId, DT.CLASS_FIRST);
         }
         // Set FIRST
-        YAHOO.util.Dom.addClass(rowEl, YAHOO.widget.DataTable.CLASS_FIRST);
+        Dom.addClass(rowEl, DT.CLASS_FIRST);
         this._sFirstTrId = rowEl.id;
     }
     else {
         this._sFirstTrId = null;
     }
-};
+},
 
 /**
- * Assigns the class YAHOO.widget.DataTable.CLASS_LAST to the last TR element
+ * Assigns the class DT.CLASS_LAST to the last TR element
  * of the DataTable page and updates internal tracker.
  *
  * @method _setLastRow
  * @private
  */
-YAHOO.widget.DataTable.prototype._setLastRow = function() {
+_setLastRow : function() {
     var rowEl = this.getLastTrEl();
     if(rowEl) {
         // Unassign previous class
         if(this._sLastTrId) {
-            YAHOO.util.Dom.removeClass(this._sLastTrId, YAHOO.widget.DataTable.CLASS_LAST);
+            Dom.removeClass(this._sLastTrId, DT.CLASS_LAST);
         }
         // Assign class
-        YAHOO.util.Dom.addClass(rowEl, YAHOO.widget.DataTable.CLASS_LAST);
+        Dom.addClass(rowEl, DT.CLASS_LAST);
         this._sLastTrId = rowEl.id;
     }
     else {
         this._sLastTrId = null;
     }
-};
+},
 
 /**
- * Assigns the classes YAHOO.widget.DataTable.CLASS_EVEN and
- * YAHOO.widget.DataTable.CLASS_ODD to alternating TR elements of the DataTable
+ * Assigns the classes DT.CLASS_EVEN and
+ * DT.CLASS_ODD to alternating TR elements of the DataTable
  * page. For performance, a subset of rows may be specified.
  *
  * @method _setRowStripes
@@ -1773,21 +7806,23 @@
  * stripe all the rows until the end.
  * @private
  */
-YAHOO.widget.DataTable.prototype._setRowStripes = function(row, range) {
+_setRowStripes : function(row, range) {
     // Default values stripe all rows
-    var allRows = this._elTbody.rows;
-    var nStartIndex = 0;
-    var nEndIndex = allRows.length;
-    
+    var allRows = this._elTbody.rows,
+        nStartIndex = 0,
+        nEndIndex = allRows.length,
+        aOdds = [], nOddIdx = 0,
+        aEvens = [], nEvenIdx = 0;
+
     // Stripe a subset
     if((row !== null) && (row !== undefined)) {
         // Validate given start row
         var elStartRow = this.getTrEl(row);
         if(elStartRow) {
             nStartIndex = elStartRow.sectionRowIndex;
-            
+
             // Validate given range
-            if(YAHOO.lang.isNumber(range) && (range > 1)) {
+            if(lang.isNumber(range) && (range > 1)) {
                 nEndIndex = nStartIndex + range;
             }
         }
@@ -1795,17 +7830,20 @@
 
     for(var i=nStartIndex; i<nEndIndex; i++) {
         if(i%2) {
-            YAHOO.util.Dom.removeClass(allRows[i], YAHOO.widget.DataTable.CLASS_EVEN);
-            YAHOO.util.Dom.addClass(allRows[i], YAHOO.widget.DataTable.CLASS_ODD);
+            aOdds[nOddIdx++] = allRows[i];
+        } else {
+            aEvens[nEvenIdx++] = allRows[i];
         }
-        else {
-            YAHOO.util.Dom.removeClass(allRows[i], YAHOO.widget.DataTable.CLASS_ODD);
-            YAHOO.util.Dom.addClass(allRows[i], YAHOO.widget.DataTable.CLASS_EVEN);
-        }
     }
-};
 
+    if (aOdds.length) {
+        Dom.replaceClass(aOdds, DT.CLASS_EVEN, DT.CLASS_ODD);
+    }
 
+    if (aEvens.length) {
+        Dom.replaceClass(aEvens, DT.CLASS_ODD, DT.CLASS_EVEN);
+    }
+},
 
 
 
@@ -1849,6 +7887,8 @@
 
 
 
+
+
 /////////////////////////////////////////////////////////////////////////////
 //
 // Private DOM Event Handlers
@@ -1856,38 +7896,39 @@
 /////////////////////////////////////////////////////////////////////////////
 
 /**
- * Handles scroll events on the CONTAINER (for IE) and TBODY elements (for everyone else).
+ * Syncs scrolltop and scrollleft of all TABLEs.
  *
  * @method _onScroll
  * @param e {HTMLEvent} The scroll event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance
  * @private
  */
-YAHOO.widget.DataTable.prototype._onScroll = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-    
-    if(oSelf._oCellEditor.isActive) {
+_onScroll : function(e, oSelf) {
+    oSelf._elTheadContainer.scrollLeft = oSelf._elTbodyContainer.scrollLeft;
+
+    if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
         oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
         oSelf.cancelCellEditor();
     }
 
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
     oSelf.fireEvent("tableScrollEvent", {event:e, target:elTarget});
-};
+},
 
 /**
  * Handles click events on the DOCUMENT.
  *
  * @method _onDocumentClick
  * @param e {HTMLEvent} The click event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onDocumentClick = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
+_onDocumentClick : function(e, oSelf) {
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
 
-    if(!YAHOO.util.Dom.isAncestor(oSelf._elTable, elTarget)) {
+    if(!Dom.isAncestor(oSelf._elContainer, elTarget)) {
         oSelf.fireEvent("tableBlurEvent");
 
         // Fires editorBlurEvent when click is not within the TABLE.
@@ -1896,1195 +7937,555 @@
         // handlers below rather than by the TABLE click handler directly.
         if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
             // Only if the click was not within the Cell Editor container
-            if(!YAHOO.util.Dom.isAncestor(oSelf._oCellEditor.container, elTarget) &&
+            if(!Dom.isAncestor(oSelf._oCellEditor.container, elTarget) &&
                     (oSelf._oCellEditor.container.id !== elTarget.id)) {
                 oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
             }
         }
     }
-};
+},
 
 /**
- * Handles keydown events on the DOCUMENT.
+ * Handles focus events on the DataTable instance.
  *
- * @method _onDocumentKeydown
- * @param e {HTMLEvent} The keydown event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @method _onTableFocus
+ * @param e {HTMLEvent} The focus event.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onDocumentKeydown = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
+_onTableFocus : function(e, oSelf) {
+    oSelf.fireEvent("tableFocusEvent");
+},
 
-    if(oSelf._oCellEditor && oSelf._oCellEditor.isActive &&
-            YAHOO.util.Dom.isAncestor(oSelf._oCellEditor.container, elTarget)) {
-        oSelf.fireEvent("editorKeydownEvent", {editor:oSelf._oCellEditor, event:e});
-    }
-};
+/**
+ * Handles focus events on the THEAD element.
+ *
+ * @method _onTheadFocus
+ * @param e {HTMLEvent} The focus event.
+ * @param oSelf {DT} DataTable instance.
+ * @private
+ */
+_onTheadFocus : function(e, oSelf) {
+    oSelf.fireEvent("theadFocusEvent");
+    oSelf.fireEvent("tableFocusEvent");
+},
 
 /**
- * Handles focus events on the TABLE element.
+ * Handles focus events on the TBODY element.
  *
- * @method _onTableFocus
+ * @method _onTbodyFocus
  * @param e {HTMLEvent} The focus event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableMouseover = function(e, oSelf) {
+_onTbodyFocus : function(e, oSelf) {
+    oSelf.fireEvent("tbodyFocusEvent");
     oSelf.fireEvent("tableFocusEvent");
-};
+},
 
 /**
- * Handles mouseover events on the TABLE element.
+ * Handles mouseover events on the DataTable instance.
  *
  * @method _onTableMouseover
  * @param e {HTMLEvent} The mouseover event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableMouseover = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
-    while(elTarget && (elTag != "table")) {
-        switch(elTag) {
-            case "body":
-                 break;
-            case "a":
-                break;
-            case "td":
-                oSelf.fireEvent("cellMouseoverEvent",{target:elTarget,event:e});
-                break;
-            case "span":
-                if(YAHOO.util.Dom.hasClass(elTarget, YAHOO.widget.DataTable.CLASS_LABEL)) {
-                    oSelf.fireEvent("headerLabelMouseoverEvent",{target:elTarget,event:e});
+_onTableMouseover : function(e, oSelf) {
+    var elTarget = Ev.getTarget(e);
+        var elTag = elTarget.nodeName.toLowerCase();
+        var bKeepBubbling = true;
+        while(elTarget && (elTag != "table")) {
+            switch(elTag) {
+                case "body":
+                     return;
+                case "a":
+                    break;
+                case "td":
+                    bKeepBubbling = oSelf.fireEvent("cellMouseoverEvent",{target:elTarget,event:e});
+                    break;
+                case "span":
+                    if(Dom.hasClass(elTarget, DT.CLASS_LABEL)) {
+                        bKeepBubbling = oSelf.fireEvent("theadLabelMouseoverEvent",{target:elTarget,event:e});
+                        // Backward compatibility
+                        bKeepBubbling = oSelf.fireEvent("headerLabelMouseoverEvent",{target:elTarget,event:e});
+                    }
+                    break;
+                case "th":
+                    bKeepBubbling = oSelf.fireEvent("theadCellMouseoverEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerCellMouseoverEvent",{target:elTarget,event:e});
+                    break;
+                case "tr":
+                    if(elTarget.parentNode.nodeName.toLowerCase() == "thead") {
+                        bKeepBubbling = oSelf.fireEvent("theadRowMouseoverEvent",{target:elTarget,event:e});
+                        // Backward compatibility
+                        bKeepBubbling = oSelf.fireEvent("headerRowMouseoverEvent",{target:elTarget,event:e});
+                    }
+                    else {
+                        bKeepBubbling = oSelf.fireEvent("rowMouseoverEvent",{target:elTarget,event:e});
+                    }
+                    break;
+                default:
+                    break;
+            }
+            if(bKeepBubbling === false) {
+                return;
+            }
+            else {
+                elTarget = elTarget.parentNode;
+                if(elTarget) {
+                    elTag = elTarget.nodeName.toLowerCase();
                 }
-                break;
-            case "th":
-                oSelf.fireEvent("headerCellMouseoverEvent",{target:elTarget,event:e});
-                break;
-            case "tr":
-                if(elTarget.parentNode.tagName.toLowerCase() == "thead") {
-                    oSelf.fireEvent("headerRowMouseoverEvent",{target:elTarget,event:e});
-                }
-                else {
-                    oSelf.fireEvent("rowMouseoverEvent",{target:elTarget,event:e});
-                }
-                break;
-            default:
-                break;
+            }
         }
-        elTarget = elTarget.parentNode;
-        if(elTarget) {
-            elTag = elTarget.tagName.toLowerCase();
-        }
-    }
-    oSelf.fireEvent("tableMouseoverEvent",{target:(elTarget || oSelf._elTable),event:e});
-};
+        oSelf.fireEvent("tableMouseoverEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
 /**
- * Handles mouseout events on the TABLE element.
+ * Handles mouseout events on the DataTable instance.
  *
  * @method _onTableMouseout
  * @param e {HTMLEvent} The mouseout event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableMouseout = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
+_onTableMouseout : function(e, oSelf) {
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
     while(elTarget && (elTag != "table")) {
         switch(elTag) {
             case "body":
-                break;
+                return;
             case "a":
                 break;
             case "td":
-                oSelf.fireEvent("cellMouseoutEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("cellMouseoutEvent",{target:elTarget,event:e});
                 break;
             case "span":
-                if(YAHOO.util.Dom.hasClass(elTarget, YAHOO.widget.DataTable.CLASS_LABEL)) {
-                    oSelf.fireEvent("headerLabelMouseoutEvent",{target:elTarget,event:e});
+                if(Dom.hasClass(elTarget, DT.CLASS_LABEL)) {
+                    bKeepBubbling = oSelf.fireEvent("theadLabelMouseoutEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerLabelMouseoutEvent",{target:elTarget,event:e});
                 }
                 break;
             case "th":
-                oSelf.fireEvent("headerCellMouseoutEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("theadCellMouseoutEvent",{target:elTarget,event:e});
+                // Backward compatibility
+                bKeepBubbling = oSelf.fireEvent("headerCellMouseoutEvent",{target:elTarget,event:e});
                 break;
             case "tr":
-                if(elTarget.parentNode.tagName.toLowerCase() == "thead") {
-                    oSelf.fireEvent("headerRowMouseoutEvent",{target:elTarget,event:e});
+                if(elTarget.parentNode.nodeName.toLowerCase() == "thead") {
+                    bKeepBubbling = oSelf.fireEvent("theadRowMouseoutEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerRowMouseoutEvent",{target:elTarget,event:e});
                 }
                 else {
-                    oSelf.fireEvent("rowMouseoutEvent",{target:elTarget,event:e});
+                    bKeepBubbling = oSelf.fireEvent("rowMouseoutEvent",{target:elTarget,event:e});
                 }
                 break;
             default:
                 break;
         }
-        elTarget = elTarget.parentNode;
-        if(elTarget) {
-            elTag = elTarget.tagName.toLowerCase();
+        if(bKeepBubbling === false) {
+            return;
         }
+        else {
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
+            }
+        }
     }
-    oSelf.fireEvent("tableMouseoutEvent",{target:(elTarget || oSelf._elTable),event:e});
-};
+    oSelf.fireEvent("tableMouseoutEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
 /**
- * Handles mousedown events on the TABLE element.
+ * Handles mousedown events on the DataTable instance.
  *
  * @method _onTableMousedown
  * @param e {HTMLEvent} The mousedown event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableMousedown = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
+_onTableMousedown : function(e, oSelf) {
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
     while(elTarget && (elTag != "table")) {
         switch(elTag) {
             case "body":
-                break;
+                return;
             case "a":
                 break;
             case "td":
-                oSelf.fireEvent("cellMousedownEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("cellMousedownEvent",{target:elTarget,event:e});
                 break;
             case "span":
-                if(YAHOO.util.Dom.hasClass(elTarget, YAHOO.widget.DataTable.CLASS_LABEL)) {
-                    oSelf.fireEvent("headerLabelMousedownEvent",{target:elTarget,event:e});
+                if(Dom.hasClass(elTarget, DT.CLASS_LABEL)) {
+                    bKeepBubbling = oSelf.fireEvent("theadLabelMousedownEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerLabelMousedownEvent",{target:elTarget,event:e});
                 }
                 break;
             case "th":
-                oSelf.fireEvent("headerCellMousedownEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("theadCellMousedownEvent",{target:elTarget,event:e});
+                // Backward compatibility
+                bKeepBubbling = oSelf.fireEvent("headerCellMousedownEvent",{target:elTarget,event:e});
                 break;
             case "tr":
-                if(elTarget.parentNode.tagName.toLowerCase() == "thead") {
-                    oSelf.fireEvent("headerRowMousedownEvent",{target:elTarget,event:e});
+                if(elTarget.parentNode.nodeName.toLowerCase() == "thead") {
+                    bKeepBubbling = oSelf.fireEvent("theadRowMousedownEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerRowMousedownEvent",{target:elTarget,event:e});
                 }
                 else {
-                    oSelf.fireEvent("rowMousedownEvent",{target:elTarget,event:e});
+                    bKeepBubbling = oSelf.fireEvent("rowMousedownEvent",{target:elTarget,event:e});
                 }
                 break;
             default:
                 break;
         }
-        elTarget = elTarget.parentNode;
-        if(elTarget) {
-            elTag = elTarget.tagName.toLowerCase();
+        if(bKeepBubbling === false) {
+            return;
         }
+        else {
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
+            }
+        }
     }
-    oSelf.fireEvent("tableMousedownEvent",{target:(elTarget || oSelf._elTable),event:e});
-};
+    oSelf.fireEvent("tableMousedownEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
 /**
- * Handles dblclick events on the TABLE element.
+ * Handles dblclick events on the DataTable instance.
  *
  * @method _onTableDblclick
  * @param e {HTMLEvent} The dblclick event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableDblclick = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
+_onTableDblclick : function(e, oSelf) {
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
     while(elTarget && (elTag != "table")) {
         switch(elTag) {
             case "body":
-                break;
+                return;
             case "td":
-                oSelf.fireEvent("cellDblclickEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("cellDblclickEvent",{target:elTarget,event:e});
                 break;
             case "span":
-                if(YAHOO.util.Dom.hasClass(elTarget, YAHOO.widget.DataTable.CLASS_LABEL)) {
-                    oSelf.fireEvent("headerLabelDblclickEvent",{target:elTarget,event:e});
+                if(Dom.hasClass(elTarget, DT.CLASS_LABEL)) {
+                    bKeepBubbling = oSelf.fireEvent("theadLabelDblclickEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerLabelDblclickEvent",{target:elTarget,event:e});
                 }
                 break;
             case "th":
-                oSelf.fireEvent("headerCellDblclickEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("theadCellDblclickEvent",{target:elTarget,event:e});
+                // Backward compatibility
+                bKeepBubbling = oSelf.fireEvent("headerCellDblclickEvent",{target:elTarget,event:e});
                 break;
             case "tr":
-                if(elTarget.parentNode.tagName.toLowerCase() == "thead") {
-                    oSelf.fireEvent("headerRowDblclickEvent",{target:elTarget,event:e});
+                if(elTarget.parentNode.nodeName.toLowerCase() == "thead") {
+                    bKeepBubbling = oSelf.fireEvent("theadRowDblclickEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerRowDblclickEvent",{target:elTarget,event:e});
                 }
                 else {
-                    oSelf.fireEvent("rowDblclickEvent",{target:elTarget,event:e});
+                    bKeepBubbling = oSelf.fireEvent("rowDblclickEvent",{target:elTarget,event:e});
                 }
                 break;
             default:
                 break;
         }
-        elTarget = elTarget.parentNode;
-        if(elTarget) {
-            elTag = elTarget.tagName.toLowerCase();
+        if(bKeepBubbling === false) {
+            return;
         }
+        else {
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
+            }
+        }
     }
-    oSelf.fireEvent("tableDblclickEvent",{target:(elTarget || oSelf._elTable),event:e});
-};
-
+    oSelf.fireEvent("tableDblclickEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 /**
- * Handles keydown events on the TABLE element. Handles arrow selection.
+ * Handles keydown events on the THEAD element.
  *
- * @method _onTableKeydown
+ * @method _onTheadKeydown
  * @param e {HTMLEvent} The key event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableKeydown = function(e, oSelf) {
-    var bSHIFT = e.shiftKey;
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    
-    // Ignore actions in the THEAD
-    if(YAHOO.util.Dom.isAncestor(oSelf._elThead, elTarget)) {
-        return;
+_onTheadKeydown : function(e, oSelf) {
+    // If tabbing to next TH label link causes THEAD to scroll,
+    // need to sync scrollLeft with TBODY
+    if(Ev.getCharCode(e) === 9) {
+        setTimeout(function() {
+            if((oSelf instanceof DT) && oSelf._sId) {
+                oSelf._elTbodyContainer.scrollLeft = oSelf._elTheadContainer.scrollLeft;
+            }
+        },0);
     }
     
-    var nKey = YAHOO.util.Event.getCharCode(e);
-    
-    // Handle TAB
-    if(nKey === 9) {
-        // From TABLE el focus first TH label link, if any
-        if(!bSHIFT && (elTarget.id === oSelf._elTable.id) && oSelf._sFirstLabelLinkId) {
-            YAHOO.util.Event.stopEvent(e);
-            
-            oSelf._focusEl(YAHOO.util.Dom.get(oSelf._sFirstLabelLinkId));
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
+    while(elTarget && (elTag != "table")) {
+        switch(elTag) {
+            case "body":
+                return;
+            case "input":
+            case "textarea":
+                // TODO
+                break;
+            case "thead":
+                bKeepBubbling = oSelf.fireEvent("theadKeyEvent",{target:elTarget,event:e});
+                break;
+            default:
+                break;
         }
-        return;
-    }
-
-    // Handle ARROW selection
-    if((nKey > 36) && (nKey < 41)) {
-        YAHOO.util.Event.stopEvent(e);
-        
-        var allRows = oSelf._elTbody.rows;
-        var sMode = oSelf.get("selectionMode");
-
-        var i, oAnchorCell, oAnchorRecord, nAnchorRecordIndex, nAnchorTrIndex, oAnchorColumn, nAnchorColKeyIndex,
-        oTriggerCell, oTriggerRecord, nTriggerRecordIndex, nTriggerTrIndex, oTriggerColumn, nTriggerColKeyIndex, elTriggerRow,
-        startIndex, endIndex, anchorPos, elNext;
-        
-        // Row mode
-        if((sMode == "standard") || (sMode == "single")) {
-            // Validate trigger row:
-            // Arrow selection only works if last selected row is on current page
-            oTriggerRecord = oSelf.getLastSelectedRecord();
-            // No selected rows found
-            if(!oTriggerRecord) {
-                    return;
-            }
-            else {
-                oTriggerRecord = oSelf.getRecord(oTriggerRecord);
-                nTriggerRecordIndex = oSelf.getRecordIndex(oTriggerRecord);
-                elTriggerRow = oSelf.getTrEl(oTriggerRecord);
-                nTriggerTrIndex = oSelf.getTrIndex(elTriggerRow);
-                
-                // Last selected row not found on this page
-                if(nTriggerTrIndex === null) {
-                    return;
-                }
-            }
-           
-            // Validate anchor row
-            oAnchorRecord = oSelf._oAnchorRecord;
-            if(!oAnchorRecord) {
-                oAnchorRecord = oSelf._oAnchorRecord = oTriggerRecord;
-            }
-            
-            nAnchorRecordIndex = oSelf.getRecordIndex(oAnchorRecord);
-            nAnchorTrIndex = oSelf.getTrIndex(oAnchorRecord);
-            // If anchor row is not on this page...
-            if(nAnchorTrIndex === null) {
-                // ...set TR index equal to top TR
-                if(nAnchorRecordIndex < oSelf.getRecordIndex(oSelf.getFirstTrEl())) {
-                    nAnchorTrIndex = 0;
-                }
-                // ...set TR index equal to bottom TR
-                else {
-                    nAnchorTrIndex = oSelf.getRecordIndex(oSelf.getLastTrEl());
-                }
-            }
-
-
-
-
-
-
-        ////////////////////////////////////////////////////////////////////////
-        //
-        // SHIFT row selection
-        //
-        ////////////////////////////////////////////////////////////////////////
-        if(bSHIFT && (sMode != "single")) {
-            if(nAnchorRecordIndex > nTriggerTrIndex) {
-                anchorPos = 1;
-            }
-            else if(nAnchorRecordIndex < nTriggerTrIndex) {
-                anchorPos = -1;
-            }
-            else {
-                anchorPos = 0;
-            }
-
-            // Arrow down
-            if(nKey == 40) {
-                // Selecting away from anchor row
-                if(anchorPos <= 0) {
-                    // Select the next row down
-                    if(nTriggerTrIndex < allRows.length-1) {
-                        oSelf.selectRow(allRows[nTriggerTrIndex+1]);
-                    }
-                }
-                // Unselecting toward anchor row
-                else {
-                    // Unselect this row towards the anchor row down
-                    oSelf.unselectRow(allRows[nTriggerTrIndex]);
-                }
-
-            }
-            // Arrow up
-            else if(nKey == 38) {
-                // Selecting away from anchor row
-                if(anchorPos >= 0) {
-                    // Select the next row up
-                    if(nTriggerTrIndex > 0) {
-                        oSelf.selectRow(allRows[nTriggerTrIndex-1]);
-                    }
-                }
-                // Unselect this row towards the anchor row up
-                else {
-                    oSelf.unselectRow(allRows[nTriggerTrIndex]);
-                }
-            }
-            // Arrow right
-            else if(nKey == 39) {
-                // Do nothing
-            }
-            // Arrow left
-            else if(nKey == 37) {
-                // Do nothing
-            }
+        if(bKeepBubbling === false) {
+            return;
         }
-        ////////////////////////////////////////////////////////////////////////
-        //
-        // Simple single row selection
-        //
-        ////////////////////////////////////////////////////////////////////////
         else {
-            // Arrow down
-            if(nKey == 40) {
-                oSelf.unselectAllRows();
-
-                // Select the next row
-                if(nTriggerTrIndex < allRows.length-1) {
-                    elNext = allRows[nTriggerTrIndex+1];
-                    oSelf.selectRow(elNext);
-                }
-                // Select only the last row
-                else {
-                    elNext = allRows[nTriggerTrIndex];
-                    oSelf.selectRow(elNext);
-                }
-
-                oSelf._oAnchorRecord = oSelf.getRecord(elNext);
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
             }
-            // Arrow up
-            else if(nKey == 38) {
-                oSelf.unselectAllRows();
+        }
+    }
+    oSelf.fireEvent("tableKeyEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
-                // Select the previous row
-                if(nTriggerTrIndex > 0) {
-                    elNext = allRows[nTriggerTrIndex-1];
-                    oSelf.selectRow(elNext);
-                }
-                // Select only the first row
-                else {
-                    elNext = allRows[nTriggerTrIndex];
-                    oSelf.selectRow(elNext);
-                }
+/**
+ * Handles keydown events on the TBODY element. Handles selection behavior,
+ * provides hooks for ENTER to edit functionality.
+ *
+ * @method _onTbodyKeydown
+ * @param e {HTMLEvent} The key event.
+ * @param oSelf {DT} DataTable instance.
+ * @private
+ */
+_onTbodyKeydown : function(e, oSelf) {
+    var sMode = oSelf.get("selectionMode");
 
-                oSelf._oAnchorRecord = oSelf.getRecord(elNext);
-            }
-            // Arrow right
-            else if(nKey == 39) {
-                // Do nothing
-            }
-            // Arrow left
-            else if(nKey == 37) {
-                // Do nothing
-            }
-
-
-
-
-
-
-
-
+    if(sMode == "standard") {
+        oSelf._handleStandardSelectionByKey(e);
     }
+    else if(sMode == "single") {
+        oSelf._handleSingleSelectionByKey(e);
+    }
+    else if(sMode == "cellblock") {
+        oSelf._handleCellBlockSelectionByKey(e);
+    }
+    else if(sMode == "cellrange") {
+        oSelf._handleCellRangeSelectionByKey(e);
+    }
+    else if(sMode == "singlecell") {
+        oSelf._handleSingleCellSelectionByKey(e);
+    }
+    
+    if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
+        oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
+    }
 
-
-
-
-
-
-
-
-
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
+    while(elTarget && (elTag != "table")) {
+        switch(elTag) {
+            case "body":
+                return;
+            case "tbody":
+                bKeepBubbling = oSelf.fireEvent("tbodyKeyEvent",{target:elTarget,event:e});
+                break;
+            default:
+                break;
         }
-        // Cell mode
+        if(bKeepBubbling === false) {
+            return;
+        }
         else {
-            // Validate trigger cell:
-            // Arrow selection only works if last selected cell is on current page
-            oTriggerCell = oSelf.getLastSelectedCell();
-            // No selected cells found
-            if(!oTriggerCell) {
-                return;
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
             }
-            else {
-                oTriggerRecord = oSelf.getRecord(oTriggerCell.recordId);
-                nTriggerRecordIndex = oSelf.getRecordIndex(oTriggerRecord);
-                elTriggerRow = oSelf.getTrEl(oTriggerRecord);
-                nTriggerTrIndex = oSelf.getTrIndex(elTriggerRow);
-
-                // Last selected cell not found on this page
-                if(nTriggerTrIndex === null) {
-                    return;
-                }
-                else {
-                    oTriggerColumn = oSelf.getColumnById(oTriggerCell.columnId);
-                    nTriggerColKeyIndex = oTriggerColumn.getKeyIndex();
-                }
-            }
-
-            // Validate anchor cell
-            oAnchorCell = oSelf._oAnchorCell;
-            if(!oAnchorCell) {
-                oAnchorCell = oSelf._oAnchorCell = oTriggerCell;
-            }
-            oAnchorRecord = oSelf._oAnchorCell.record;
-            nAnchorRecordIndex = oSelf._oRecordSet.getRecordIndex(oAnchorRecord);
-            nAnchorTrIndex = oSelf.getTrIndex(oAnchorRecord);
-            // If anchor cell is not on this page...
-            if(nAnchorTrIndex === null) {
-                // ...set TR index equal to top TR
-                if(nAnchorRecordIndex < oSelf.getRecordIndex(oSelf.getFirstTrEl())) {
-                    nAnchorTrIndex = 0;
-                }
-                // ...set TR index equal to bottom TR
-                else {
-                    nAnchorTrIndex = oSelf.getRecordIndex(oSelf.getLastTrEl());
-                }
-            }
-
-            oAnchorColumn = oSelf._oAnchorCell.column;
-            nAnchorColKeyIndex = oAnchorColumn.getKeyIndex();
-
-
-            ////////////////////////////////////////////////////////////////////////
-            //
-            // SHIFT cell block selection
-            //
-            ////////////////////////////////////////////////////////////////////////
-            if(bSHIFT && (sMode == "cellblock")) {
-                // Arrow DOWN
-                if(nKey == 40) {
-                    // Is the anchor cell above, below, or same row as trigger
-                    if(nAnchorRecordIndex > nTriggerRecordIndex) {
-                        anchorPos = 1;
-                    }
-                    else if(nAnchorRecordIndex < nTriggerRecordIndex) {
-                        anchorPos = -1;
-                    }
-                    else {
-                        anchorPos = 0;
-                    }
-
-                    // Selecting away from anchor cell
-                    if(anchorPos <= 0) {
-                        // Select the horiz block on the next row...
-                        // ...making sure there is room below the trigger row
-                        if(nTriggerTrIndex < allRows.length-1) {
-                            // Select in order from anchor to trigger...
-                            startIndex = nAnchorColKeyIndex;
-                            endIndex = nTriggerColKeyIndex;
-                            // ...going left
-                            if(startIndex > endIndex) {
-                                for(i=startIndex; i>=endIndex; i--) {
-                                    elNext = allRows[nTriggerTrIndex+1].cells[i];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                            // ... going right
-                            else {
-                                for(i=startIndex; i<=endIndex; i++) {
-                                    elNext = allRows[nTriggerTrIndex+1].cells[i];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else {
-                        startIndex = Math.min(nAnchorColKeyIndex, nTriggerColKeyIndex);
-                        endIndex = Math.max(nAnchorColKeyIndex, nTriggerColKeyIndex);
-                        // Unselect the horiz block on this row towards the next row
-                        for(i=startIndex; i<=endIndex; i++) {
-                            oSelf.unselectCell(allRows[nTriggerTrIndex].cells[i]);
-                        }
-                    }
-                }
-                // Arrow up
-                else if(nKey == 38) {
-                    // Is the anchor cell above, below, or same row as trigger
-                    if(nAnchorRecordIndex > nTriggerRecordIndex) {
-                        anchorPos = 1;
-                    }
-                    else if(nAnchorRecordIndex < nTriggerRecordIndex) {
-                        anchorPos = -1;
-                    }
-                    else {
-                        anchorPos = 0;
-                    }
-                    
-                    // Selecting away from anchor cell
-                    if(anchorPos >= 0) {
-                        // Select the horiz block on the previous row...
-                        // ...making sure there is room
-                        if(nTriggerTrIndex > 0) {
-                            // Select in order from anchor to trigger...
-                            startIndex = nAnchorColKeyIndex;
-                            endIndex = nTriggerColKeyIndex;
-                            // ...going left
-                            if(startIndex > endIndex) {
-                                for(i=startIndex; i>=endIndex; i--) {
-                                    elNext = allRows[nTriggerTrIndex-1].cells[i];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                            // ... going right
-                            else {
-                                for(i=startIndex; i<=endIndex; i++) {
-                                    elNext = allRows[nTriggerTrIndex-1].cells[i];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else {
-                        startIndex = Math.min(nAnchorColKeyIndex, nTriggerColKeyIndex);
-                        endIndex = Math.max(nAnchorColKeyIndex, nTriggerColKeyIndex);
-                        // Unselect the horiz block on this row towards the previous row
-                        for(i=startIndex; i<=endIndex; i++) {
-                            oSelf.unselectCell(allRows[nTriggerTrIndex].cells[i]);
-                        }
-                    }
-                }
-                // Arrow right
-                else if(nKey == 39) {
-                    // Is the anchor cell left, right, or same column
-                    if(nAnchorColKeyIndex > nTriggerColKeyIndex) {
-                        anchorPos = 1;
-                    }
-                    else if(nAnchorColKeyIndex < nTriggerColKeyIndex) {
-                        anchorPos = -1;
-                    }
-                    else {
-                        anchorPos = 0;
-                    }
-
-                    // Selecting away from anchor cell
-                    if(anchorPos <= 0) {
-                        // Select the next vert block to the right...
-                        // ...making sure there is room
-                        if(nTriggerColKeyIndex < allRows[nTriggerTrIndex].cells.length-1) {
-                            // Select in order from anchor to trigger...
-                            startIndex = nAnchorTrIndex;
-                            endIndex = nTriggerTrIndex;
-                            // ...going up
-                            if(startIndex > endIndex) {
-                                for(i=startIndex; i>=endIndex; i--) {
-                                    elNext = allRows[i].cells[nTriggerColKeyIndex+1];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                            // ... going down
-                            else {
-                                for(i=startIndex; i<=endIndex; i++) {
-                                    elNext = allRows[i].cells[nTriggerColKeyIndex+1];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else {
-                        // Unselect the vert block on this column towards the right
-                        startIndex = Math.min(nAnchorTrIndex, nTriggerTrIndex);
-                        endIndex = Math.max(nAnchorTrIndex, nTriggerTrIndex);
-                        for(i=startIndex; i<=endIndex; i++) {
-                            oSelf.unselectCell(allRows[i].cells[nTriggerColKeyIndex]);
-                        }
-                    }
-                }
-                // Arrow left
-                else if(nKey == 37) {
-                    // Is the anchor cell left, right, or same column
-                    if(nAnchorColKeyIndex > nTriggerColKeyIndex) {
-                        anchorPos = 1;
-                    }
-                    else if(nAnchorColKeyIndex < nTriggerColKeyIndex) {
-                        anchorPos = -1;
-                    }
-                    else {
-                        anchorPos = 0;
-                    }
-
-                    // Selecting away from anchor cell
-                    if(anchorPos >= 0) {
-                        //Select the previous vert block to the left
-                        if(nTriggerColKeyIndex > 0) {
-                            // Select in order from anchor to trigger...
-                            startIndex = nAnchorTrIndex;
-                            endIndex = nTriggerTrIndex;
-                            // ...going up
-                            if(startIndex > endIndex) {
-                                for(i=startIndex; i>=endIndex; i--) {
-                                    elNext = allRows[i].cells[nTriggerColKeyIndex-1];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                            // ... going down
-                            else {
-                                for(i=startIndex; i<=endIndex; i++) {
-                                    elNext = allRows[i].cells[nTriggerColKeyIndex-1];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else {
-                        // Unselect the vert block on this column towards the left
-                        startIndex = Math.min(nAnchorTrIndex, nTriggerTrIndex);
-                        endIndex = Math.max(nAnchorTrIndex, nTriggerTrIndex);
-                        for(i=startIndex; i<=endIndex; i++) {
-                            oSelf.unselectCell(allRows[i].cells[nTriggerColKeyIndex]);
-                        }
-                    }
-                }
-            }
-            ////////////////////////////////////////////////////////////////////////
-            //
-            // SHIFT cell range selection
-            //
-            ////////////////////////////////////////////////////////////////////////
-            else if(bSHIFT && (sMode == "cellrange")) {
-                // Is the anchor cell above, below, or same row as trigger
-                if(nAnchorRecordIndex > nTriggerRecordIndex) {
-                    anchorPos = 1;
-                }
-                else if(nAnchorRecordIndex < nTriggerRecordIndex) {
-                    anchorPos = -1;
-                }
-                else {
-                    anchorPos = 0;
-                }
-
-                // Arrow down
-                if(nKey == 40) {
-                    // Selecting away from anchor cell
-                    if(anchorPos <= 0) {
-                        // Select all cells to the end of this row
-                        for(i=nTriggerColKeyIndex+1; i<allRows[nTriggerTrIndex].cells.length; i++){
-                            elNext = allRows[nTriggerTrIndex].cells[i];
-                            oSelf.selectCell(elNext);
-                        }
-
-                        // Select some of the cells on the next row down
-                        if(nTriggerTrIndex < allRows.length-1) {
-                            for(i=0; i<=nTriggerColKeyIndex; i++){
-                                elNext = allRows[nTriggerTrIndex+1].cells[i];
-                                oSelf.selectCell(elNext);
-                            }
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else {
-                        // Unselect all cells to the end of this row
-                        for(i=nTriggerColKeyIndex; i<allRows[nTriggerTrIndex].cells.length; i++){
-                            oSelf.unselectCell(allRows[nTriggerTrIndex].cells[i]);
-                        }
-
-                        // Unselect some of the cells on the next row down
-                        for(i=0; i<nTriggerColKeyIndex; i++){
-                            oSelf.unselectCell(allRows[nTriggerTrIndex+1].cells[i]);
-                        }
-                    }
-                }
-                // Arrow up
-                else if(nKey == 38) {
-                    // Selecting away from anchor cell
-                    if(anchorPos >= 0) {
-                        // Select all the cells to the beginning of this row
-                        for(i=nTriggerColKeyIndex-1; i>-1; i--){
-                            elNext = allRows[nTriggerTrIndex].cells[i];
-                            oSelf.selectCell(elNext);
-                        }
-
-                        // Select some of the cells from the end of the previous row
-                        if(nTriggerTrIndex > 0) {
-                            for(i=allRows[nTriggerTrIndex].cells.length-1; i>=nTriggerColKeyIndex; i--){
-                                elNext = allRows[nTriggerTrIndex-1].cells[i];
-                                oSelf.selectCell(elNext);
-                            }
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else {
-                        // Unselect all the cells to the beginning of this row
-                        for(i=nTriggerColKeyIndex; i>-1; i--){
-                            oSelf.unselectCell(allRows[nTriggerTrIndex].cells[i]);
-                        }
-
-                        // Unselect some of the cells from the end of the previous row
-                        for(i=allRows[nTriggerTrIndex].cells.length-1; i>nTriggerColKeyIndex; i--){
-                            oSelf.unselectCell(allRows[nTriggerTrIndex-1].cells[i]);
-                        }
-                    }
-                }
-                // Arrow right
-                else if(nKey == 39) {
-                    // Selecting away from anchor cell
-                    if(anchorPos < 0) {
-                        // Select the next cell to the right
-                        if(nTriggerColKeyIndex < allRows[nTriggerTrIndex].cells.length-1) {
-                            elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex+1];
-                            oSelf.selectCell(elNext);
-                        }
-                        // Select the first cell of the next row
-                        else if(nTriggerTrIndex < allRows.length-1) {
-                            elNext = allRows[nTriggerTrIndex+1].cells[0];
-                            oSelf.selectCell(elNext);
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else if(anchorPos > 0) {
-                        oSelf.unselectCell(allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex]);
-
-                        // Unselect this cell towards the right
-                        if(nTriggerColKeyIndex < allRows[nTriggerTrIndex].cells.length-1) {
-                        }
-                        // Unselect this cells towards the first cell of the next row
-                        else {
-                        }
-                    }
-                    // Anchor is on this row
-                    else {
-                        // Selecting away from anchor
-                        if(nAnchorColKeyIndex <= nTriggerColKeyIndex) {
-                            // Select the next cell to the right
-                            if(nTriggerColKeyIndex < allRows[nTriggerTrIndex].cells.length-1) {
-                                elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex+1];
-                                oSelf.selectCell(elNext);
-                            }
-                            // Select the first cell on the next row
-                            else if(nTriggerTrIndex < allRows.length-1){
-                                elNext = allRows[nTriggerTrIndex+1].cells[0];
-                                oSelf.selectCell(elNext);
-                            }
-                        }
-                        // Unselecting towards anchor
-                        else {
-                            // Unselect this cell towards the right
-                            oSelf.unselectCell(allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex]);
-                        }
-                    }
-                }
-                // Arrow left
-                else if(nKey == 37) {
-                    // Unselecting towards the anchor
-                    if(anchorPos < 0) {
-                        oSelf.unselectCell(allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex]);
-
-                        // Unselect this cell towards the left
-                        if(nTriggerColKeyIndex > 0) {
-                        }
-                        // Unselect this cell towards the last cell of the previous row
-                        else {
-                        }
-                    }
-                    // Selecting towards the anchor
-                    else if(anchorPos > 0) {
-                        // Select the next cell to the left
-                        if(nTriggerColKeyIndex > 0) {
-                            elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex-1];
-                            oSelf.selectCell(elNext);
-                        }
-                        // Select the last cell of the previous row
-                        else if(nTriggerTrIndex > 0){
-                            elNext = allRows[nTriggerTrIndex-1].cells[allRows[nTriggerTrIndex-1].cells.length-1];
-                            oSelf.selectCell(elNext);
-                        }
-                    }
-                    // Anchor is on this row
-                    else {
-                        // Selecting away from anchor cell
-                        if(nAnchorColKeyIndex >= nTriggerColKeyIndex) {
-                            // Select the next cell to the left
-                            if(nTriggerColKeyIndex > 0) {
-                                elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex-1];
-                                oSelf.selectCell(elNext);
-                            }
-                            // Select the last cell of the previous row
-                            else if(nTriggerTrIndex > 0){
-                                elNext = allRows[nTriggerTrIndex-1].cells[allRows[nTriggerTrIndex-1].cells.length-1];
-                                oSelf.selectCell(elNext);
-                            }
-                        }
-                        // Unselecting towards anchor cell
-                        else {
-                            oSelf.unselectCell(allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex]);
-
-                            // Unselect this cell towards the left
-                            if(nTriggerColKeyIndex > 0) {
-                            }
-                            // Unselect this cell towards the last cell of the previous row
-                            else {
-                            }
-                        }
-                    }
-                }
-            }
-            ////////////////////////////////////////////////////////////////////////
-            //
-            // Simple single cell selection
-            //
-            ////////////////////////////////////////////////////////////////////////
-            else if((sMode == "cellblock") || (sMode == "cellrange") || (sMode == "singlecell")) {
-                // Arrow down
-                if(nKey == 40) {
-                    oSelf.unselectAllCells();
-
-                    // Select the next cell down
-                    if(nTriggerTrIndex < allRows.length-1) {
-                        elNext = allRows[nTriggerTrIndex+1].cells[nTriggerColKeyIndex];
-                        oSelf.selectCell(elNext);
-                    }
-                    // Select only the bottom cell
-                    else {
-                        elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex];
-                        oSelf.selectCell(elNext);
-                    }
-
-                    oSelf._oAnchorCell = {record:oSelf.getRecord(elNext), column:oSelf.getColumn(elNext)};
-                }
-                // Arrow up
-                else if(nKey == 38) {
-                    oSelf.unselectAllCells();
-
-                    // Select the next cell up
-                    if(nTriggerTrIndex > 0) {
-                        elNext = allRows[nTriggerTrIndex-1].cells[nTriggerColKeyIndex];
-                        oSelf.selectCell(elNext);
-                    }
-                    // Select only the top cell
-                    else {
-                        elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex];
-                        oSelf.selectCell(elNext);
-                    }
-
-                    oSelf._oAnchorCell = {record:oSelf.getRecord(elNext), column:oSelf.getColumn(elNext)};
-                }
-                // Arrow right
-                else if(nKey == 39) {
-                    oSelf.unselectAllCells();
-
-                    // Select the next cell to the right
-                    if(nTriggerColKeyIndex < allRows[nTriggerTrIndex].cells.length-1) {
-                        elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex+1];
-                        oSelf.selectCell(elNext);
-                    }
-                    // Select only the right cell
-                    else {
-                        elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex];
-                        oSelf.selectCell(elNext);
-                    }
-
-                    oSelf._oAnchorCell = {record:oSelf.getRecord(elNext), column:oSelf.getColumn(elNext)};
-                }
-                // Arrow left
-                else if(nKey == 37) {
-                    oSelf.unselectAllCells();
-
-                    // Select the next cell to the left
-                    if(nTriggerColKeyIndex > 0) {
-                        elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex-1];
-                        oSelf.selectCell(elNext);
-                    }
-                    // Select only the left cell
-                    else {
-                        elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex];
-                        oSelf.selectCell(elNext);
-                    }
-
-                    oSelf._oAnchorCell = {record:oSelf.getRecord(elNext), column:oSelf.getColumn(elNext)};
-                }
-            }
-
-
-
-
-
-
-
-
-
-
-
-
-
         }
     }
-    else {
-        //TODO: handle tab across cells
-        //TODO: handle backspace
-        //TODO: handle delete
-        //TODO: handle arrow selection across pages
-        return;
-    }
-};
+    oSelf.fireEvent("tableKeyEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
 /**
  * Handles keypress events on the TABLE. Mainly to support stopEvent on Mac.
  *
  * @method _onTableKeypress
  * @param e {HTMLEvent} The key event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableKeypress = function(e, oSelf) {
-    var isMac = (navigator.userAgent.toLowerCase().indexOf("mac") != -1);
-    if(isMac) {
-        var nKey = YAHOO.util.Event.getCharCode(e);
+_onTableKeypress : function(e, oSelf) {
+    if(ua.webkit) {
+        var nKey = Ev.getCharCode(e);
         // arrow down
         if(nKey == 40) {
-            YAHOO.util.Event.stopEvent(e);
+            Ev.stopEvent(e);
         }
         // arrow up
         else if(nKey == 38) {
-            YAHOO.util.Event.stopEvent(e);
+            Ev.stopEvent(e);
         }
     }
-};
+},
 
 /**
  * Handles click events on the THEAD element.
  *
  * @method _onTheadClick
  * @param e {HTMLEvent} The click event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTheadClick = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
+_onTheadClick : function(e, oSelf) {
+    // Always blur the cell editor
     if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
         oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
     }
 
-    while(elTarget && (elTag != "thead")) {
-            switch(elTag) {
-                case "body":
-                    break;
-                case "span":
-                    if(YAHOO.util.Dom.hasClass(elTarget, YAHOO.widget.DataTable.CLASS_LABEL)) {
-                        oSelf.fireEvent("headerLabelClickEvent",{target:elTarget,event:e});
-                    }
-                    break;
-                case "th":
-                    oSelf.fireEvent("headerCellClickEvent",{target:elTarget,event:e});
-                    break;
-                case "tr":
-                    oSelf.fireEvent("headerRowClickEvent",{target:elTarget,event:e});
-                    break;
-                default:
-                    break;
-            }
-            elTarget = elTarget.parentNode;
-            if(elTarget) {
-                elTag = elTarget.tagName.toLowerCase();
-            }
-    }
-    oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elTable),event:e});
-};
-
-/**
- * Handles click events on the primary TBODY element.
- *
- * @method _onTbodyClick
- * @param e {HTMLEvent} The click event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
- * @private
- */
-YAHOO.widget.DataTable.prototype._onTbodyClick = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
-    if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
-        oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
-    }
-
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
     while(elTarget && (elTag != "table")) {
         switch(elTag) {
             case "body":
-                break;
+                return;
             case "input":
                 if(elTarget.type.toLowerCase() == "checkbox") {
-                    oSelf.fireEvent("checkboxClickEvent",{target:elTarget,event:e});
+                    bKeepBubbling = oSelf.fireEvent("theadCheckboxClickEvent",{target:elTarget,event:e});
                 }
                 else if(elTarget.type.toLowerCase() == "radio") {
-                    oSelf.fireEvent("radioClickEvent",{target:elTarget,event:e});
+                    bKeepBubbling = oSelf.fireEvent("theadRadioClickEvent",{target:elTarget,event:e});
                 }
-                oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elTable),event:e});
-                return;
+                break;
             case "a":
-                oSelf.fireEvent("linkClickEvent",{target:elTarget,event:e});
-                oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elTable),event:e});
-                return;
+                bKeepBubbling = oSelf.fireEvent("theadLinkClickEvent",{target:elTarget,event:e});
+                break;
             case "button":
-                oSelf.fireEvent("buttonClickEvent",{target:elTarget,event:e});
-                oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elTable),event:e});
-                return;
-            case "td":
-                oSelf.fireEvent("cellClickEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("theadButtonClickEvent",{target:elTarget,event:e});
                 break;
+            case "span":
+                if(Dom.hasClass(elTarget, DT.CLASS_LABEL)) {
+                    bKeepBubbling = oSelf.fireEvent("theadLabelClickEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerLabelClickEvent",{target:elTarget,event:e});
+                }
+                break;
+            case "th":
+                bKeepBubbling = oSelf.fireEvent("theadCellClickEvent",{target:elTarget,event:e});
+                // Backward compatibility
+                bKeepBubbling = oSelf.fireEvent("headerCellClickEvent",{target:elTarget,event:e});
+                break;
             case "tr":
-                oSelf.fireEvent("rowClickEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("theadRowClickEvent",{target:elTarget,event:e});
+                // Backward compatibility
+                bKeepBubbling = oSelf.fireEvent("headerRowClickEvent",{target:elTarget,event:e});
                 break;
             default:
                 break;
         }
-        elTarget = elTarget.parentNode;
-        if(elTarget) {
-            elTag = elTarget.tagName.toLowerCase();
+        if(bKeepBubbling === false) {
+            return;
         }
+        else {
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
+            }
+        }
     }
-    oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elTable),event:e});
-};
+    oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
-/*TODO: delete
- * Handles keyup events on the TBODY. Executes deletion.
- *
- * @method _onTbodyKeyup
- * @param e {HTMLEvent} The key event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
- * @private
- */
-/*YAHOO.widget.DataTable.prototype._onTbodyKeyup = function(e, oSelf) {
-   var nKey = YAHOO.util.Event.getCharCode(e);
-    // delete
-    if(nKey == 46) {//TODO: if something is selected
-        //TODO: delete row
-    }
-};*/
-
 /**
- * Handles click events on paginator links.
+ * Handles click events on the primary TBODY element.
  *
- * @method _onPaginatorLinkClick
+ * @method _onTbodyClick
  * @param e {HTMLEvent} The click event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onPaginatorLinkClick = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
+_onTbodyClick : function(e, oSelf) {
+    // Always blur the cell editor
     if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
         oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
     }
 
+    // Fire Custom Events
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
     while(elTarget && (elTag != "table")) {
         switch(elTag) {
             case "body":
                 return;
-            case "a":
-                YAHOO.util.Event.stopEvent(e);
-                //TODO: after the showPage call, figure out which link
-                //TODO: was clicked and reset focus to the new version of it
-                switch(elTarget.className) {
-                    case YAHOO.widget.DataTable.CLASS_PAGE:
-                        oSelf.showPage(parseInt(elTarget.innerHTML,10));
-                        return;
-                    case YAHOO.widget.DataTable.CLASS_FIRST:
-                        oSelf.showPage(1);
-                        return;
-                    case YAHOO.widget.DataTable.CLASS_LAST:
-                        oSelf.showPage(oSelf.get("paginator").totalPages);
-                        return;
-                    case YAHOO.widget.DataTable.CLASS_PREVIOUS:
-                        oSelf.showPage(oSelf.get("paginator").currentPage - 1);
-                        return;
-                    case YAHOO.widget.DataTable.CLASS_NEXT:
-                        oSelf.showPage(oSelf.get("paginator").currentPage + 1);
-                        return;
+            case "input":
+                if(elTarget.type.toLowerCase() == "checkbox") {
+                    bKeepBubbling = oSelf.fireEvent("checkboxClickEvent",{target:elTarget,event:e});
                 }
+                else if(elTarget.type.toLowerCase() == "radio") {
+                    bKeepBubbling = oSelf.fireEvent("radioClickEvent",{target:elTarget,event:e});
+                }
                 break;
+            case "a":
+                bKeepBubbling = oSelf.fireEvent("linkClickEvent",{target:elTarget,event:e});
+                break;
+            case "button":
+                bKeepBubbling = oSelf.fireEvent("buttonClickEvent",{target:elTarget,event:e});
+                break;
+            case "td":
+                bKeepBubbling = oSelf.fireEvent("cellClickEvent",{target:elTarget,event:e});
+                break;
+            case "tr":
+                bKeepBubbling = oSelf.fireEvent("rowClickEvent",{target:elTarget,event:e});
+                break;
             default:
-                return;
+                break;
         }
-        elTarget = elTarget.parentNode;
-        if(elTarget) {
-            elTag = elTarget.tagName.toLowerCase();
+        if(bKeepBubbling === false) {
+            return;
         }
         else {
-            return;
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
+            }
         }
     }
-};
+    oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
-/**
- * Handles change events on paginator SELECT element.
- *
- * @method _onPaginatorDropdownChange
- * @param e {HTMLEvent} The change event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
- * @private
- */
-YAHOO.widget.DataTable.prototype._onPaginatorDropdownChange = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var newValue = elTarget[elTarget.selectedIndex].value;
-
-    var newRowsPerPage = YAHOO.lang.isValue(parseInt(newValue,10)) ? parseInt(newValue,10) : null;
-    if(newRowsPerPage !== null) {
-        var newStartRecordIndex = (oSelf.get("paginator").currentPage-1) * newRowsPerPage;
-        oSelf.updatePaginator({rowsPerPage:newRowsPerPage, startRecordIndex:newStartRecordIndex});
-        oSelf.refreshView();
-    }
-    else {
-        YAHOO.log("Could not paginate with " + newValue + " rows per page", "error", oSelf.toString());
-    }
-};
-
-/**
+/*TODO undeprecate?
  * Handles change events on SELECT elements within DataTable.
  *
  * @method _onDropdownChange
  * @param e {HTMLEvent} The change event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
+ * @deprecated
  */
-YAHOO.widget.DataTable.prototype._onDropdownChange = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
+_onDropdownChange : function(e, oSelf) {
+    var elTarget = Ev.getTarget(e);
     //TODO: pass what args?
     //var value = elTarget[elTarget.selectedIndex].value;
     oSelf.fireEvent("dropdownChangeEvent", {event:e, target:elTarget});
-};
+},
 
 
 
@@ -3117,13 +8518,6 @@
 
 
 
-
-
-
-
-
-
-
 /////////////////////////////////////////////////////////////////////////////
 //
 // Public member variables
@@ -3137,18 +8531,27 @@
 //
 /////////////////////////////////////////////////////////////////////////////
 
-// OBJECT ACCESSORS
+/**
+ * Returns unique id assigned to instance, which is a useful prefix for
+ * generating unique DOM ID strings.
+ *
+ * @method getId
+ * @return {String} Unique ID of the DataSource instance.
+ */
+getId : function() {
+    return this._sId;
+},
 
 /**
- * Public accessor to the unique name of the DataSource instance.
+ * DataSource instance name, for logging.
  *
  * @method toString
  * @return {String} Unique name of the DataSource instance.
  */
 
-YAHOO.widget.DataTable.prototype.toString = function() {
-    return "DataTable " + this._sName;
-};
+toString : function() {
+    return "DataTable instance " + this._sId;
+},
 
 /**
  * Returns the DataTable instance's DataSource instance.
@@ -3156,9 +8559,9 @@
  * @method getDataSource
  * @return {YAHOO.util.DataSource} DataSource instance.
  */
-YAHOO.widget.DataTable.prototype.getDataSource = function() {
+getDataSource : function() {
     return this._oDataSource;
-};
+},
 
 /**
  * Returns the DataTable instance's ColumnSet instance.
@@ -3166,9 +8569,9 @@
  * @method getColumnSet
  * @return {YAHOO.widget.ColumnSet} ColumnSet instance.
  */
-YAHOO.widget.DataTable.prototype.getColumnSet = function() {
+getColumnSet : function() {
     return this._oColumnSet;
-};
+},
 
 /**
  * Returns the DataTable instance's RecordSet instance.
@@ -3176,9 +8579,9 @@
  * @method getRecordSet
  * @return {YAHOO.widget.RecordSet} RecordSet instance.
  */
-YAHOO.widget.DataTable.prototype.getRecordSet = function() {
+getRecordSet : function() {
     return this._oRecordSet;
-};
+},
 
 /**
  * Returns the DataTable instance's Cell Editor as an object literal with the
@@ -3217,6 +8620,10 @@
  *
  *  </dd>
  *
+ * <dt>defaultValue</dt>
+ * <dd>Dynamically settable default value</dd>
+ * </dl>
+ *
  * <dt>value</dt>
  * <dd>Current input value</dd>
  * </dl>
@@ -3225,13 +8632,12 @@
  *
  *
  *
- *
  * @method getCellEditor
  * @return {Object} Cell Editor object literal values.
  */
-YAHOO.widget.DataTable.prototype.getCellEditor = function() {
+getCellEditor : function() {
     return this._oCellEditor;
-};
+},
 
 
 
@@ -3278,14 +8684,14 @@
 // DOM ACCESSORS
 
 /**
- * Returns DOM reference to the DataTable's TABLE element.
+ * Returns DOM reference to the DataTable's container element.
  *
- * @method getTableEl
- * @return {HTMLElement} Reference to TABLE element.
+ * @method getContainerEl
+ * @return {HTMLElement} Reference to DIV element.
  */
-YAHOO.widget.DataTable.prototype.getTableEl = function() {
-    return this._elTable;
-};
+getContainerEl : function() {
+    return this._elContainer;
+},
 
 /**
  * Returns DOM reference to the DataTable's THEAD element.
@@ -3293,9 +8699,9 @@
  * @method getTheadEl
  * @return {HTMLElement} Reference to THEAD element.
  */
-YAHOO.widget.DataTable.prototype.getTheadEl = function() {
+getTheadEl : function() {
     return this._elThead;
-};
+},
 
 /**
  * Returns DOM reference to the DataTable's primary TBODY element.
@@ -3303,15 +8709,9 @@
  * @method getTbodyEl
  * @return {HTMLElement} Reference to TBODY element.
  */
-YAHOO.widget.DataTable.prototype.getTbodyEl = function() {
+getTbodyEl : function() {
     return this._elTbody;
-};
-// Backward compatibility
-YAHOO.widget.DataTable.prototype.getBody = function() {
-    YAHOO.log("The method getBody() has been deprecated" +
-            " in favor of getTbodyEl()", "warn", this.toString());
-    return this.getTbodyEl();
-};
+},
 
 /**
  * Returns DOM reference to the DataTable's secondary TBODY element that is
@@ -3320,9 +8720,9 @@
  * @method getMsgTbodyEl
  * @return {HTMLElement} Reference to TBODY element.
  */
-YAHOO.widget.DataTable.prototype.getMsgTbodyEl = function() {
+getMsgTbodyEl : function() {
     return this._elMsgTbody;
-};
+},
 
 /**
  * Returns DOM reference to the TD element within the secondary TBODY that is
@@ -3331,9 +8731,9 @@
  * @method getMsgTdEl
  * @return {HTMLElement} Reference to TD element.
  */
-YAHOO.widget.DataTable.prototype.getMsgTdEl = function() {
+getMsgTdEl : function() {
     return this._elMsgTd;
-};
+},
 
 /**
  * Returns the corresponding TR reference for a given DOM element, ID string or
@@ -3346,9 +8746,9 @@
  * get: by element reference, ID string, page row index, or Record.
  * @return {HTMLElement} Reference to TR element, or null.
  */
-YAHOO.widget.DataTable.prototype.getTrEl = function(row) {
+getTrEl : function(row) {
     var allRows = this._elTbody.rows;
-    
+
     // By Record
     if(row instanceof YAHOO.widget.Record) {
         var nTrIndex = this.getTrIndex(row);
@@ -3361,20 +8761,20 @@
             }
     }
     // By page row index
-    else if(YAHOO.lang.isNumber(row) && (row > -1) && (row < allRows.length)) {
+    else if(lang.isNumber(row) && (row > -1) && (row < allRows.length)) {
         return allRows[row];
     }
     // By ID string or element reference
     else {
         var elRow;
-        var el = YAHOO.util.Dom.get(row);
-        
+        var el = Dom.get(row);
+
         // Validate HTML element
         if(el && (el.ownerDocument == document)) {
             // Validate TR element
-            if(el.tagName.toLowerCase() != "tr") {
+            if(el.nodeName.toLowerCase() != "tr") {
                 // Traverse up the DOM to find the corresponding TR element
-                elRow = YAHOO.util.Dom.getAncestorByTagName(el,"tr");
+                elRow = Dom.getAncestorByTagName(el,"tr");
             }
             else {
                 elRow = el;
@@ -3387,16 +8787,9 @@
             }
         }
     }
-    
-    YAHOO.log("Could not get TR element for row " + row, "warn", this.toString());
+
     return null;
-};
-// Backward compatibility
-YAHOO.widget.DataTable.prototype.getRow = function(index) {
-    YAHOO.log("The method getRow() has been deprecated" +
-            " in favor of getTrEl()", "warn", this.toString());
-    return this.getTrEl(index);
-};
+},
 
 /**
  * Returns DOM reference to the first TR element in the DataTable page, or null.
@@ -3404,9 +8797,9 @@
  * @method getFirstTrEl
  * @return {HTMLElement} Reference to TR element.
  */
-YAHOO.widget.DataTable.prototype.getFirstTrEl = function() {
+getFirstTrEl : function() {
     return this._elTbody.rows[0] || null;
-};
+},
 
 /**
  * Returns DOM reference to the last TR element in the DataTable page, or null.
@@ -3414,14 +8807,69 @@
  * @method getLastTrEl
  * @return {HTMLElement} Reference to last TR element.
  */
-YAHOO.widget.DataTable.prototype.getLastTrEl = function() {
+getLastTrEl : function() {
     var allRows = this._elTbody.rows;
         if(allRows.length > 0) {
             return allRows[allRows.length-1] || null;
         }
-};
+},
 
 /**
+ * Returns DOM reference to the next TR element from the given TR element, or null.
+ *
+ * @method getNextTrEl
+ * @param row {HTMLElement | String | Number | YAHOO.widget.Record} Element
+ * reference, ID string, page row index, or Record from which to get next TR element.
+ * @return {HTMLElement} Reference to next TR element.
+ */
+getNextTrEl : function(row) {
+    var nThisTrIndex = this.getTrIndex(row);
+    if(nThisTrIndex !== null) {
+        var allRows = this._elTbody.rows;
+        if(nThisTrIndex < allRows.length-1) {
+            return allRows[nThisTrIndex+1];
+        }
+    }
+
+    YAHOO.log("Could not get next TR element for row " + row, "info", this.toString());
+    return null;
+},
+
+/**
+ * Returns DOM reference to the previous TR element from the given TR element, or null.
+ *
+ * @method getPreviousTrEl
+ * @param row {HTMLElement | String | Number | YAHOO.widget.Record} Element
+ * reference, ID string, page row index, or Record from which to get previous TR element.
+ * @return {HTMLElement} Reference to previous TR element.
+ */
+getPreviousTrEl : function(row) {
+    var nThisTrIndex = this.getTrIndex(row);
+    if(nThisTrIndex !== null) {
+        var allRows = this._elTbody.rows;
+        if(nThisTrIndex > 0) {
+            return allRows[nThisTrIndex-1];
+        }
+    }
+
+    YAHOO.log("Could not get previous TR element for row " + row, "info", this.toString());
+    return null;
+},
+
+/**
+ * Returns DOM reference to a TD liner element.
+ *
+ * @method getTdLinerEl
+ * @param cell {HTMLElement | String | Object} DOM element reference or string ID, or
+ * object literal of syntax {record:oRecord, column:oColumn}.
+ * @return {HTMLElement} Reference to TD liner element.
+ */
+getTdLinerEl : function(cell) {
+    var elCell = this.getTdEl(cell);
+    return elCell.firstChild || null;
+},
+
+/**
  * Returns DOM reference to a TD element.
  *
  * @method getTdEl
@@ -3429,16 +8877,16 @@
  * object literal of syntax {record:oRecord, column:oColumn}.
  * @return {HTMLElement} Reference to TD element.
  */
-YAHOO.widget.DataTable.prototype.getTdEl = function(cell) {
+getTdEl : function(cell) {
     var elCell;
-    var el = YAHOO.util.Dom.get(cell);
+    var el = Dom.get(cell);
 
     // Validate HTML element
     if(el && (el.ownerDocument == document)) {
         // Validate TD element
-        if(el.tagName.toLowerCase() != "td") {
+        if(el.nodeName.toLowerCase() != "td") {
             // Traverse up the DOM to find the corresponding TR element
-            elCell = YAHOO.util.Dom.getAncestorByTagName(el, "td");
+            elCell = Dom.getAncestorByTagName(el, "td");
         }
         else {
             elCell = el;
@@ -3450,62 +8898,213 @@
             return elCell;
         }
     }
-    else if(cell.record && cell.column && cell.column.getKeyIndex) {
-        var oRecord = cell.record;
+    else if(cell) {
+        var oRecord, nColKeyIndex;
+
+        if(lang.isString(cell.columnId) && lang.isString(cell.recordId)) {
+            oRecord = this.getRecord(cell.recordId);
+            var oColumn = this.getColumnById(cell.columnId);
+            if(oColumn) {
+                nColKeyIndex = oColumn.getKeyIndex();
+            }
+
+        }
+        if(cell.record && cell.column && cell.column.getKeyIndex) {
+            oRecord = cell.record;
+            nColKeyIndex = cell.column.getKeyIndex();
+        }
         var elRow = this.getTrEl(oRecord);
-        if(elRow && elRow.cells && elRow.cells.length > 0) {
-            return elRow.cells[cell.column.getKeyIndex()] || null;
+        if((nColKeyIndex !== null) && elRow && elRow.cells && elRow.cells.length > 0) {
+            return elRow.cells[nColKeyIndex] || null;
         }
     }
-    
-    YAHOO.log("Could not get TD element for cell " + cell, "warn", this.toString());
+
     return null;
-};
+},
 
 /**
+ * Returns DOM reference to the first TD element in the DataTable page (by default),
+ * the first TD element of the optionally given row, or null.
+ *
+ * @method getFirstTdEl
+ * @param row {HTMLElement} (optional) row from which to get first TD
+ * @return {HTMLElement} Reference to TD element.
+ */
+getFirstTdEl : function(row) {
+    var elRow = this.getTrEl(row) || this.getFirstTrEl();
+    if(elRow && (elRow.cells.length > 0)) {
+        return elRow.cells[0];
+    }
+    YAHOO.log("Could not get first TD element for row " + elRow, "info", this.toString());
+    return null;
+},
+
+/**
+ * Returns DOM reference to the last TD element in the DataTable page (by default),
+ * the first TD element of the optionally given row, or null.
+ *
+ * @method getLastTdEl
+ * @return {HTMLElement} Reference to last TD element.
+ */
+getLastTdEl : function(row) {
+    var elRow = this.getTrEl(row) || this.getLastTrEl();
+    if(elRow && (elRow.cells.length > 0)) {
+        return elRow.cells[elRow.cells.length-1];
+    }
+    YAHOO.log("Could not get last TD element for row " + elRow, "info", this.toString());
+    return null;
+},
+
+/**
+ * Returns DOM reference to the next TD element from the given cell, or null.
+ *
+ * @method getNextTdEl
+ * @param cell {HTMLElement | String | Object} DOM element reference or string ID, or
+ * object literal of syntax {record:oRecord, column:oColumn} from which to get next TD element.
+ * @return {HTMLElement} Reference to next TD element, or null.
+ */
+getNextTdEl : function(cell) {
+    var elCell = this.getTdEl(cell);
+    if(elCell) {
+        var nThisTdIndex = elCell.yuiCellIndex;
+        var elRow = this.getTrEl(elCell);
+        if(nThisTdIndex < elRow.cells.length-1) {
+            return elRow.cells[nThisTdIndex+1];
+        }
+        else {
+            var elNextRow = this.getNextTrEl(elRow);
+            if(elNextRow) {
+                return elNextRow.cells[0];
+            }
+        }
+    }
+    YAHOO.log("Could not get next TD element for cell " + cell, "info", this.toString());
+    return null;
+},
+
+/**
+ * Returns DOM reference to the previous TD element from the given cell, or null.
+ *
+ * @method getPreviousTdEl
+ * @param cell {HTMLElement | String | Object} DOM element reference or string ID, or
+ * object literal of syntax {record:oRecord, column:oColumn} from which to get previous TD element.
+ * @return {HTMLElement} Reference to previous TD element, or null.
+ */
+getPreviousTdEl : function(cell) {
+    var elCell = this.getTdEl(cell);
+    if(elCell) {
+        var nThisTdIndex = elCell.yuiCellIndex;
+        var elRow = this.getTrEl(elCell);
+        if(nThisTdIndex > 0) {
+            return elRow.cells[nThisTdIndex-1];
+        }
+        else {
+            var elPreviousRow = this.getPreviousTrEl(elRow);
+            if(elPreviousRow) {
+                return this.getLastTdEl(elPreviousRow);
+            }
+        }
+    }
+    YAHOO.log("Could not get next TD element for cell " + cell, "info", this.toString());
+    return null;
+},
+
+/**
+ * Returns DOM reference to the above TD element from the given cell, or null.
+ *
+ * @method getAboveTdEl
+ * @param cell {HTMLElement | String | Object} DOM element reference or string ID, or
+ * object literal of syntax {record:oRecord, column:oColumn} from which to get next TD element.
+ * @return {HTMLElement} Reference to next TD element, or null.
+ */
+getAboveTdEl : function(cell) {
+    var elCell = this.getTdEl(cell);
+    if(elCell) {
+        var elPreviousRow = this.getPreviousTrEl(elCell);
+        if(elPreviousRow) {
+            return elPreviousRow.cells[elCell.yuiCellIndex];
+        }
+    }
+    YAHOO.log("Could not get above TD element for cell " + cell, "info", this.toString());
+    return null;
+},
+
+/**
+ * Returns DOM reference to the below TD element from the given cell, or null.
+ *
+ * @method getBelowTdEl
+ * @param cell {HTMLElement | String | Object} DOM element reference or string ID, or
+ * object literal of syntax {record:oRecord, column:oColumn} from which to get previous TD element.
+ * @return {HTMLElement} Reference to previous TD element, or null.
+ */
+getBelowTdEl : function(cell) {
+    var elCell = this.getTdEl(cell);
+    if(elCell) {
+        var elNextRow = this.getNextTrEl(elCell);
+        if(elNextRow) {
+            return elNextRow.cells[elCell.yuiCellIndex];
+        }
+    }
+    YAHOO.log("Could not get below TD element for cell " + cell, "info", this.toString());
+    return null;
+},
+
+/**
+ * Returns DOM reference to a TH liner element.
+ *
+ * @method getThLinerEl
+ * @param theadCell {YAHOO.widget.Column | HTMLElement | String} Column instance,
+ * DOM element reference, or string ID.
+ * @return {HTMLElement} Reference to TH liner element.
+ */
+getThLinerEl : function(theadCell) {
+    var elCell = this.getThEl(theadCell);
+    return elCell.firstChild || null;
+},
+
+/**
  * Returns DOM reference to a TH element.
  *
  * @method getThEl
- * @param header {YAHOO.widget.Column | HTMLElement | String} Column instance,
+ * @param theadCell {YAHOO.widget.Column | HTMLElement | String} Column instance,
  * DOM element reference, or string ID.
  * @return {HTMLElement} Reference to TH element.
  */
-YAHOO.widget.DataTable.prototype.getThEl = function(header) {
-    var elHeader;
-        
+getThEl : function(theadCell) {
+    var elTheadCell;
+
     // Validate Column instance
-    if(header instanceof YAHOO.widget.Column) {
-        var oColumn = header;
-        elHeader = YAHOO.util.Dom.get(this.id + "-col" + oColumn.getId());
-        if(elHeader) {
-            return elHeader;
+    if(theadCell instanceof YAHOO.widget.Column) {
+        var oColumn = theadCell;
+        elTheadCell = oColumn.getThEl();
+        if(elTheadCell) {
+            return elTheadCell;
         }
     }
     // Validate HTML element
     else {
-        var el = YAHOO.util.Dom.get(header);
+        var el = Dom.get(theadCell);
 
         if(el && (el.ownerDocument == document)) {
             // Validate TH element
-            if(el.tagName.toLowerCase() != "th") {
+            if(el.nodeName.toLowerCase() != "th") {
                 // Traverse up the DOM to find the corresponding TR element
-                elHeader = YAHOO.util.Dom.getAncestorByTagName(el,"th");
+                elTheadCell = Dom.getAncestorByTagName(el,"th");
             }
             else {
-                elHeader = el;
+                elTheadCell = el;
             }
 
             // Make sure the TH is in this THEAD
-            if(elHeader && (elHeader.parentNode.parentNode == this._elThead)) {
+            if(elTheadCell && (elTheadCell.parentNode.parentNode == this._elThead)) {
                 // Now we can return the TD element
-                return elHeader;
+                return elTheadCell;
             }
         }
     }
 
-    YAHOO.log("Could not get TH element for header " + header, "warn", this.toString());
     return null;
-};
+},
 
 /**
  * Returns the page row index of given row. Returns null if the row is not on the
@@ -3517,9 +9116,9 @@
  * or a Record's RecordSet index.
  * @return {Number} Page row index, or null if row does not exist or is not on current page.
  */
-YAHOO.widget.DataTable.prototype.getTrIndex = function(row) {
+getTrIndex : function(row) {
     var nRecordIndex;
-    
+
     // By Record
     if(row instanceof YAHOO.widget.Record) {
         nRecordIndex = this._oRecordSet.getRecordIndex(row);
@@ -3529,17 +9128,28 @@
         }
     }
     // Calculate page row index from Record index
-    else if(YAHOO.lang.isNumber(row)) {
+    else if(lang.isNumber(row)) {
         nRecordIndex = row;
     }
-    if(YAHOO.lang.isNumber(nRecordIndex)) {
+    if(lang.isNumber(nRecordIndex)) {
         // Validate the number
         if((nRecordIndex > -1) && (nRecordIndex < this._oRecordSet.getLength())) {
             // DataTable is paginated
-            if(this.get("paginated")) {
+            var oPaginator = this.get('paginator');
+            if(oPaginator instanceof Pag || this.get('paginated')) {
                 // Get the first and last Record on current page
-                var startRecordIndex = this.get("paginator").startRecordIndex;
-                var endRecordIndex = startRecordIndex + this.get("paginator").rowsPerPage - 1;
+                var startRecordIndex = 0,
+                    endRecordIndex   = 0;
+
+                if (oPaginator instanceof Pag) {
+                    var rng = oPaginator.getPageRecords();
+                    startRecordIndex = rng[0];
+                    endRecordIndex   = rng[1];
+                } else {
+                    startRecordIndex = oPaginator.startRecordIndex;
+                    endRecordIndex = startRecordIndex + oPaginator.rowsPerPage - 1;
+                }
+
                 // This Record is on current page
                 if((nRecordIndex >= startRecordIndex) && (nRecordIndex <= endRecordIndex)) {
                     return nRecordIndex - startRecordIndex;
@@ -3568,10 +9178,10 @@
             return elRow.sectionRowIndex;
         }
     }
-    
-    YAHOO.log("Could not get page row index for row " + row, "warn", this.toString());
+
+    YAHOO.log("Could not get page row index for row " + row, "info", this.toString());
     return null;
-};
+},
 
 
 
@@ -3622,75 +9232,82 @@
 
 /**
  * Resets a RecordSet with the given data and populates the page view
- * with the new data. Any previous data and selection states are cleared.
- * However, sort states are not cleared, so if the given data is in a particular
- * sort order, implementers should take care to reset the sortedBy property. If
- * pagination is enabled, the currentPage is shown and Paginator UI updated,
- * otherwise all rows are displayed as a single page. For performance, existing
- * DOM elements are reused when possible.
+ * with the new data. Any previous data, and selection and sort states are
+ * cleared. The render method should be called as a separate step in order
+ * to update the UI. 
  *
  * @method initializeTable
- * @param oData {Object | Object[]} An object literal of data or an array of
- * object literals containing data.
  */
-YAHOO.widget.DataTable.prototype.initializeTable = function(oData) {
+initializeTable : function() {
+    // Reset init flag
+    this._bInit = true;
+    
     // Clear the RecordSet
     this._oRecordSet.reset();
 
-    // Add data to RecordSet
-    var records = this._oRecordSet.addRecords(oData);
-
     // Clear selections
     this._unselectAllTrEls();
     this._unselectAllTdEls();
     this._aSelections = null;
     this._oAnchorRecord = null;
     this._oAnchorCell = null;
+    
+    // Clear sort
+    this.set("sortedBy", null);
+},
 
-    // Refresh the view
-    this.refreshView();
-    this.fireEvent("initEvent");
-};
-
 /**
- * Refreshes the view with existing Records from the RecordSet while
+ * Renders the view with existing Records from the RecordSet while
  * maintaining sort, pagination, and selection states. For performance, reuses
  * existing DOM elements when possible while deleting extraneous elements.
  *
- * @method refreshView
+ * @method render
  */
-YAHOO.widget.DataTable.prototype.refreshView = function() {
-    var i, j, k, l, aRecords;
-    var oPaginator = this.updatePaginator();
+render : function() {
+    this._oChainRender.stop();
+    this.showTableMessage(DT.MSG_LOADING, DT.CLASS_LOADING);
+    YAHOO.log("DataTable rendering...", "info", this.toString());
 
+    var i, j, k, l, len, allRecords;
+
     // Paginator is enabled, show a subset of Records and update Paginator UI
-    if(this.get("paginated")) {
-        var rowsPerPage = oPaginator.rowsPerPage;
-        var startRecordIndex = (oPaginator.currentPage - 1) * rowsPerPage;
-        aRecords = this._oRecordSet.getRecords(startRecordIndex, rowsPerPage);
-        this.formatPaginators();
+    var oPaginator = this.get('paginator');
+    var bPaginated = oPaginator instanceof Pag || this.get('paginated');
+    if(bPaginated) {
+        if (oPaginator instanceof Pag) {
+            allRecords = this._oRecordSet.getRecords(
+                            oPaginator.getStartIndex(),
+                            oPaginator.getRowsPerPage());
+            oPaginator.render();
+        }
+        else {
+            // Backward compatibility
+            this.updatePaginator();
+            var rowsPerPage = oPaginator.rowsPerPage;
+            var startRecordIndex = (oPaginator.currentPage - 1) * rowsPerPage;
+            allRecords = this._oRecordSet.getRecords(startRecordIndex, rowsPerPage);
+            this.formatPaginators();
+        }
     }
     // Show all records
     else {
-        aRecords = this._oRecordSet.getRecords();
+        allRecords = this._oRecordSet.getRecords();
     }
 
     var elTbody = this._elTbody;
-    var elRows = elTbody.rows;
+    var allRows = elTbody.rows;
 
-    // Has rows
-    if(YAHOO.lang.isArray(aRecords) && (aRecords.length > 0)) {
-        this.hideTableMessage();
-
+    // Should have rows
+    if(lang.isArray(allRecords) && (allRecords.length > 0)) {
         // Keep track of selected rows
-        var aSelectedRows = this.getSelectedRows();
+        var allSelectedRows = this.getSelectedRows();
         // Keep track of selected cells
-        var aSelectedCells = this.getSelectedCells();
+        var allSelectedCells = this.getSelectedCells();
         // Anything to reinstate?
-        var bReselect = (aSelectedRows.length>0) || (aSelectedCells.length > 0);
+        var bReselect = (allSelectedRows.length>0) || (allSelectedCells.length > 0);
 
         // Remove extra rows from the bottom so as to preserve ID order
-        while(elTbody.hasChildNodes() && (elRows.length > aRecords.length)) {
+        while(elTbody.hasChildNodes() && (allRows.length > allRecords.length)) {
             elTbody.deleteRow(-1);
         }
 
@@ -3700,59 +9317,151 @@
             this._unselectAllTdEls();
         }
 
-        // From the top, update in-place existing rows
-        for(i=0; i<elRows.length; i++) {
-            this._updateTrEl(elRows[i], aRecords[i]);
-        }
+        this.hideTableMessage();
 
-        // Add TR elements as necessary
-        for(i=elRows.length; i<aRecords.length; i++) {
-            this._addTrEl(aRecords[i]);
+        // How many rows to work with each loop
+        var loopN = this.get("renderLoopSize");
+        var loopStart,
+            loopEnd;
+        
+        // From the top, update in-place existing rows, so as to reuse DOM elements
+        if(allRows.length > 0) {
+            loopEnd = allRows.length; // End at last row
+            this._oChainRender.add({
+                method: function(oArg) {
+                    if((this instanceof DT) && this._sId) {
+                        var i = oArg.nCurrentRow,
+                            // Must reference allRows.length instead of loopEnd
+                            // here because loopEnd is reused below outside
+                            // this closure.
+                            len = loopN > 0 ? Math.min(i + loopN,allRows.length) : allRows.length;
+                        for(; i < len; ++i) {
+                            this._updateTrEl(allRows[i], allRecords[i]);
+                        }
+                        if (loopN > 0) {
+                            this._syncColWidths();
+                        }
+                        oArg.nCurrentRow = i;
+                    }
+                },
+                iterations: (loopN > 0) ? Math.ceil(loopEnd/loopN) : 1,
+                argument: {nCurrentRow:0}, // Start at first row
+                scope: this,
+                timeout: (loopN > 0) ? 0 : -1
+            });
         }
 
-        // Reinstate selected and sorted classes
-        if(bReselect) {
-            // Loop over each row
-            for(j=0; j<elRows.length; j++) {
-                var thisRow = elRows[j];
-                var sMode = this.get("selectionMode");
-                if ((sMode == "standard") || (sMode == "single")) {
-                    // Set SELECTED
-                    for(k=0; k<aSelectedRows.length; k++) {
-                        if(aSelectedRows[k] === thisRow.yuiRecordId) {
-                            YAHOO.util.Dom.addClass(thisRow, YAHOO.widget.DataTable.CLASS_SELECTED);
-                            if(j === elRows.length-1) {
-                                this._oAnchorRecord = this.getRecord(thisRow.yuiRecordId);
-                            }
+        // Add more TR elements as necessary
+        loopStart = allRows.length; // where to start
+        loopEnd = allRecords.length; // where to end
+        var nRowsNeeded = (loopEnd - loopStart); // how many needed
+        if(nRowsNeeded > 0) {
+            this._oChainRender.add({
+                method: function(oArg) {
+                    if((this instanceof DT) && this._sId) {
+                        var i = oArg.nCurrentRow,
+                            len = loopN > 0 ? Math.min(i + loopN,loopEnd) : loopEnd,
+                            df = document.createDocumentFragment(),
+                            tr;
+                        for(; i < len; ++i) {
+                            tr = this._createTrEl(allRecords[i]);
+                            tr.className = (i%2) ? DT.CLASS_ODD : DT.CLASS_EVEN;
+                            df.appendChild(tr);
                         }
+                        this._elTbody.appendChild(df);
+                        if (loopN > 0) {
+                            this._syncColWidths();
+                        }
+                        oArg.nCurrentRow = i;
                     }
-                }
-                else {
-                    // Loop over each cell
-                    for(k=0; k<thisRow.cells.length; k++) {
-                        var thisCell = thisRow.cells[k];
-                        // Set SELECTED
-                        for(l=0; l<aSelectedCells.length; l++) {
-                            if((aSelectedCells[l].recordId === thisRow.yuiRecordId) &&
-                                    (aSelectedCells[l].columnId === thisCell.yuiColumnId)) {
-                                YAHOO.util.Dom.addClass(thisCell, YAHOO.widget.DataTable.CLASS_SELECTED);
-                                if(k === thisRow.cells.length-1) {
-                                    this._oAnchorCell = {record:this.getRecord(thisRow.yuiRecordId), column:this.getColumnById(thisCell.yuiColumnId)};
+                },
+                iterations: (loopN > 0) ? Math.ceil(nRowsNeeded/loopN) : 1,
+                argument: {nCurrentRow:loopStart}, // start at last row
+                scope: this,
+                timeout: (loopN > 0) ? 0 : -1
+            });
+        }
+
+        this._oChainRender.add({
+            method: function(oArg) {
+                if((this instanceof DT) && this._sId) {
+                    this._setFirstRow();
+                    this._setLastRow();
+
+                    // Reinstate selected and sorted classes
+                    if(bReselect) {
+                        // Loop over each row
+                        for(j=0; j<allRows.length; j++) {
+                            var thisRow = allRows[j];
+                            var sMode = this.get("selectionMode");
+                            if ((sMode == "standard") || (sMode == "single")) {
+                                // Set SELECTED
+                                for(k=0; k<allSelectedRows.length; k++) {
+                                    if(allSelectedRows[k] === thisRow.yuiRecordId) {
+                                        Dom.addClass(thisRow, DT.CLASS_SELECTED);
+                                        if(j === allRows.length-1) {
+                                            this._oAnchorRecord = this.getRecord(thisRow.yuiRecordId);
+                                        }
+                                    }
                                 }
                             }
+                            else {
+                                // Loop over each cell
+                                for(k=0; k<thisRow.cells.length; k++) {
+                                    var thisCell = thisRow.cells[k];
+                                    // Set SELECTED
+                                    for(l=0; l<allSelectedCells.length; l++) {
+                                        if((allSelectedCells[l].recordId === thisRow.yuiRecordId) &&
+                                                (allSelectedCells[l].columnId === thisCell.yuiColumnId)) {
+                                            Dom.addClass(thisCell, DT.CLASS_SELECTED);
+                                            if(k === thisRow.cells.length-1) {
+                                                this._oAnchorCell = {record:this.getRecord(thisRow.yuiRecordId), column:this.getColumnById(thisCell.yuiColumnId)};
+                                            }
+                                        }
+                                    }
+                                }
+                            }
                         }
                     }
                 }
-            }
-        }
+                
+                if(this._bInit) {
+                    this._forceGeckoRedraw();
+
+                    this._oChainRender.add({
+                        method: function() {
+                            if((this instanceof DT) && this._sId && this._bInit) {
+                                this._bInit = false;
+                                this.fireEvent("initEvent");
+                                YAHOO.log("DataTable initialized with " + allRecords.length + " of " + this._oRecordSet.getLength() + " rows", "info", this.toString());
+                            }
+                        },
+                        scope: this
+                    });
+                    this._oChainRender.run();
+                }
+                else {
+                    this.fireEvent("renderEvent");
+                    // Backward compatibility
+                    this.fireEvent("refreshEvent");
+                    YAHOO.log("DataTable rendered " + allRecords.length + " of " + this._oRecordSet.getLength() + " rows", "info", this.toString());
+                }
+            
+            },
+            scope: this,
+            timeout: (loopN > 0) ? 0 : -1
+        }); 
         
-        // Set FIRST/LAST, EVEN/ODD
-        this._setFirstRow();
-        this._setLastRow();
-        this._setRowStripes();
-
-        this.fireEvent("refreshEvent");
-        YAHOO.log("DataTable showing " + aRecords.length + " of " + this._oRecordSet.getLength() + " rows", "info", this.toString());
+        this._oChainRender.add({
+            method: function() {
+                if((this instanceof DT) && this._sId) {
+                    this._syncColWidths();
+                }
+            },
+            scope: this
+        });
+                    
+        this._oChainRender.run();  
     }
     // Empty
     else {
@@ -3761,9 +9470,9 @@
             elTbody.deleteRow(-1);
         }
 
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_EMPTY, YAHOO.widget.DataTable.CLASS_EMPTY);
+        this.showTableMessage(DT.MSG_EMPTY, DT.CLASS_EMPTY);
     }
-};
+},
 
 /**
  * Nulls out the entire DataTable instance and related objects, removes attached
@@ -3773,11 +9482,32 @@
  *
  * @method destroy
  */
-YAHOO.widget.DataTable.prototype.destroy = function() {
+destroy : function() {
+    this._oChainRender.stop();
+    
+    //TODO: destroy static resizer proxy and column proxy?
+    
+    var i;
+    // Destroy ColumnDDs
+    var aTree = this._oColumnSet.tree[0];
+    for(i=0; i<aTree.length; i++) {
+        if(aTree[i]._dd) {
+            aTree[i]._dd = aTree[i]._dd.unreg();
+        }
+    }
+
+    // Destroy ColumnResizers
+    var aKeys = this._oColumnSet.keys;
+    for(i=0; i<aKeys.length; i++) {
+        if(aKeys[i]._ddResizer) {
+            aKeys[i]._ddResizer = aKeys[i]._ddResizer.unreg();
+        }
+    }
+    
     // Destroy Cell Editor
-    YAHOO.util.Event.purgeElement(this._oCellEditor.container, true);
+    Ev.purgeElement(this._oCellEditor.container, true);
     document.body.removeChild(this._oCellEditor.container);
-    
+
     var instanceName = this.toString();
     var elContainer = this._elContainer;
 
@@ -3786,64 +9516,96 @@
     this.unsubscribeAll();
 
     // Unhook DOM events
-    YAHOO.util.Event.purgeElement(elContainer, true);
+    Ev.purgeElement(elContainer, true);
+    Ev.removeListener(document, "click", this._onDocumentClick);
 
     // Remove DOM elements
     elContainer.innerHTML = "";
 
     // Null out objects
     for(var param in this) {
-        if(YAHOO.lang.hasOwnProperty(this, param)) {
+        if(lang.hasOwnProperty(this, param)) {
             this[param] = null;
         }
     }
+    
+    // Clean up static values
+    DT._nCurrentCount--;
+    
+    if(DT._nCurrentCount < 1) {
+        if(DT._elStylesheet) {
+            document.getElementsByTagName('head')[0].removeChild(DT._elStylesheet);
+            DT._elStylesheet = null;
+        }
+    }
 
     YAHOO.log("DataTable instance destroyed: " + instanceName);
-};
+},
 
 /**
  * Displays message within secondary TBODY.
  *
  * @method showTableMessage
- * @param sHTML {String} (optional) Value for innerHTML.
+ * @param sHTML {String} (optional) Value for innerHTMlang.
  * @param sClassName {String} (optional) Classname.
  */
-YAHOO.widget.DataTable.prototype.showTableMessage = function(sHTML, sClassName) {
+showTableMessage : function(sHTML, sClassName) {
     var elCell = this._elMsgTd;
-    if(YAHOO.lang.isString(sHTML)) {
-        elCell.innerHTML = sHTML;
+    if(lang.isString(sHTML)) {
+        elCell.firstChild.innerHTML = sHTML;
     }
-    if(YAHOO.lang.isString(sClassName)) {
-        YAHOO.util.Dom.addClass(elCell, sClassName);
+    if(lang.isString(sClassName)) {
+        Dom.addClass(elCell.firstChild, sClassName);
     }
+
+    this._elMsgTbody.parentNode.style.width = this.getTheadEl().parentNode.offsetWidth+"px";
+
     this._elMsgTbody.style.display = "";
+
     this.fireEvent("tableMsgShowEvent", {html:sHTML, className:sClassName});
     YAHOO.log("DataTable showing message: " + sHTML, "info", this.toString());
-};
+},
 
 /**
  * Hides secondary TBODY.
  *
  * @method hideTableMessage
  */
-YAHOO.widget.DataTable.prototype.hideTableMessage = function() {
+hideTableMessage : function() {
     if(this._elMsgTbody.style.display != "none") {
         this._elMsgTbody.style.display = "none";
+        this._elMsgTbody.parentNode.style.width = "";
         this.fireEvent("tableMsgHideEvent");
         YAHOO.log("DataTable message hidden", "info", this.toString());
     }
-};
+},
 
 /**
- * Brings focus to DataTable instance.
+ * Brings focus to the TBODY element. Alias to focusTbodyEl.
  *
  * @method focus
  */
-YAHOO.widget.DataTable.prototype.focus = function() {
-    this._focusEl(this._elTable);
-};
+focus : function() {
+    this.focusTbodyEl();
+},
 
+/**
+ * Brings focus to the THEAD element.
+ *
+ * @method focusTheadEl
+ */
+focusTheadEl : function() {
+    this._focusEl(this._elThead);
+},
 
+/**
+ * Brings focus to the TBODY element.
+ *
+ * @method focusTbodyEl
+ */
+focusTbodyEl : function() {
+    this._focusEl(this._elTbody);
+},
 
 
 
@@ -3908,6 +9670,7 @@
 
 
 
+
 // RECORDSET FUNCTIONS
 
 /**
@@ -3918,10 +9681,10 @@
  * element reference or page row index.
  * @return {Number} Record's RecordSet index, or null.
  */
-YAHOO.widget.DataTable.prototype.getRecordIndex = function(row) {
+getRecordIndex : function(row) {
     var nTrIndex;
 
-    if(!YAHOO.lang.isNumber(row)) {
+    if(!lang.isNumber(row)) {
         // By Record
         if(row instanceof YAHOO.widget.Record) {
             return this._oRecordSet.getRecordIndex(row);
@@ -3940,18 +9703,22 @@
         nTrIndex = row;
     }
 
-    if(YAHOO.lang.isNumber(nTrIndex)) {
-        if(this.get("paginated")) {
-            return this.get("paginator").startRecordIndex + nTrIndex;
+    if(lang.isNumber(nTrIndex)) {
+        var oPaginator = this.get("paginator");
+        if(oPaginator instanceof Pag) {
+            return oPaginator.get('recordOffset') + nTrIndex;
         }
+        else if (this.get('paginated')) {
+            return oPaginator.startRecordIndex + nTrIndex;
+        }
         else {
             return nTrIndex;
         }
     }
 
-    YAHOO.log("Could not get Record index for row " + row, "warn", this.toString());
+    YAHOO.log("Could not get Record index for row " + row, "info", this.toString());
     return null;
-};
+},
 
 /**
  * For the given identifier, returns the associated Record instance.
@@ -3961,9 +9728,9 @@
  * child of a TR element), RecordSet position index, or Record ID.
  * @return {YAHOO.widget.Record} Record instance.
  */
-YAHOO.widget.DataTable.prototype.getRecord = function(row) {
+getRecord : function(row) {
     var oRecord = this._oRecordSet.getRecord(row);
-    
+
     if(!oRecord) {
         // Validate TR element
         var elRow = this.getTrEl(row);
@@ -3971,15 +9738,15 @@
             oRecord = this._oRecordSet.getRecord(elRow.yuiRecordId);
         }
     }
-    
+
     if(oRecord instanceof YAHOO.widget.Record) {
         return this._oRecordSet.getRecord(oRecord);
     }
     else {
-        YAHOO.log("Could not get Record for row at " + row, "warn", this.toString());
+        YAHOO.log("Could not get Record for row at " + row, "info", this.toString());
         return null;
     }
-};
+},
 
 
 
@@ -4037,9 +9804,9 @@
  * TH/TD element (or child of a TH/TD element), a Column key, or a ColumnSet key index.
  * @return {YAHOO.widget.Column} Column instance.
  */
- YAHOO.widget.DataTable.prototype.getColumn = function(column) {
+getColumn : function(column) {
     var oColumn = this._oColumnSet.getColumn(column);
-    
+
     if(!oColumn) {
         // Validate TD element
         var elCell = this.getTdEl(column);
@@ -4055,10 +9822,10 @@
         }
     }
     if(!oColumn) {
-        YAHOO.log("Could not get Column for column at " + column, "warn", this.toString());
+        YAHOO.log("Could not get Column for column at " + column, "info", this.toString());
     }
     return oColumn;
-};
+},
 
 /**
  * For the given Column ID, returns the associated Column instance. Note: For
@@ -4068,60 +9835,113 @@
  * @param column {String} Column ID string.
  * @return {YAHOO.widget.Column} Column instance.
  */
- YAHOO.widget.DataTable.prototype.getColumnById = function(column) {
+getColumnById : function(column) {
     return this._oColumnSet.getColumnById(column);
-};
+},
 
 /**
+ * For the given Column instance, returns next direction to sort.
+ *
+ * @method getColumnSortDir
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @return {String} DataTable.widget.CLASS_ASC or DataTable.widget.CLASS_DESC.
+ */
+getColumnSortDir : function(oColumn) {
+    // Backward compatibility
+    if(oColumn.sortOptions && oColumn.sortOptions.defaultOrder) {
+        if(oColumn.sortOptions.defaultOrder == "asc") {
+            oColumn.sortOptions.defaultDir = DT.CLASS_ASC;
+        }
+        else if (oColumn.sortOptions.defaultOrder == "desc") {
+            oColumn.sortOptions.defaultDir = DT.CLASS_DESC;
+        }
+    }
+    
+    // What is the Column's default sort direction?
+    var sortDir = (oColumn.sortOptions && oColumn.sortOptions.defaultDir) ? oColumn.sortOptions.defaultDir : DT.CLASS_ASC;
+
+    // Already sorted?
+    var bSorted = false;
+    var oSortedBy = this.get("sortedBy");
+    if(oSortedBy && (oSortedBy.key === oColumn.key)) {
+        bSorted = true;
+        if(oSortedBy.dir) {
+            sortDir = (oSortedBy.dir == DT.CLASS_ASC) ? DT.CLASS_DESC : DT.CLASS_ASC;
+        }
+        else {
+            sortDir = (sortDir == DT.CLASS_ASC) ? DT.CLASS_DESC : DT.CLASS_ASC;
+        }
+    }
+    return sortDir;
+},
+
+/**
  * Sorts given Column.
  *
  * @method sortColumn
  * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @param sDir {String} (Optional) DT.CLASS_ASC or
+ * DT.CLASS_DESC
  */
-YAHOO.widget.DataTable.prototype.sortColumn = function(oColumn) {
+sortColumn : function(oColumn, sDir) {
     if(oColumn && (oColumn instanceof YAHOO.widget.Column)) {
         if(!oColumn.sortable) {
-            YAHOO.util.Dom.addClass(this.getThEl(oColumn), YAHOO.widget.DataTable.CLASS_SORTABLE);
+            Dom.addClass(this.getThEl(oColumn), DT.CLASS_SORTABLE);
         }
-        // What is the default sort direction?
-        var sortDir = (oColumn.sortOptions && oColumn.sortOptions.defaultOrder) ? oColumn.sortOptions.defaultOrder : "asc";
-
-        // Already sorted?
-        var oSortedBy = this.get("sortedBy");
-        if(oSortedBy && (oSortedBy.key === oColumn.key)) {
-            if(oSortedBy.dir) {
-                sortDir = (oSortedBy.dir == "asc") ? "desc" : "asc";
-            }
-            else {
-                sortDir = (sortDir == "asc") ? "desc" : "asc";
-            }
+        
+        // Validate given direction
+        if(sDir && (sDir !== DT.CLASS_ASC) && (sDir !== DT.CLASS_DESC)) {
+            sDir = null;
         }
+        
+        // Get the sort dir
+        var sortDir = sDir || this.getColumnSortDir(oColumn);
 
-        // Is there a custom sort handler function defined?
-        var sortFnc = (oColumn.sortOptions && YAHOO.lang.isFunction(oColumn.sortOptions.sortFunction)) ?
-                oColumn.sortOptions.sortFunction : function(a, b, desc) {
-                    var sorted = YAHOO.util.Sort.compare(a.getData(oColumn.key),b.getData(oColumn.key), desc);
-                    if(sorted === 0) {
-                        return YAHOO.util.Sort.compare(a.getId(),b.getId(), desc);
-                    }
-                    else {
-                        return sorted;
-                    }
-        };
-
         // Do the actual sort
-        var desc = (sortDir == "desc") ? true : false;
-        this._oRecordSet.sortRecords(sortFnc, desc);
+        var oSortedBy = this.get("sortedBy") || {};
+        var bSorted = (oSortedBy.key === oColumn.key) ? true : false;
+        if(!bSorted || sDir) {
+            // Is there a custom sort handler function defined?
+            var sortFnc = (oColumn.sortOptions && lang.isFunction(oColumn.sortOptions.sortFunction)) ?
+                    // Custom sort function
+                    oColumn.sortOptions.sortFunction :
 
+                    // Default sort function
+                    function(a, b, desc) {
+                        var sorted = YAHOO.util.Sort.compare(a.getData(oColumn.key),b.getData(oColumn.key), desc);
+                        if(sorted === 0) {
+                            return YAHOO.util.Sort.compare(a.getId(),b.getId(), desc);
+                        }
+                        else {
+                            return sorted;
+                        }
+                    };
+
+            this._oRecordSet.sortRecords(sortFnc, ((sortDir == DT.CLASS_DESC) ? true : false));
+        }
+        else {
+            this._oRecordSet.reverseRecords();
+        }
+
         // Update sortedBy tracker
         this.set("sortedBy", {key:oColumn.key, dir:sortDir, column:oColumn});
 
         // Reset to first page
         //TODO: Keep selection in view
-        this.updatePaginator({currentPage:1});
+        var oPaginator = this.get('paginator');
+        if (oPaginator instanceof Pag) {
+            // TODO : is this server-side op safe?  Will fire changeRequest
+            // event mechanism
+            oPaginator.setPage(1,true);
+        }
+        else if (this.get('paginated')) {
+            // Backward compatibility
+            this.updatePaginator({currentPage:1});
+        }
 
         // Update the UI
-        this.refreshView();
+        DT.formatTheadCell(oColumn.getThEl().firstChild.firstChild, oColumn, this);
+        this.render();
 
         this.fireEvent("columnSortEvent",{column:oColumn,dir:sortDir});
         YAHOO.log("Column \"" + oColumn.key + "\" sorted \"" + sortDir + "\"", "info", this.toString());
@@ -4129,36 +9949,534 @@
     else {
         YAHOO.log("Could not sort Column \"" + oColumn.key + "\"", "warn", this.toString());
     }
-};
+},
 
+/**
+ * Sets DOM elements of given Column to given pixel width. No validations
+ * against minimum width and no updating Column.width value.
+ *
+ * @method _setColumnWidth
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @param sWidth {String} New width value.
+ * @private
+ */
+_setColumnWidth : function(oColumn, sWidth) {
+    oColumn = this.getColumn(oColumn);
+    if(oColumn) {
+        // Create STYLE node
+        if(!DT._bStylesheetFallback) {
+            var s;
+            if(!DT._elStylesheet) {
+                    s = document.createElement('style');
+                    s.type = 'text/css';
+                    DT._elStylesheet = document.getElementsByTagName('head').item(0).appendChild(s);
+            }
+                
+            if(DT._elStylesheet) {
+                s = DT._elStylesheet;
+                
+                var sClassname = ".yui-dt-col-" + oColumn.getId();
+                
+                // Create rule for the Column
+                var rule = DT._oStylesheetRules[sClassname];
+                if (!rule) {
+                    if (s.styleSheet && s.styleSheet.addRule) {
+                        s.styleSheet.addRule(sClassname,"overflow:hidden");
+                        s.styleSheet.addRule(sClassname,"width:"+sWidth);
+                        rule = s.styleSheet.rules[s.styleSheet.rules.length-1];
+                    } else if (s.sheet && s.sheet.insertRule) {
+                        s.sheet.insertRule(sClassname+" {overflow:hidden;width:"+sWidth+";}",s.sheet.cssRules.length);
+                        rule = s.sheet.cssRules[s.sheet.cssRules.length-1];
+                    } else {
+                        DT._bStylesheetFallback = true;
+                    }
+                    DT._oStylesheetRules[sClassname] = rule;
+                }
+                
+                // Update existing rule for the Column
+                else {
+                    rule.style.width = sWidth;
+                } 
+                return;
+            }
+            
+            DT._bStylesheetFallback = true;
+        }
+        // Do it the old fashioned way
+        if(DT._bStylesheetFallback) {           
+            if(sWidth == "auto") {
+                sWidth = ""; 
+            }
 
+            if (!this._aFallbackColResizer[this._elTbody.rows.length]) {
+                /*
+                Compile a custom function to do all the cell width
+                assignments at the same time.  A new resizer function is created
+                for each new unique number of rows in _elTbody.  This will
+                result in a function declaration like:
+                function (oColumn,sWidth) {
+                    var colIdx = oColumn.getKeyIndex();
+                    oColumn.getThEl().firstChild.style.width =
+                    this._elTbody.rows[0].cells[colIdx].firstChild.style.width =
+                    this._elTbody.rows[0].cells[colIdx].style.width =
+                    this._elTbody.rows[1].cells[colIdx].firstChild.style.width =
+                    this._elTbody.rows[1].cells[colIdx].style.width =
+                    ... (for all row indices in this._elTbody.rows.length - 1)
+                    this._elTbody.rows[99].cells[colIdx].firstChild.style.width =
+                    this._elTbody.rows[99].cells[colIdx].style.width = sWidth;
+                    ending with the sWidth as the initial assignment   ^
+                }
+                */
+                var i,j,k;
+                var resizerDef = [
+                    'var colIdx=oColumn.getKeyIndex();',
+                    'oColumn.getThEl().firstChild.style.width='
+                ];
+                for (i=this._elTbody.rows.length-1, j=2; i >= 0; --i) {
+                    resizerDef[j++] = 'this._elTbody.rows[';
+                    resizerDef[j++] = i;
+                    resizerDef[j++] = '].cells[colIdx].firstChild.style.width=';
+                    resizerDef[j++] = 'this._elTbody.rows[';
+                    resizerDef[j++] = i;
+                    resizerDef[j++] = '].cells[colIdx].style.width=';
+                }
+                resizerDef[j] = 'sWidth;';
+                resizerDef[j+1] = 'oColumn.getThEl().firstChild.style.overflow=';
+                for (i=this._elTbody.rows.length-1, k=j+2; i >= 0; --i) {
+                    resizerDef[k++] = 'this._elTbody.rows[';
+                    resizerDef[k++] = i;
+                    resizerDef[k++] = '].cells[colIdx].firstChild.style.overflow=';
+                    resizerDef[k++] = 'this._elTbody.rows[';
+                    resizerDef[k++] = i;
+                    resizerDef[k++] = '].cells[colIdx].style.overflow=';
+                }
+                resizerDef[k] = '"hidden";';
+                this._aFallbackColResizer[this._elTbody.rows.length] =
+                    new Function('oColumn','sWidth',resizerDef.join(''));
+            }
+            var resizerFn = this._aFallbackColResizer[this._elTbody.rows.length];
 
+            if (resizerFn) {
+                resizerFn.call(this,oColumn,sWidth);
+                //this._syncScrollPadding();
+                return;
+            }
+        }
+    }
+    else {
+        YAHOO.log("Could not set width of Column " + oColumn + " to " + sWidth, "warn", this.toString());
+    }
+},
 
+/**
+ * Sets given Column to given pixel width. If new width is less than minimum
+ * width, sets to minimum width. Updates oColumn.width value.
+ *
+ * @method setColumnWidth
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @param nWidth {Number} New width in pixels.
+ */
+setColumnWidth : function(oColumn, nWidth) {
+    oColumn = this.getColumn(oColumn);
+    if(oColumn) {
+        // Validate new width against minimum width
+        if(lang.isNumber(nWidth)) {
+            nWidth = (nWidth > oColumn.minWidth) ? nWidth : oColumn.minWidth;
 
+            // Save state
+            oColumn.width = nWidth;
+            
+            // Resize the DOM elements
+            //this._oChainSync.stop();
+            this._setColumnWidth(oColumn, nWidth+"px");
+            this._syncScrollPadding();
+            
+            this.fireEvent("columnSetWidthEvent",{column:oColumn,width:nWidth});
+            YAHOO.log("Set width of Column " + oColumn + " to " + nWidth + "px", "info", this.toString());
+            return;
+        }
+    }
+    YAHOO.log("Could not set width of Column " + oColumn + " to " + nWidth + "px", "warn", this.toString());
+},
 
 
+/**
+ * Hides given Column. NOTE: You cannot hide/show nested Columns. You can only
+ * hide/show non-nested Columns, and top-level parent Columns (which will
+ * hide/show all children Columns).
+ *
+ * @method hideColumn
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ */
+hideColumn : function(oColumn) {
+    oColumn = this.getColumn(oColumn);
+    if(oColumn && !oColumn.hidden) {
+        // Only top-level Columns can get hidden
+        if(oColumn.getTreeIndex() !== null) {
+            var allrows = this.getTbodyEl().rows;
+            var l = allrows.length;
+            var allDescendants = this._oColumnSet.getDescendants(oColumn);
+            for(var i=0; i<allDescendants.length; i++) {
+                var thisColumn = allDescendants[i];
+                thisColumn.hidden = true;
 
+                var elTheadCell = thisColumn.getThEl();
+                var elTheadCellLiner = elTheadCell.firstChild;
+                // Store to reinstate later
+                thisColumn._nLastWidth = elTheadCellLiner.offsetWidth - 
+                        (parseInt(Dom.getStyle(elTheadCellLiner,"paddingLeft"),10)|0) -
+                        (parseInt(Dom.getStyle(elTheadCellLiner,"paddingRight"),10)|0);
+                Dom.addClass(elTheadCell,DT.CLASS_HIDDEN);
 
+                // Adjust body cells (if key Column)
+                var thisKeyIndex = thisColumn.getKeyIndex();
+                if(thisKeyIndex !== null) {
+                    for(var j=0;j<l;j++) {
+                        Dom.addClass(allrows[j].cells[thisKeyIndex],DT.CLASS_HIDDEN);
+                    }
 
+                    this._setColumnWidth(thisColumn, "1px");
+                    
+                    // Disable interactive features
+                    if(thisColumn.resizeable) {
+                        Dom.removeClass(thisColumn.getResizerEl(),DT.CLASS_RESIZER);
+                    }
+                    if(thisColumn.sortable) {
+                        Dom.removeClass(thisColumn.getThEl(),DT.CLASS_SORTABLE);
+                        thisColumn.getThEl().firstChild.firstChild.firstChild.style.display = "none";
+                    }
+                }
+                // Just set thead cell width directly for parent Column
+                else {
+                    elTheadCell.firstChild.style.width = "1px";
+                }
+                
+                this.fireEvent("columnHideEvent",{column:thisColumn});
+                YAHOO.log("Column \"" + oColumn.key + "\" hidden", "info", this.toString());
+            }
+        }
+        else {
+            YAHOO.log("Could not hide Column \"" + oColumn.key + "\". Only non-nested Columns can be hidden", "warn", this.toString());
+        }
+    }
+},
 
+/**
+ * Shows given Column. NOTE: You cannot hide/show nested Columns. You can only
+ * hide/show non-nested Columns, and top-level parent Columns (which will
+ * hide/show all children Columns).
+ *
+ * @method showColumn
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ */
+showColumn : function(oColumn) {
+    oColumn = this.getColumn(oColumn);
+    if(oColumn && oColumn.hidden) {
+        // Only top-level Columns can get hidden
+        if(oColumn.getTreeIndex() !== null) {
+            var allrows = this.getTbodyEl().rows;
+            var l = allrows.length;
+            var allDescendants = this._oColumnSet.getDescendants(oColumn);
+            for(var i=0; i<allDescendants.length; i++) {
+                var thisColumn = allDescendants[i];
+                thisColumn.hidden = false;
+                
+                var elTheadCell = thisColumn.getThEl();
+                Dom.removeClass(elTheadCell,DT.CLASS_HIDDEN);
 
+                // Adjust body cells (if key Column)
+                var thisKeyIndex = thisColumn.getKeyIndex();
+                if(thisKeyIndex !== null) {
+                    for(var j=0;j<l;j++) {
+                        Dom.removeClass(allrows[j].cells[thisKeyIndex],DT.CLASS_HIDDEN);
+                    }
+                    
+                    this.setColumnWidth(thisColumn, (thisColumn._nLastWidth || thisColumn.minWidth), true);
 
+                    // Enable interactive features
+                    if(thisColumn.sortable) {
+                        thisColumn.getThEl().firstChild.firstChild.firstChild.style.display = "";
+                        Dom.removeClass(thisColumn.getThEl(),DT.CLASS_SORTABLE);
+                    }
+                    if(thisColumn.resizeable) {
+                        thisColumn._ddResizer.resetResizerEl();
+                        Dom.addClass(thisColumn.getResizerEl(),DT.CLASS_RESIZER);
+                    }
+                }
+                else {
+                    elTheadCell.firstChild.style.width = "";
+                }
 
+                thisColumn._nLastWidth = null;
+                this.fireEvent("columnShowEvent",{column:thisColumn});
+                YAHOO.log("Column \"" + oColumn.key + "\" shown", "info", this.toString());
+            }
+        }
+        else {
+            YAHOO.log("Could not show Column \"" + oColumn.key + "\". Only non-nested Columns can be shown", "warn", this.toString());
+        }
+    }
+},
 
+/**
+ * Removes given Column. NOTE: You cannot remove nested Columns. You can only remove
+ * non-nested Columns, and top-level parent Columns (which will remove all
+ * children Columns).
+ *
+ * @method removeColumn
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @return oColumn {YAHOO.widget.Column} Removed Column instance.
+ */
+removeColumn : function(oColumn) {
+    var nColTreeIndex = oColumn.getTreeIndex();
+    if(nColTreeIndex !== null) {
+        this._oChainRender.stop();
+        var aOrigColumnDefs = this._oColumnSet.getDefinitions();
 
+        oColumn = aOrigColumnDefs.splice(nColTreeIndex,1)[0];
+        this._initColumnSet(aOrigColumnDefs);
+        this._initTheadEls();
 
+        this.render();
+        this.fireEvent("columnRemoveEvent",{column:oColumn});
+        YAHOO.log("Column \"" + oColumn.key + "\" removed", "info", this.toString());
+        return oColumn;
+    }
+    YAHOO.log("Could not remove Column \"" + oColumn.key + "\". Only non-nested Columns can be removed", "warn", this.toString());
+},
 
+/**
+ * Inserts given Column at the index if given, otherwise at the end. NOTE: You
+ * can only add non-nested Columns and top-level parent Columns. You cannot add
+ * a nested Column to an existing parent.
+ *
+ * @method insertColumn
+ * @param oColumn {Object | YAHOO.widget.Column} Object literal Column
+ * definition or a Column instance.
+ * @param index {Number} (optional) Column key index.
+ */
+insertColumn : function(oColumn, index) {
+    // Validate Column
+    if(oColumn instanceof YAHOO.widget.Column) {
+        oColumn = oColumn.getDefinition();
+    }
+    else if(oColumn.constructor !== Object) {
+        YAHOO.log("Could not insert Column \"" + oColumn + "\" due to invalid argument", "warn", this.toString());
+        return;
+    }
+    
+    var oColumnSet = this._oColumnSet;
 
+    // Validate index
+    if(!lang.isValue(index) || !lang.isNumber(index)) {
+        index = oColumnSet.tree[0].length;
+    }
+    
+    this._oChainRender.stop();
+    var aNewColumnDefs = this._oColumnSet.getDefinitions();
+    aNewColumnDefs.splice(index, 0, oColumn);
+    this._initColumnSet(aNewColumnDefs);
+    this._initTheadEls();
+    this.render();
+    this.fireEvent("columnInsertEvent",{column:oColumn,index:index});
+    YAHOO.log("Column \"" + oColumn.key + "\" inserted into index " + index, "info", this.toString());
+},
 
+/**
+ * Selects given Column. NOTE: You cannot select/unselect nested Columns. You can only
+ * select/unselect non-nested Columns, and bottom-level key Columns.
+ *
+ * @method selectColumn
+ * @param column {HTMLElement | String | Number} DOM reference or ID string to a
+ * TH/TD element (or child of a TH/TD element), a Column key, or a ColumnSet key index.
+ */
+selectColumn : function(oColumn) {
+    oColumn = this.getColumn(oColumn);
+    if(oColumn && !oColumn.selected) {
+        // Only bottom-level Columns can get hidden
+        if(oColumn.getKeyIndex() !== null) {
+            oColumn.selected = true;
+            
+            // Update head cell
+            var elTh = oColumn.getThEl();
+            Dom.addClass(elTh,DT.CLASS_SELECTED);
 
+            // Update body cells
+            var allRows = this.getTbodyEl().rows;
+            var oChainRender = this._oChainRender;
+            oChainRender.add({
+                method: function(oArg) {
+                    if((this instanceof DT) && this._sId && allRows[oArg.rowIndex] && allRows[oArg.rowIndex].cells[oArg.cellIndex]) {
+                        Dom.addClass(allRows[oArg.rowIndex].cells[oArg.cellIndex],DT.CLASS_SELECTED);                    
+                    }
+                    oArg.rowIndex++;
+                },
+                scope: this,
+                iterations: allRows.length,
+                argument: {rowIndex:0,cellIndex:oColumn.getKeyIndex()}
+            });
+            oChainRender.run();       
+            
+            this.fireEvent("columnSelectEvent",{column:oColumn});
+            YAHOO.log("Column \"" + oColumn.key + "\" selected", "info", this.toString());
+        }
+        else {
+            YAHOO.log("Could not select Column \"" + oColumn.key + "\". Only non-nested Columns can be selected", "warn", this.toString());
+        }
+    }
+},
 
+/**
+ * Unselects given Column. NOTE: You cannot select/unselect nested Columns. You can only
+ * select/unselect non-nested Columns, and bottom-level key Columns.
+ *
+ * @method unSelectColumn
+ * @param column {HTMLElement | String | Number} DOM reference or ID string to a
+ * TH/TD element (or child of a TH/TD element), a Column key, or a ColumnSet key index.
+ */
+unselectColumn : function(oColumn) {
+    oColumn = this.getColumn(oColumn);
+    if(oColumn && oColumn.selected) {
+        // Only bottom-level Columns can get hidden
+        if(oColumn.getKeyIndex() !== null) {
+            oColumn.selected = false;
+            
+            // Update head cell
+            var elTh = oColumn.getThEl();
+            Dom.removeClass(elTh,DT.CLASS_SELECTED);
 
+            // Update body cells
+            var allRows = this.getTbodyEl().rows;
+            var oChainRender = this._oChainRender;
+            oChainRender.add({
+                method: function(oArg) {
+                    if((this instanceof DT) && this._sId && allRows[oArg.rowIndex] && allRows[oArg.rowIndex].cells[oArg.cellIndex]) {
+                        Dom.removeClass(allRows[oArg.rowIndex].cells[oArg.cellIndex],DT.CLASS_SELECTED); 
+                    }                   
+                    oArg.rowIndex++;
+                },
+                scope: this,
+                iterations:allRows.length,
+                argument: {rowIndex:0,cellIndex:oColumn.getKeyIndex()}
+            });
+            oChainRender.run();       
+            
+            this.fireEvent("columnUnselectEvent",{column:oColumn});
+            YAHOO.log("Column \"" + oColumn.key + "\" unselected", "info", this.toString());
+        }
+        else {
+            YAHOO.log("Could not unselect Column \"" + oColumn.key + "\". Only non-nested Columns can be unselected", "warn", this.toString());
+        }
+    }
+},
 
+/**
+ * Returns an array selected Column instances.
+ *
+ * @method getSelectedColumns
+ * @return {YAHOO.widget.Column[]} Array of Column instances.
+ */
+getSelectedColumns : function(oColumn) {
+    var selectedColumns = [];
+    var aKeys = this._oColumnSet.keys;
+    for(var i=0,len=aKeys.length; i<len; i++) {
+        if(aKeys[i].selected) {
+            selectedColumns[selectedColumns.length] = aKeys[i];
+        }
+    }
+    return selectedColumns;
+},
 
+/**
+ * Assigns the class DT.CLASS_HIGHLIGHTED to cells of the given Column.
+ * NOTE: You cannot highlight/unhighlight nested Columns. You can only
+ * highlight/unhighlight non-nested Columns, and bottom-level key Columns.
+ *
+ * @method highlightColumn
+ * @param column {HTMLElement | String | Number} DOM reference or ID string to a
+ * TH/TD element (or child of a TH/TD element), a Column key, or a ColumnSet key index.
+ */
+highlightColumn : function(column) {
+    var oColumn = this.getColumn(column);
+    // Only bottom-level Columns can get highlighted
+    if(oColumn && (oColumn.getKeyIndex() !== null)) {
+        /*// Make sure previous row is unhighlighted
+        var sId = oColumn.getId();
+        var sLastId = this._sLastHighlightedColumnId;
+        if(sLastId && (sLastId !== sId)) {
+            this.unhighlightColumn(this.getColumn(sLastId));
+        }*/
 
+        //this._sLastHighlightedColumnId = sId;
+            
+        // Update head cell
+        var elTh = oColumn.getThEl();
+        Dom.addClass(elTh,DT.CLASS_HIGHLIGHTED);
 
+        // Update body cells
+        var allRows = this.getTbodyEl().rows;
+        var oChainRender = this._oChainRender;
+        oChainRender.add({
+            method: function(oArg) {
+                if((this instanceof DT) && this._sId && allRows[oArg.rowIndex] && allRows[oArg.rowIndex].cells[oArg.cellIndex]) {
+                    Dom.addClass(allRows[oArg.rowIndex].cells[oArg.cellIndex],DT.CLASS_HIGHLIGHTED);   
+                }                 
+                oArg.rowIndex++;
+            },
+            scope: this,
+            iterations:allRows.length,
+            argument: {rowIndex:0,cellIndex:oColumn.getKeyIndex()}
+        });
+        oChainRender.run();       
+            
+        this.fireEvent("columnHighlightEvent",{column:oColumn});
+        YAHOO.log("Column \"" + oColumn.key + "\" highlighed", "info", this.toString());
+    }
+    else {
+        YAHOO.log("Could not highlight Column \"" + oColumn.key + "\". Only non-nested Columns can be highlighted", "warn", this.toString());
+    }
+},
 
+/**
+ * Removes the class DT.CLASS_HIGHLIGHTED to cells of the given Column.
+ * NOTE: You cannot highlight/unhighlight nested Columns. You can only
+ * highlight/unhighlight non-nested Columns, and bottom-level key Columns.
+ *
+ * @method unhighlightColumn
+ * @param column {HTMLElement | String | Number} DOM reference or ID string to a
+ * TH/TD element (or child of a TH/TD element), a Column key, or a ColumnSet key index.
+ */
+unhighlightColumn : function(column) {
+    var oColumn = this.getColumn(column);
+    // Only bottom-level Columns can get highlighted
+    if(oColumn && (oColumn.getKeyIndex() !== null)) {
+        // Update head cell
+        var elTh = oColumn.getThEl();
+        Dom.removeClass(elTh,DT.CLASS_HIGHLIGHTED);
 
+        // Update body cells
+        var allRows = this.getTbodyEl().rows;
+        var oChainRender = this._oChainRender;
+        oChainRender.add({
+            method: function(oArg) {
+                if((this instanceof DT) && this._sId && allRows[oArg.rowIndex] && allRows[oArg.rowIndex].cells[oArg.cellIndex]) {
+                    Dom.removeClass(allRows[oArg.rowIndex].cells[oArg.cellIndex],DT.CLASS_HIGHLIGHTED);
+                }                 
+                oArg.rowIndex++;
+            },
+            scope: this,
+            iterations:allRows.length,
+            argument: {rowIndex:0,cellIndex:oColumn.getKeyIndex()}
+        });
+        oChainRender.run();       
+            
+        this.fireEvent("columnUnhighlightEvent",{column:oColumn});
+        YAHOO.log("Column \"" + oColumn.key + "\" unhighlighted", "info", this.toString());
+    }
+    else {
+        YAHOO.log("Could not unhighlight Column \"" + oColumn.key + "\". Only non-nested Columns can be unhighlighted", "warn", this.toString());
+    }
+},
 
 
 
@@ -4175,8 +10493,63 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 // ROW FUNCTIONS
 
+/**
+ * Adds one TR element at the given index and populates with given Record data.
+ *
+ * @method _addTrEl
+ * @param oRecord {YAHOO.widget.Record} Record instance. 
+ * @param index {Number} TR index.
+ * @return {HTMLElement} Reference to new TR element. 
+ * @private 
+ */
+_addTrEl : function(oRecord, index) {
+    var elNewTr = this._createTrEl(oRecord);
+    if(elNewTr) {
+        if (index >= 0 && index < this._elTbody.rows.length) {
+            this._elTbody.insertBefore(elNewTr,
+                this._elTbody.rows[index]);
+            if (!index) {
+                this._setFirstRow();
+            }
+        } else {
+            this._elTbody.appendChild(elNewTr);
+            this._setLastRow();
+            index = this._elTbody.rows.length - 1;
+        }
+        this._setRowStripes(index);
+    }
+    return elNewTr;
+},
 
 /**
  * Adds one new Record of data into the RecordSet at the index if given,
@@ -4187,70 +10560,71 @@
  * @param oData {Object} Object literal of data for the row.
  * @param index {Number} (optional) RecordSet position index at which to add data.
  */
-YAHOO.widget.DataTable.prototype.addRow = function(oData, index) {
+addRow : function(oData, index) {
     if(oData && (oData.constructor == Object)) {
         var oRecord = this._oRecordSet.addRecord(oData, index);
         if(oRecord) {
-            var nTrIndex = this.getTrIndex(oRecord);
+            var recIndex;
+            var oPaginator = this.get('paginator');
 
-            // Row is on current page
-            if(YAHOO.lang.isNumber(nTrIndex)) {
-                // Paginated so just refresh the view to keep pagination state
-                if(this.get("paginated")) {
-                    this.refreshView();
+            // Paginated
+            if (oPaginator instanceof Pag || this.get('paginated')) {
+                recIndex = this.getRecordIndex(oRecord);
+                var endRecIndex;
+                if (oPaginator instanceof Pag) {
+                    // Update the paginator's totalRecords
+                    var totalRecords = oPaginator.get('totalRecords');
+                    if (totalRecords !== Pag.VALUE_UNLIMITED) {
+                        oPaginator.set('totalRecords',totalRecords + 1);
+                    }
+
+                    endRecIndex = (oPaginator.getPageRecords())[1];
                 }
-                // Add the TR element
+                // Backward compatibility
                 else {
-                    var newTrId = this._addTrEl(oRecord, nTrIndex);
-                    if(newTrId) {
-                        // Is this an insert or an append?
-                        var append = (YAHOO.lang.isNumber(nTrIndex) &&
-                                (nTrIndex == this._elTbody.rows.length-1)) ? true : false;
+                    endRecIndex = oPaginator.startRecordIndex +
+                                  oPaginator.rowsPerPage - 1;
+                    this.updatePaginator();
+                }
 
-                        // Stripe the one new row
-                        if(append) {
-                            if((this._elTbody.rows.length-1)%2) {
-                                YAHOO.util.Dom.addClass(newTrId, YAHOO.widget.DataTable.CLASS_ODD);
-                            }
-                            else {
-                                YAHOO.util.Dom.addClass(newTrId, YAHOO.widget.DataTable.CLASS_EVEN);
-                            }
-                        }
-                        // Restripe all the rows after the new one
-                        else {
-                            this._setRowStripes(nTrIndex);
-                        }
-
-                        // If new row is at the bottom
-                        if(append) {
-                            this._setLastRow();
-                        }
-                        // If new row is at the top
-                        else if(YAHOO.lang.isNumber(index) && (nTrIndex === 0)) {
-                            this._setFirstRow();
-                        }
-                    }
+                // New record affects the view
+                if (recIndex <= endRecIndex) {
+                    // Defer UI updates to the render method
+                    this.render();
                 }
+                
+                this.fireEvent("rowAddEvent", {record:oRecord});
+                YAHOO.log("Added a row for Record " + YAHOO.lang.dump(oRecord) + " at RecordSet index " + recIndex, "info", this.toString()); 
+                return;
             }
-            // Record is not on current page so just update pagination UI
+            // Not paginated
             else {
-                this.updatePaginator();
-            }
-
-            // TODO: what args to pass?
-            this.fireEvent("rowAddEvent", {record:oRecord});
-
-            // For log message
-            nTrIndex = (YAHOO.lang.isValue(nTrIndex))? nTrIndex : "n/a";
-
-            YAHOO.log("Added row: Record ID = " + oRecord.getId() +
-                    ", Record index = " + this.getRecordIndex(oRecord) +
-                    ", page row index = " + nTrIndex, "info", this.toString());
-            return;
+                recIndex = this.getTrIndex(oRecord);
+                if(lang.isNumber(recIndex)) {
+                    // Add the TR element
+                    this._oChainRender.add({
+                        method: function(oArg) {
+                            if((this instanceof DT) && this._sId) {
+                                var elNewTr = this._addTrEl(oRecord, recIndex);
+                                if(elNewTr) {
+                                    this.hideTableMessage();
+            
+                                    this.fireEvent("rowAddEvent", {record:oRecord});
+                                    YAHOO.log("Added a row for Record " + YAHOO.lang.dump(oRecord) + " at RecordSet index " + recIndex, "info", this.toString());
+                                }
+                            }
+                        },
+                        scope: this,
+                        timeout: (this.get("renderLoopSize") > 0) ? 0 : -1
+                    });
+                    this._oChainRender.run();
+                    return;
+                }
+            }            
         }
     }
-    YAHOO.log("Could not add row with " + YAHOO.lang.dump(oData), "error", this.toString());
-};
+    YAHOO.log("Could not add row with " + lang.dump(oData), "error", this.toString());
+},
 
 /**
  * Convenience method to add multiple rows.
@@ -4259,24 +10633,86 @@
  * @param aData {Object[]} Array of object literal data for the rows.
  * @param index {Number} (optional) RecordSet position index at which to add data.
  */
-YAHOO.widget.DataTable.prototype.addRows = function(aData, index) {
-    if(YAHOO.lang.isArray(aData)) {
-        var i;
-        if(YAHOO.lang.isNumber(index)) {
-            for(i=aData.length-1; i>-1; i--) {
-                this.addRow(aData[i], index);
+addRows : function(aData, index) {
+    if(lang.isArray(aData)) {
+        var aRecords = this._oRecordSet.addRecords(aData, index);
+        if(aRecords) {
+            var recIndex = this.getRecordIndex(aRecords[0]);
+            
+            // Paginated
+            var oPaginator = this.get('paginator');
+            if (oPaginator instanceof Pag ||
+                this.get('paginated')) {
+                var endRecIndex;
+                if (oPaginator instanceof Pag) {
+                    // Update the paginator's totalRecords
+                    var totalRecords = oPaginator.get('totalRecords');
+                    if (totalRecords !== Pag.VALUE_UNLIMITED) {
+                        oPaginator.set('totalRecords',totalRecords + aRecords.length);
+                    }
+
+                    endRecIndex = (oPaginator.getPageRecords())[1];
+                }
+                // Backward compatibility
+                else {
+                    endRecIndex = oPaginator.startRecordIndex +
+                                  oPaginator.rowsPerPage - 1;
+                    this.updatePaginator();
+                }
+
+                // At least one of the new records affects the view
+                if (recIndex <= endRecIndex) {
+                    this.render();
+                }
+                
+                this.fireEvent("rowsAddEvent", {records:aRecords});
+                YAHOO.log("Added " + aRecords.length + 
+                        " rows at index " + recIndex +
+                        " with data " + lang.dump(aData), "info", this.toString());
+                return;
             }
+            // Not paginated
+            else {
+                // Add the TR elements
+                var loopN = this.get("renderLoopSize");
+                var loopEnd = recIndex + aData.length;
+                var nRowsNeeded = (loopEnd - recIndex); // how many needed
+                this._oChainRender.add({
+                    method: function(oArg) {
+                        if((this instanceof DT) && this._sId) {
+                            var i = oArg.nCurrentRow,
+                                j = oArg.nCurrentRecord,
+                                len = loopN > 0 ? Math.min(i + loopN,loopEnd) : loopEnd;
+                            for(; i < len; ++i,++j) {
+                                this._addTrEl(aRecords[j], i);
+                            }
+                            oArg.nCurrentRow = i;
+                            oArg.nCurrentRecord = j;
+                        }
+                    },
+                    iterations: (loopN > 0) ? Math.ceil(loopEnd/loopN) : 1,
+                    argument: {nCurrentRow:recIndex,nCurrentRecord:0},
+                    scope: this,
+                    timeout: (loopN > 0) ? 0 : -1
+                });
+                this._oChainRender.add({
+                    method: function() {
+                        this.fireEvent("rowsAddEvent", {records:aRecords});
+                        YAHOO.log("Added " + aRecords.length + 
+                                " rows at index " + recIndex +
+                                " with data " + lang.dump(aData), "info", this.toString());
+                    },
+                    scope: this,
+                    timeout: -1 // Needs to run immediately after the DOM insertions above
+                });
+                this._oChainRender.run();
+                this.hideTableMessage();                
+                return;
+            }            
         }
-        else {
-            for(i=0; i<aData.length; i++) {
-                this.addRow(aData[i]);
-            }
-        }
     }
-    else {
-        YAHOO.log("Could not add rows " + YAHOO.lang.dump(aData));
-    }
-};
+    YAHOO.log("Could not add rows with " + lang.dump(aData));    
+},
 
 /**
  * For the given row, updates the associated Record with the given data. If the
@@ -4289,14 +10725,14 @@
  * of the TR element.
  * @param oData {Object} Object literal of data for the row.
  */
-YAHOO.widget.DataTable.prototype.updateRow = function(row, oData) {
+updateRow : function(row, oData) {
     var oldRecord, oldData, updatedRecord, elRow;
 
     // Get the Record directly
-    if((row instanceof YAHOO.widget.Record) || (YAHOO.lang.isNumber(row))) {
+    if((row instanceof YAHOO.widget.Record) || (lang.isNumber(row))) {
             // Get the Record directly
             oldRecord = this._oRecordSet.getRecord(row);
-            
+
             // Is this row on current page?
             elRow = this.getTrEl(oldRecord);
     }
@@ -4312,31 +10748,43 @@
     if(oldRecord) {
         // Copy data from the Record for the event that gets fired later
         var oRecordData = oldRecord.getData();
-        oldData = {};
-        for(var param in oRecordData) {
-            oldData[param] = oRecordData[param];
-        }
+        oldData = YAHOO.widget.DataTable._cloneObject(oRecordData);
 
         updatedRecord = this._oRecordSet.updateRecord(oldRecord, oData);
     }
     else {
         YAHOO.log("Could not update row " + row + " with the data : " +
-                YAHOO.lang.dump(oData), "error", this.toString());
+                lang.dump(oData), "error", this.toString());
         return;
 
     }
-    
+
     // Update the TR only if row is on current page
     if(elRow) {
-        this._updateTrEl(elRow, updatedRecord);
+        this._oChainRender.add({
+            method: function() {
+                if((this instanceof DT) && this._sId) {
+                    this._updateTrEl(elRow, updatedRecord);
+                    //this._oChainSync.run();
+                    this.fireEvent("rowUpdateEvent", {record:updatedRecord, oldData:oldData});
+                    YAHOO.log("DataTable row updated: Record ID = " + updatedRecord.getId() +
+                            ", Record index = " + this.getRecordIndex(updatedRecord) +
+                            ", page row index = " + this.getTrIndex(updatedRecord), "info", this.toString());
+                }
+            },
+            scope: this,
+            timeout: (this.get("renderLoopSize") > 0) ? 0 : -1
+        });
+        this._oChainRender.run();
     }
+    else {
+        this.fireEvent("rowUpdateEvent", {record:updatedRecord, oldData:oldData});
+        YAHOO.log("DataTable row updated: Record ID = " + updatedRecord.getId() +
+                ", Record index = " + this.getRecordIndex(updatedRecord) +
+                ", page row index = " + this.getTrIndex(updatedRecord), "info", this.toString());   
+    }
+},
 
-    this.fireEvent("rowUpdateEvent", {record:updatedRecord, oldData:oldData});
-    YAHOO.log("DataTable row updated: Record ID = " + updatedRecord.getId() +
-            ", Record index = " + this.getRecordIndex(updatedRecord) +
-            ", page row index = " + this.getTrIndex(updatedRecord), "info", this.toString());
-};
-
 /**
  * Deletes the given row's Record from the RecordSet. If the row is on current page,
  * the corresponding DOM elements are also deleted.
@@ -4345,83 +10793,103 @@
  * @param row {HTMLElement | String | Number} DOM element reference or ID string
  * to DataTable page element or RecordSet index.
  */
-YAHOO.widget.DataTable.prototype.deleteRow = function(row) {
-    // Get the Record index...
-    var oRecord = null;
-    // ...by Record index
-    if(YAHOO.lang.isNumber(row)) {
-        oRecord = this._oRecordSet.getRecord(row);
-    }
-    // ...by element reference
-    else {
-        var elRow = YAHOO.util.Dom.get(row);
-        elRow = this.getTrEl(elRow);
-        if(elRow) {
-            oRecord = this.getRecord(elRow);
-        }
-    }
-    if(oRecord) {
-        var sRecordId = oRecord.getId();
+deleteRow : function(row) {
+    var nRecordIndex = this.getRecordIndex(row);
+    if(lang.isNumber(nRecordIndex)) {
+        var oRecord = this.getRecord(nRecordIndex);
+        if(oRecord) {
+            var nTrIndex = this.getTrIndex(nRecordIndex);
+            
+            // Remove from selection tracker if there
+            var sRecordId = oRecord.getId();
+            var tracker = this._aSelections || [];
+            for(var j=tracker.length-1; j>-1; j--) {
+                if((lang.isNumber(tracker[j]) && (tracker[j] === sRecordId)) ||
+                        ((tracker[j].constructor == Object) && (tracker[j].recordId === sRecordId))) {
+                    tracker.splice(j,1);
+                }
+            }
+    
+            // Delete Record from RecordSet
+            var oData = this._oRecordSet.deleteRecord(nRecordIndex);
+    
+            // Update the UI
+            if(oData) {
+                // If paginated and the deleted row was on this or a prior page, just
+                // re-render
+                var oPaginator = this.get('paginator');
+                if (oPaginator instanceof Pag ||
+                    this.get('paginated')) {
         
-        // Remove from selection tracker if there
-        var tracker = this._aSelections || [];
-        for(var j=tracker.length-1; j>-1; j--) {
-            if((YAHOO.lang.isNumber(tracker[j]) && (tracker[j] === sRecordId)) ||
-                    ((tracker[j].constructor == Object) && (tracker[j].recordId === sRecordId))) {
-                tracker.splice(j,1);
-            }
-        }
-
-        // Copy data from the Record for the event that gets fired later
-        var nRecordIndex = this.getRecordIndex(oRecord);
-        var oRecordData = oRecord.getData();
-        var oData = {};
-        for(var param in oRecordData) {
-            oData[param] = oRecordData[param];
-        }
-
-        // Grab the TR index before deleting the Record
-        var nTrIndex = this.getTrIndex(oRecord);
-
-        // Delete Record from RecordSet
-        this._oRecordSet.deleteRecord(nRecordIndex);
-
-        // If row is on current page, delete the TR element
-        if(YAHOO.lang.isNumber(nTrIndex)) {
-            var isLast = (nTrIndex == this.getLastTrEl().sectionRowIndex) ?
-                    true : false;
-            this._deleteTrEl(nTrIndex);
-
-            // Empty body
-            if(this._elTbody.rows.length === 0) {
-                this.showTableMessage(YAHOO.widget.DataTable.MSG_EMPTY, YAHOO.widget.DataTable.CLASS_EMPTY);
-            }
-            // Update UI
-            else {
-                // Set FIRST/LAST
-                if(nTrIndex === 0) {
-                    this._setFirstRow();
+                    var endRecIndex;
+                    if (oPaginator instanceof Pag) {
+                        // Update the paginator's totalRecords
+                        var totalRecords = oPaginator.get('totalRecords');
+                        if (totalRecords !== Pag.VALUE_UNLIMITED) {
+                            oPaginator.set('totalRecords',totalRecords - 1);
+                        }
+        
+                        endRecIndex = (oPaginator.getPageRecords())[1];
+                    } else {
+                        // Backward compatibility
+                        endRecIndex = oPaginator.startRecordIndex +
+                                      oPaginator.rowsPerPage - 1;
+        
+                        this.updatePaginator();
+                    }
+        
+                    // If the deleted record was on this or a prior page, re-render
+                    if (nRecordIndex <= endRecIndex) {
+                        this.render();
+                    }
+                    return;
                 }
-                if(isLast) {
-                    this._setLastRow();
+                else {
+                    if(lang.isNumber(nTrIndex)) {
+                        this._oChainRender.add({
+                            method: function() {
+                                if((this instanceof DT) && this._sId) {
+                                    var isLast = (nTrIndex == this.getLastTrEl().sectionRowIndex);
+                                    this._deleteTrEl(nTrIndex);
+                    
+                                    // Empty body
+                                    if(this._elTbody.rows.length === 0) {
+                                        this.showTableMessage(DT.MSG_EMPTY, DT.CLASS_EMPTY);
+                                    }
+                                    // Update UI
+                                    else {
+                                        // Set FIRST/LAST
+                                        if(nTrIndex === 0) {
+                                            this._setFirstRow();
+                                        }
+                                        if(isLast) {
+                                            this._setLastRow();
+                                        }
+                                        // Set EVEN/ODD
+                                        if(nTrIndex != this._elTbody.rows.length) {
+                                            this._setRowStripes(nTrIndex);
+                                        }                                
+                                    }
+                    
+                                    this.fireEvent("rowDeleteEvent", {recordIndex:nRecordIndex,
+                                    oldData:oData, trElIndex:nTrIndex});
+                                    YAHOO.log("Deleted row with data " + YAHOO.lang.dump(oData) +
+                                    " at RecordSet index " + nRecordIndex + " and page row index " + nTrIndex, "info", this.toString());     
+                                }
+                            },
+                            scope: this,
+                            timeout: (this.get("renderLoopSize") > 0) ? 0 : -1
+                        });
+                        this._oChainRender.run();
+                        return;
+                    }
                 }
-                // Set EVEN/ODD
-                if(nTrIndex != this._elTbody.rows.length) {
-                    this._setRowStripes(nTrIndex);
-                }
             }
         }
-
-        this.fireEvent("rowDeleteEvent", {recordIndex:nRecordIndex,
-                oldData:oData, trElIndex:nTrIndex});
-        YAHOO.log("DataTable row deleted: Record ID = " + sRecordId +
-                ", Record index = " + nRecordIndex +
-                ", page row index = " + nTrIndex, "info", this.toString());
     }
-    else {
-        YAHOO.log("Could not delete row: " + row, "warn", this.toString());
-    }
-};
+    YAHOO.log("Could not delete row: " + row, "warn", this.toString());
+    return null;
+},
 
 /**
  * Convenience method to delete multiple rows.
@@ -4432,38 +10900,123 @@
  * @param count {Number} (optional) How many rows to delete. A negative value
  * will delete towards the beginning.
  */
-YAHOO.widget.DataTable.prototype.deleteRows = function(row, count) {
-    // Get the Record index...
-    var nRecordIndex = null;
-    // ...by Record index
-    if(YAHOO.lang.isNumber(row)) {
-        nRecordIndex = row;
-    }
-    // ...by element reference
-    else {
-        var elRow = YAHOO.util.Dom.get(row);
-        elRow = this.getTrEl(elRow);
-        if(elRow) {
-            nRecordIndex = this.getRecordIndex(elRow);
-        }
-    }
-    if(nRecordIndex !== null) {
-        if(count && YAHOO.lang.isNumber(count)) {
-            // Start with highest index and work down
-            var startIndex = (count > 0) ? nRecordIndex + count -1 : nRecordIndex;
-            var endIndex = (count > 0) ? nRecordIndex : nRecordIndex + count + 1;
-            for(var i=startIndex; i>endIndex-1; i--) {
-                this.deleteRow(i);
+deleteRows : function(row, count) {
+    var nRecordIndex = this.getRecordIndex(row);
+    if(lang.isNumber(nRecordIndex)) {
+        var oRecord = this.getRecord(nRecordIndex);
+        if(oRecord) {
+            var nTrIndex = this.getTrIndex(nRecordIndex);
+            
+            // Remove from selection tracker if there
+            var sRecordId = oRecord.getId();
+            var tracker = this._aSelections || [];
+            for(var j=tracker.length-1; j>-1; j--) {
+                if((lang.isNumber(tracker[j]) && (tracker[j] === sRecordId)) ||
+                        ((tracker[j].constructor == Object) && (tracker[j].recordId === sRecordId))) {
+                    tracker.splice(j,1);
+                }
             }
+    
+            // Delete Record from RecordSet
+            var highIndex = nRecordIndex+1;
+            var lowIndex = nRecordIndex;
+        
+            // Validate count and account for negative value
+            if(count && lang.isNumber(count)) {
+                highIndex = (count > 0) ? nRecordIndex + count -1 : nRecordIndex;
+                lowIndex = (count > 0) ? nRecordIndex : nRecordIndex + count + 1;
+                count = (count > 0) ? count : count*-1;
+            }
+            else {
+                count = 1;
+            }
+            
+            var aData = this._oRecordSet.deleteRecords(lowIndex, count);
+    
+            // Update the UI
+            if(aData) {
+                // If paginated and the deleted row was on this or a prior page, just
+                // re-render
+                var oPaginator = this.get('paginator');
+                if (oPaginator instanceof Pag ||
+                    this.get('paginated')) {
+        
+                    var endRecIndex;
+                    if (oPaginator instanceof Pag) {
+                        // Update the paginator's totalRecords
+                        var totalRecords = oPaginator.get('totalRecords');
+                        if (totalRecords !== Pag.VALUE_UNLIMITED) {
+                            oPaginator.set('totalRecords',totalRecords - 1);
+                        }
+        
+                        endRecIndex = (oPaginator.getPageRecords())[1];
+                    } else {
+                        // Backward compatibility
+                        endRecIndex = oPaginator.startRecordIndex +
+                                      oPaginator.rowsPerPage - 1;
+        
+                        this.updatePaginator();
+                    }
+        
+                    // If the lowest deleted record was on this or a prior page, re-render
+                    if (lowIndex <= endRecIndex) {
+                        this.render();
+                    }
+                    return;
+                }
+                else {
+                    if(lang.isNumber(nTrIndex)) {
+                        // Delete the TR elements starting with highest index
+                        var loopN = this.get("renderLoopSize");
+                        var loopEnd = lowIndex;
+                        var nRowsNeeded = count; // how many needed
+                        this._oChainRender.add({
+                            method: function(oArg) {
+                                if((this instanceof DT) && this._sId) {
+                                    var i = oArg.nCurrentRow,
+                                        len = (loopN > 0) ? (Math.max(i - loopN,loopEnd)-1) : loopEnd-1;
+                                    for(; i>len; --i) {
+                                        this._deleteTrEl(i);
+                                    }
+                                    oArg.nCurrentRow = i;
+                                }
+                            },
+                            iterations: (loopN > 0) ? Math.ceil(count/loopN) : 1,
+                            argument: {nCurrentRow:highIndex},
+                            scope: this,
+                            timeout: (loopN > 0) ? 0 : -1
+                        });
+                        this._oChainRender.add({
+                            method: function() {    
+                                // Empty body
+                                if(this._elTbody.rows.length === 0) {
+                                    this.showTableMessage(DT.MSG_EMPTY, DT.CLASS_EMPTY);
+                                }
+                                else {
+                                    this._setFirstRow();
+                                    this._setLastRow();
+                                    this._setRowStripes();
+                                }
+                                
+                                this.fireEvent("rowsDeleteEvent", {recordIndex:count,
+                                oldData:aData, count:nTrIndex});
+                                YAHOO.log("DataTable row deleted: Record ID = " + sRecordId +
+                                    ", Record index = " + nRecordIndex +
+                                    ", page row index = " + nTrIndex, "info", this.toString());
+                            },
+                            scope: this,
+                            timeout: -1 // Needs to run immediately after the DOM deletions above
+                        });
+                        this._oChainRender.run();
+                        return;
+                    }
+                }
+            }
         }
-        else {
-            this.deleteRow(nRecordIndex);
-        }
     }
-    else {
-        YAHOO.log("Could not delete row " + row, "info", this.toString());
-    }
-};
+    YAHOO.log("Could not delete " + count + " rows at row " + row, "warn", this.toString());
+    return null;
+},
 
 
 
@@ -4516,398 +11069,139 @@
  * Outputs markup into the given TD based on given Record.
  *
  * @method formatCell
- * @param elCell {HTMLElement} TD Element.
+ * @param elCell {HTMLElement} The liner DIV element within the TD.
  * @param oRecord {YAHOO.widget.Record} (Optional) Record instance.
  * @param oColumn {YAHOO.widget.Column} (Optional) Column instance.
- * @return {HTML} Markup.
  */
-YAHOO.widget.DataTable.prototype.formatCell = function(elCell, oRecord, oColumn) {
+formatCell : function(elCell, oRecord, oColumn) {
     if(!(oRecord instanceof YAHOO.widget.Record)) {
         oRecord = this.getRecord(elCell);
     }
     if(!(oColumn instanceof YAHOO.widget.Column)) {
-        oColumn = this._oColumnSet.getColumn(elCell.yuiColumnKey);
+        oColumn = this._oColumnSet.getColumn(elCell.parentNode.yuiColumnKey);
     }
-    
+
     if(oRecord && oColumn) {
         var sKey = oColumn.key;
         var oData = oRecord.getData(sKey);
 
-        var fnFormatter;
-        if(YAHOO.lang.isString(oColumn.formatter)) {
-            switch(oColumn.formatter) {
-                case "button":
-                    fnFormatter = YAHOO.widget.DataTable.formatButton;
-                    break;
-                case "checkbox":
-                    fnFormatter = YAHOO.widget.DataTable.formatCheckbox;
-                    break;
-                case "currency":
-                    fnFormatter = YAHOO.widget.DataTable.formatCurrency;
-                    break;
-                case "date":
-                    fnFormatter = YAHOO.widget.DataTable.formatDate;
-                    break;
-                case "dropdown":
-                    fnFormatter = YAHOO.widget.DataTable.formatDropdown;
-                    break;
-                case "email":
-                    fnFormatter = YAHOO.widget.DataTable.formatEmail;
-                    break;
-                case "link":
-                    fnFormatter = YAHOO.widget.DataTable.formatLink;
-                    break;
-                case "number":
-                    fnFormatter = YAHOO.widget.DataTable.formatNumber;
-                    break;
-                case "radio":
-                    fnFormatter = YAHOO.widget.DataTable.formatRadio;
-                    break;
-                case "text":
-                    fnFormatter = YAHOO.widget.DataTable.formatText;
-                    break;
-                case "textarea":
-                    fnFormatter = YAHOO.widget.DataTable.formatTextarea;
-                    break;
-                case "textbox":
-                    fnFormatter = YAHOO.widget.DataTable.formatTextbox;
-                    break;
-                case "html":
-                    // This is the default
-                    break;
-                default:
-                    YAHOO.log("Could not find formatter function \"" +
-                            oColumn.formatter + "\"", "warn", this.toString());
-                    fnFormatter = null;
-            }
+        // Add classNames
+        var aClasses;
+        if(lang.isString(oColumn.className)) {
+            aClasses = [oColumn.className];
         }
-        else if(YAHOO.lang.isFunction(oColumn.formatter)) {
-            fnFormatter = oColumn.formatter;
+        else if(lang.isArray(oColumn.className)) {
+            aClasses = oColumn.className;
         }
+        else {
+            aClasses = [];
+        }
 
+        //TODO: document special keys will get stripped here
+        aClasses[aClasses.length] = "yui-dt-col-"+sKey.replace(/[^\w\-.:]/g,"");
+        
+        aClasses[aClasses.length] = "yui-dt-col-"+oColumn.getId();
+        
+        aClasses[aClasses.length] = DT.CLASS_LINER;
+
+        if(oColumn.sortable) {
+            aClasses[aClasses.length] = DT.CLASS_SORTABLE;
+        }
+        if(oColumn.resizeable) {
+            aClasses[aClasses.length] = DT.CLASS_RESIZEABLE;
+        }
+        if(oColumn.editor) {
+            aClasses[aClasses.length] = DT.CLASS_EDITABLE;
+        }
+
+        elCell.className = "";
+        Dom.addClass(elCell, aClasses.join(" "));
+
+
+        var fnFormatter = typeof oColumn.formatter === 'function' ?
+                          oColumn.formatter :
+                          DT.Formatter[oColumn.formatter+''];
+
         // Apply special formatter
         if(fnFormatter) {
             fnFormatter.call(this, elCell, oRecord, oColumn, oData);
         }
         else {
-            elCell.innerHTML = (YAHOO.lang.isValue(oData)) ? oData.toString() : "";
+            elCell.innerHTML = oData === undefined ||
+                               oData === null ||
+                               (typeof oData === 'number' && isNaN(oData)) ?
+                                "" : oData.toString();
         }
 
-        // Add custom classNames
-        var aCustomClasses = null;
-        if(YAHOO.lang.isString(oColumn.className)) {
-            aCustomClasses = [oColumn.className];
-        }
-        else if(YAHOO.lang.isArray(oColumn.className)) {
-            aCustomClasses = oColumn.className;
-        }
-        if(aCustomClasses) {
-            for(var i=0; i<aCustomClasses.length; i++) {
-                YAHOO.util.Dom.addClass(elCell, aCustomClasses[i]);
-            }
-        }
-        
-        YAHOO.util.Dom.addClass(elCell, "yui-dt-col-"+sKey);
-
-        // Is editable?
-        if(oColumn.editor) {
-            YAHOO.util.Dom.addClass(elCell,YAHOO.widget.DataTable.CLASS_EDITABLE);
-        }
-        
         this.fireEvent("cellFormatEvent", {record:oRecord, column:oColumn, key:sKey, el:elCell});
     }
     else {
         YAHOO.log("Could not format cell " + elCell, "error", this.toString());
     }
-};
+},
 
 
-/**
- * Formats a BUTTON element.
- *
- * @method DataTable.formatButton
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object | Boolean} Data value for the cell. By default, the value
- * is what gets written to the BUTTON.
- * @static
- */
-YAHOO.widget.DataTable.formatButton= function(el, oRecord, oColumn, oData) {
-    var sValue = YAHOO.lang.isValue(oData) ? oData : "Click";
-    //TODO: support YAHOO.widget.Button
-    //if(YAHOO.widget.Button) {
-    
-    //}
-    //else {
-        el.innerHTML = "<button type=\"button\" class=\""+
-                YAHOO.widget.DataTable.CLASS_BUTTON + "\">" + sValue + "</button>";
-    //}
-};
 
-/**
- * Formats a CHECKBOX element.
- *
- * @method DataTable.formatCheckbox
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object | Boolean} Data value for the cell. Can be a simple
- * Boolean to indicate whether checkbox is checked or not. Can be object literal
- * {checked:bBoolean, label:sLabel}. Other forms of oData require a custom
- * formatter.
- * @static
- */
-YAHOO.widget.DataTable.formatCheckbox = function(el, oRecord, oColumn, oData) {
-    var bChecked = oData;
-    bChecked = (bChecked) ? " checked" : "";
-    el.innerHTML = "<input type=\"checkbox\"" + bChecked +
-            " class=\"" + YAHOO.widget.DataTable.CLASS_CHECKBOX + "\">";
-};
 
-/**
- * Formats currency. Default unit is USD.
- *
- * @method DataTable.formatCurrency
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Number} Data value for the cell.
- * @static
- */
-YAHOO.widget.DataTable.formatCurrency = function(el, oRecord, oColumn, oData) {
-    if(YAHOO.lang.isNumber(oData)) {
-        var nAmount = oData;
-        var markup;
 
-        // Round to the penny
-        nAmount = Math.round(nAmount*100)/100;
 
-        // Default currency is USD
-        markup = "$"+nAmount;
 
-        // Normalize digits
-        var dotIndex = markup.indexOf(".");
-        if(dotIndex < 0) {
-            markup += ".00";
-        }
-        else {
-            while(dotIndex > markup.length-3) {
-                markup += "0";
-            }
-        }
-        el.innerHTML = markup;
-    }
-    else {
-        el.innerHTML = YAHOO.lang.isValue(oData) ? oData : "";
-    }
-};
 
-/**
- * Formats JavaScript Dates.
- *
- * @method DataTable.formatDate
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} Data value for the cell, or null.
- * @static
- */
-YAHOO.widget.DataTable.formatDate = function(el, oRecord, oColumn, oData) {
-    var oDate = oData;
-    if(oDate instanceof Date) {
-        el.innerHTML = (oDate.getMonth()+1) + "/" + oDate.getDate()  + "/" + oDate.getFullYear();
-    }
-    else {
-        el.innerHTML = YAHOO.lang.isValue(oData) ? oData : "";
-    }
-};
 
-/**
- * Formats SELECT elements.
- *
- * @method DataTable.formatDropdown
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} Data value for the cell, or null.
- * @static
- */
-YAHOO.widget.DataTable.formatDropdown = function(el, oRecord, oColumn, oData) {
-    var selectedValue = (YAHOO.lang.isValue(oData)) ? oData : oRecord.getData(oColumn.key);
-    var options = (YAHOO.lang.isArray(oColumn.dropdownOptions)) ?
-            oColumn.dropdownOptions : null;
 
-    var selectEl;
-    var collection = el.getElementsByTagName("select");
-    
-    // Create the form element only once, so we can attach the onChange listener
-    if(collection.length === 0) {
-        // Create SELECT element
-        selectEl = document.createElement("select");
-        YAHOO.util.Dom.addClass(selectEl, YAHOO.widget.DataTable.CLASS_DROPDOWN);
-        selectEl = el.appendChild(selectEl);
 
-        // Add event listener
-        YAHOO.util.Event.addListener(selectEl,"change",this._onDropdownChange,this);
-    }
 
-    selectEl = collection[0];
 
-    // Update the form element
-    if(selectEl) {
-        // Clear out previous options
-        selectEl.innerHTML = "";
-        
-        // We have options to populate
-        if(options) {
-            // Create OPTION elements
-            for(var i=0; i<options.length; i++) {
-                var option = options[i];
-                var optionEl = document.createElement("option");
-                optionEl.value = (YAHOO.lang.isValue(option.value)) ?
-                        option.value : option;
-                optionEl.innerHTML = (YAHOO.lang.isValue(option.text)) ?
-                        option.text : option;
-                optionEl = selectEl.appendChild(optionEl);
-            }
-        }
-        // Selected value is our only option
-        else {
-            selectEl.innerHTML = "<option value=\"" + selectedValue + "\">" + selectedValue + "</option>";
-        }
-    }
-    else {
-        el.innerHTML = YAHOO.lang.isValue(oData) ? oData : "";
-    }
-};
 
-/**
- * Formats emails.
- *
- * @method DataTable.formatEmail
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} Data value for the cell, or null.
- * @static
- */
-YAHOO.widget.DataTable.formatEmail = function(el, oRecord, oColumn, oData) {
-    if(YAHOO.lang.isString(oData)) {
-        el.innerHTML = "<a href=\"mailto:" + oData + "\">" + oData + "</a>";
-    }
-    else {
-        el.innerHTML = YAHOO.lang.isValue(oData) ? oData : "";
-    }
-};
 
-/**
- * Formats links.
- *
- * @method DataTable.formatLink
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} Data value for the cell, or null.
- * @static
- */
-YAHOO.widget.DataTable.formatLink = function(el, oRecord, oColumn, oData) {
-    if(YAHOO.lang.isString(oData)) {
-        el.innerHTML = "<a href=\"" + oData + "\">" + oData + "</a>";
-    }
-    else {
-        el.innerHTML = YAHOO.lang.isValue(oData) ? oData : "";
-    }
-};
 
-/**
- * Formats numbers.
- *
- * @method DataTable.formatNumber
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} Data value for the cell, or null.
- * @static
- */
-YAHOO.widget.DataTable.formatNumber = function(el, oRecord, oColumn, oData) {
-    if(YAHOO.lang.isNumber(oData)) {
-        el.innerHTML = oData;
-    }
-    else {
-        el.innerHTML = YAHOO.lang.isValue(oData) ? oData : "";
-    }
-};
 
-/**
- * Formats INPUT TYPE=RADIO elements.
- *
- * @method DataTable.formatRadio
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} (Optional) Data value for the cell.
- * @static
- */
-YAHOO.widget.DataTable.formatRadio = function(el, oRecord, oColumn, oData) {
-    var bChecked = oData;
-    bChecked = (bChecked) ? " checked" : "";
-    el.innerHTML = "<input type=\"radio\"" + bChecked +
-            " name=\"" + oColumn.getKey() + "-radio\"" +
-            " class=\"" + YAHOO.widget.DataTable.CLASS_RADIO+ "\">";
-};
 
-/**
- * Formats text strings.
- *
- * @method DataTable.formatText
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} (Optional) Data value for the cell.
- * @static
- */
-YAHOO.widget.DataTable.formatText = function(el, oRecord, oColumn, oData) {
-    var value = (YAHOO.lang.isValue(oRecord.getData(oColumn.key))) ?
-            oRecord.getData(oColumn.key) : "";
-    //TODO: move to util function
-    el.innerHTML = value.toString().replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
-};
 
-/**
- * Formats TEXTAREA elements.
- *
- * @method DataTable.formatTextarea
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} (Optional) Data value for the cell.
- * @static
- */
-YAHOO.widget.DataTable.formatTextarea = function(el, oRecord, oColumn, oData) {
-    var value = (YAHOO.lang.isValue(oRecord.getData(oColumn.key))) ?
-            oRecord.getData(oColumn.key) : "";
-    var markup = "<textarea>" + value + "</textarea>";
-    el.innerHTML = markup;
-};
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// PAGINATION
+
 /**
- * Formats INPUT TYPE=TEXT elements.
- *
- * @method DataTable.formatTextbox
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} (Optional) Data value for the cell.
- * @static
+ * Delegates the Pag changeRequest events to the configured
+ * handler.
+ * @method onPaginatorChange
+ * @param {Object} an object literal describing the proposed pagination state
  */
-YAHOO.widget.DataTable.formatTextbox = function(el, oRecord, oColumn, oData) {
-    var value = (YAHOO.lang.isValue(oRecord.getData(oColumn.key))) ?
-            oRecord.getData(oColumn.key) : "";
-    var markup = "<input type=\"text\" value=\"" + value + "\">";
-    el.innerHTML = markup;
-};
+onPaginatorChange : function (oState) {
+    var handler = this.get('paginationEventHandler');
 
+    handler(oState,this);
+},
 
 
 
@@ -4955,347 +11249,1549 @@
 
 
 
-// PAGINATION
 
+
+
+// SELECTION/HIGHLIGHTING
+
 /**
- * Updates Paginator values in response to RecordSet changes and/or DOM events.
- * Pass in all, a subset, or no values.
+ * ID string of last highlighted cell element
  *
- * @method updatePaginator
- * @param oNewValues {Object} (Optional) Object literal of Paginator values, or
- * a subset of Paginator values.
- * @param {Object} Object literal of all Paginator values.
+ * @property _sLastHighlightedTdElId
+ * @type String
+ * @private
  */
+//_sLastHighlightedTdElId : null,
 
-YAHOO.widget.DataTable.prototype.updatePaginator = function(oNewValues) {
-    // Complete the set
-    var oValidPaginator = this.get("paginator");
-    var nOrigCurrentPage = oValidPaginator.currentPage;
-    for(var param in oNewValues) {
-        if(YAHOO.lang.hasOwnProperty(oValidPaginator, param)) {
-            oValidPaginator[param] = oNewValues[param];
-        }
-    }
-    
-    oValidPaginator.totalRecords = this._oRecordSet.getLength();
-    oValidPaginator.rowsThisPage = Math.min(oValidPaginator.rowsPerPage, oValidPaginator.totalRecords);
-    oValidPaginator.totalPages = Math.ceil(oValidPaginator.totalRecords / oValidPaginator.rowsThisPage);
-    if(isNaN(oValidPaginator.totalPages)) {
-        oValidPaginator.totalPages = 0;
-    }
-    if(oValidPaginator.currentPage > oValidPaginator.totalPages) {
-        if(oValidPaginator.totalPages < 1) {
-            oValidPaginator.currentPage = 1;
-        }
-        else {
-            oValidPaginator.currentPage = oValidPaginator.totalPages;
-        }
-    }
+/**
+ * ID string of last highlighted row element
+ *
+ * @property _sLastHighlightedTrElId
+ * @type String
+ * @private
+ */
+//_sLastHighlightedTrElId : null,
 
-    if(oValidPaginator.currentPage !== nOrigCurrentPage) {
-        oValidPaginator.startRecordIndex = (oValidPaginator.currentPage-1)*oValidPaginator.rowsPerPage;
-    }
+/**
+ * Array to track row selections (by sRecordId) and/or cell selections
+ * (by {recordId:sRecordId, columnId:sColumnId})
+ *
+ * @property _aSelections
+ * @type Object[]
+ * @private
+ */
+_aSelections : null,
 
+/**
+ * Record instance of the row selection anchor.
+ *
+ * @property _oAnchorRecord
+ * @type YAHOO.widget.Record
+ * @private
+ */
+_oAnchorRecord : null,
 
-    this.set("paginator", oValidPaginator);
-    return this.get("paginator");
-};
+/**
+ * Object literal representing cell selection anchor:
+ * {recordId:sRecordId, columnId:sColumnId}.
+ *
+ * @property _oAnchorCell
+ * @type Object
+ * @private
+ */
+_oAnchorCell : null,
 
 /**
- * Displays given page of a paginated DataTable.
+ * Convenience method to remove the class DT.CLASS_SELECTED
+ * from all TR elements on the page.
  *
- * @method showPage
- * @param nPage {Number} Which page.
+ * @method _unselectAllTrEls
+ * @private
  */
-YAHOO.widget.DataTable.prototype.showPage = function(nPage) {
-    // Validate input
-    if(!YAHOO.lang.isNumber(nPage) || (nPage < 1) || (nPage > this.get("paginator").totalPages)) {
-        nPage = 1;
-    }
-    this.updatePaginator({currentPage:nPage});
-    this.refreshView();
-};
+_unselectAllTrEls : function() {
+    var selectedRows = Dom.getElementsByClassName(DT.CLASS_SELECTED,"tr",this._elTbody);
+    Dom.removeClass(selectedRows, DT.CLASS_SELECTED);
+},
 
 /**
- * Updates Paginator containers with markup. Override this method to customize pagination UI.
+ * Returns object literal of values that represent the selection trigger. Used
+ * to determine selection behavior resulting from a key event.
  *
- * @method formatPaginators
+ * @method _getSelectionTrigger
+ * @private
  */
- YAHOO.widget.DataTable.prototype.formatPaginators = function() {
-    var pag = this.get("paginator");
-    var i;
+_getSelectionTrigger : function() {
+    var sMode = this.get("selectionMode");
+    var oTrigger = {};
+    var oTriggerCell, oTriggerRecord, nTriggerRecordIndex, elTriggerRow, nTriggerTrIndex;
 
-    // For Opera workaround
-    var dropdownEnabled = false;
+    // Cell mode
+    if((sMode == "cellblock") || (sMode == "cellrange") || (sMode == "singlecell")) {
+        oTriggerCell = this.getLastSelectedCell();
+        // No selected cells found
+        if(!oTriggerCell) {
+            return null;
+        }
+        else {
+            oTriggerRecord = this.getRecord(oTriggerCell.recordId);
+            nTriggerRecordIndex = this.getRecordIndex(oTriggerRecord);
+            elTriggerRow = this.getTrEl(oTriggerRecord);
+            nTriggerTrIndex = this.getTrIndex(elTriggerRow);
 
-    // Links are enabled
-    if(pag.pageLinks > -1) {
-        for(i=0; i<pag.links.length; i++) {
-            this.formatPaginatorLinks(pag.links[i], pag.currentPage, pag.pageLinksStart, pag.pageLinks, pag.totalPages);
+            // Selected cell not found on this page
+            if(nTriggerTrIndex === null) {
+                return null;
+            }
+            else {
+                oTrigger.record = oTriggerRecord;
+                oTrigger.recordIndex = nTriggerRecordIndex;
+                oTrigger.el = this.getTdEl(oTriggerCell);
+                oTrigger.trIndex = nTriggerTrIndex;
+                oTrigger.column = this.getColumnById(oTriggerCell.columnId);
+                oTrigger.colKeyIndex = oTrigger.column.getKeyIndex();
+                oTrigger.cell = oTriggerCell;
+                return oTrigger;
+            }
         }
     }
-
-    // Dropdown is enabled
-    for(i=0; i<pag.dropdowns.length; i++) {
-         if(pag.dropdownOptions) {
-            dropdownEnabled = true;
-            this.formatPaginatorDropdown(pag.dropdowns[i], pag.dropdownOptions);
+    // Row mode
+    else {
+        oTriggerRecord = this.getLastSelectedRecord();
+        // No selected rows found
+        if(!oTriggerRecord) {
+                return null;
         }
         else {
-            pag.dropdowns[i].style.display = "none";
+            // Selected row found, but is it on current page?
+            oTriggerRecord = this.getRecord(oTriggerRecord);
+            nTriggerRecordIndex = this.getRecordIndex(oTriggerRecord);
+            elTriggerRow = this.getTrEl(oTriggerRecord);
+            nTriggerTrIndex = this.getTrIndex(elTriggerRow);
+
+            // Selected row not found on this page
+            if(nTriggerTrIndex === null) {
+                return null;
+            }
+            else {
+                oTrigger.record = oTriggerRecord;
+                oTrigger.recordIndex = nTriggerRecordIndex;
+                oTrigger.el = elTriggerRow;
+                oTrigger.trIndex = nTriggerTrIndex;
+                return oTrigger;
+            }
         }
     }
+},
 
-    // For Opera artifacting in dropdowns
-    if(dropdownEnabled && navigator.userAgent.toLowerCase().indexOf("opera") != -1) {
-        document.body.style += '';
-    }
-    YAHOO.log("Paginators formatted", "info", this.toString());
-};
-
 /**
- * Updates Paginator dropdown. If dropdown doesn't exist, the markup is created.
- * Sets dropdown elements's "selected" value.
+ * Returns object literal of values that represent the selection anchor. Used
+ * to determine selection behavior resulting from a user event.
  *
- * @method formatPaginatorDropdown
- * @param elDropdown {HTMLElement} The SELECT element.
- * @param dropdownOptions {Object[]} OPTION values for display in the SELECT element.
+ * @method _getSelectionAnchor
+ * @param oTrigger {Object} (Optional) Object literal of selection trigger values
+ * (for key events).
+ * @private
  */
-YAHOO.widget.DataTable.prototype.formatPaginatorDropdown = function(elDropdown, dropdownOptions) {
-    if(elDropdown && (elDropdown.ownerDocument == document)) {
-        // Clear OPTION elements
-        while (elDropdown.firstChild) {
-            elDropdown.removeChild(elDropdown.firstChild);
+_getSelectionAnchor : function(oTrigger) {
+    var sMode = this.get("selectionMode");
+    var oAnchor = {};
+    var oAnchorRecord, nAnchorRecordIndex, nAnchorTrIndex;
+
+    // Cell mode
+    if((sMode == "cellblock") || (sMode == "cellrange") || (sMode == "singlecell")) {
+        // Validate anchor cell
+        var oAnchorCell = this._oAnchorCell;
+        if(!oAnchorCell) {
+            if(oTrigger) {
+                oAnchorCell = this._oAnchorCell = oTrigger.cell;
+            }
+            else {
+                return null;
+            }
         }
+        oAnchorRecord = this._oAnchorCell.record;
+        nAnchorRecordIndex = this._oRecordSet.getRecordIndex(oAnchorRecord);
+        nAnchorTrIndex = this.getTrIndex(oAnchorRecord);
+        // If anchor cell is not on this page...
+        if(nAnchorTrIndex === null) {
+            // ...set TR index equal to top TR
+            if(nAnchorRecordIndex < this.getRecordIndex(this.getFirstTrEl())) {
+                nAnchorTrIndex = 0;
+            }
+            // ...set TR index equal to bottom TR
+            else {
+                nAnchorTrIndex = this.getRecordIndex(this.getLastTrEl());
+            }
+        }
 
-        // Create OPTION elements
-        for(var j=0; j<dropdownOptions.length; j++) {
-            var dropdownOption = dropdownOptions[j];
-            var optionEl = document.createElement("option");
-            optionEl.value = (YAHOO.lang.isValue(dropdownOption.value)) ?
-                    dropdownOption.value : dropdownOption;
-            optionEl.innerHTML = (YAHOO.lang.isValue(dropdownOption.text)) ?
-                    dropdownOption.text : dropdownOption;
-            optionEl = elDropdown.appendChild(optionEl);
+        oAnchor.record = oAnchorRecord;
+        oAnchor.recordIndex = nAnchorRecordIndex;
+        oAnchor.trIndex = nAnchorTrIndex;
+        oAnchor.column = this._oAnchorCell.column;
+        oAnchor.colKeyIndex = oAnchor.column.getKeyIndex();
+        oAnchor.cell = oAnchorCell;
+        return oAnchor;
+    }
+    // Row mode
+    else {
+        oAnchorRecord = this._oAnchorRecord;
+        if(!oAnchorRecord) {
+            if(oTrigger) {
+                oAnchorRecord = this._oAnchorRecord = oTrigger.record;
+            }
+            else {
+                return null;
+            }
         }
 
-        var options = elDropdown.options;
-        // Update dropdown's "selected" value
-        if(options.length) {
-            for(var i=options.length-1; i>-1; i--) {
-                if((this.get("paginator").rowsPerPage + "") === options[i].value) {
-                    options[i].selected = true;
-                }
+        nAnchorRecordIndex = this.getRecordIndex(oAnchorRecord);
+        nAnchorTrIndex = this.getTrIndex(oAnchorRecord);
+        // If anchor row is not on this page...
+        if(nAnchorTrIndex === null) {
+            // ...set TR index equal to top TR
+            if(nAnchorRecordIndex < this.getRecordIndex(this.getFirstTrEl())) {
+                nAnchorTrIndex = 0;
             }
+            // ...set TR index equal to bottom TR
+            else {
+                nAnchorTrIndex = this.getRecordIndex(this.getLastTrEl());
+            }
         }
 
-        // Show the dropdown
-        elDropdown.style.display = "";
-        return;
+        oAnchor.record = oAnchorRecord;
+        oAnchor.recordIndex = nAnchorRecordIndex;
+        oAnchor.trIndex = nAnchorTrIndex;
+        return oAnchor;
     }
-    YAHOO.log("Could not update Paginator dropdown " + elDropdown, "error", this.toString());
-};
+},
 
 /**
- * Updates Paginator links container with markup.
+ * Determines selection behavior resulting from a mouse event when selection mode
+ * is set to "standard".
  *
- * @method formatPaginatorLinks
- * @param elContainer {HTMLElement} The link container element.
- * @param nCurrentPage {Number} Current page.
- * @param nPageLinksStart {Number} First page link to display.
- * @param nPageLinksLength {Number} How many page links to display.
- * @param nTotalPages {Number} Total number of pages.
+ * @method _handleStandardSelectionByMouse
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
+ * @private
  */
-YAHOO.widget.DataTable.prototype.formatPaginatorLinks = function(elContainer, nCurrentPage, nPageLinksStart, nPageLinksLength, nTotalPages) {
-    if(elContainer && (elContainer.ownerDocument == document) &&
-            YAHOO.lang.isNumber(nCurrentPage) && YAHOO.lang.isNumber(nPageLinksStart) &&
-            YAHOO.lang.isNumber(nTotalPages)) {
-        // Set up markup for first/last/previous/next
-        var bIsFirstPage = (nCurrentPage == 1) ? true : false;
-        var bIsLastPage = (nCurrentPage == nTotalPages) ? true : false;
-        var sFirstLinkMarkup = (bIsFirstPage) ?
-                " <span class=\"" + YAHOO.widget.DataTable.CLASS_DISABLED +
-                " " + YAHOO.widget.DataTable.CLASS_FIRST + "\"><<</span> " :
-                " <a href=\"#\" class=\"" + YAHOO.widget.DataTable.CLASS_FIRST + "\"><<</a> ";
-        var sPrevLinkMarkup = (bIsFirstPage) ?
-                " <span class=\"" + YAHOO.widget.DataTable.CLASS_DISABLED +
-                " " + YAHOO.widget.DataTable.CLASS_PREVIOUS + "\"><</span> " :
-                " <a href=\"#\" class=\"" + YAHOO.widget.DataTable.CLASS_PREVIOUS + "\"><</a> " ;
-        var sNextLinkMarkup = (bIsLastPage) ?
-                " <span class=\"" + YAHOO.widget.DataTable.CLASS_DISABLED +
-                " " + YAHOO.widget.DataTable.CLASS_NEXT + "\">></span> " :
-                " <a href=\"#\" class=\"" + YAHOO.widget.DataTable.CLASS_NEXT + "\">></a> " ;
-        var sLastLinkMarkup = (bIsLastPage) ?
-                " <span class=\"" + YAHOO.widget.DataTable.CLASS_DISABLED +
-                " " + YAHOO.widget.DataTable.CLASS_LAST +  "\">>></span> " :
-                " <a href=\"#\" class=\"" + YAHOO.widget.DataTable.CLASS_LAST + "\">>></a> ";
+_handleStandardSelectionByMouse : function(oArgs) {
+    var elTarget = oArgs.target;
 
-        // Start with first and previous
-        var sMarkup = sFirstLinkMarkup + sPrevLinkMarkup;
-        
-        // Ok to show all links
-        var nMaxLinks = nTotalPages;
-        var nFirstLink = 1;
-        var nLastLink = nTotalPages;
+    // Validate target row
+    var elTargetRow = this.getTrEl(elTarget);
+    if(elTargetRow) {
+        var e = oArgs.event;
+        var bSHIFT = e.shiftKey;
+        var bCTRL = e.ctrlKey || ((navigator.userAgent.toLowerCase().indexOf("mac") != -1) && e.metaKey);
 
-        if(nPageLinksLength > 0) {
-        // Calculate how many links to show
-            nMaxLinks = (nPageLinksStart+nPageLinksLength < nTotalPages) ?
-                    nPageLinksStart+nPageLinksLength-1 : nTotalPages;
+        var oTargetRecord = this.getRecord(elTargetRow);
+        var nTargetRecordIndex = this._oRecordSet.getRecordIndex(oTargetRecord);
 
-            // Try to keep the current page in the middle
-            nFirstLink = (nCurrentPage - Math.floor(nMaxLinks/2) > 0) ? nCurrentPage - Math.floor(nMaxLinks/2) : 1;
-            nLastLink = (nCurrentPage + Math.floor(nMaxLinks/2) <= nTotalPages) ? nCurrentPage + Math.floor(nMaxLinks/2) : nTotalPages;
+        var oAnchor = this._getSelectionAnchor();
 
-            // Keep the last link in range
-            if(nFirstLink === 1) {
-                nLastLink = nMaxLinks;
+        var i;
+
+        // Both SHIFT and CTRL
+        if(bSHIFT && bCTRL) {
+            // Validate anchor
+            if(oAnchor) {
+                if(this.isSelected(oAnchor.record)) {
+                    // Select all rows between anchor row and target row, including target row
+                    if(oAnchor.recordIndex < nTargetRecordIndex) {
+                        for(i=oAnchor.recordIndex+1; i<=nTargetRecordIndex; i++) {
+                            if(!this.isSelected(i)) {
+                                this.selectRow(i);
+                            }
+                        }
+                    }
+                    // Select all rows between target row and anchor row, including target row
+                    else {
+                        for(i=oAnchor.recordIndex-1; i>=nTargetRecordIndex; i--) {
+                            if(!this.isSelected(i)) {
+                                this.selectRow(i);
+                            }
+                        }
+                    }
+                }
+                else {
+                    // Unselect all rows between anchor row and target row
+                    if(oAnchor.recordIndex < nTargetRecordIndex) {
+                        for(i=oAnchor.recordIndex+1; i<=nTargetRecordIndex-1; i++) {
+                            if(this.isSelected(i)) {
+                                this.unselectRow(i);
+                            }
+                        }
+                    }
+                    // Unselect all rows between target row and anchor row
+                    else {
+                        for(i=nTargetRecordIndex+1; i<=oAnchor.recordIndex-1; i++) {
+                            if(this.isSelected(i)) {
+                                this.unselectRow(i);
+                            }
+                        }
+                    }
+                    // Select the target row
+                    this.selectRow(oTargetRecord);
+                }
             }
-            // Keep the first link in range
-            else if(nLastLink === nTotalPages) {
-                nFirstLink = nTotalPages - nMaxLinks + 1;
+            // Invalid anchor
+            else {
+                // Set anchor
+                this._oAnchorRecord = oTargetRecord;
+
+                // Toggle selection of target
+                if(this.isSelected(oTargetRecord)) {
+                    this.unselectRow(oTargetRecord);
+                }
+                else {
+                    this.selectRow(oTargetRecord);
+                }
             }
+        }
+         // Only SHIFT
+        else if(bSHIFT) {
+            this.unselectAllRows();
 
-            // An even number of links can get funky
-            if(nLastLink - nFirstLink === nMaxLinks) {
-                nLastLink--;
+            // Validate anchor
+            if(oAnchor) {
+                // Select all rows between anchor row and target row,
+                // including the anchor row and target row
+                if(oAnchor.recordIndex < nTargetRecordIndex) {
+                    for(i=oAnchor.recordIndex; i<=nTargetRecordIndex; i++) {
+                        this.selectRow(i);
+                    }
+                }
+                // Select all rows between target row and anchor row,
+                // including the target row and anchor row
+                else {
+                    for(i=oAnchor.recordIndex; i>=nTargetRecordIndex; i--) {
+                        this.selectRow(i);
+                    }
+                }
             }
-      }
-        
-        // Generate markup for each page
-        for(var i=nFirstLink; i<=nLastLink; i++) {
-            if(i != nCurrentPage) {
-                sMarkup += " <a href=\"#\" class=\"" + YAHOO.widget.DataTable.CLASS_PAGE + "\">" + i + "</a> ";
+            // Invalid anchor
+            else {
+                // Set anchor
+                this._oAnchorRecord = oTargetRecord;
+
+                // Select target row only
+                this.selectRow(oTargetRecord);
             }
+        }
+        // Only CTRL
+        else if(bCTRL) {
+            // Set anchor
+            this._oAnchorRecord = oTargetRecord;
+
+            // Toggle selection of target
+            if(this.isSelected(oTargetRecord)) {
+                this.unselectRow(oTargetRecord);
+            }
             else {
-                sMarkup += " <span class=\"" + YAHOO.widget.DataTable.CLASS_SELECTED + "\">" + i + "</span>";
+                this.selectRow(oTargetRecord);
             }
         }
-        sMarkup += sNextLinkMarkup + sLastLinkMarkup;
-        elContainer.innerHTML = sMarkup;
-        return;
+        // Neither SHIFT nor CTRL
+        else {
+            this._handleSingleSelectionByMouse(oArgs);
+            return;
+        }
     }
-    YAHOO.log("Could not format Paginator links", "error", this.toString());
-};
+},
 
+/**
+ * Determines selection behavior resulting from a key event when selection mode
+ * is set to "standard".
+ *
+ * @method _handleStandardSelectionByKey
+ * @param e {HTMLEvent} Event object.
+ * @private
+ */
+_handleStandardSelectionByKey : function(e) {
+    var nKey = Ev.getCharCode(e);
 
+    if((nKey == 38) || (nKey == 40)) {
+        var bSHIFT = e.shiftKey;
 
+        // Validate trigger
+        var oTrigger = this._getSelectionTrigger();
+        // Arrow selection only works if last selected row is on current page
+        if(!oTrigger) {
+            return null;
+        }
 
+        Ev.stopEvent(e);
 
+        // Validate anchor
+        var oAnchor = this._getSelectionAnchor(oTrigger);
 
+        // Determine which direction we're going to
+        if(bSHIFT) {
+            // Selecting down away from anchor row
+            if((nKey == 40) && (oAnchor.recordIndex <= oTrigger.trIndex)) {
+                this.selectRow(this.getNextTrEl(oTrigger.el));
+            }
+            // Selecting up away from anchor row
+            else if((nKey == 38) && (oAnchor.recordIndex >= oTrigger.trIndex)) {
+                this.selectRow(this.getPreviousTrEl(oTrigger.el));
+            }
+            // Unselect trigger
+            else {
+                this.unselectRow(oTrigger.el);
+            }
+        }
+        else {
+            this._handleSingleSelectionByKey(e);
+        }
+    }
+},
 
+/**
+ * Determines selection behavior resulting from a mouse event when selection mode
+ * is set to "single".
+ *
+ * @method _handleSingleSelectionByMouse
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
+ * @private
+ */
+_handleSingleSelectionByMouse : function(oArgs) {
+    var elTarget = oArgs.target;
 
+    // Validate target row
+    var elTargetRow = this.getTrEl(elTarget);
+    if(elTargetRow) {
+        var oTargetRecord = this.getRecord(elTargetRow);
 
+        // Set anchor
+        this._oAnchorRecord = oTargetRecord;
 
+        // Select only target
+        this.unselectAllRows();
+        this.selectRow(oTargetRecord);
+    }
+},
 
+/**
+ * Determines selection behavior resulting from a key event when selection mode
+ * is set to "single".
+ *
+ * @method _handleSingleSelectionByKey
+ * @param e {HTMLEvent} Event object.
+ * @private
+ */
+_handleSingleSelectionByKey : function(e) {
+    var nKey = Ev.getCharCode(e);
 
+    if((nKey == 38) || (nKey == 40)) {
+        // Validate trigger
+        var oTrigger = this._getSelectionTrigger();
+        // Arrow selection only works if last selected row is on current page
+        if(!oTrigger) {
+            return null;
+        }
 
+        Ev.stopEvent(e);
 
+        // Determine the new row to select
+        var elNew;
+        if(nKey == 38) { // arrow up
+            elNew = this.getPreviousTrEl(oTrigger.el);
 
+            // Validate new row
+            if(elNew === null) {
+                //TODO: wrap around to last tr on current page
+                //elNew = this.getLastTrEl();
 
+                //TODO: wrap back to last tr of previous page
 
+                // Top row selection is sticky
+                elNew = this.getFirstTrEl();
+            }
+        }
+        else if(nKey == 40) { // arrow down
+            elNew = this.getNextTrEl(oTrigger.el);
 
+            // Validate new row
+            if(elNew === null) {
+                //TODO: wrap around to first tr on current page
+                //elNew = this.getFirstTrEl();
 
+                //TODO: wrap forward to first tr of previous page
 
+                // Bottom row selection is sticky
+                elNew = this.getLastTrEl();
+            }
+        }
 
+        // Unselect all rows
+        this.unselectAllRows();
 
+        // Select the new row
+        this.selectRow(elNew);
 
+        // Set new anchor
+        this._oAnchorRecord = this.getRecord(elNew);
+    }
+},
 
+/**
+ * Determines selection behavior resulting from a mouse event when selection mode
+ * is set to "cellblock".
+ *
+ * @method _handleCellBlockSelectionByMouse
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
+ * @private
+ */
+_handleCellBlockSelectionByMouse : function(oArgs) {
+    var elTarget = oArgs.target;
 
+    // Validate target cell
+    var elTargetCell = this.getTdEl(elTarget);
+    if(elTargetCell) {
+        var e = oArgs.event;
+        var bSHIFT = e.shiftKey;
+        var bCTRL = e.ctrlKey || ((navigator.userAgent.toLowerCase().indexOf("mac") != -1) && e.metaKey);
 
+        var elTargetRow = this.getTrEl(elTargetCell);
+        var nTargetTrIndex = this.getTrIndex(elTargetRow);
+        var oTargetColumn = this.getColumn(elTargetCell);
+        var nTargetColKeyIndex = oTargetColumn.getKeyIndex();
+        var oTargetRecord = this.getRecord(elTargetRow);
+        var nTargetRecordIndex = this._oRecordSet.getRecordIndex(oTargetRecord);
+        var oTargetCell = {record:oTargetRecord, column:oTargetColumn};
 
+        var oAnchor = this._getSelectionAnchor();
 
+        var allRows = this.getTbodyEl().rows;
+        var startIndex, endIndex, currentRow, i, j;
 
+        // Both SHIFT and CTRL
+        if(bSHIFT && bCTRL) {
 
+            // Validate anchor
+            if(oAnchor) {
+                // Anchor is selected
+                if(this.isSelected(oAnchor.cell)) {
+                    // All cells are on the same row
+                    if(oAnchor.recordIndex === nTargetRecordIndex) {
+                        // Select all cells between anchor cell and target cell, including target cell
+                        if(oAnchor.colKeyIndex < nTargetColKeyIndex) {
+                            for(i=oAnchor.colKeyIndex+1; i<=nTargetColKeyIndex; i++) {
+                                this.selectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                        // Select all cells between target cell and anchor cell, including target cell
+                        else if(nTargetColKeyIndex < oAnchor.colKeyIndex) {
+                            for(i=nTargetColKeyIndex; i<oAnchor.colKeyIndex; i++) {
+                                this.selectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                    }
+                    // Anchor row is above target row
+                    else if(oAnchor.recordIndex < nTargetRecordIndex) {
+                        startIndex = Math.min(oAnchor.colKeyIndex, nTargetColKeyIndex);
+                        endIndex = Math.max(oAnchor.colKeyIndex, nTargetColKeyIndex);
 
+                        // Select all cells from startIndex to endIndex on rows between anchor row and target row
+                        for(i=oAnchor.trIndex; i<=nTargetTrIndex; i++) {
+                            for(j=startIndex; j<=endIndex; j++) {
+                                this.selectCell(allRows[i].cells[j]);
+                            }
+                        }
+                    }
+                    // Anchor row is below target row
+                    else {
+                        startIndex = Math.min(oAnchor.trIndex, nTargetColKeyIndex);
+                        endIndex = Math.max(oAnchor.trIndex, nTargetColKeyIndex);
 
+                        // Select all cells from startIndex to endIndex on rows between target row and anchor row
+                        for(i=oAnchor.trIndex; i>=nTargetTrIndex; i--) {
+                            for(j=endIndex; j>=startIndex; j--) {
+                                this.selectCell(allRows[i].cells[j]);
+                            }
+                        }
+                    }
+                }
+                // Anchor cell is unselected
+                else {
+                    // All cells are on the same row
+                    if(oAnchor.recordIndex === nTargetRecordIndex) {
+                        // Unselect all cells between anchor cell and target cell
+                        if(oAnchor.colKeyIndex < nTargetColKeyIndex) {
+                            for(i=oAnchor.colKeyIndex+1; i<nTargetColKeyIndex; i++) {
+                                this.unselectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                        // Select all cells between target cell and anchor cell
+                        else if(nTargetColKeyIndex < oAnchor.colKeyIndex) {
+                            for(i=nTargetColKeyIndex+1; i<oAnchor.colKeyIndex; i++) {
+                                this.unselectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                    }
+                    // Anchor row is above target row
+                    if(oAnchor.recordIndex < nTargetRecordIndex) {
+                        // Unselect all cells from anchor cell to target cell
+                        for(i=oAnchor.trIndex; i<=nTargetTrIndex; i++) {
+                            currentRow = allRows[i];
+                            for(j=0; j<currentRow.cells.length; j++) {
+                                // This is the anchor row, only unselect cells after the anchor cell
+                                if(currentRow.sectionRowIndex === oAnchor.trIndex) {
+                                    if(j>oAnchor.colKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // This is the target row, only unelect cells before the target cell
+                                else if(currentRow.sectionRowIndex === nTargetTrIndex) {
+                                    if(j<nTargetColKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // Unselect all cells on this row
+                                else {
+                                    this.unselectCell(currentRow.cells[j]);
+                                }
+                            }
+                        }
+                    }
+                    // Anchor row is below target row
+                    else {
+                        // Unselect all cells from target cell to anchor cell
+                        for(i=nTargetTrIndex; i<=oAnchor.trIndex; i++) {
+                            currentRow = allRows[i];
+                            for(j=0; j<currentRow.cells.length; j++) {
+                                // This is the target row, only unselect cells after the target cell
+                                if(currentRow.sectionRowIndex == nTargetTrIndex) {
+                                    if(j>nTargetColKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // This is the anchor row, only unselect cells before the anchor cell
+                                else if(currentRow.sectionRowIndex == oAnchor.trIndex) {
+                                    if(j<oAnchor.colKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // Unselect all cells on this row
+                                else {
+                                    this.unselectCell(currentRow.cells[j]);
+                                }
+                            }
+                        }
+                    }
 
+                    // Select the target cell
+                    this.selectCell(elTargetCell);
+                }
+            }
+            // Invalid anchor
+            else {
+                // Set anchor
+                this._oAnchorCell = oTargetCell;
 
+                // Toggle selection of target
+                if(this.isSelected(oTargetCell)) {
+                    this.unselectCell(oTargetCell);
+                }
+                else {
+                    this.selectCell(oTargetCell);
+                }
+            }
 
+        }
+         // Only SHIFT
+        else if(bSHIFT) {
+            this.unselectAllCells();
 
+            // Validate anchor
+            if(oAnchor) {
+                // All cells are on the same row
+                if(oAnchor.recordIndex === nTargetRecordIndex) {
+                    // Select all cells between anchor cell and target cell,
+                    // including the anchor cell and target cell
+                    if(oAnchor.colKeyIndex < nTargetColKeyIndex) {
+                        for(i=oAnchor.colKeyIndex; i<=nTargetColKeyIndex; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+                    }
+                    // Select all cells between target cell and anchor cell
+                    // including the target cell and anchor cell
+                    else if(nTargetColKeyIndex < oAnchor.colKeyIndex) {
+                        for(i=nTargetColKeyIndex; i<=oAnchor.colKeyIndex; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+                    }
+                }
+                // Anchor row is above target row
+                else if(oAnchor.recordIndex < nTargetRecordIndex) {
+                    // Select the cellblock from anchor cell to target cell
+                    // including the anchor cell and the target cell
+                    startIndex = Math.min(oAnchor.colKeyIndex, nTargetColKeyIndex);
+                    endIndex = Math.max(oAnchor.colKeyIndex, nTargetColKeyIndex);
 
+                    for(i=oAnchor.trIndex; i<=nTargetTrIndex; i++) {
+                        for(j=startIndex; j<=endIndex; j++) {
+                            this.selectCell(allRows[i].cells[j]);
+                        }
+                    }
+                }
+                // Anchor row is below target row
+                else {
+                    // Select the cellblock from target cell to anchor cell
+                    // including the target cell and the anchor cell
+                    startIndex = Math.min(oAnchor.colKeyIndex, nTargetColKeyIndex);
+                    endIndex = Math.max(oAnchor.colKeyIndex, nTargetColKeyIndex);
 
+                    for(i=nTargetTrIndex; i<=oAnchor.trIndex; i++) {
+                        for(j=startIndex; j<=endIndex; j++) {
+                            this.selectCell(allRows[i].cells[j]);
+                        }
+                    }
+                }
+            }
+            // Invalid anchor
+            else {
+                // Set anchor
+                this._oAnchorCell = oTargetCell;
 
+                // Select target only
+                this.selectCell(oTargetCell);
+            }
+        }
+        // Only CTRL
+        else if(bCTRL) {
 
+            // Set anchor
+            this._oAnchorCell = oTargetCell;
 
+            // Toggle selection of target
+            if(this.isSelected(oTargetCell)) {
+                this.unselectCell(oTargetCell);
+            }
+            else {
+                this.selectCell(oTargetCell);
+            }
 
+        }
+        // Neither SHIFT nor CTRL
+        else {
+            this._handleSingleCellSelectionByMouse(oArgs);
+        }
+    }
+},
 
+/**
+ * Determines selection behavior resulting from a key event when selection mode
+ * is set to "cellblock".
+ *
+ * @method _handleCellBlockSelectionByKey
+ * @param e {HTMLEvent} Event object.
+ * @private
+ */
+_handleCellBlockSelectionByKey : function(e) {
+    var nKey = Ev.getCharCode(e);
+    var bSHIFT = e.shiftKey;
+    if((nKey == 9) || !bSHIFT) {
+        this._handleSingleCellSelectionByKey(e);
+        return;
+    }
 
+    if((nKey > 36) && (nKey < 41)) {
+        // Validate trigger
+        var oTrigger = this._getSelectionTrigger();
+        // Arrow selection only works if last selected row is on current page
+        if(!oTrigger) {
+            return null;
+        }
 
+        Ev.stopEvent(e);
 
+        // Validate anchor
+        var oAnchor = this._getSelectionAnchor(oTrigger);
 
+        var i, startIndex, endIndex, elNew, elNewRow;
+        var allRows = this.getTbodyEl().rows;
+        var elThisRow = oTrigger.el.parentNode;
 
+        // Determine which direction we're going to
 
-// SELECTION/HIGHLIGHTING
+        if(nKey == 40) { // arrow down
+            // Selecting away from anchor cell
+            if(oAnchor.recordIndex <= oTrigger.recordIndex) {
+                // Select the horiz block on the next row...
+                // ...making sure there is room below the trigger row
+                elNewRow = this.getNextTrEl(oTrigger.el);
+                if(elNewRow) {
+                    startIndex = oAnchor.colKeyIndex;
+                    endIndex = oTrigger.colKeyIndex;
+                    // ...going left
+                    if(startIndex > endIndex) {
+                        for(i=startIndex; i>=endIndex; i--) {
+                            elNew = elNewRow.cells[i];
+                            this.selectCell(elNew);
+                        }
+                    }
+                    // ... going right
+                    else {
+                        for(i=startIndex; i<=endIndex; i++) {
+                            elNew = elNewRow.cells[i];
+                            this.selectCell(elNew);
+                        }
+                    }
+                }
+            }
+            // Unselecting towards anchor cell
+            else {
+                startIndex = Math.min(oAnchor.colKeyIndex, oTrigger.colKeyIndex);
+                endIndex = Math.max(oAnchor.colKeyIndex, oTrigger.colKeyIndex);
+                // Unselect the horiz block on this row towards the next row
+                for(i=startIndex; i<=endIndex; i++) {
+                    this.unselectCell(elThisRow.cells[i]);
+                }
+            }
+        }
+        // Arrow up
+        else if(nKey == 38) {
+            // Selecting away from anchor cell
+            if(oAnchor.recordIndex >= oTrigger.recordIndex) {
+                // Select the horiz block on the previous row...
+                // ...making sure there is room
+                elNewRow = this.getPreviousTrEl(oTrigger.el);
+                if(elNewRow) {
+                    // Select in order from anchor to trigger...
+                    startIndex = oAnchor.colKeyIndex;
+                    endIndex = oTrigger.colKeyIndex;
+                    // ...going left
+                    if(startIndex > endIndex) {
+                        for(i=startIndex; i>=endIndex; i--) {
+                            elNew = elNewRow.cells[i];
+                            this.selectCell(elNew);
+                        }
+                    }
+                    // ... going right
+                    else {
+                        for(i=startIndex; i<=endIndex; i++) {
+                            elNew = elNewRow.cells[i];
+                            this.selectCell(elNew);
+                        }
+                    }
+                }
+            }
+            // Unselecting towards anchor cell
+            else {
+                startIndex = Math.min(oAnchor.colKeyIndex, oTrigger.colKeyIndex);
+                endIndex = Math.max(oAnchor.colKeyIndex, oTrigger.colKeyIndex);
+                // Unselect the horiz block on this row towards the previous row
+                for(i=startIndex; i<=endIndex; i++) {
+                    this.unselectCell(elThisRow.cells[i]);
+                }
+            }
+        }
+        // Arrow right
+        else if(nKey == 39) {
+            // Selecting away from anchor cell
+            if(oAnchor.colKeyIndex <= oTrigger.colKeyIndex) {
+                // Select the next vert block to the right...
+                // ...making sure there is room
+                if(oTrigger.colKeyIndex < elThisRow.cells.length-1) {
+                    // Select in order from anchor to trigger...
+                    startIndex = oAnchor.trIndex;
+                    endIndex = oTrigger.trIndex;
+                    // ...going up
+                    if(startIndex > endIndex) {
+                        for(i=startIndex; i>=endIndex; i--) {
+                            elNew = allRows[i].cells[oTrigger.colKeyIndex+1];
+                            this.selectCell(elNew);
+                        }
+                    }
+                    // ... going down
+                    else {
+                        for(i=startIndex; i<=endIndex; i++) {
+                            elNew = allRows[i].cells[oTrigger.colKeyIndex+1];
+                            this.selectCell(elNew);
+                        }
+                    }
+                }
+            }
+            // Unselecting towards anchor cell
+            else {
+                // Unselect the vert block on this column towards the right
+                startIndex = Math.min(oAnchor.trIndex, oTrigger.trIndex);
+                endIndex = Math.max(oAnchor.trIndex, oTrigger.trIndex);
+                for(i=startIndex; i<=endIndex; i++) {
+                    this.unselectCell(allRows[i].cells[oTrigger.colKeyIndex]);
+                }
+            }
+        }
+        // Arrow left
+        else if(nKey == 37) {
+            // Selecting away from anchor cell
+            if(oAnchor.colKeyIndex >= oTrigger.colKeyIndex) {
+                //Select the previous vert block to the left
+                if(oTrigger.colKeyIndex > 0) {
+                    // Select in order from anchor to trigger...
+                    startIndex = oAnchor.trIndex;
+                    endIndex = oTrigger.trIndex;
+                    // ...going up
+                    if(startIndex > endIndex) {
+                        for(i=startIndex; i>=endIndex; i--) {
+                            elNew = allRows[i].cells[oTrigger.colKeyIndex-1];
+                            this.selectCell(elNew);
+                        }
+                    }
+                    // ... going down
+                    else {
+                        for(i=startIndex; i<=endIndex; i++) {
+                            elNew = allRows[i].cells[oTrigger.colKeyIndex-1];
+                            this.selectCell(elNew);
+                        }
+                    }
+                }
+            }
+            // Unselecting towards anchor cell
+            else {
+                // Unselect the vert block on this column towards the left
+                startIndex = Math.min(oAnchor.trIndex, oTrigger.trIndex);
+                endIndex = Math.max(oAnchor.trIndex, oTrigger.trIndex);
+                for(i=startIndex; i<=endIndex; i++) {
+                    this.unselectCell(allRows[i].cells[oTrigger.colKeyIndex]);
+                }
+            }
+        }
+    }
+},
 
 /**
- * ID string of last highlighted cell element
+ * Determines selection behavior resulting from a mouse event when selection mode
+ * is set to "cellrange".
  *
- * @property _sLastHighlightedTdElId
- * @type String
+ * @method _handleCellRangeSelectionByMouse
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
  * @private
  */
-YAHOO.widget.DataTable.prototype._sLastHighlightedTdElId = null;
+_handleCellRangeSelectionByMouse : function(oArgs) {
+    var elTarget = oArgs.target;
 
-/**
- * ID string of last highlighted row element
- *
- * @property _sLastHighlightedTrElId
- * @type String
- * @private
- */
-YAHOO.widget.DataTable.prototype._sLastHighlightedTrElId = null;
+    // Validate target cell
+    var elTargetCell = this.getTdEl(elTarget);
+    if(elTargetCell) {
+        var e = oArgs.event;
+        var bSHIFT = e.shiftKey;
+        var bCTRL = e.ctrlKey || ((navigator.userAgent.toLowerCase().indexOf("mac") != -1) && e.metaKey);
 
-/**
- * Array to track row selections (by sRecordId) and/or cell selections
- * (by {recordId:sRecordId, columnId:sColumnId})
- *
- * @property _aSelections
- * @type Object[]
- * @private
- */
-YAHOO.widget.DataTable.prototype._aSelections = null;
+        var elTargetRow = this.getTrEl(elTargetCell);
+        var nTargetTrIndex = this.getTrIndex(elTargetRow);
+        var oTargetColumn = this.getColumn(elTargetCell);
+        var nTargetColKeyIndex = oTargetColumn.getKeyIndex();
+        var oTargetRecord = this.getRecord(elTargetRow);
+        var nTargetRecordIndex = this._oRecordSet.getRecordIndex(oTargetRecord);
+        var oTargetCell = {record:oTargetRecord, column:oTargetColumn};
 
+        var oAnchor = this._getSelectionAnchor();
+
+        var allRows = this.getTbodyEl().rows;
+        var currentRow, i, j;
+
+        // Both SHIFT and CTRL
+        if(bSHIFT && bCTRL) {
+
+            // Validate anchor
+            if(oAnchor) {
+                // Anchor is selected
+                if(this.isSelected(oAnchor.cell)) {
+                    // All cells are on the same row
+                    if(oAnchor.recordIndex === nTargetRecordIndex) {
+                        // Select all cells between anchor cell and target cell, including target cell
+                        if(oAnchor.colKeyIndex < nTargetColKeyIndex) {
+                            for(i=oAnchor.colKeyIndex+1; i<=nTargetColKeyIndex; i++) {
+                                this.selectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                        // Select all cells between target cell and anchor cell, including target cell
+                        else if(nTargetColKeyIndex < oAnchor.colKeyIndex) {
+                            for(i=nTargetColKeyIndex; i<oAnchor.colKeyIndex; i++) {
+                                this.selectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                    }
+                    // Anchor row is above target row
+                    else if(oAnchor.recordIndex < nTargetRecordIndex) {
+                        // Select all cells on anchor row from anchor cell to the end of the row
+                        for(i=oAnchor.colKeyIndex+1; i<elTargetRow.cells.length; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+
+                        // Select all cells on all rows between anchor row and target row
+                        for(i=oAnchor.trIndex+1; i<nTargetTrIndex; i++) {
+                            for(j=0; j<allRows[i].cells.length; j++){
+                                this.selectCell(allRows[i].cells[j]);
+                            }
+                        }
+
+                        // Select all cells on target row from first cell to the target cell
+                        for(i=0; i<=nTargetColKeyIndex; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+                    }
+                    // Anchor row is below target row
+                    else {
+                        // Select all cells on target row from target cell to the end of the row
+                        for(i=nTargetColKeyIndex; i<elTargetRow.cells.length; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+
+                        // Select all cells on all rows between target row and anchor row
+                        for(i=nTargetTrIndex+1; i<oAnchor.trIndex; i++) {
+                            for(j=0; j<allRows[i].cells.length; j++){
+                                this.selectCell(allRows[i].cells[j]);
+                            }
+                        }
+
+                        // Select all cells on anchor row from first cell to the anchor cell
+                        for(i=0; i<oAnchor.colKeyIndex; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+                    }
+                }
+                // Anchor cell is unselected
+                else {
+                    // All cells are on the same row
+                    if(oAnchor.recordIndex === nTargetRecordIndex) {
+                        // Unselect all cells between anchor cell and target cell
+                        if(oAnchor.colKeyIndex < nTargetColKeyIndex) {
+                            for(i=oAnchor.colKeyIndex+1; i<nTargetColKeyIndex; i++) {
+                                this.unselectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                        // Select all cells between target cell and anchor cell
+                        else if(nTargetColKeyIndex < oAnchor.colKeyIndex) {
+                            for(i=nTargetColKeyIndex+1; i<oAnchor.colKeyIndex; i++) {
+                                this.unselectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                    }
+                    // Anchor row is above target row
+                    if(oAnchor.recordIndex < nTargetRecordIndex) {
+                        // Unselect all cells from anchor cell to target cell
+                        for(i=oAnchor.trIndex; i<=nTargetTrIndex; i++) {
+                            currentRow = allRows[i];
+                            for(j=0; j<currentRow.cells.length; j++) {
+                                // This is the anchor row, only unselect cells after the anchor cell
+                                if(currentRow.sectionRowIndex === oAnchor.trIndex) {
+                                    if(j>oAnchor.colKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // This is the target row, only unelect cells before the target cell
+                                else if(currentRow.sectionRowIndex === nTargetTrIndex) {
+                                    if(j<nTargetColKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // Unselect all cells on this row
+                                else {
+                                    this.unselectCell(currentRow.cells[j]);
+                                }
+                            }
+                        }
+                    }
+                    // Anchor row is below target row
+                    else {
+                        // Unselect all cells from target cell to anchor cell
+                        for(i=nTargetTrIndex; i<=oAnchor.trIndex; i++) {
+                            currentRow = allRows[i];
+                            for(j=0; j<currentRow.cells.length; j++) {
+                                // This is the target row, only unselect cells after the target cell
+                                if(currentRow.sectionRowIndex == nTargetTrIndex) {
+                                    if(j>nTargetColKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // This is the anchor row, only unselect cells before the anchor cell
+                                else if(currentRow.sectionRowIndex == oAnchor.trIndex) {
+                                    if(j<oAnchor.colKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // Unselect all cells on this row
+                                else {
+                                    this.unselectCell(currentRow.cells[j]);
+                                }
+                            }
+                        }
+                    }
+
+                    // Select the target cell
+                    this.selectCell(elTargetCell);
+                }
+            }
+            // Invalid anchor
+            else {
+                // Set anchor
+                this._oAnchorCell = oTargetCell;
+
+                // Toggle selection of target
+                if(this.isSelected(oTargetCell)) {
+                    this.unselectCell(oTargetCell);
+                }
+                else {
+                    this.selectCell(oTargetCell);
+                }
+            }
+        }
+         // Only SHIFT
+        else if(bSHIFT) {
+
+            this.unselectAllCells();
+
+            // Validate anchor
+            if(oAnchor) {
+                // All cells are on the same row
+                if(oAnchor.recordIndex === nTargetRecordIndex) {
+                    // Select all cells between anchor cell and target cell,
+                    // including the anchor cell and target cell
+                    if(oAnchor.colKeyIndex < nTargetColKeyIndex) {
+                        for(i=oAnchor.colKeyIndex; i<=nTargetColKeyIndex; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+                    }
+                    // Select all cells between target cell and anchor cell
+                    // including the target cell and anchor cell
+                    else if(nTargetColKeyIndex < oAnchor.colKeyIndex) {
+                        for(i=nTargetColKeyIndex; i<=oAnchor.colKeyIndex; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+                    }
+                }
+                // Anchor row is above target row
+                else if(oAnchor.recordIndex < nTargetRecordIndex) {
+                    // Select all cells from anchor cell to target cell
+                    // including the anchor cell and target cell
+                    for(i=oAnchor.trIndex; i<=nTargetTrIndex; i++) {
+                        currentRow = allRows[i];
+                        for(j=0; j<currentRow.cells.length; j++) {
+                            // This is the anchor row, only select the anchor cell and after
+                            if(currentRow.sectionRowIndex == oAnchor.trIndex) {
+                                if(j>=oAnchor.colKeyIndex) {
+                                    this.selectCell(currentRow.cells[j]);
+                                }
+                            }
+                            // This is the target row, only select the target cell and before
+                            else if(currentRow.sectionRowIndex == nTargetTrIndex) {
+                                if(j<=nTargetColKeyIndex) {
+                                    this.selectCell(currentRow.cells[j]);
+                                }
+                            }
+                            // Select all cells on this row
+                            else {
+                                this.selectCell(currentRow.cells[j]);
+                            }
+                        }
+                    }
+                }
+                // Anchor row is below target row
+                else {
+                    // Select all cells from target cell to anchor cell,
+                    // including the target cell and anchor cell
+                    for(i=nTargetTrIndex; i<=oAnchor.trIndex; i++) {
+                        currentRow = allRows[i];
+                        for(j=0; j<currentRow.cells.length; j++) {
+                            // This is the target row, only select the target cell and after
+                            if(currentRow.sectionRowIndex == nTargetTrIndex) {
+                                if(j>=nTargetColKeyIndex) {
+                                    this.selectCell(currentRow.cells[j]);
+                                }
+                            }
+                            // This is the anchor row, only select the anchor cell and before
+                            else if(currentRow.sectionRowIndex == oAnchor.trIndex) {
+                                if(j<=oAnchor.colKeyIndex) {
+                                    this.selectCell(currentRow.cells[j]);
+                                }
+                            }
+                            // Select all cells on this row
+                            else {
+                                this.selectCell(currentRow.cells[j]);
+                            }
+                        }
+                    }
+                }
+            }
+            // Invalid anchor
+            else {
+                // Set anchor
+                this._oAnchorCell = oTargetCell;
+
+                // Select target only
+                this.selectCell(oTargetCell);
+            }
+
+
+        }
+        // Only CTRL
+        else if(bCTRL) {
+
+            // Set anchor
+            this._oAnchorCell = oTargetCell;
+
+            // Toggle selection of target
+            if(this.isSelected(oTargetCell)) {
+                this.unselectCell(oTargetCell);
+            }
+            else {
+                this.selectCell(oTargetCell);
+            }
+
+        }
+        // Neither SHIFT nor CTRL
+        else {
+            this._handleSingleCellSelectionByMouse(oArgs);
+        }
+    }
+},
+
 /**
- * Record instance of the row selection anchor.
+ * Determines selection behavior resulting from a key event when selection mode
+ * is set to "cellrange".
  *
- * @property _oAnchorRecord
- * @type YAHOO.widget.Record
+ * @method _handleCellRangeSelectionByKey
+ * @param e {HTMLEvent} Event object.
  * @private
  */
-YAHOO.widget.DataTable.prototype._oAnchorRecord = null;
+_handleCellRangeSelectionByKey : function(e) {
+    var nKey = Ev.getCharCode(e);
+    var bSHIFT = e.shiftKey;
+    if((nKey == 9) || !bSHIFT) {
+        this._handleSingleCellSelectionByKey(e);
+        return;
+    }
 
+    if((nKey > 36) && (nKey < 41)) {
+        // Validate trigger
+        var oTrigger = this._getSelectionTrigger();
+        // Arrow selection only works if last selected row is on current page
+        if(!oTrigger) {
+            return null;
+        }
+
+        Ev.stopEvent(e);
+
+        // Validate anchor
+        var oAnchor = this._getSelectionAnchor(oTrigger);
+
+        var i, elNewRow, elNew;
+        var allRows = this.getTbodyEl().rows;
+        var elThisRow = oTrigger.el.parentNode;
+
+        // Arrow down
+        if(nKey == 40) {
+            elNewRow = this.getNextTrEl(oTrigger.el);
+
+            // Selecting away from anchor cell
+            if(oAnchor.recordIndex <= oTrigger.recordIndex) {
+                // Select all cells to the end of this row
+                for(i=oTrigger.colKeyIndex+1; i<elThisRow.cells.length; i++){
+                    elNew = elThisRow.cells[i];
+                    this.selectCell(elNew);
+                }
+
+                // Select some of the cells on the next row down
+                if(elNewRow) {
+                    for(i=0; i<=oTrigger.colKeyIndex; i++){
+                        elNew = elNewRow.cells[i];
+                        this.selectCell(elNew);
+                    }
+                }
+            }
+            // Unselecting towards anchor cell
+            else {
+                // Unselect all cells to the end of this row
+                for(i=oTrigger.colKeyIndex; i<elThisRow.cells.length; i++){
+                    this.unselectCell(elThisRow.cells[i]);
+                }
+
+                // Unselect some of the cells on the next row down
+                if(elNewRow) {
+                    for(i=0; i<oTrigger.colKeyIndex; i++){
+                        this.unselectCell(elNewRow.cells[i]);
+                    }
+                }
+            }
+        }
+        // Arrow up
+        else if(nKey == 38) {
+            elNewRow = this.getPreviousTrEl(oTrigger.el);
+
+            // Selecting away from anchor cell
+            if(oAnchor.recordIndex >= oTrigger.recordIndex) {
+                // Select all the cells to the beginning of this row
+                for(i=oTrigger.colKeyIndex-1; i>-1; i--){
+                    elNew = elThisRow.cells[i];
+                    this.selectCell(elNew);
+                }
+
+                // Select some of the cells from the end of the previous row
+                if(elNewRow) {
+                    for(i=elThisRow.cells.length-1; i>=oTrigger.colKeyIndex; i--){
+                        elNew = elNewRow.cells[i];
+                        this.selectCell(elNew);
+                    }
+                }
+            }
+            // Unselecting towards anchor cell
+            else {
+                // Unselect all the cells to the beginning of this row
+                for(i=oTrigger.colKeyIndex; i>-1; i--){
+                    this.unselectCell(elThisRow.cells[i]);
+                }
+
+                // Unselect some of the cells from the end of the previous row
+                if(elNewRow) {
+                    for(i=elThisRow.cells.length-1; i>oTrigger.colKeyIndex; i--){
+                        this.unselectCell(elNewRow.cells[i]);
+                    }
+                }
+            }
+        }
+        // Arrow right
+        else if(nKey == 39) {
+            elNewRow = this.getNextTrEl(oTrigger.el);
+
+            // Selecting away from anchor cell
+            if(oAnchor.recordIndex < oTrigger.recordIndex) {
+                // Select the next cell to the right
+                if(oTrigger.colKeyIndex < elThisRow.cells.length-1) {
+                    elNew = elThisRow.cells[oTrigger.colKeyIndex+1];
+                    this.selectCell(elNew);
+                }
+                // Select the first cell of the next row
+                else if(elNewRow) {
+                    elNew = elNewRow.cells[0];
+                    this.selectCell(elNew);
+                }
+            }
+            // Unselecting towards anchor cell
+            else if(oAnchor.recordIndex > oTrigger.recordIndex) {
+                this.unselectCell(elThisRow.cells[oTrigger.colKeyIndex]);
+
+                // Unselect this cell towards the right
+                if(oTrigger.colKeyIndex < elThisRow.cells.length-1) {
+                }
+                // Unselect this cells towards the first cell of the next row
+                else {
+                }
+            }
+            // Anchor is on this row
+            else {
+                // Selecting away from anchor
+                if(oAnchor.colKeyIndex <= oTrigger.colKeyIndex) {
+                    // Select the next cell to the right
+                    if(oTrigger.colKeyIndex < elThisRow.cells.length-1) {
+                        elNew = elThisRow.cells[oTrigger.colKeyIndex+1];
+                        this.selectCell(elNew);
+                    }
+                    // Select the first cell on the next row
+                    else if(oTrigger.trIndex < allRows.length-1){
+                        elNew = elNewRow.cells[0];
+                        this.selectCell(elNew);
+                    }
+                }
+                // Unselecting towards anchor
+                else {
+                    // Unselect this cell towards the right
+                    this.unselectCell(elThisRow.cells[oTrigger.colKeyIndex]);
+                }
+            }
+        }
+        // Arrow left
+        else if(nKey == 37) {
+            elNewRow = this.getPreviousTrEl(oTrigger.el);
+
+            // Unselecting towards the anchor
+            if(oAnchor.recordIndex < oTrigger.recordIndex) {
+                this.unselectCell(elThisRow.cells[oTrigger.colKeyIndex]);
+
+                // Unselect this cell towards the left
+                if(oTrigger.colKeyIndex > 0) {
+                }
+                // Unselect this cell towards the last cell of the previous row
+                else {
+                }
+            }
+            // Selecting towards the anchor
+            else if(oAnchor.recordIndex > oTrigger.recordIndex) {
+                // Select the next cell to the left
+                if(oTrigger.colKeyIndex > 0) {
+                    elNew = elThisRow.cells[oTrigger.colKeyIndex-1];
+                    this.selectCell(elNew);
+                }
+                // Select the last cell of the previous row
+                else if(oTrigger.trIndex > 0){
+                    elNew = elNewRow.cells[elNewRow.cells.length-1];
+                    this.selectCell(elNew);
+                }
+            }
+            // Anchor is on this row
+            else {
+                // Selecting away from anchor cell
+                if(oAnchor.colKeyIndex >= oTrigger.colKeyIndex) {
+                    // Select the next cell to the left
+                    if(oTrigger.colKeyIndex > 0) {
+                        elNew = elThisRow.cells[oTrigger.colKeyIndex-1];
+                        this.selectCell(elNew);
+                    }
+                    // Select the last cell of the previous row
+                    else if(oTrigger.trIndex > 0){
+                        elNew = elNewRow.cells[elNewRow.cells.length-1];
+                        this.selectCell(elNew);
+                    }
+                }
+                // Unselecting towards anchor cell
+                else {
+                    this.unselectCell(elThisRow.cells[oTrigger.colKeyIndex]);
+
+                    // Unselect this cell towards the left
+                    if(oTrigger.colKeyIndex > 0) {
+                    }
+                    // Unselect this cell towards the last cell of the previous row
+                    else {
+                    }
+                }
+            }
+        }
+    }
+},
+
 /**
- * Object literal representing cell selection anchor:
- * {recordId:sRecordId, columnId:sColumnId}.
+ * Determines selection behavior resulting from a mouse event when selection mode
+ * is set to "singlecell".
  *
- * @property _oAnchorCell
- * @type Object
+ * @method _handleSingleCellSelectionByMouse
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
  * @private
  */
-YAHOO.widget.DataTable.prototype._oAnchorCell = null;
+_handleSingleCellSelectionByMouse : function(oArgs) {
+    var elTarget = oArgs.target;
 
+    // Validate target cell
+    var elTargetCell = this.getTdEl(elTarget);
+    if(elTargetCell) {
+        var elTargetRow = this.getTrEl(elTargetCell);
+        var oTargetRecord = this.getRecord(elTargetRow);
+        var oTargetColumn = this.getColumn(elTargetCell);
+        var oTargetCell = {record:oTargetRecord, column:oTargetColumn};
+
+        // Set anchor
+        this._oAnchorCell = oTargetCell;
+
+        // Select only target
+        this.unselectAllCells();
+        this.selectCell(oTargetCell);
+    }
+},
+
 /**
- * Convenience method to remove the class YAHOO.widget.DataTable.CLASS_SELECTED
- * from all TR elements on the page.
+ * Determines selection behavior resulting from a key event when selection mode
+ * is set to "singlecell".
  *
- * @method _unselectAllTrEls
+ * @method _handleSingleCellSelectionByKey
+ * @param e {HTMLEvent} Event object.
  * @private
  */
-YAHOO.widget.DataTable.prototype._unselectAllTrEls = function() {
-    var selectedRows = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"tr",this._elTbody);
-    YAHOO.util.Dom.removeClass(selectedRows, YAHOO.widget.DataTable.CLASS_SELECTED);
-};
+_handleSingleCellSelectionByKey : function(e) {
+    var nKey = Ev.getCharCode(e);
+    if((nKey == 9) || ((nKey > 36) && (nKey < 41))) {
+        var bSHIFT = e.shiftKey;
 
+        // Validate trigger
+        var oTrigger = this._getSelectionTrigger();
+        // Arrow selection only works if last selected row is on current page
+        if(!oTrigger) {
+            return null;
+        }
+
+        // Determine the new cell to select
+        var elNew;
+        if(nKey == 40) { // Arrow down
+            elNew = this.getBelowTdEl(oTrigger.el);
+
+            // Validate new cell
+            if(elNew === null) {
+                //TODO: wrap around to first tr on current page
+
+                //TODO: wrap forward to first tr of next page
+
+                // Bottom selection is sticky
+                elNew = oTrigger.el;
+            }
+        }
+        else if(nKey == 38) { // Arrow up
+            elNew = this.getAboveTdEl(oTrigger.el);
+
+            // Validate new cell
+            if(elNew === null) {
+                //TODO: wrap around to last tr on current page
+
+                //TODO: wrap back to last tr of previous page
+
+                // Top selection is sticky
+                elNew = oTrigger.el;
+            }
+        }
+        else if((nKey == 39) || (!bSHIFT && (nKey == 9))) { // Arrow right or tab
+            elNew = this.getNextTdEl(oTrigger.el);
+
+            // Validate new cell
+            if(elNew === null) {
+                //TODO: wrap around to first td on current page
+
+                //TODO: wrap forward to first td of next page
+
+                // Top-left selection is sticky, and release TAB focus
+                //elNew = oTrigger.el;
+                return;
+            }
+        }
+        else if((nKey == 37) || (bSHIFT && (nKey == 9))) { // Arrow left or shift-tab
+            elNew = this.getPreviousTdEl(oTrigger.el);
+
+            // Validate new cell
+            if(elNew === null) {
+                //TODO: wrap around to last td on current page
+
+                //TODO: wrap back to last td of previous page
+
+                // Bottom-right selection is sticky, and release TAB focus
+                //elNew = oTrigger.el;
+                return;
+            }
+        }
+
+        Ev.stopEvent(e);
+        
+        // Unselect all cells
+        this.unselectAllCells();
+
+        // Select the new cell
+        this.selectCell(elNew);
+
+        // Set new anchor
+        this._oAnchorCell = {record:this.getRecord(elNew), column:this.getColumn(elNew)};
+    }
+},
+
 /**
  * Returns array of selected TR elements on the page.
  *
  * @method getSelectedTrEls
  * @return {HTMLElement[]} Array of selected TR elements.
  */
-YAHOO.widget.DataTable.prototype.getSelectedTrEls = function() {
-    return YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"tr",this._elTbody);
-};
+getSelectedTrEls : function() {
+    return Dom.getElementsByClassName(DT.CLASS_SELECTED,"tr",this._elTbody);
+},
 
 /**
  * Sets given row to the selected state.
@@ -5304,14 +12800,14 @@
  * @param row {HTMLElement | String | YAHOO.widget.Record | Number} HTML element
  * reference or ID string, Record instance, or RecordSet position index.
  */
-YAHOO.widget.DataTable.prototype.selectRow = function(row) {
+selectRow : function(row) {
     var oRecord, elRow;
-    
+
     if(row instanceof YAHOO.widget.Record) {
         oRecord = this._oRecordSet.getRecord(row);
         elRow = this.getTrEl(oRecord);
     }
-    else if(YAHOO.lang.isNumber(row)) {
+    else if(lang.isNumber(row)) {
         oRecord = this.getRecord(row);
         elRow = this.getTrEl(oRecord);
     }
@@ -5319,26 +12815,35 @@
         elRow = this.getTrEl(row);
         oRecord = this.getRecord(elRow);
     }
-    
+
     if(oRecord) {
         // Update selection trackers
         var tracker = this._aSelections || [];
         var sRecordId = oRecord.getId();
+        var index = -1;
 
         // Remove if already there:
         // Use Array.indexOf if available...
-        if(tracker.indexOf && (tracker.indexOf(sRecordId) >  -1)) {
+        /*if(tracker.indexOf && (tracker.indexOf(sRecordId) >  -1)) {
             tracker.splice(tracker.indexOf(sRecordId),1);
+        }*/
+        if(tracker.indexOf) {
+            index = tracker.indexOf(sRecordId);
+            
         }
         // ...or do it the old-fashioned way
         else {
             for(var j=tracker.length-1; j>-1; j--) {
-               if(tracker[j] === sRecordId){
-                    tracker.splice(j,1);
+                if(tracker[j] === sRecordId){
+                    index = j;
                     break;
                 }
             }
         }
+        if(index > -1) {
+            tracker.splice(index,1);
+        }
+        
         // Add to the end
         tracker.push(sRecordId);
         this._aSelections = tracker;
@@ -5350,41 +12855,32 @@
 
         // Update UI
         if(elRow) {
-            YAHOO.util.Dom.addClass(elRow, YAHOO.widget.DataTable.CLASS_SELECTED);
+            Dom.addClass(elRow, DT.CLASS_SELECTED);
         }
 
         this.fireEvent("rowSelectEvent", {record:oRecord, el:elRow});
         YAHOO.log("Selected " + elRow, "info", this.toString());
     }
-    YAHOO.log("Could not select " + row, "warn", this.toString());
-};
-// Backward compatibility
-YAHOO.widget.DataTable.prototype.select = function(els) {
-    YAHOO.log("The method select() has been deprecated" +
-            " in favor of selectRow()", "warn", this.toString());
-    if(!YAHOO.lang.isArray(els)) {
-        els = [els];
+    else {
+        YAHOO.log("Could not select row " + row, "warn", this.toString());
     }
-    for(var i=0; i<els.length; i++) {
-        this.selectRow(els[i]);
-    }
-};
+},
 
 /**
  * Sets given row to the selected state.
  *
- * @method selectRow
+ * @method unselectRow
  * @param row {HTMLElement | String | YAHOO.widget.Record | Number} HTML element
  * reference or ID string, Record instance, or RecordSet position index.
  */
-YAHOO.widget.DataTable.prototype.unselectRow = function(row) {
+unselectRow : function(row) {
     var elRow = this.getTrEl(row);
 
     var oRecord;
     if(row instanceof YAHOO.widget.Record) {
         oRecord = this._oRecordSet.getRecord(row);
     }
-    else if(YAHOO.lang.isNumber(row)) {
+    else if(lang.isNumber(row)) {
         oRecord = this.getRecord(row);
     }
     else {
@@ -5395,30 +12891,34 @@
         // Update selection trackers
         var tracker = this._aSelections || [];
         var sRecordId = oRecord.getId();
+        var index = -1;
 
         // Remove if found
         var bFound = false;
-        
+
         // Use Array.indexOf if available...
-        if(tracker.indexOf && (tracker.indexOf(sRecordId) >  -1)) {
-            tracker.splice(tracker.indexOf(sRecordId),1);
+        if(tracker.indexOf) {
+            index = tracker.indexOf(sRecordId);
         }
         // ...or do it the old-fashioned way
         else {
             for(var j=tracker.length-1; j>-1; j--) {
-               if(tracker[j] === sRecordId){
-                    tracker.splice(j,1);
+                if(tracker[j] === sRecordId){
+                    index = j;
                     break;
                 }
             }
         }
-        
+        if(index > -1) {
+            tracker.splice(index,1);
+        }
+
         if(bFound) {
             // Update tracker
             this._aSelections = tracker;
 
             // Update the UI
-            YAHOO.util.Dom.removeClass(elRow, YAHOO.widget.DataTable.CLASS_SELECTED);
+            Dom.removeClass(elRow, DT.CLASS_SELECTED);
 
             this.fireEvent("rowUnselectEvent", {record:oRecord, el:elRow});
             YAHOO.log("Unselected " + elRow, "info", this.toString());
@@ -5427,24 +12927,24 @@
         }
 
         // Update the UI
-        YAHOO.util.Dom.removeClass(elRow, YAHOO.widget.DataTable.CLASS_SELECTED);
+        Dom.removeClass(elRow, DT.CLASS_SELECTED);
 
         this.fireEvent("rowUnselectEvent", {record:oRecord, el:elRow});
         YAHOO.log("Unselected " + elRow, "info", this.toString());
     }
     YAHOO.log("Could not unselect row " + row, "warn", this.toString());
-};
+},
 
 /**
  * Clears out all row selections.
  *
  * @method unselectAllRows
  */
-YAHOO.widget.DataTable.prototype.unselectAllRows = function() {
+unselectAllRows : function() {
     // Remove all rows from tracker
     var tracker = this._aSelections || [];
     for(var j=tracker.length-1; j>-1; j--) {
-       if(YAHOO.lang.isString(tracker[j])){
+       if(lang.isString(tracker[j])){
             tracker.splice(j,1);
         }
     }
@@ -5460,19 +12960,19 @@
     //TODO: that takes an array of rows or unselects all if none given
     this.fireEvent("unselectAllRowsEvent");
     YAHOO.log("Unselected all rows", "info", this.toString());
-};
+},
 
 /**
- * Convenience method to remove the class YAHOO.widget.DataTable.CLASS_SELECTED
+ * Convenience method to remove the class DT.CLASS_SELECTED
  * from all TD elements in the internal tracker.
  *
  * @method _unselectAllTdEls
  * @private
  */
-YAHOO.widget.DataTable.prototype._unselectAllTdEls = function() {
-    var selectedCells = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"td",this._elTbody);
-    YAHOO.util.Dom.removeClass(selectedCells, YAHOO.widget.DataTable.CLASS_SELECTED);
-};
+_unselectAllTdEls : function() {
+    var selectedCells = Dom.getElementsByClassName(DT.CLASS_SELECTED,"td",this._elTbody);
+    Dom.removeClass(selectedCells, DT.CLASS_SELECTED);
+},
 
 /**
  * Returns array of selected TD elements on the page.
@@ -5480,9 +12980,9 @@
  * @method getSelectedTdEls
  * @return {HTMLElement[]} Array of selected TD elements.
  */
-YAHOO.widget.DataTable.prototype.getSelectedTdEls = function() {
-    return YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"td",this._elTbody);
-};
+getSelectedTdEls : function() {
+    return Dom.getElementsByClassName(DT.CLASS_SELECTED,"td",this._elTbody);
+},
 
 /**
  * Sets given cell to the selected state.
@@ -5491,12 +12991,12 @@
  * @param cell {HTMLElement | String} DOM element reference or ID string
  * to DataTable page element or RecordSet index.
  */
-YAHOO.widget.DataTable.prototype.selectCell = function(cell) {
+selectCell : function(cell) {
 /*TODO:
 accept {record}
 */
     var elCell = this.getTdEl(cell);
-    
+
     if(elCell) {
         var oRecord = this.getRecord(elCell);
         var sColumnId = elCell.yuiColumnId;
@@ -5524,15 +13024,15 @@
             }
 
             // Update the UI
-            YAHOO.util.Dom.addClass(elCell, YAHOO.widget.DataTable.CLASS_SELECTED);
+            Dom.addClass(elCell, DT.CLASS_SELECTED);
 
             this.fireEvent("cellSelectEvent", {record:oRecord, column:this.getColumnById(sColumnId), key: elCell.yuiColumnKey, el:elCell});
             YAHOO.log("Selected " + elCell, "info", this.toString());
             return;
         }
     }
-    YAHOO.log("Could not select " + cell, "warn", this.toString());
-};
+    YAHOO.log("Could not select cell " + cell, "warn", this.toString());
+},
 
 /**
  * Sets given cell to the unselected state.
@@ -5541,7 +13041,7 @@
  * @param cell {HTMLElement | String} DOM element reference or ID string
  * to DataTable page element or RecordSet index.
  */
-YAHOO.widget.DataTable.prototype.unselectCell = function(cell) {
+unselectCell : function(cell) {
     var elCell = this.getTdEl(cell);
 
     if(elCell) {
@@ -5558,12 +13058,12 @@
                 if((tracker[j].recordId === id) && (tracker[j].columnId === sColumnId)){
                     // Remove from tracker
                     tracker.splice(j,1);
-                    
+
                     // Update tracker
                     this._aSelections = tracker;
 
                     // Update the UI
-                    YAHOO.util.Dom.removeClass(elCell, YAHOO.widget.DataTable.CLASS_SELECTED);
+                    Dom.removeClass(elCell, DT.CLASS_SELECTED);
 
                     this.fireEvent("cellUnselectEvent", {record:oRecord, column: this.getColumnById(sColumnId), key:elCell.yuiColumnKey, el:elCell});
                     YAHOO.log("Unselected " + elCell, "info", this.toString());
@@ -5572,15 +13072,15 @@
             }
         }
     }
-    YAHOO.log("Could not unselect " + cell, "warn", this.toString());
-};
+    YAHOO.log("Could not unselect cell " + cell, "warn", this.toString());
+},
 
 /**
  * Clears out all cell selections.
  *
  * @method unselectAllCells
  */
-YAHOO.widget.DataTable.prototype.unselectAllCells= function() {
+unselectAllCells: function() {
     // Remove all cells from tracker
     var tracker = this._aSelections || [];
     for(var j=tracker.length-1; j>-1; j--) {
@@ -5594,12 +13094,12 @@
 
     // Update UI
     this._unselectAllTdEls();
-    
+
     //TODO: send data
     //TODO: or fire individual cellUnselectEvent
     this.fireEvent("unselectAllCellsEvent");
     YAHOO.log("Unselected all cells", "info", this.toString());
-};
+},
 
 /**
  * Returns true if given item is selected, false otherwise.
@@ -5612,21 +13112,19 @@
  * of a cell.
  * @return {Boolean} True if item is selected.
  */
-YAHOO.widget.DataTable.prototype.isSelected = function(o) {
-    var oRecord, sRecordId, j;
-
-    var el = this.getTrEl(o) || this.getTdEl(o);
-    if(el) {
-        return YAHOO.util.Dom.hasClass(el,YAHOO.widget.DataTable.CLASS_SELECTED);
+isSelected : function(o) {
+    if(o && (o.ownerDocument == document)) {
+        return (Dom.hasClass(this.getTdEl(o),DT.CLASS_SELECTED) || Dom.hasClass(this.getTrEl(o),DT.CLASS_SELECTED));
     }
     else {
+        var oRecord, sRecordId, j;
         var tracker = this._aSelections;
-        if(tracker && tracker.length > 1) {
+        if(tracker && tracker.length > 0) {
             // Looking for a Record?
             if(o instanceof YAHOO.widget.Record) {
                 oRecord = o;
             }
-            else if(YAHOO.lang.isNumber(o)) {
+            else if(lang.isNumber(o)) {
                 oRecord = this.getRecord(o);
             }
             if(oRecord) {
@@ -5634,8 +13132,10 @@
 
                 // Is it there?
                 // Use Array.indexOf if available...
-                if(tracker.indexOf && (tracker.indexOf(sRecordId) >  -1)) {
-                    return true;
+                if(tracker.indexOf) {
+                    if(tracker.indexOf(sRecordId) >  -1) {
+                        return true;
+                    }
                 }
                 // ...or do it the old-fashioned way
                 else {
@@ -5660,7 +13160,7 @@
         }
     }
     return false;
-};
+},
 
 /**
  * Returns selected rows as an array of Record IDs.
@@ -5668,16 +13168,16 @@
  * @method getSelectedRows
  * @return {String[]} Array of selected rows by Record ID.
  */
-YAHOO.widget.DataTable.prototype.getSelectedRows = function() {
+getSelectedRows : function() {
     var aSelectedRows = [];
     var tracker = this._aSelections || [];
     for(var j=0; j<tracker.length; j++) {
-       if(YAHOO.lang.isString(tracker[j])){
+       if(lang.isString(tracker[j])){
             aSelectedRows.push(tracker[j]);
         }
     }
     return aSelectedRows;
-};
+},
 
 /**
  * Returns selected cells as an array of object literals:
@@ -5686,7 +13186,7 @@
  * @method getSelectedCells
  * @return {Object[]} Array of selected cells by Record ID and Column ID.
  */
-YAHOO.widget.DataTable.prototype.getSelectedCells = function() {
+getSelectedCells : function() {
     var aSelectedCells = [];
     var tracker = this._aSelections || [];
     for(var j=0; j<tracker.length; j++) {
@@ -5695,7 +13195,7 @@
         }
     }
     return aSelectedCells;
-};
+},
 
 /**
  * Returns last selected Record ID.
@@ -5703,16 +13203,16 @@
  * @method getLastSelectedRecord
  * @return {String} Record ID of last selected row.
  */
-YAHOO.widget.DataTable.prototype.getLastSelectedRecord = function() {
+getLastSelectedRecord : function() {
     var tracker = this._aSelections;
-    if(tracker.length > 0) {
+    if(tracker && tracker.length > 0) {
         for(var i=tracker.length-1; i>-1; i--) {
-           if(YAHOO.lang.isString(tracker[i])){
+           if(lang.isString(tracker[i])){
                 return tracker[i];
             }
         }
     }
-};
+},
 
 /**
  * Returns last selected cell as an object literal:
@@ -5721,104 +13221,104 @@
  * @method getLastSelectedCell
  * @return {Object} Object literal representation of a cell.
  */
-YAHOO.widget.DataTable.prototype.getLastSelectedCell = function() {
+getLastSelectedCell : function() {
     var tracker = this._aSelections;
-    if(tracker.length > 0) {
+    if(tracker && tracker.length > 0) {
         for(var i=tracker.length-1; i>-1; i--) {
            if(tracker[i].recordId && tracker[i].columnId){
                 return tracker[i];
             }
         }
     }
-};
+},
 
 /**
- * Assigns the class YAHOO.widget.DataTable.CLASS_HIGHLIGHTED to the given row.
+ * Assigns the class DT.CLASS_HIGHLIGHTED to the given row.
  *
  * @method highlightRow
  * @param row {HTMLElement | String} DOM element reference or ID string.
  */
-YAHOO.widget.DataTable.prototype.highlightRow = function(row) {
+highlightRow : function(row) {
     var elRow = this.getTrEl(row);
 
     if(elRow) {
         // Make sure previous row is unhighlighted
-        if(this._sLastHighlightedTrElId) {
-            YAHOO.util.Dom.removeClass(this._sLastHighlightedTrElId,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);
-        }
+/*        if(this._sLastHighlightedTrElId) {
+            Dom.removeClass(this._sLastHighlightedTrElId,DT.CLASS_HIGHLIGHTED);
+        }*/
         var oRecord = this.getRecord(elRow);
-        YAHOO.util.Dom.addClass(elRow,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);
-        this._sLastHighlightedTrElId = elRow.id;
+        Dom.addClass(elRow,DT.CLASS_HIGHLIGHTED);
+        //this._sLastHighlightedTrElId = elRow.id;
         this.fireEvent("rowHighlightEvent", {record:oRecord, el:elRow});
         YAHOO.log("Highlighted " + elRow, "info", this.toString());
         return;
     }
-    YAHOO.log("Could not highlight " + row, "warn", this.toString());
-};
+    YAHOO.log("Could not highlight row " + row, "warn", this.toString());
+},
 
 /**
- * Removes the class YAHOO.widget.DataTable.CLASS_HIGHLIGHTED from the given row.
+ * Removes the class DT.CLASS_HIGHLIGHTED from the given row.
  *
  * @method unhighlightRow
  * @param row {HTMLElement | String} DOM element reference or ID string.
  */
-YAHOO.widget.DataTable.prototype.unhighlightRow = function(row) {
+unhighlightRow : function(row) {
     var elRow = this.getTrEl(row);
 
     if(elRow) {
         var oRecord = this.getRecord(elRow);
-        YAHOO.util.Dom.removeClass(elRow,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);
+        Dom.removeClass(elRow,DT.CLASS_HIGHLIGHTED);
         this.fireEvent("rowUnhighlightEvent", {record:oRecord, el:elRow});
         YAHOO.log("Unhighlighted " + elRow, "info", this.toString());
         return;
     }
-    YAHOO.log("Could not unhighlight " + row, "warn", this.toString());
-};
+    YAHOO.log("Could not unhighlight row " + row, "warn", this.toString());
+},
 
 /**
- * Assigns the class YAHOO.widget.DataTable.CLASS_HIGHLIGHTED to the given cell.
+ * Assigns the class DT.CLASS_HIGHLIGHTED to the given cell.
  *
  * @method highlightCell
  * @param cell {HTMLElement | String} DOM element reference or ID string.
  */
-YAHOO.widget.DataTable.prototype.highlightCell = function(cell) {
+highlightCell : function(cell) {
     var elCell = this.getTdEl(cell);
 
     if(elCell) {
         // Make sure previous cell is unhighlighted
-        if(this._sLastHighlightedTdElId) {
-            YAHOO.util.Dom.removeClass(this._sLastHighlightedTdElId,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);
-        }
-        
+        /*if(this._sLastHighlightedTdElId) {
+            Dom.removeClass(this._sLastHighlightedTdElId,DT.CLASS_HIGHLIGHTED);
+        }*/
+
         var oRecord = this.getRecord(elCell);
         var sColumnId = elCell.yuiColumnId;
-        YAHOO.util.Dom.addClass(elCell,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);
-        this._sLastHighlightedTdElId = elCell.id;
+        Dom.addClass(elCell,DT.CLASS_HIGHLIGHTED);
+        //this._sLastHighlightedTdElId = elCell.id;
         this.fireEvent("cellHighlightEvent", {record:oRecord, column:this.getColumnById(sColumnId), key:elCell.yuiColumnKey, el:elCell});
         YAHOO.log("Highlighted " + elCell, "info", this.toString());
         return;
     }
-    YAHOO.log("Could not highlight " + cell, "warn", this.toString());
-};
+    YAHOO.log("Could not highlight cell " + cell, "warn", this.toString());
+},
 
 /**
- * Removes the class YAHOO.widget.DataTable.CLASS_HIGHLIGHTED from the given cell.
+ * Removes the class DT.CLASS_HIGHLIGHTED from the given cell.
  *
  * @method unhighlightCell
  * @param cell {HTMLElement | String} DOM element reference or ID string.
  */
-YAHOO.widget.DataTable.prototype.unhighlightCell = function(cell) {
+unhighlightCell : function(cell) {
     var elCell = this.getTdEl(cell);
 
     if(elCell) {
         var oRecord = this.getRecord(elCell);
-        YAHOO.util.Dom.removeClass(elCell,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);
+        Dom.removeClass(elCell,DT.CLASS_HIGHLIGHTED);
         this.fireEvent("cellUnhighlightEvent", {record:oRecord, column:this.getColumnById(elCell.yuiColumnId), key:elCell.yuiColumnKey, el:elCell});
         YAHOO.log("Unhighlighted " + elCell, "info", this.toString());
         return;
     }
-    YAHOO.log("Could not unhighlight " + cell, "warn", this.toString());
-};
+    YAHOO.log("Could not unhighlight cell " + cell, "warn", this.toString());
+},
 
 
 
@@ -5866,26 +13366,17 @@
 
 // INLINE EDITING
 
-/*TODO: for TAB handling
- * Shows Cell Editor for next cell.
- *
- * @method editNextCell
- * @param elCell {HTMLElement} Cell element from which to edit next cell.
- */
-//YAHOO.widget.DataTable.prototype.editNextCell = function(elCell) {
-//};
-
 /**
  * Shows Cell Editor for given cell.
  *
  * @method showCellEditor
- * @param elCell {HTMLElement | String} Cell element to edit.
+ * @param elCell {HTMLElement | String} Cell to edit.
  * @param oRecord {YAHOO.widget.Record} (Optional) Record instance.
  * @param oColumn {YAHOO.widget.Column} (Optional) Column instance.
  */
-YAHOO.widget.DataTable.prototype.showCellEditor = function(elCell, oRecord, oColumn) {
-    elCell = YAHOO.util.Dom.get(elCell);
-    
+showCellEditor : function(elCell, oRecord, oColumn) {
+    elCell = Dom.get(elCell);
+
     if(elCell && (elCell.ownerDocument === document)) {
         if(!oRecord || !(oRecord instanceof YAHOO.widget.Record)) {
             oRecord = this.getRecord(elCell);
@@ -5895,7 +13386,7 @@
         }
         if(oRecord && oColumn) {
             var oCellEditor = this._oCellEditor;
-            
+
             // Clear previous Editor
             if(oCellEditor.isActive) {
                 this.cancelCellEditor();
@@ -5905,83 +13396,97 @@
             if(!oColumn.editor) {
                 return;
             }
-            
+
             // Update Editor values
             oCellEditor.cell = elCell;
             oCellEditor.record = oRecord;
             oCellEditor.column = oColumn;
             oCellEditor.validator = (oColumn.editorOptions &&
-                    YAHOO.lang.isFunction(oColumn.editorOptions.validator)) ?
+                    lang.isFunction(oColumn.editorOptions.validator)) ?
                     oColumn.editorOptions.validator : null;
             oCellEditor.value = oRecord.getData(oColumn.key);
+            oCellEditor.defaultValue = null;
 
             // Move Editor
             var elContainer = oCellEditor.container;
-            var x = YAHOO.util.Dom.getX(elCell);
-            var y = YAHOO.util.Dom.getY(elCell);
+            var x = Dom.getX(elCell);
+            var y = Dom.getY(elCell);
 
             // SF doesn't get xy for cells in scrolling table
             // when tbody display is set to block
             if(isNaN(x) || isNaN(y)) {
                 x = elCell.offsetLeft + // cell pos relative to table
-                        YAHOO.util.Dom.getX(this._elTable) - // plus table pos relative to document
+                        Dom.getX(this._elTbody.parentNode) - // plus table pos relative to document
                         this._elTbody.scrollLeft; // minus tbody scroll
                 y = elCell.offsetTop + // cell pos relative to table
-                        YAHOO.util.Dom.getY(this._elTable) - // plus table pos relative to document
+                        Dom.getY(this._elTbody.parentNode) - // plus table pos relative to document
                         this._elTbody.scrollTop + // minus tbody scroll
-                        this._elThead.offsetHeight; // account for fixed headers
+                        this._elThead.offsetHeight; // account for fixed THEAD cells
             }
-            
+
             elContainer.style.left = x + "px";
             elContainer.style.top = y + "px";
 
+            // Hook to customize the UI
+            this.doBeforeShowCellEditor(this._oCellEditor);
+
+            //TODO: This is temporarily up here due so elements can be focused
             // Show Editor
             elContainer.style.display = "";
-            
+
+            // Handle ESC key
+            Ev.addListener(elContainer, "keydown", function(e, oSelf) {
+                // ESC hides Cell Editor
+                if((e.keyCode == 27)) {
+                    oSelf.cancelCellEditor();
+                    oSelf.focusTbodyEl();
+                }
+                else {
+                    oSelf.fireEvent("editorKeydownEvent", {editor:oSelf._oCellEditor, event:e});
+                }
+            }, this);
+
             // Render Editor markup
             var fnEditor;
-            if(YAHOO.lang.isString(oColumn.editor)) {
+            if(lang.isString(oColumn.editor)) {
                 switch(oColumn.editor) {
                     case "checkbox":
-                        fnEditor = YAHOO.widget.DataTable.editCheckbox;
+                        fnEditor = DT.editCheckbox;
                         break;
                     case "date":
-                        fnEditor = YAHOO.widget.DataTable.editDate;
+                        fnEditor = DT.editDate;
                         break;
                     case "dropdown":
-                        fnEditor = YAHOO.widget.DataTable.editDropdown;
+                        fnEditor = DT.editDropdown;
                         break;
                     case "radio":
-                        fnEditor = YAHOO.widget.DataTable.editRadio;
+                        fnEditor = DT.editRadio;
                         break;
                     case "textarea":
-                        fnEditor = YAHOO.widget.DataTable.editTextarea;
+                        fnEditor = DT.editTextarea;
                         break;
                     case "textbox":
-                        fnEditor = YAHOO.widget.DataTable.editTextbox;
+                        fnEditor = DT.editTextbox;
                         break;
                     default:
                         fnEditor = null;
                 }
             }
-            else if(YAHOO.lang.isFunction(oColumn.editor)) {
+            else if(lang.isFunction(oColumn.editor)) {
                 fnEditor = oColumn.editor;
             }
 
             if(fnEditor) {
                 // Create DOM input elements
                 fnEditor(this._oCellEditor, this);
-                
+
                 // Show Save/Cancel buttons
                 if(!oColumn.editorOptions || !oColumn.editorOptions.disableBtns) {
                     this.showCellEditorBtns(elContainer);
                 }
 
-                // Hook to customize the UI
-                this.doBeforeShowCellEditor(this._oCellEditor);
+                oCellEditor.isActive = true;
 
-                oCellEditor.isActive = true;
-                
                 //TODO: verify which args to pass
                 this.fireEvent("editorShowEvent", {editor:oCellEditor});
                 YAHOO.log("Cell Editor shown for " + elCell, "info", this.toString());
@@ -5990,7 +13495,7 @@
         }
     }
     YAHOO.log("Could not show Cell Editor for " + elCell, "warn", this.toString());
-};
+},
 
 /**
  * Overridable abstract method to customize Cell Editor UI.
@@ -5998,8 +13503,8 @@
  * @method doBeforeShowCellEditor
  * @param oCellEditor {Object} Cell Editor object literal.
  */
-YAHOO.widget.DataTable.prototype.doBeforeShowCellEditor = function(oCellEditor) {
-};
+doBeforeShowCellEditor : function(oCellEditor) {
+},
 
 /**
  * Adds Save/Cancel buttons to Cell Editor.
@@ -6007,22 +13512,28 @@
  * @method showCellEditorBtns
  * @param elContainer {HTMLElement} Cell Editor container.
  */
-YAHOO.widget.DataTable.prototype.showCellEditorBtns = function(elContainer) {
+showCellEditorBtns : function(elContainer) {
     // Buttons
     var elBtnsDiv = elContainer.appendChild(document.createElement("div"));
-    YAHOO.util.Dom.addClass(elBtnsDiv, YAHOO.widget.DataTable.CLASS_BUTTON);
+    Dom.addClass(elBtnsDiv, DT.CLASS_BUTTON);
 
     // Save button
     var elSaveBtn = elBtnsDiv.appendChild(document.createElement("button"));
-    YAHOO.util.Dom.addClass(elSaveBtn, YAHOO.widget.DataTable.CLASS_DEFAULT);
+    Dom.addClass(elSaveBtn, DT.CLASS_DEFAULT);
     elSaveBtn.innerHTML = "OK";
-    YAHOO.util.Event.addListener(elSaveBtn, "click", this.saveCellEditor, this, true);
+    Ev.addListener(elSaveBtn, "click", function(oArgs, oSelf) {
+        oSelf.onEventSaveCellEditor(oArgs, oSelf);
+        oSelf.focusTbodyEl();
+    }, this, true);
 
     // Cancel button
     var elCancelBtn = elBtnsDiv.appendChild(document.createElement("button"));
     elCancelBtn.innerHTML = "Cancel";
-    YAHOO.util.Event.addListener(elCancelBtn, "click", this.cancelCellEditor, this, true);
-};
+    Ev.addListener(elCancelBtn, "click", function(oArgs, oSelf) {
+        oSelf.onEventCancelCellEditor(oArgs, oSelf);
+        oSelf.focusTbodyEl();
+    }, this, true);
+},
 
 /**
  * Clears Cell Editor of all state and UI.
@@ -6030,45 +13541,52 @@
  * @method resetCellEditor
  */
 
-YAHOO.widget.DataTable.prototype.resetCellEditor = function() {
+resetCellEditor : function() {
     var elContainer = this._oCellEditor.container;
     elContainer.style.display = "none";
-    YAHOO.util.Event.purgeElement(elContainer, true);
+    Ev.purgeElement(elContainer, true);
     elContainer.innerHTML = "";
     this._oCellEditor.value = null;
     this._oCellEditor.isActive = false;
-};
+    
+},
 
 /**
  * Saves Cell Editor input to Record.
  *
  * @method saveCellEditor
  */
-YAHOO.widget.DataTable.prototype.saveCellEditor = function() {
-    //TODO: Copy the editor's values to pass to the event
+saveCellEditor : function() {
     if(this._oCellEditor.isActive) {
         var newData = this._oCellEditor.value;
-        var oldData = this._oCellEditor.record.getData(this._oCellEditor.column.key);
+        // Copy the data to pass to the event
+        var oldData = YAHOO.widget.DataTable._cloneObject(this._oCellEditor.record.getData(this._oCellEditor.column.key));
 
         // Validate input data
         if(this._oCellEditor.validator) {
-            this._oCellEditor.value = this._oCellEditor.validator.call(this, newData, oldData, this._oCellEditor);
-            if(this._oCellEditor.value === null ) {
+            newData = this._oCellEditor.value = this._oCellEditor.validator.call(this, newData, oldData, this._oCellEditor);
+            if(newData === null ) {
                 this.resetCellEditor();
                 this.fireEvent("editorRevertEvent",
                         {editor:this._oCellEditor, oldData:oldData, newData:newData});
                 YAHOO.log("Could not save Cell Editor input due to invalid data " +
-                        YAHOO.lang.dump(newData), "warn", this.toString());
+                        lang.dump(newData), "warn", this.toString());
                 return;
             }
         }
-
         // Update the Record
-        this._oRecordSet.updateKey(this._oCellEditor.record, this._oCellEditor.column.key, this._oCellEditor.value);
-
+        this._oRecordSet.updateRecordValue(this._oCellEditor.record, this._oCellEditor.column.key, this._oCellEditor.value);
         // Update the UI
-        this.formatCell(this._oCellEditor.cell);
-
+        this.formatCell(this._oCellEditor.cell.firstChild);
+        
+        // Bug fix 1764044
+        this._oChainRender.add({
+            method: function() {
+                this._syncColWidths();
+            },
+            scope: this
+        });
+        this._oChainRender.run();
         // Clear out the Cell Editor
         this.resetCellEditor();
 
@@ -6079,14 +13597,14 @@
     else {
         YAHOO.log("Cell Editor not active to save input", "warn", this.toString());
     }
-};
+},
 
 /**
  * Cancels Cell Editor.
  *
  * @method cancelCellEditor
  */
-YAHOO.widget.DataTable.prototype.cancelCellEditor = function() {
+cancelCellEditor : function() {
     if(this._oCellEditor.isActive) {
         this.resetCellEditor();
         //TODO: preserve values for the event?
@@ -6096,300 +13614,24 @@
     else {
         YAHOO.log("Cell Editor not active to cancel input", "warn", this.toString());
     }
-};
+},
 
-/**
- * Enables CHECKBOX Editor.
- *
- * @method editCheckbox
- * @param oEditor {Object} Object literal representation of Editor values.
- * @param oSelf {YAHOO.widget.DataTable} Reference back to DataTable instance.
- * @static
- */
-//YAHOO.widget.DataTable.editCheckbox = function(elContainer, oRecord, oColumn, oEditor, oSelf) {
-YAHOO.widget.DataTable.editCheckbox = function(oEditor, oSelf) {
-    var elCell = oEditor.cell;
-    var oRecord = oEditor.record;
-    var oColumn = oEditor.column;
-    var elContainer = oEditor.container;
-    var aCheckedValues = oRecord.getData(oColumn.key);
-    if(!YAHOO.lang.isArray(aCheckedValues)) {
-        aCheckedValues = [aCheckedValues];
-    }
 
-    // Checkboxes
-    if(oColumn.editorOptions && YAHOO.lang.isArray(oColumn.editorOptions.checkboxOptions)) {
-        var checkboxOptions = oColumn.editorOptions.checkboxOptions;
-        var checkboxValue, checkboxId, elLabel, j, k;
-        // First create the checkbox buttons in an IE-friendly way
-        for(j=0; j<checkboxOptions.length; j++) {
-            checkboxValue = YAHOO.lang.isValue(checkboxOptions[j].label) ?
-                    checkboxOptions[j].label : checkboxOptions[j];
-            checkboxId =  oSelf.id + "-editor-checkbox" + j;
-            elContainer.innerHTML += "<input type=\"checkbox\"" +
-                    " name=\"" + oSelf.id + "-editor-checkbox\"" +
-                    " value=\"" + checkboxValue + "\"" +
-                    " id=\"" +  checkboxId + "\">";
-            // Then create the labels in an IE-friendly way
-            elLabel = elContainer.appendChild(document.createElement("label"));
-            elLabel.htmlFor = checkboxId;
-            elLabel.innerHTML = checkboxValue;
-        }
-        var aCheckboxEls = [];
-        var checkboxEl;
-        // Loop through checkboxes to check them
-        for(j=0; j<checkboxOptions.length; j++) {
-            checkboxEl = YAHOO.util.Dom.get(oSelf.id + "-editor-checkbox" + j);
-            aCheckboxEls.push(checkboxEl);
-            for(k=0; k<aCheckedValues.length; k++) {
-                if(checkboxEl.value === aCheckedValues[k]) {
-                    checkboxEl.checked = true;
-                }
-            }
-            // Focus the first checkbox
-            if(j===0) {
-                oSelf._focusEl(checkboxEl);
-            }
-        }
-        // Loop through checkboxes to assign click handlers
-        for(j=0; j<checkboxOptions.length; j++) {
-            checkboxEl = YAHOO.util.Dom.get(oSelf.id + "-editor-checkbox" + j);
-            YAHOO.util.Event.addListener(checkboxEl, "click", function(){
-                var aNewValues = [];
-                for(var m=0; m<aCheckboxEls.length; m++) {
-                    if(aCheckboxEls[m].checked) {
-                        aNewValues.push(aCheckboxEls[m].value);
-                    }
-                }
-                oSelf._oCellEditor.value = aNewValues;
-                oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
-            });
-        }
-    }
-};
 
-/**
- * Enables Date Editor.
- *
- * @method editDate
- * @param oEditor {Object} Object literal representation of Editor values.
- * @param oSelf {YAHOO.widget.DataTable} Reference back to DataTable instance.
- * @static
- */
-YAHOO.widget.DataTable.editDate = function(oEditor, oSelf) {
-    var elCell = oEditor.cell;
-    var oRecord = oEditor.record;
-    var oColumn = oEditor.column;
-    var elContainer = oEditor.container;
-    var value = oRecord.getData(oColumn.key);
 
-    // Calendar widget
-    if(YAHOO.widget.Calendar) {
-        var selectedValue = (value.getMonth()+1)+"/"+value.getDate()+"/"+value.getFullYear();
-        var calContainer = elContainer.appendChild(document.createElement("div"));
-        calContainer.id = oSelf.id + "-col" + oColumn.getId() + "-dateContainer";
-        var calendar =
-                new YAHOO.widget.Calendar(oSelf.id + "-col" + oColumn.getId() + "-date",
-                calContainer.id,
-                {selected:selectedValue, pagedate:value});
-        calendar.render();
-        calContainer.style.cssFloat = "none";
 
-        //var calFloatClearer = elContainer.appendChild(document.createElement("br"));
-        //calFloatClearer.style.clear = "both";
-        
-        calendar.selectEvent.subscribe(function(type, args, obj) {
-            oSelf._oCellEditor.value = new Date(args[0][0][0], args[0][0][1]-1, args[0][0][2]);
-            oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
-        });
-    }
-    else {
-        //TODO;
-    }
-};
 
-/**
- * Enables SELECT Editor.
- *
- * @method editDropdown
- * @param oEditor {Object} Object literal representation of Editor values.
- * @param oSelf {YAHOO.widget.DataTable} Reference back to DataTable instance.
- * @static
- */
-YAHOO.widget.DataTable.editDropdown = function(oEditor, oSelf) {
-    var elCell = oEditor.cell;
-    var oRecord = oEditor.record;
-    var oColumn = oEditor.column;
-    var elContainer = oEditor.container;
-    var value = oRecord.getData(oColumn.key);
 
-    // Textbox
-    var elDropdown = elContainer.appendChild(document.createElement("select"));
-    var dropdownOptions = (oColumn.editorOptions && YAHOO.lang.isArray(oColumn.editorOptions.dropdownOptions)) ?
-            oColumn.editorOptions.dropdownOptions : [];
-    for(var j=0; j<dropdownOptions.length; j++) {
-        var dropdownOption = dropdownOptions[j];
-        var elOption = document.createElement("option");
-        elOption.value = (YAHOO.lang.isValue(dropdownOption.value)) ?
-                dropdownOption.value : dropdownOption;
-        elOption.innerHTML = (YAHOO.lang.isValue(dropdownOption.text)) ?
-                dropdownOption.text : dropdownOption;
-        elOption = elDropdown.appendChild(elOption);
-        if(value === elDropdown.options[j].value) {
-            elDropdown.options[j].selected = true;
-        }
-    }
-    
-    // Set up a listener on each check box to track the input value
-    YAHOO.util.Event.addListener(elDropdown, "change",
-        function(){
-            oSelf._oCellEditor.value = elDropdown[elDropdown.selectedIndex].value;
-            oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
-    });
-            
-    // Focus the dropdown
-    oSelf._focusEl(elDropdown);
-};
 
-/**
- * Enables INPUT TYPE=RADIO Editor.
- *
- * @method editRadio
- * @param oEditor {Object} Object literal representation of Editor values.
- * @param oSelf {YAHOO.widget.DataTable} Reference back to DataTable instance.
- * @static
- */
-YAHOO.widget.DataTable.editRadio = function(oEditor, oSelf) {
-    var elCell = oEditor.cell;
-    var oRecord = oEditor.record;
-    var oColumn = oEditor.column;
-    var elContainer = oEditor.container;
-    var value = oRecord.getData(oColumn.key);
 
-    // Radios
-    if(oColumn.editorOptions && YAHOO.lang.isArray(oColumn.editorOptions.radioOptions)) {
-        var radioOptions = oColumn.editorOptions.radioOptions;
-        var radioValue, radioId, elLabel, j;
-        // First create the radio buttons in an IE-friendly way
-        for(j=0; j<radioOptions.length; j++) {
-            radioValue = YAHOO.lang.isValue(radioOptions[j].label) ?
-                    radioOptions[j].label : radioOptions[j];
-            radioId =  oSelf.id + "-editor-radio" + j;
-            elContainer.innerHTML += "<input type=\"radio\"" +
-                    " name=\"" + oSelf.id + "-editor-radio\"" +
-                    " value=\"" + radioValue + "\"" +
-                    " id=\"" +  radioId + "\">";
-            // Then create the labels in an IE-friendly way
-            elLabel = elContainer.appendChild(document.createElement("label"));
-            elLabel.htmlFor = radioId;
-            elLabel.innerHTML = radioValue;
-        }
-        // Then check one, and assign click handlers
-        for(j=0; j<radioOptions.length; j++) {
-            var radioEl = YAHOO.util.Dom.get(oSelf.id + "-editor-radio" + j);
-            if(value === radioEl.value) {
-                radioEl.checked = true;
-                oSelf._focusEl(radioEl);
-            }
-            YAHOO.util.Event.addListener(radioEl, "click",
-                function(){
-                    oSelf._oCellEditor.value = this.value;
-                    oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
-            });
-        }
-    }
-};
 
-/**
- * Enables TEXTAREA Editor.
- *
- * @method editTextarea
- * @param oEditor {Object} Object literal representation of Editor values.
- * @param oSelf {YAHOO.widget.DataTable} Reference back to DataTable instance.
- * @static
- */
-YAHOO.widget.DataTable.editTextarea = function(oEditor, oSelf) {
-   var elCell = oEditor.cell;
-   var oRecord = oEditor.record;
-   var oColumn = oEditor.column;
-   var elContainer = oEditor.container;
-   var value = oRecord.getData(oColumn.key);
 
-    // Textarea
-    var elTextarea = elContainer.appendChild(document.createElement("textarea"));
-    elTextarea.style.width = elCell.offsetWidth + "px"; //(parseInt(elCell.offsetWidth,10)) + "px";
-    elTextarea.style.height = "3em"; //(parseInt(elCell.offsetHeight,10)) + "px";
-    elTextarea.value = YAHOO.lang.isValue(value) ? value : "";
-    
-    // Set up a listener on each check box to track the input value
-    YAHOO.util.Event.addListener(elTextarea, "keyup", function(){
-        //TODO: set on a timeout
-        oSelf._oCellEditor.value = elTextarea.value;
-        oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
-    });
-    
-    // Select the text
-    elTextarea.focus();
-    elTextarea.select();
-};
 
-/**
- * Enables INPUT TYPE=TEXT Editor.
- *
- * @method editTextbox
- * @param oEditor {Object} Object literal representation of Editor values.
- * @param oSelf {YAHOO.widget.DataTable} Reference back to DataTable instance.
- * @static
- */
-YAHOO.widget.DataTable.editTextbox = function(oEditor, oSelf) {
-   var elCell = oEditor.cell;
-   var oRecord = oEditor.record;
-   var oColumn = oEditor.column;
-   var elContainer = oEditor.container;
-   var value = YAHOO.lang.isValue(oRecord.getData(oColumn.key)) ? oRecord.getData(oColumn.key) : "";
 
-    // Textbox
-    var elTextbox = elContainer.appendChild(document.createElement("input"));
-    elTextbox.type = "text";
-    elTextbox.style.width = elCell.offsetWidth + "px"; //(parseInt(elCell.offsetWidth,10)) + "px";
-    //elTextbox.style.height = "1em"; //(parseInt(elCell.offsetHeight,10)) + "px";
-    elTextbox.value = value;
 
-    // Set up a listener on each textbox to track the input value
-    YAHOO.util.Event.addListener(elTextbox, "keyup", function(){
-        //TODO: set on a timeout
-        oSelf._oCellEditor.value = elTextbox.value;
-        oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
-    });
 
-    // Select the text
-    elTextbox.focus();
-    elTextbox.select();
-};
 
-/*
- * Validates Editor input value to type Number, doing type conversion as
- * necessary. A valid Number value is return, else the previous value is returned
- * if input value does not validate.
- * 
- *
- * @method validateNumber
- * @param oData {Object} Data to validate.
- * @static
-*/
-YAHOO.widget.DataTable.validateNumber = function(oData) {
-    //Convert to number
-    var number = oData * 1;
 
-    // Validate
-    if(YAHOO.lang.isNumber(number)) {
-        return number;
-    }
-    else {
-        YAHOO.log("Could not validate data " + YAHOO.lang.dump(oData) + " to type Number", "warn", this.toString());
-        return null;
-    }
-};
 
 
 
@@ -6412,22 +13654,6 @@
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 // ABSTRACT METHODS
 
 /**
@@ -6437,12 +13663,13 @@
  * @method doBeforeLoadData
  * @param sRequest {String} Original request.
  * @param oResponse {Object} Response object.
+ * @param oPayload {MIXED} additional arguments
  * @return {Boolean} Return true to continue loading data into RecordSet and
  * updating DataTable with new Records, false to cancel.
  */
-YAHOO.widget.DataTable.prototype.doBeforeLoadData = function(sRequest, oResponse) {
+doBeforeLoadData : function(sRequest, oResponse, oPayload) {
     return true;
-};
+},
 
 
 
@@ -6519,213 +13746,81 @@
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventSortColumn = function(oArgs) {
-//TODO: support nested header column sorting
+onEventSortColumn : function(oArgs) {
+//TODO: support form elements in sortable columns
     var evt = oArgs.event;
     var target = oArgs.target;
-    YAHOO.util.Event.stopEvent(evt);
-    
+
     var el = this.getThEl(target) || this.getTdEl(target);
     if(el && el.yuiColumnKey) {
         var oColumn = this.getColumn(el.yuiColumnKey);
         if(oColumn.sortable) {
+            Ev.stopEvent(evt);
             this.sortColumn(oColumn);
         }
-        else {
-            YAHOO.log("Column for " + target + " not sortable", "warn", this.toString());
-        }
     }
     else {
         YAHOO.log("Could not find Column for " + target, "warn", this.toString());
     }
-};
+},
 
 /**
+ * Overridable custom event handler to select Column.
+ *
+ * @method onEventSelectColumn
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
+ */
+onEventSelectColumn : function(oArgs) {
+    this.selectColumn(oArgs.target);
+},
+
+/**
+ * Overridable custom event handler to highlight Column. Accounts for spurious
+ * caused-by-child events. 
+ *
+ * @method onEventHighlightColumn
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
+ */
+onEventHighlightColumn : function(oArgs) {
+    //TODO: filter for all spurious events at a lower level
+    if(!Dom.isAncestor(oArgs.target,Ev.getRelatedTarget(oArgs.event))) {
+        this.highlightColumn(oArgs.target);
+    }
+},
+
+/**
+ * Overridable custom event handler to unhighlight Column. Accounts for spurious
+ * caused-by-child events. 
+ *
+ * @method onEventUnhighlightColumn
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
+ */
+onEventUnhighlightColumn : function(oArgs) {
+    //TODO: filter for all spurious events at a lower level
+    if(!Dom.isAncestor(oArgs.target,Ev.getRelatedTarget(oArgs.event))) {
+        this.unhighlightColumn(oArgs.target);
+    }
+},
+
+/**
  * Overridable custom event handler to manage selection according to desktop paradigm.
  *
  * @method onEventSelectRow
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventSelectRow = function(oArgs) {
+onEventSelectRow : function(oArgs) {
     var sMode = this.get("selectionMode");
-    if ((sMode == "singlecell") || (sMode == "cellblock") || (sMode == "cellrange")) {
-        return;
+    if(sMode == "single") {
+        this._handleSingleSelectionByMouse(oArgs);
     }
-
-    var evt = oArgs.event;
-    var elTarget = oArgs.target;
-
-    var bSHIFT = evt.shiftKey;
-    var bCTRL = evt.ctrlKey || ((navigator.userAgent.toLowerCase().indexOf("mac") != -1) && evt.metaKey);
-    var i;
-    //var nAnchorPos;
-
-    // Validate target row
-    var elTargetRow = this.getTrEl(elTarget);
-    if(elTargetRow) {
-        var nAnchorRecordIndex, nAnchorTrIndex;
-        var allRows = this._elTbody.rows;
-        var oTargetRecord = this.getRecord(elTargetRow);
-        var nTargetRecordIndex = this._oRecordSet.getRecordIndex(oTargetRecord);
-        var nTargetTrIndex = this.getTrIndex(elTargetRow);
-
-        var oAnchorRecord = this._oAnchorRecord;
-        if(oAnchorRecord) {
-            nAnchorRecordIndex = this._oRecordSet.getRecordIndex(oAnchorRecord);
-            nAnchorTrIndex = this.getTrIndex(oAnchorRecord);
-            if(nAnchorTrIndex === null) {
-                if(nAnchorRecordIndex < this.getRecordIndex(this.getFirstTrEl())) {
-                    nAnchorTrIndex = 0;
-                }
-                else {
-                    nAnchorTrIndex = this.getRecordIndex(this.getLastTrEl());
-                }
-            }
-        }
-
-        // Both SHIFT and CTRL
-        if((sMode != "single") && bSHIFT && bCTRL) {
-            // Validate anchor
-            if(oAnchorRecord) {
-                if(this.isSelected(oAnchorRecord)) {
-                    // Select all rows between anchor row and target row, including target row
-                    if(nAnchorRecordIndex < nTargetRecordIndex) {
-                        for(i=nAnchorRecordIndex+1; i<=nTargetRecordIndex; i++) {
-                            if(!this.isSelected(i)) {
-                                this.selectRow(i);
-                            }
-                        }
-                    }
-                    // Select all rows between target row and anchor row, including target row
-                    else {
-                        for(i=nAnchorRecordIndex-1; i>=nTargetRecordIndex; i--) {
-                            if(!this.isSelected(i)) {
-                                this.selectRow(i);
-                            }
-                        }
-                    }
-                }
-                else {
-                    // Unselect all rows between anchor row and target row
-                    if(nAnchorRecordIndex < nTargetRecordIndex) {
-                        for(i=nAnchorRecordIndex+1; i<=nTargetRecordIndex-1; i++) {
-                            if(this.isSelected(i)) {
-                                this.unselectRow(i);
-                            }
-                        }
-                    }
-                    // Unselect all rows between target row and anchor row
-                    else {
-                        for(i=nTargetRecordIndex+1; i<=nAnchorRecordIndex-1; i++) {
-                            if(this.isSelected(i)) {
-                                this.unselectRow(i);
-                            }
-                        }
-                    }
-                    // Select the target row
-                    this.selectRow(oTargetRecord);
-                }
-            }
-            // Invalid anchor
-            else {
-                // Set anchor
-                this._oAnchorRecord = oTargetRecord;
-
-                // Toggle selection of target
-                if(this.isSelected(oTargetRecord)) {
-                    this.unselectRow(oTargetRecord);
-                }
-                else {
-                    this.selectRow(oTargetRecord);
-                }
-            }
-        }
-        // Only SHIFT
-        else if((sMode != "single") && bSHIFT) {
-            this.unselectAllRows();
-
-            // Validate anchor
-            if(oAnchorRecord) {
-                // Select all rows between anchor row and target row,
-                // including the anchor row and target row
-                if(nAnchorRecordIndex < nTargetRecordIndex) {
-                    for(i=nAnchorRecordIndex; i<=nTargetRecordIndex; i++) {
-                        this.selectRow(i);
-                    }
-                }
-                // Select all rows between target row and anchor row,
-                // including the target row and anchor row
-                else {
-                    for(i=nAnchorRecordIndex; i>=nTargetRecordIndex; i--) {
-                        this.selectRow(i);
-                    }
-                }
-            }
-            // Invalid anchor
-            else {
-                // Set anchor
-                this._oAnchorRecord = oTargetRecord;
-
-                // Select target row only
-                this.selectRow(oTargetRecord);
-            }
-        }
-        // Only CTRL
-        else if((sMode != "single") && bCTRL) {
-            // Set anchor
-            this._oAnchorRecord = oTargetRecord;
-
-            // Toggle selection of target
-            if(this.isSelected(oTargetRecord)) {
-                this.unselectRow(oTargetRecord);
-            }
-            else {
-                this.selectRow(oTargetRecord);
-            }
-        }
-        // Neither SHIFT nor CTRL and "single" mode
-        else if(sMode == "single") {
-            this.unselectAllRows();
-            this.selectRow(oTargetRecord);
-        }
-        // Neither SHIFT nor CTRL
-        else {
-            // Set anchor
-            this._oAnchorRecord = oTargetRecord;
-
-            // Select only target
-            this.unselectAllRows();
-            this.selectRow(oTargetRecord);
-        }
-
-        // Clear any selections that are a byproduct of the click or dblclick
-        var sel;
-        if(window.getSelection) {
-        	sel = window.getSelection();
-        }
-        else if(document.getSelection) {
-        	sel = document.getSelection();
-        }
-        else if(document.selection) {
-        	sel = document.selection;
-        }
-        if(sel) {
-            if(sel.empty) {
-                sel.empty();
-            }
-            else if (sel.removeAllRanges) {
-                sel.removeAllRanges();
-            }
-            else if(sel.collapse) {
-                sel.collapse();
-            }
-        }
-    }
     else {
-        YAHOO.log("Could not select row " + elTarget, "warn", this.toString());
+        this._handleStandardSelectionByMouse(oArgs);
     }
-};
+},
 
 /**
  * Overridable custom event handler to select cell.
@@ -6734,447 +13829,78 @@
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventSelectCell = function(oArgs) {
+onEventSelectCell : function(oArgs) {
     var sMode = this.get("selectionMode");
-    if ((sMode == "standard") || (sMode == "single")) {
-        return;
+    if(sMode == "cellblock") {
+        this._handleCellBlockSelectionByMouse(oArgs);
     }
-
-    var evt = oArgs.event;
-    var elTarget = oArgs.target;
-
-    var bSHIFT = evt.shiftKey;
-    var bCTRL = evt.ctrlKey  || ((navigator.userAgent.toLowerCase().indexOf("mac") != -1) && evt.metaKey);
-    var i, j, currentRow, startIndex, endIndex;
-    
-    var elTargetCell = this.getTdEl(elTarget);
-    if(elTargetCell) {
-        var nAnchorRecordIndex, nAnchorTrIndex, oAnchorColumn, nAnchorColKeyIndex;
-        
-        var elTargetRow = this.getTrEl(elTargetCell);
-        var allRows = this._elTbody.rows;
-        
-        var oTargetRecord = this.getRecord(elTargetRow);
-        var nTargetRecordIndex = this._oRecordSet.getRecordIndex(oTargetRecord);
-        var oTargetColumn = this.getColumn(elTargetCell);
-        var nTargetColKeyIndex = oTargetColumn.getKeyIndex();
-        var nTargetTrIndex = this.getTrIndex(elTargetRow);
-        var oTargetCell = {record:oTargetRecord, column:oTargetColumn};
-
-        var oAnchorRecord = (this._oAnchorCell) ? this._oAnchorCell.record : null;
-        if(oAnchorRecord) {
-            nAnchorRecordIndex = this._oRecordSet.getRecordIndex(oAnchorRecord);
-            oAnchorColumn = this._oAnchorCell.column;
-            nAnchorColKeyIndex = oAnchorColumn.getKeyIndex();
-            nAnchorTrIndex = this.getTrIndex(oAnchorRecord);
-            if(nAnchorTrIndex === null) {
-                if(nAnchorRecordIndex < this.getRecordIndex(this.getFirstTrEl())) {
-                    nAnchorTrIndex = 0;
-                }
-                else {
-                    nAnchorTrIndex = this.getRecordIndex(this.getLastTrEl());
-                }
-            }
-        }
-        var oAnchorCell = {record:oAnchorRecord, column:oAnchorColumn};
-
-        // Both SHIFT and CTRL
-        if((sMode != "singlecell") && bSHIFT && bCTRL) {
-            // Validate anchor
-            if(oAnchorRecord && oAnchorColumn) {
-                // Anchor is selected
-                if(this.isSelected(this._oAnchorCell)) {
-                    // All cells are on the same row
-                    if(nAnchorRecordIndex === nTargetRecordIndex) {
-                        // Select all cells between anchor cell and target cell, including target cell
-                        if(nAnchorColKeyIndex < nTargetColKeyIndex) {
-                            for(i=nAnchorColKeyIndex+1; i<=nTargetColKeyIndex; i++) {
-                                this.selectCell(allRows[nTargetTrIndex].cells[i]);
-                            }
-                        }
-                        // Select all cells between target cell and anchor cell, including target cell
-                        else if(nTargetColKeyIndex < nAnchorColKeyIndex) {
-                            for(i=nTargetColKeyIndex; i<nAnchorColKeyIndex; i++) {
-                                this.selectCell(allRows[nTargetTrIndex].cells[i]);
-                            }
-                        }
-                    }
-                    // Anchor row is above target row
-                    else if(nAnchorRecordIndex < nTargetRecordIndex) {
-                        if(sMode == "cellrange") {
-                            // Select all cells on anchor row from anchor cell to the end of the row
-                            for(i=nAnchorColKeyIndex+1; i<allRows[nAnchorTrIndex].cells.length; i++) {
-                                this.selectCell(allRows[nAnchorTrIndex].cells[i]);
-                            }
-                            
-                            // Select all cells on all rows between anchor row and target row
-                            for(i=nAnchorTrIndex+1; i<nTargetTrIndex; i++) {
-                                for(j=0; j<allRows[i].cells.length; j++){
-                                    this.selectCell(allRows[i].cells[j]);
-                                }
-                            }
-
-                            // Select all cells on target row from first cell to the target cell
-                            for(i=0; i<=nTargetColKeyIndex; i++) {
-                                this.selectCell(allRows[nTargetTrIndex].cells[i]);
-                            }
-                        }
-                        else if(sMode == "cellblock") {
-                            startIndex = Math.min(nAnchorColKeyIndex, nTargetColKeyIndex);
-                            endIndex = Math.max(nAnchorColKeyIndex, nTargetColKeyIndex);
-                            
-                            // Select all cells from startIndex to endIndex on rows between anchor row and target row
-                            for(i=nAnchorTrIndex; i<=nTargetTrIndex; i++) {
-                                for(j=startIndex; j<=endIndex; j++) {
-                                    this.selectCell(allRows[i].cells[j]);
-                                }
-                            }
-                        }
-                    }
-                    // Anchor row is below target row
-                    else {
-                        if(sMode == "cellrange") {
-                            // Select all cells on target row from target cell to the end of the row
-                            for(i=nTargetColKeyIndex; i<allRows[nTargetTrIndex].cells.length; i++) {
-                                this.selectCell(allRows[nTargetTrIndex].cells[i]);
-                            }
-
-                            // Select all cells on all rows between target row and anchor row
-                            for(i=nTargetTrIndex+1; i<nAnchorTrIndex; i++) {
-                                for(j=0; j<allRows[i].cells.length; j++){
-                                    this.selectCell(allRows[i].cells[j]);
-                                }
-                            }
-
-                            // Select all cells on anchor row from first cell to the anchor cell
-                            for(i=0; i<nAnchorColKeyIndex; i++) {
-                                this.selectCell(allRows[nAnchorTrIndex].cells[i]);
-                            }
-                        }
-                        else if(sMode == "cellblock") {
-                            startIndex = Math.min(nAnchorTrIndex, nTargetColKeyIndex);
-                            endIndex = Math.max(nAnchorTrIndex, nTargetColKeyIndex);
-
-                            // Select all cells from startIndex to endIndex on rows between target row and anchor row
-                            for(i=nAnchorTrIndex; i>=nTargetTrIndex; i--) {
-                                for(j=endIndex; j>=startIndex; j--) {
-                                    this.selectCell(allRows[i].cells[j]);
-                                }
-                            }
-                        }
-                    }
-                }
-                // Anchor cell is unselected
-                else {
-                    // All cells are on the same row
-                    if(nAnchorRecordIndex === nTargetRecordIndex) {
-                        // Unselect all cells between anchor cell and target cell
-                        if(nAnchorColKeyIndex < nTargetColKeyIndex) {
-                            for(i=nAnchorColKeyIndex+1; i<nTargetColKeyIndex; i++) {
-                                this.unselectCell(allRows[nTargetTrIndex].cells[i]);
-                            }
-                        }
-                        // Select all cells between target cell and anchor cell
-                        else if(nTargetColKeyIndex < nAnchorColKeyIndex) {
-                            for(i=nTargetColKeyIndex+1; i<nAnchorColKeyIndex; i++) {
-                                this.unselectCell(allRows[nTargetTrIndex].cells[i]);
-                            }
-                        }
-                    }
-                    // Anchor row is above target row
-                    if(nAnchorRecordIndex < nTargetRecordIndex) {
-                        // Unselect all cells from anchor cell to target cell
-                        for(i=nAnchorTrIndex; i<=nTargetTrIndex; i++) {
-                            currentRow = allRows[i];
-                            for(j=0; j<currentRow.cells.length; j++) {
-                                // This is the anchor row, only unselect cells after the anchor cell
-                                if(currentRow.sectionRowIndex === nAnchorTrIndex) {
-                                    if(j>nAnchorColKeyIndex) {
-                                        this.unselectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // This is the target row, only unelect cells before the target cell
-                                else if(currentRow.sectionRowIndex === nTargetTrIndex) {
-                                    if(j<nTargetColKeyIndex) {
-                                        this.unselectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // Unselect all cells on this row
-                                else {
-                                    this.unselectCell(currentRow.cells[j]);
-                                }
-                            }
-                        }
-                    }
-                    // Anchor row is below target row
-                    else {
-                        // Unselect all cells from target cell to anchor cell
-                        for(i=nTargetTrIndex; i<=nAnchorTrIndex; i++) {
-                            currentRow = allRows[i];
-                            for(j=0; j<currentRow.cells.length; j++) {
-                                // This is the target row, only unselect cells after the target cell
-                                if(currentRow.sectionRowIndex == nTargetTrIndex) {
-                                    if(j>nTargetColKeyIndex) {
-                                        this.unselectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // This is the anchor row, only unselect cells before the anchor cell
-                                else if(currentRow.sectionRowIndex == nAnchorTrIndex) {
-                                    if(j<nAnchorColKeyIndex) {
-                                        this.unselectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // Unselect all cells on this row
-                                else {
-                                    this.unselectCell(currentRow.cells[j]);
-                                }
-                            }
-                        }
-                    }
-
-                    // Select the target cell
-                    this.selectCell(elTargetCell);
-                }
-            }
-            // Invalid anchor
-            else {
-                // Set anchor
-                this._oAnchorCell = oTargetCell;
-
-                // Toggle selection of target
-                if(this.isSelected(oTargetCell)) {
-                    this.unselectCell(oTargetCell);
-                }
-                else {
-                    this.selectCell(oTargetCell);
-                }
-            }
-        }
-        // Only SHIFT
-        else if((sMode != "singlecell") && bSHIFT) {
-            this.unselectAllCells();
-
-            // Validate anchor
-            if(oAnchorCell) {
-                // All cells are on the same row
-                if(nAnchorRecordIndex === nTargetRecordIndex) {
-                    // Select all cells between anchor cell and target cell,
-                    // including the anchor cell and target cell
-                    if(nAnchorColKeyIndex < nTargetColKeyIndex) {
-                        for(i=nAnchorColKeyIndex; i<=nTargetColKeyIndex; i++) {
-                            this.selectCell(allRows[nTargetTrIndex].cells[i]);
-                        }
-                    }
-                    // Select all cells between target cell and anchor cell
-                    // including the target cell and anchor cell
-                    else if(nTargetColKeyIndex < nAnchorColKeyIndex) {
-                        for(i=nTargetColKeyIndex; i<=nAnchorColKeyIndex; i++) {
-                            this.selectCell(allRows[nTargetTrIndex].cells[i]);
-                        }
-                    }
-                }
-                // Anchor row is above target row
-                else if(nAnchorRecordIndex < nTargetRecordIndex) {
-                    if(sMode == "cellrange") {
-                        // Select all cells from anchor cell to target cell
-                        // including the anchor cell and target cell
-                        for(i=nAnchorTrIndex; i<=nTargetTrIndex; i++) {
-                            currentRow = allRows[i];
-                            for(j=0; j<currentRow.cells.length; j++) {
-                                // This is the anchor row, only select the anchor cell and after
-                                if(currentRow.sectionRowIndex == nAnchorTrIndex) {
-                                    if(j>=nAnchorColKeyIndex) {
-                                        this.selectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // This is the target row, only select the target cell and before
-                                else if(currentRow.sectionRowIndex == nTargetTrIndex) {
-                                    if(j<=nTargetColKeyIndex) {
-                                        this.selectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // Select all cells on this row
-                                else {
-                                    this.selectCell(currentRow.cells[j]);
-                                }
-                            }
-                        }
-                    }
-                    else if(sMode == "cellblock") {
-                        // Select the cellblock from anchor cell to target cell
-                        // including the anchor cell and the target cell
-                        startIndex = Math.min(nAnchorColKeyIndex, nTargetColKeyIndex);
-                        endIndex = Math.max(nAnchorColKeyIndex, nTargetColKeyIndex);
-
-                        for(i=nAnchorTrIndex; i<=nTargetTrIndex; i++) {
-                            for(j=startIndex; j<=endIndex; j++) {
-                                this.selectCell(allRows[i].cells[j]);
-                            }
-                        }
-                    }
-                }
-                // Anchor row is below target row
-                else {
-                    if(sMode == "cellrange") {
-                        // Select all cells from target cell to anchor cell,
-                        // including the target cell and anchor cell
-                        for(i=nTargetTrIndex; i<=nAnchorTrIndex; i++) {
-                            currentRow = allRows[i];
-                            for(j=0; j<currentRow.cells.length; j++) {
-                                // This is the target row, only select the target cell and after
-                                if(currentRow.sectionRowIndex == nTargetTrIndex) {
-                                    if(j>=nTargetColKeyIndex) {
-                                        this.selectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // This is the anchor row, only select the anchor cell and before
-                                else if(currentRow.sectionRowIndex == nAnchorTrIndex) {
-                                    if(j<=nAnchorColKeyIndex) {
-                                        this.selectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // Select all cells on this row
-                                else {
-                                    this.selectCell(currentRow.cells[j]);
-                                }
-                            }
-                        }
-                    }
-                    else if(sMode == "cellblock") {
-                        // Select the cellblock from target cell to anchor cell
-                        // including the target cell and the anchor cell
-                        startIndex = Math.min(nAnchorColKeyIndex, nTargetColKeyIndex);
-                        endIndex = Math.max(nAnchorColKeyIndex, nTargetColKeyIndex);
-
-                        for(i=nTargetTrIndex; i<=nAnchorTrIndex; i++) {
-                            for(j=startIndex; j<=endIndex; j++) {
-                                this.selectCell(allRows[i].cells[j]);
-                            }
-                        }
-                    }
-                }
-            }
-            // Invalid anchor
-            else {
-                // Set anchor
-                this._oAnchorCell = oTargetCell;
-
-                // Select target only
-                this.selectCell(oTargetCell);
-            }
-        }
-        // Only CTRL
-        else if((sMode != "singlecell") && bCTRL) {
-            // Set anchor
-            this._oAnchorCell = oTargetCell;
-
-            // Toggle selection of target
-            if(this.isSelected(oTargetCell)) {
-                this.unselectCell(oTargetCell);
-            }
-            else {
-                this.selectCell(oTargetCell);
-            }
-        }
-        // Neither SHIFT nor CTRL, or multi-selection has been disabled
-        else {
-            // Set anchor
-            this._oAnchorCell = oTargetCell;
-
-            // Select only target
-            this.unselectAllCells();
-            this.selectCell(oTargetCell);
-        }
-
-        // Clear any selections that are a byproduct of the click or dblclick
-        var sel;
-        if(window.getSelection) {
-        	sel = window.getSelection();
-        }
-        else if(document.getSelection) {
-        	sel = document.getSelection();
-        }
-        else if(document.selection) {
-        	sel = document.selection;
-        }
-        if(sel) {
-            if(sel.empty) {
-                sel.empty();
-            }
-            else if (sel.removeAllRanges) {
-                sel.removeAllRanges();
-            }
-            else if(sel.collapse) {
-                sel.collapse();
-            }
-        }
+    else if(sMode == "cellrange") {
+        this._handleCellRangeSelectionByMouse(oArgs);
     }
     else {
-        YAHOO.log("Could not select cell " + elTarget, "warn", this.toString());
+        this._handleSingleCellSelectionByMouse(oArgs);
     }
-};
+},
 
-
-
-
-
-
-
-
-
-
-
 /**
- * Overridable custom event handler to highlight row.
+ * Overridable custom event handler to highlight row. Accounts for spurious
+ * caused-by-child events. 
  *
  * @method onEventHighlightRow
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventHighlightRow = function(oArgs) {
-    var evt = oArgs.event;
-    var elTarget = oArgs.target;
-    this.highlightRow(elTarget);
-};
+onEventHighlightRow : function(oArgs) {
+    //TODO: filter for all spurious events at a lower level
+    if(!Dom.isAncestor(oArgs.target,Ev.getRelatedTarget(oArgs.event))) {
+        this.highlightRow(oArgs.target);
+    }
+},
 
 /**
- * Overridable custom event handler to unhighlight row.
+ * Overridable custom event handler to unhighlight row. Accounts for spurious
+ * caused-by-child events. 
  *
  * @method onEventUnhighlightRow
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventUnhighlightRow = function(oArgs) {
-    var evt = oArgs.event;
-    var elTarget = oArgs.target;
-    this.unhighlightRow(elTarget);
-};
+onEventUnhighlightRow : function(oArgs) {
+    //TODO: filter for all spurious events at a lower level
+    if(!Dom.isAncestor(oArgs.target,Ev.getRelatedTarget(oArgs.event))) {
+        this.unhighlightRow(oArgs.target);
+    }
+},
 
 /**
- * Overridable custom event handler to highlight cell.
+ * Overridable custom event handler to highlight cell. Accounts for spurious
+ * caused-by-child events. 
  *
  * @method onEventHighlightCell
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventHighlightCell = function(oArgs) {
-    var evt = oArgs.event;
-    var elTarget = oArgs.target;
-    this.highlightCell(elTarget);
-};
+onEventHighlightCell : function(oArgs) {
+    //TODO: filter for all spurious events at a lower level
+    if(!Dom.isAncestor(oArgs.target,Ev.getRelatedTarget(oArgs.event))) {
+        this.highlightCell(oArgs.target);
+    }
+},
 
 /**
- * Overridable custom event handler to unhighlight cell.
+ * Overridable custom event handler to unhighlight cell. Accounts for spurious
+ * caused-by-child events. 
  *
  * @method onEventUnhighlightCell
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventUnhighlightCell = function(oArgs) {
-    var evt = oArgs.event;
-    var elTarget = oArgs.target;
-    this.unhighlightCell(elTarget);
-};
+onEventUnhighlightCell : function(oArgs) {
+    //TODO: filter for all spurious events at a lower level
+    if(!Dom.isAncestor(oArgs.target,Ev.getRelatedTarget(oArgs.event))) {
+        this.unhighlightCell(oArgs.target);
+    }
+},
 
 /**
  * Overridable custom event handler to format cell.
@@ -7183,20 +13909,18 @@
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventFormatCell = function(oArgs) {
-    var evt = oArgs.event;
+onEventFormatCell : function(oArgs) {
     var target = oArgs.target;
-    var elTag = target.tagName.toLowerCase();
 
     var elCell = this.getTdEl(target);
     if(elCell && elCell.yuiColumnKey) {
         var oColumn = this.getColumn(elCell.yuiColumnKey);
-        this.formatCell(elCell, this.getRecord(elCell), oColumn);
+        this.formatCell(elCell.firstChild, this.getRecord(elCell), oColumn);
     }
     else {
         YAHOO.log("Could not format cell " + target, "warn", this.toString());
     }
-};
+},
 
 /**
  * Overridable custom event handler to edit cell.
@@ -7205,10 +13929,8 @@
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventShowCellEditor = function(oArgs) {
-    var evt = oArgs.event;
+onEventShowCellEditor : function(oArgs) {
     var target = oArgs.target;
-    var elTag = target.tagName.toLowerCase();
 
     var elCell = this.getTdEl(target);
     if(elCell) {
@@ -7217,13 +13939,7 @@
     else {
         YAHOO.log("Could not edit cell " + target, "warn", this.toString());
     }
-};
-// Backward compatibility
-YAHOO.widget.DataTable.prototype.onEventEditCell = function(oArgs) {
-    YAHOO.log("The method onEventEditCell() has been deprecated" +
-        " in favor of onEventShowCellEditor()", "warn", this.toString());
-    this.onEventShowCellEditor(oArgs);
-};
+},
 
 /**
  * Overridable custom event handler to save Cell Editor input.
@@ -7231,59 +13947,20 @@
  * @method onEventSaveCellEditor
  * @param oArgs.editor {Object} Cell Editor object literal.
  */
-YAHOO.widget.DataTable.prototype.onEventSaveCellEditor = function(oArgs) {
+onEventSaveCellEditor : function(oArgs) {
     this.saveCellEditor();
-};
+},
 
 /**
- * Callback function for creating a progressively enhanced DataTable first
- * receives data from DataSource and populates the RecordSet, then initializes
- * DOM elements.
+ * Overridable custom event handler to cancel Cell Editor.
  *
- * @method _onDataReturnEnhanceTable
- * @param sRequest {String} Original request.
- * @param oResponse {Object} Response object.
- * @param bError {Boolean} (optional) True if there was a data error.
- * @private
+ * @method onEventCancelCellEditor
+ * @param oArgs.editor {Object} Cell Editor object literal.
  */
-YAHOO.widget.DataTable.prototype._onDataReturnEnhanceTable = function(sRequest, oResponse) {
-    // Pass data through abstract method for any transformations
-    var ok = this.doBeforeLoadData(sRequest, oResponse);
+onEventCancelCellEditor : function(oArgs) {
+    this.cancelCellEditor();
+},
 
-    // Data ok to populate
-    if(ok && oResponse && !oResponse.error && YAHOO.lang.isArray(oResponse.results)) {
-        // Update RecordSet
-        this._oRecordSet.addRecords(oResponse.results);
-
-        // Initialize DOM elements
-        this._initTableEl();
-        if(!this._elTable || !this._elThead || !this._elTbody) {
-            YAHOO.log("Could not instantiate DataTable due to an invalid DOM elements", "error", this.toString());
-            return;
-        }
-
-        // Call Element's constructor after DOM elements are created
-        // but *before* UI is updated with data
-        YAHOO.widget.DataTable.superclass.constructor.call(this, this._elContainer, this._oConfigs);
-
-        //HACK: Set the Paginator values
-        if(this._oConfigs.paginator) {
-            this.updatePaginator(this._oConfigs.paginator);
-        }
-
-        // Update the UI
-        this.refreshView();
-    }
-    // Error
-    else if(ok && oResponse.error) {
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_ERROR, YAHOO.widget.DataTable.CLASS_ERROR);
-    }
-    // Empty
-    else if(ok){
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_EMPTY, YAHOO.widget.DataTable.CLASS_EMPTY);
-    }
-};
-    
 /**
  * Callback function receives data from DataSource and populates an entire
  * DataTable with Records and TR elements, clearing previous Records, if any.
@@ -7291,34 +13968,14 @@
  * @method onDataReturnInitializeTable
  * @param sRequest {String} Original request.
  * @param oResponse {Object} Response object.
- * @param bError {Boolean} (optional) True if there was a data error.
+ * @param oPayload {MIXED} (optional) Additional argument(s)
  */
-YAHOO.widget.DataTable.prototype.onDataReturnInitializeTable = function(sRequest, oResponse) {
-    this.fireEvent("dataReturnEvent", {request:sRequest,response:oResponse});
+onDataReturnInitializeTable : function(sRequest, oResponse, oPayload) {
+    this.initializeTable();
 
-    // Pass data through abstract method for any transformations
-    var ok = this.doBeforeLoadData(sRequest, oResponse);
+    this.onDataReturnSetRows(sRequest,oResponse,oPayload);
+},
 
-    // Data ok to populate
-    if(ok && oResponse && !oResponse.error && YAHOO.lang.isArray(oResponse.results)) {
-        this.initializeTable(oResponse.results);
-    }
-    // Error
-    else if(ok && oResponse.error) {
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_ERROR, YAHOO.widget.DataTable.CLASS_ERROR);
-    }
-    // Empty
-    else if(ok){
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_EMPTY, YAHOO.widget.DataTable.CLASS_EMPTY);
-    }
-};
-// Backward compatibility
-YAHOO.widget.DataTable.prototype.onDataReturnReplaceRows = function(sRequest, oResponse) {
-    YAHOO.log("The method onDataReturnReplaceRows() has been deprecated" +
-            " in favor of onDataReturnInitializeTable()", "warn", this.toString());
-    this.onDataReturnInitializeTable(sRequest, oResponse);
-};
-
 /**
  * Callback function receives data from DataSource and appends to an existing
  * DataTable new Records and, if applicable, creates or updates
@@ -7327,64 +13984,203 @@
  * @method onDataReturnAppendRows
  * @param sRequest {String} Original request.
  * @param oResponse {Object} Response object.
- * @param bError {Boolean} (optional) True if there was a data error.
+ * @param oPayload {MIXED} (optional) Additional argument(s)
  */
-YAHOO.widget.DataTable.prototype.onDataReturnAppendRows = function(sRequest, oResponse) {
-    this.fireEvent("dataReturnEvent", {request:sRequest,response:oResponse});
-    
+onDataReturnAppendRows : function(sRequest, oResponse, oPayload) {
+    this.fireEvent("dataReturnEvent", {request:sRequest,response:oResponse,payload:oPayload});
+
     // Pass data through abstract method for any transformations
-    var ok = this.doBeforeLoadData(sRequest, oResponse);
-    
+    var ok = this.doBeforeLoadData(sRequest, oResponse, oPayload);
+
     // Data ok to append
-    if(ok && oResponse && !oResponse.error && YAHOO.lang.isArray(oResponse.results)) {
+    if(ok && oResponse && !oResponse.error && lang.isArray(oResponse.results)) {
+
         this.addRows(oResponse.results);
+
+        // Handle the meta && payload
+        this._handleDataReturnPayload(sRequest, oResponse,
+            this._mergeResponseMeta(oPayload, oResponse.meta));
+
+        // Default the Paginator's totalRecords from the RecordSet length
+        var oPaginator = this.get('paginator');
+        if (oPaginator && oPaginator instanceof Pag &&
+            oPaginator.get('totalRecords') < this._oRecordSet.getLength()) {
+            oPaginator.set('totalRecords',this._oRecordSet.getLength());
+        }
     }
     // Error
     else if(ok && oResponse.error) {
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_ERROR, YAHOO.widget.DataTable.CLASS_ERROR);
+        this.showTableMessage(DT.MSG_ERROR, DT.CLASS_ERROR);
     }
-};
+},
 
 /**
- * Callback function receives data from DataSource and inserts into top of an
- * existing DataTable new Records and, if applicable, creates or updates
- * corresponding TR elements.
+ * Callback function receives data from DataSource and inserts new records
+ * starting at the index specified in oPayload.insertIndex.  If applicable,
+ * creates or updates corresponding TR elements.
  *
  * @method onDataReturnInsertRows
  * @param sRequest {String} Original request.
  * @param oResponse {Object} Response object.
- * @param bError {Boolean} (optional) True if there was a data error.
+ * @param oPayload {MIXED} (optional) Additional argument(s)
  */
-YAHOO.widget.DataTable.prototype.onDataReturnInsertRows = function(sRequest, oResponse) {
-    this.fireEvent("dataReturnEvent", {request:sRequest,response:oResponse});
-    
+onDataReturnInsertRows : function(sRequest, oResponse, oPayload) {
+    this.fireEvent("dataReturnEvent", {request:sRequest,response:oResponse,payload:oPayload});
+
     // Pass data through abstract method for any transformations
-    var ok = this.doBeforeLoadData(sRequest, oResponse);
-    
+    var ok = this.doBeforeLoadData(sRequest, oResponse, oPayload);
+
     // Data ok to append
-    if(ok && oResponse && !oResponse.error && YAHOO.lang.isArray(oResponse.results)) {
-        this.addRows(oResponse.results, 0);
+    if(ok && oResponse && !oResponse.error && lang.isArray(oResponse.results)) {
+        var meta = this._mergeResponseMeta({
+                // backward compatibility
+                recordInsertIndex: (oPayload ? oPayload.insertIndex || 0 : 0) },
+                oPayload, oResponse.meta);
+
+        this.addRows(oResponse.results, meta.insertIndex);
+
+        // Handle the magic meta values
+        this._handleDataReturnPayload(sRequest,oResponse,meta);
+
+        // Default the Paginator's totalRecords from the RecordSet length
+        var oPaginator = this.get('paginator');
+        if (oPaginator && oPaginator instanceof Pag &&
+            oPaginator.get('totalRecords') < this._oRecordSet.getLength()) {
+            oPaginator.set('totalRecords',this._oRecordSet.getLength());
+        }
     }
     // Error
     else if(ok && oResponse.error) {
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_ERROR, YAHOO.widget.DataTable.CLASS_ERROR);
+        this.showTableMessage(DT.MSG_ERROR, DT.CLASS_ERROR);
     }
-};
+},
 
+/**
+ * Receives reponse from DataSource and populates the RecordSet with the
+ * results.
+ * @method onDataReturnSetRows
+ * @param oRequest {MIXED} Original generated request.
+ * @param oResponse {Object} Response object.
+ * @param oPayload {MIXED} (optional) Additional argument(s)
+ */
+onDataReturnSetRows : function(oRequest, oResponse, oPayload) {
+    this.fireEvent("dataReturnEvent", {request:oRequest,response:oResponse,payload:oPayload});
 
+    // Pass data through abstract method for any transformations
+    var ok = this.doBeforeLoadData(oRequest, oResponse, oPayload);
 
+    // Data ok to set
+    if(ok && oResponse && !oResponse.error && lang.isArray(oResponse.results)) {
+        var oPaginator = this.get('paginator');
+        if (!(oPaginator instanceof Pag)) {
+            oPaginator = null;
+        }
 
+        var meta = this._mergeResponseMeta({
+                // backward compatibility
+                recordStartIndex: oPayload ? oPayload.startIndex : null },
+                oPayload, oResponse.meta);
 
+        if (!lang.isNumber(meta.recordStartIndex)) {
+            // Default to the current page offset if paginating; 0 if not.
+            meta.recordStartIndex = oPaginator && meta.pagination ?
+                meta.pagination.recordOffset || 0 : 0;
+        }
 
+        this._oRecordSet.setRecords(oResponse.results, meta.recordStartIndex);
 
+        // Handle the magic meta values
+        this._handleDataReturnPayload(oRequest,oResponse,meta);
 
+        // Default the Paginator's totalRecords from the RecordSet length
+        if (oPaginator && oPaginator.get('totalRecords') < this._oRecordSet.getLength()) {
+            oPaginator.set('totalRecords',this._oRecordSet.getLength());
+        }
 
+        this.render();
+    }
+    // Error
+    else if(ok && oResponse.error) {
+        this.showTableMessage(DT.MSG_ERROR, DT.CLASS_ERROR);
+    }
+},
 
+/**
+ * Merges meta information from the response (as defined in the DataSource's
+ * responseSchema.metaFields member) into the payload.  A few magic keys are
+ * given special treatment: sortKey and sortDir => sorting.key|dir and all
+ * keys paginationFoo => pagination.foo.  Merging is shallow with the exception
+ * of the magic keys being added to their respective nested objects.
+ *
+ * @method _mergeResponseMeta
+ * @param * {object} Any number of objects to merge together.  Last in wins.
+ * @return {object} A new object containing the combined keys of all objects.
+ * @private
+ */
+_mergeResponseMeta : function () {
+    var meta = {},
+        a = arguments,
+        i = 0,len = a.length,
+        k,o;
 
+    for (; i < len; ++i) {
+        o = a[i];
+        if (lang.isObject(o)) {
+            for (k in o) {
+                if (lang.hasOwnProperty(o,k)) {
+                    if (k.indexOf('pagination') === 0 && k.charAt(10)) {
+                        if (!meta.pagination) {
+                            meta.pagination = {};
+                        }
+                        meta.pagination[k.substr(10,1).toLowerCase()+k.substr(11)] = o[k];
+                    } else if (/^sort(Key|Dir)/.test(k)) {
+                        if (!meta.sorting) {
+                            var curSort = this.get('sortedBy');
+                            meta.sorting = curSort ? { key : curSort.key } : {};
+                        }
+                        meta.sorting[RegExp.$1.toLowerCase()] = o[k];
+                    } else {
+                        meta[k] = o[k];
+                    }
+                }
+            }
+        }
+    }
 
+    return meta;
+},
 
+/**
+ * Updates the DataTable with data sent in an onDataReturn* payload
+ * @method _handleDataReturnPayload
+ * @param oRequest {MIXED} Original generated request.
+ * @param oResponse {Object} Response object.
+ * @param meta {MIXED} Argument(s) provided in payload or response meta
+ * @private
+ */
+_handleDataReturnPayload : function (oRequest, oResponse, meta) {
+    if (meta) {
+        // Update with any pagination information
+        var oPaginator = this.get('paginator');
+        if (oPaginator instanceof Pag) {
+            if (!lang.isUndefined(meta.totalRecords)) {
+                oPaginator.set('totalRecords',parseInt(meta.totalRecords,10)|0);
+            }
 
+            if (lang.isObject(meta.pagination)) {
+                // Set the paginator values in preparation for refresh
+                oPaginator.set('rowsPerPage',meta.pagination.rowsPerPage);
+                oPaginator.set('recordOffset',meta.pagination.recordOffset);
+            }
+        }
 
+        // Update with any sorting information
+        if (meta.sorting) {
+            // Set the sorting values in preparation for refresh
+            this.set('sortedBy', meta.sorting);
+        }
+    }
+},
 
 
 
@@ -7405,6 +14201,19 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
     /////////////////////////////////////////////////////////////////////////////
     //
     // Custom Events
@@ -7418,9 +14227,9 @@
      */
 
     /**
-     * Fired when the DataTable's view is refreshed.
+     * Fired when the DataTable's view is rendered.
      *
-     * @event refreshEvent
+     * @event renderEvent
      */
 
     /**
@@ -7433,18 +14242,66 @@
      */
 
     /**
-     * Fired when the DataTable has a focus.
+     * Fired when the DataTable has a focus event.
      *
      * @event tableFocusEvent
      */
 
     /**
-     * Fired when the DataTable has a blur.
+     * Fired when the DataTable THEAD element has a focus event.
      *
+     * @event theadFocusEvent
+     */
+
+    /**
+     * Fired when the DataTable TBODY element has a focus event.
+     *
+     * @event tbodyFocusEvent
+     */
+
+    /**
+     * Fired when the DataTable has a blur event.
+     *
      * @event tableBlurEvent
      */
 
+    /*TODO
+     * Fired when the DataTable THEAD element has a blur event.
+     *
+     * @event theadBlurEvent
+     */
+
+    /*TODO
+     * Fired when the DataTable TBODY element has a blur event.
+     *
+     * @event tbodyBlurEvent
+     */
+
     /**
+     * Fired when the DataTable has a key event.
+     *
+     * @event tableKeyEvent
+     * @param oArgs.event {HTMLEvent} The event object.
+     * @param oArgs.target {HTMLElement} The DataTable's TABLE element.
+     */
+
+    /**
+     * Fired when the DataTable THEAD element has a key event.
+     *
+     * @event theadKeyEvent
+     * @param oArgs.event {HTMLEvent} The event object.
+     * @param oArgs.target {HTMLElement} The DataTable's TABLE element.
+     */
+
+    /**
+     * Fired when the DataTable TBODY element has a key event.
+     *
+     * @event tbodyKeyEvent
+     * @param oArgs.event {HTMLEvent} The event object.
+     * @param oArgs.target {HTMLElement} The DataTable's TABLE element.
+     */
+
+    /**
      * Fired when the DataTable has a mouseover.
      *
      * @event tableMouseoverEvent
@@ -7515,125 +14372,125 @@
      */
 
     /**
-     * Fired when a header row has a mouseover.
+     * Fired when a THEAD row has a mouseover.
      *
-     * @event headerRowMouseoverEvent
+     * @event theadRowMouseoverEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TR element.
      */
 
     /**
-     * Fired when a header row has a mouseout.
+     * Fired when a THEAD row has a mouseout.
      *
-     * @event headerRowMouseoutEvent
+     * @event theadRowMouseoutEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TR element.
      */
 
     /**
-     * Fired when a header row has a mousedown.
+     * Fired when a THEAD row has a mousedown.
      *
-     * @event headerRowMousedownEvent
+     * @event theadRowMousedownEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TR element.
      */
 
     /**
-     * Fired when a header row has a click.
+     * Fired when a THEAD row has a click.
      *
-     * @event headerRowClickEvent
+     * @event theadRowClickEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TR element.
      */
 
     /**
-     * Fired when a header row has a dblclick.
+     * Fired when a THEAD row has a dblclick.
      *
-     * @event headerRowDblclickEvent
+     * @event theadRowDblclickEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TR element.
      */
 
     /**
-     * Fired when a header cell has a mouseover.
+     * Fired when a THEAD cell has a mouseover.
      *
-     * @event headerCellMouseoverEvent
+     * @event theadCellMouseoverEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TH element.
      *
      */
 
     /**
-     * Fired when a header cell has a mouseout.
+     * Fired when a THEAD cell has a mouseout.
      *
-     * @event headerCellMouseoutEvent
+     * @event theadCellMouseoutEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TH element.
      *
      */
 
     /**
-     * Fired when a header cell has a mousedown.
+     * Fired when a THEAD cell has a mousedown.
      *
-     * @event headerCellMousedownEvent
+     * @event theadCellMousedownEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TH element.
      */
 
     /**
-     * Fired when a header cell has a click.
+     * Fired when a THEAD cell has a click.
      *
-     * @event headerCellClickEvent
+     * @event theadCellClickEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TH element.
      */
 
     /**
-     * Fired when a header cell has a dblclick.
+     * Fired when a THEAD cell has a dblclick.
      *
-     * @event headerCellDblclickEvent
+     * @event theadCellDblclickEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TH element.
      */
 
     /**
-     * Fired when a header label has a mouseover.
+     * Fired when a THEAD label has a mouseover.
      *
-     * @event headerLabelMouseoverEvent
+     * @event theadLabelMouseoverEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The SPAN element.
      *
      */
 
     /**
-     * Fired when a header label has a mouseout.
+     * Fired when a THEAD label has a mouseout.
      *
-     * @event headerLabelMouseoutEvent
+     * @event theadLabelMouseoutEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The SPAN element.
      *
      */
 
     /**
-     * Fired when a header label has a mousedown.
+     * Fired when a THEAD label has a mousedown.
      *
-     * @event headerLabelMousedownEvent
+     * @event theadLabelMousedownEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The SPAN element.
      */
 
     /**
-     * Fired when a header label has a click.
+     * Fired when a THEAD label has a click.
      *
-     * @event headerLabelClickEvent
+     * @event theadLabelClickEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The SPAN element.
      */
 
     /**
-     * Fired when a header label has a dblclick.
+     * Fired when a THEAD label has a dblclick.
      *
-     * @event headerLabelDblclickEvent
+     * @event theadLabelDblclickEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The SPAN element.
      */
@@ -7643,18 +14500,91 @@
      *
      * @event columnSortEvent
      * @param oArgs.column {YAHOO.widget.Column} The Column instance.
-     * @param oArgs.dir {String} Sort direction "asc" or "desc".
+     * @param oArgs.dir {String} Sort direction: YAHOO.widget.DataTable.CLASS_ASC
+     * or YAHOO.widget.DataTable.CLASS_DESC.
      */
 
     /**
-     * Fired when a column is resized.
+     * Fired when a column width is set.
      *
+     * @event columnSetWidthEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     * @param oArgs.width {Number} The width in pixels.
+     */
+
+    /**
+     * Fired when a column is drag-resized.
+     *
      * @event columnResizeEvent
      * @param oArgs.column {YAHOO.widget.Column} The Column instance.
      * @param oArgs.target {HTMLElement} The TH element.
+     * @param oArgs.width {Number} Width in pixels.     
      */
 
     /**
+     * Fired when a ColumnSet is re-initialized due to a Column being drag-reordered.
+     *
+     * @event columnReorderEvent
+     */
+
+    /**
+     * Fired when a column is hidden.
+     *
+     * @event columnHideEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     */
+
+    /**
+     * Fired when a column is shown.
+     *
+     * @event columnShowEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     */
+
+    /**
+     * Fired when a column is selected.
+     *
+     * @event columnSelectEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     */
+
+    /**
+     * Fired when a column is unselected.
+     *
+     * @event columnUnselectEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     */
+    /**
+     * Fired when a column is removed.
+     *
+     * @event columnRemoveEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     */
+
+    /**
+     * Fired when a column is inserted.
+     *
+     * @event columnInsertEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     * @param oArgs.index {Number} The index position.
+     */
+
+    /**
+     * Fired when a column is highlighted.
+     *
+     * @event columnHighlightEvent
+     * @param oArgs.column {YAHOO.widget.Column} The highlighted Column.
+     */
+
+    /**
+     * Fired when a column is unhighlighted.
+     *
+     * @event columnUnhighlightEvent
+     * @param oArgs.column {YAHOO.widget.Column} The unhighlighted Column.
+     */
+
+
+    /**
      * Fired when a row has a mouseover.
      *
      * @event rowMouseoverEvent
@@ -7700,6 +14630,13 @@
      * @event rowAddEvent
      * @param oArgs.record {YAHOO.widget.Record} The added Record.
      */
+     
+    /**
+     * Fired when rows are added.
+     *
+     * @event rowsAddEvent
+     * @param oArgs.record {YAHOO.widget.Record[]} The added Records.
+     */
 
     /**
      * Fired when a row is updated.
@@ -7717,6 +14654,15 @@
      * @param oArgs.recordIndex {Number} Index of the deleted Record.
      * @param oArgs.trElIndex {Number} Index of the deleted TR element, if on current page.
      */
+     
+    /**
+     * Fired when rows are deleted.
+     *
+     * @event rowsDeleteEvent
+     * @param oArgs.oldData {Object[]} Array of object literals of the deleted data.
+     * @param oArgs.recordIndex {Number} Index of the first deleted Record.
+     * @param oArgs.count {Number} Number of deleted Records.
+     */
 
     /**
      * Fired when a row is selected.
@@ -7734,13 +14680,13 @@
      * @param oArgs.record {YAHOO.widget.Record} The unselected Record.
      */
 
-    /*TODO: delete and use rowUnselectEvent?
+    /**
      * Fired when all row selections are cleared.
      *
      * @event unselectAllRowsEvent
      */
 
-    /*
+    /**
      * Fired when a row is highlighted.
      *
      * @event rowHighlightEvent
@@ -7748,7 +14694,7 @@
      * @param oArgs.record {YAHOO.widget.Record} The highlighted Record.
      */
 
-    /*
+    /**
      * Fired when a row is unhighlighted.
      *
      * @event rowUnhighlightEvent
@@ -7849,19 +14795,12 @@
 
      */
 
-    /*TODO: hide from doc and use cellUnselectEvent
+    /**
      * Fired when all cell selections are cleared.
      *
      * @event unselectAllCellsEvent
      */
 
-    /*TODO: implement
-     * Fired when DataTable paginator is updated.
-     *
-     * @event paginatorUpdateEvent
-     * @param paginator {Object} Object literal of Paginator values.
-     */
-
     /**
      * Fired when an Editor is activated.
      *
@@ -7882,7 +14821,7 @@
      *
      * @event editorRevertEvent
      * @param oArgs.editor {Object} The Editor object literal.
-     * @param oArgs.newData {Object} New data value.
+     * @param oArgs.newData {Object} New data value from form input field.
      * @param oArgs.oldData {Object} Old data value.
      */
 
@@ -7891,7 +14830,7 @@
      *
      * @event editorSaveEvent
      * @param oArgs.editor {Object} The Editor object literal.
-     * @param oArgs.newData {Object} New data value.
+     * @param oArgs.newData {Object} New data value from form input field.
      * @param oArgs.oldData {Object} Old data value.
      */
 
@@ -7956,1583 +14895,496 @@
      */
 
 
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
 
-/**
- * The ColumnSet class defines and manages a DataTable's Columns,
- * including nested hierarchies and access to individual Column instances.
- *
- * @namespace YAHOO.widget
- * @class ColumnSet
- * @uses YAHOO.util.EventProvider
- * @constructor
- * @param aHeaders {Object[]} Array of object literals that define header cells.
- */
-YAHOO.widget.ColumnSet = function(aHeaders) {
-    this._sName = "instance" + YAHOO.widget.ColumnSet._nCount;
 
-    // DOM tree representation of all Columns
-    var tree = [];
-    // Flat representation of all Columns
-    var flat = [];
-    // Flat representation of only Columns that are meant to display data
-    var keys = [];
-    // Array of HEADERS attribute values for all keys in the "keys" array
-    var headers = [];
 
-    // Tracks current node list depth being tracked
-    var nodeDepth = -1;
 
-    // Internal recursive function to defined Column instances
-    var oSelf = this;
-    var parseColumns = function(nodeList, parent) {
-        // One level down
-        nodeDepth++;
 
-        // Create corresponding tree node if not already there for this depth
-        if(!tree[nodeDepth]) {
-            tree[nodeDepth] = [];
-        }
 
 
-        // Parse each node at this depth for attributes and any children
-        for(var j=0; j<nodeList.length; j++) {
-            var currentNode = nodeList[j];
 
-            // Instantiate a new Column for each node
-            var oColumn = new YAHOO.widget.Column(currentNode);
-            oColumn._sId = YAHOO.widget.Column._nCount + "";
-            oColumn._sName = "Column instance" + YAHOO.widget.Column._nCount;
-            // Assign a key if not found
-            if(!YAHOO.lang.isValue(oColumn.key)) {
-                oColumn.key = "yui-dt-col" + YAHOO.widget.Column._nCount;
-            }
-            // Increment counter
-            YAHOO.widget.Column._nCount++;
 
-            // Add the new Column to the flat list
-            flat.push(oColumn);
 
-            // Assign its parent as an attribute, if applicable
-            if(parent) {
-                oColumn.parent = parent;
-            }
 
-            // The Column has descendants
-            if(YAHOO.lang.isArray(currentNode.children)) {
-                oColumn.children = currentNode.children;
 
-                // Determine COLSPAN value for this Column
-                var terminalChildNodes = 0;
-                var countTerminalChildNodes = function(ancestor) {
-                    var descendants = ancestor.children;
-                    // Drill down each branch and count terminal nodes
-                    for(var k=0; k<descendants.length; k++) {
-                        // Keep drilling down
-                        if(YAHOO.lang.isArray(descendants[k].children)) {
-                            countTerminalChildNodes(descendants[k]);
-                        }
-                        // Reached branch terminus
-                        else {
-                            terminalChildNodes++;
-                        }
-                    }
-                };
-                countTerminalChildNodes(currentNode);
-                oColumn._colspan = terminalChildNodes;
 
-                // Cascade certain properties to children if not defined on their own
-                var currentChildren = currentNode.children;
-                for(var k=0; k<currentChildren.length; k++) {
-                    var child = currentChildren[k];
-                    if(oColumn.className && (child.className === undefined)) {
-                        child.className = oColumn.className;
-                    }
-                    if(oColumn.editor && (child.editor === undefined)) {
-                        child.editor = oColumn.editor;
-                    }
-                    if(oColumn.editorOptions && (child.editorOptions === undefined)) {
-                        child.editorOptions = oColumn.editorOptions;
-                    }
-                    if(oColumn.formatter && (child.formatter === undefined)) {
-                        child.formatter = oColumn.formatter;
-                    }
-                    if(oColumn.resizeable && (child.resizeable === undefined)) {
-                        child.resizeable = oColumn.resizeable;
-                    }
-                    if(oColumn.sortable && (child.sortable === undefined)) {
-                        child.sortable = oColumn.sortable;
-                    }
-                    if(oColumn.width && (child.width === undefined)) {
-                        child.width = oColumn.width;
-                    }
-                    // Backward compatibility
-                    if(oColumn.type && (child.type === undefined)) {
-                        child.type = oColumn.type;
-                    }
-                    if(oColumn.type && !oColumn.formatter) {
-                        YAHOO.log("The property type has been" +
-                        " deprecated in favor of formatter", "warn", oColumn.toString());
-                        oColumn.formatter = oColumn.type;
-                    }
-                    if(oColumn.text && !YAHOO.lang.isValue(oColumn.label)) {
-                        YAHOO.log("The property text has been" +
-                        " deprecated in favor of label", "warn", oColumn.toString());
-                        oColumn.label = oColumn.text;
-                    }
-                    if(oColumn.parser) {
-                        YAHOO.log("The property parser is no longer supported",
-                        "warn", this.toString());
-                    }
-                    if(oColumn.sortOptions && ((oColumn.sortOptions.ascFunction) ||
-                            (oColumn.sortOptions.descFunction))) {
-                        YAHOO.log("The properties sortOptions.ascFunction and " +
-                        " sortOptions.descFunction have been deprecated in favor " +
-                        " of sortOptions.sortFunction", "warn", oColumn.toString());
-                    }
-                }
 
-                // The children themselves must also be parsed for Column instances
-                if(!tree[nodeDepth+1]) {
-                    tree[nodeDepth+1] = [];
-                }
-                parseColumns(currentChildren, oColumn);
-            }
-            // This Column does not have any children
-            else {
-                oColumn._nKeyIndex = keys.length;
-                oColumn._colspan = 1;
-                keys.push(oColumn);
-            }
 
-            // Add the Column to the top-down tree
-            tree[nodeDepth].push(oColumn);
-        }
-        nodeDepth--;
-    };
 
-    // Parse out Column instances from the array of object literals
-    if(YAHOO.lang.isArray(aHeaders)) {
-        parseColumns(aHeaders);
-    }
 
-    // Determine ROWSPAN value for each Column in the tree
-    var parseTreeForRowspan = function(tree) {
-        var maxRowDepth = 1;
-        var currentRow;
-        var currentColumn;
 
-        // Calculate the max depth of descendants for this row
-        var countMaxRowDepth = function(row, tmpRowDepth) {
-            tmpRowDepth = tmpRowDepth || 1;
 
-            for(var n=0; n<row.length; n++) {
-                var col = row[n];
-                // Column has children, so keep counting
-                if(YAHOO.lang.isArray(col.children)) {
-                    tmpRowDepth++;
-                    countMaxRowDepth(col.children, tmpRowDepth);
-                    tmpRowDepth--;
-                }
-                // No children, is it the max depth?
-                else {
-                    if(tmpRowDepth > maxRowDepth) {
-                        maxRowDepth = tmpRowDepth;
-                    }
-                }
 
-            }
-        };
 
-        // Count max row depth for each row
-        for(var m=0; m<tree.length; m++) {
-            currentRow = tree[m];
-            countMaxRowDepth(currentRow);
 
-            // Assign the right ROWSPAN values to each Column in the row
-            for(var p=0; p<currentRow.length; p++) {
-                currentColumn = currentRow[p];
-                if(!YAHOO.lang.isArray(currentColumn.children)) {
-                    currentColumn._rowspan = maxRowDepth;
-                }
-                else {
-                    currentColumn._rowspan = 1;
-                }
-            }
 
-            // Reset counter for next row
-            maxRowDepth = 1;
-        }
-    };
-    parseTreeForRowspan(tree);
 
-
-
-
-
-    // Store header relationships in an array for HEADERS attribute
-    var recurseAncestorsForHeaders = function(i, oColumn) {
-        headers[i].push(oColumn._sId);
-        if(oColumn.parent) {
-            recurseAncestorsForHeaders(i, oColumn.parent);
-        }
-    };
-    for(var i=0; i<keys.length; i++) {
-        headers[i] = [];
-        recurseAncestorsForHeaders(i, keys[i]);
-        headers[i] = headers[i].reverse();
-    }
-
-    // Save to the ColumnSet instance
-    this.tree = tree;
-    this.flat = flat;
-    this.keys = keys;
-    this.headers = headers;
-
-    YAHOO.widget.ColumnSet._nCount++;
-    YAHOO.log("ColumnSet initialized", "info", this.toString());
-};
-
 /////////////////////////////////////////////////////////////////////////////
 //
-// Public member variables
+// Deprecated APIs
 //
 /////////////////////////////////////////////////////////////////////////////
 
 /**
- * Internal class variable to index multiple ColumnSet instances.
- *
- * @property ColumnSet._nCount
- * @type Number
- * @private
- * @static
+ * @method getBody
+ * @deprecated Use getTbodyEl().
  */
-YAHOO.widget.ColumnSet._nCount = 0;
+getBody : function() {
+    // Backward compatibility
+    YAHOO.log("The method getBody() has been deprecated" +
+            " in favor of getTbodyEl()", "warn", this.toString());
+    return this.getTbodyEl();
+},
 
 /**
- * Unique instance name.
- *
- * @property _sName
- * @type String
- * @private
+ * @method getCell
+ * @deprecated Use getTdEl().
  */
-YAHOO.widget.ColumnSet.prototype._sName = null;
+getCell : function(index) {
+    // Backward compatibility
+    YAHOO.log("The method getCell() has been deprecated" +
+            " in favor of getTdEl()", "warn", this.toString());
+    return this.getTdEl(index);
+},
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public member variables
-//
-/////////////////////////////////////////////////////////////////////////////
-
 /**
- * Top-down tree representation of Column hierarchy.
- *
- * @property tree
- * @type YAHOO.widget.Column[]
+ * @method getRow
+ * @deprecated Use getTrEl().
  */
-YAHOO.widget.ColumnSet.prototype.tree = null;
+getRow : function(index) {
+    // Backward compatibility
+    YAHOO.log("The method getRow() has been deprecated" +
+            " in favor of getTrEl()", "warn", this.toString());
+    return this.getTrEl(index);
+},
 
 /**
- * Flattened representation of all Columns.
- *
- * @property flat
- * @type YAHOO.widget.Column[]
- * @default []
+ * @method refreshView
+ * @deprecated Use render.
  */
-YAHOO.widget.ColumnSet.prototype.flat = null;
+refreshView : function() {
+    // Backward compatibility
+    YAHOO.log("The method refreshView() has been deprecated" +
+            " in favor of render()", "warn", this.toString());
+    this.render();
+},
 
 /**
- * Array of Columns that map one-to-one to a table column.
- *
- * @property keys
- * @type YAHOO.widget.Column[]
- * @default []
+ * @method select
+ * @deprecated Use selectRow.
  */
-YAHOO.widget.ColumnSet.prototype.keys = null;
+select : function(els) {
+    // Backward compatibility
+    YAHOO.log("The method select() has been deprecated" +
+            " in favor of selectRow()", "warn", this.toString());
+    if(!lang.isArray(els)) {
+        els = [els];
+    }
+    for(var i=0; i<els.length; i++) {
+        this.selectRow(els[i]);
+    }
+},
 
 /**
- * ID index of nested parent hierarchies for HEADERS accessibility attribute.
- *
- * @property headers
- * @type String[]
- * @default []
+ * @method updatePaginator
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.widget.ColumnSet.prototype.headers = null;
+updatePaginator : function(oNewValues) {
+    // Complete the set (default if not present)
+    var oValidPaginator = this.get("paginator");
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public methods
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Public accessor to the unique name of the ColumnSet instance.
- *
- * @method toString
- * @return {String} Unique name of the ColumnSet instance.
- */
-
-YAHOO.widget.ColumnSet.prototype.toString = function() {
-    return "ColumnSet " + this._sName;
-};
-
-/**
- * Returns Column instance with given ID.
- *
- * @method getColumnById
- * @param column {String} Column ID.
- * @return {YAHOO.widget.Column} Column instance.
- */
-
-YAHOO.widget.ColumnSet.prototype.getColumnById = function(column) {
-    if(YAHOO.lang.isString(column)) {
-        var allColumns = this.flat;
-        for(var i=allColumns.length-1; i>-1; i--) {
-            if(allColumns[i]._sId === column) {
-                return allColumns[i];
-            }
+    var nOrigCurrentPage = oValidPaginator.currentPage;
+    for(var param in oNewValues) {
+        if(lang.hasOwnProperty(oValidPaginator, param)) {
+            oValidPaginator[param] = oNewValues[param];
         }
     }
-    return null;
-};
 
-/**
- * Returns Column instance with given key or ColumnSet key index.
- *
- * @method getColumn
- * @param column {String | Number} Column key or ColumnSet key index.
- * @return {YAHOO.widget.Column} Column instance.
- */
-
-YAHOO.widget.ColumnSet.prototype.getColumn = function(column) {
-    if(YAHOO.lang.isNumber(column) && this.keys[column]) {
-        return this.keys[column];
+    oValidPaginator.totalRecords = this._oRecordSet.getLength();
+    oValidPaginator.rowsThisPage = Math.min(oValidPaginator.rowsPerPage, oValidPaginator.totalRecords);
+    oValidPaginator.totalPages = Math.ceil(oValidPaginator.totalRecords / oValidPaginator.rowsThisPage);
+    if(isNaN(oValidPaginator.totalPages)) {
+        oValidPaginator.totalPages = 0;
     }
-    else if(YAHOO.lang.isString(column)) {
-        var allColumns = this.flat;
-        var aColumns = [];
-        for(var i=0; i<allColumns.length; i++) {
-            if(allColumns[i].key === column) {
-                aColumns.push(allColumns[i]);
-            }
+    if(oValidPaginator.currentPage > oValidPaginator.totalPages) {
+        if(oValidPaginator.totalPages < 1) {
+            oValidPaginator.currentPage = 1;
         }
-        if(aColumns.length === 1) {
-            return aColumns[0];
+        else {
+            oValidPaginator.currentPage = oValidPaginator.totalPages;
         }
-        else if(aColumns.length > 1) {
-            return aColumns;
-        }
     }
-    return null;
-};
 
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
+    if(oValidPaginator.currentPage !== nOrigCurrentPage) {
+        oValidPaginator.startRecordIndex = (oValidPaginator.currentPage-1)*oValidPaginator.rowsPerPage;
+    }
 
+
+    this.set("paginator", oValidPaginator);
+    return this.get("paginator");
+},
+
 /**
- * The Column class defines and manages attributes of DataTable Columns
- *
- * @namespace YAHOO.widget
- * @class Column
- * @constructor
- * @param oConfigs {Object} Object literal of configuration values.
+ * @method showPage
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.widget.Column = function(oConfigs) {
-    // Object literal defines Column attributes
-    if(oConfigs && (oConfigs.constructor == Object)) {
-        for(var sConfig in oConfigs) {
-            if(sConfig) {
-                this[sConfig] = oConfigs[sConfig];
+showPage : function(nPage) {
+    var oPaginator = this.get('paginator');
+    // Validate input
+    if(!lang.isNumber(nPage) || (nPage < 1)) {
+        if (oPaginator instanceof Pag) {
+            if (!oPaginator.hasPage(nPage)) {
+                nPage = 1;
             }
+        } else if (nPage > oPaginator.totalPages) {
+            nPage = 1;
         }
     }
-};
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Private member variables
-//
-/////////////////////////////////////////////////////////////////////////////
+    if (oPaginator instanceof Pag) {
+        oPaginator.setPage(nPage);
+    } else {
+        this.updatePaginator({currentPage:nPage});
+        this.render();
+    }
+},
 
 /**
- * Internal class variable to index multiple Column instances.
- *
- * @property Column._nCount
- * @type Number
- * @private
- * @static
+ * @method formatPaginators
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.widget.Column._nCount = 0;
+formatPaginators : function() {
+    var pag = this.get("paginator");
+    if (pag instanceof Pag) {
+        pag.update();
+        return;
+    }
 
-/**
- * Unique instance name.
- *
- * @property _sName
- * @type String
- * @private
- */
-YAHOO.widget.Column.prototype._sName = null;
+    var i;
 
-/**
- * Unique String identifier assigned at instantiation.
- *
- * @property _sId
- * @type String
- * @private
- */
-YAHOO.widget.Column.prototype._sId = null;
+    // For Opera workaround
+    var dropdownEnabled = false;
 
-/**
- * Reference to Column's current position index within its ColumnSet's keys array, if applicable.
- *
- * @property _nKeyIndex
- * @type Number
- * @private
- */
-YAHOO.widget.Column.prototype._nKeyIndex = null;
+    // Links are enabled
+    if(pag.pageLinks > -1) {
+        for(i=0; i<pag.links.length; i++) {
+            this.formatPaginatorLinks(pag.links[i], pag.currentPage, pag.pageLinksStart, pag.pageLinks, pag.totalPages);
+        }
+    }
 
-/**
- * Number of table cells the Column spans.
- *
- * @property _colspan
- * @type Number
- * @private
- */
-YAHOO.widget.Column.prototype._colspan = 1;
+    // Dropdown is enabled
+    for(i=0; i<pag.dropdowns.length; i++) {
+         if(pag.dropdownOptions) {
+            dropdownEnabled = true;
+            this.formatPaginatorDropdown(pag.dropdowns[i], pag.dropdownOptions);
+        }
+        else {
+            pag.dropdowns[i].style.display = "none";
+        }
+    }
 
-/**
- * Number of table rows the Column spans.
- *
- * @property _rowspan
- * @type Number
- * @private
- */
-YAHOO.widget.Column.prototype._rowspan = 1;
+    // For Opera artifacting in dropdowns
+    if(dropdownEnabled && ua.opera) {
+        document.body.style += '';
+    }
+    YAHOO.log("Paginators formatted", "info", this.toString());
+},
 
 /**
- * Column's parent Column instance, or null.
- *
- * @property _parent
- * @type YAHOO.widget.Column
- * @private
+ * @method formatPaginatorDropdown
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.widget.Column.prototype._parent = null;
+formatPaginatorDropdown : function(elDropdown, dropdownOptions) {
+    if(elDropdown && (elDropdown.ownerDocument == document)) {
+        // Clear OPTION elements
+        while (elDropdown.firstChild) {
+            elDropdown.removeChild(elDropdown.firstChild);
+        }
 
-/**
- * Current offsetWidth of the Column (in pixels).
- *
- * @property _width
- * @type Number
- * @private
- */
-YAHOO.widget.Column.prototype._width = null;
+        // Create OPTION elements
+        for(var j=0; j<dropdownOptions.length; j++) {
+            var dropdownOption = dropdownOptions[j];
+            var optionEl = document.createElement("option");
+            optionEl.value = (lang.isValue(dropdownOption.value)) ?
+                    dropdownOption.value : dropdownOption;
+            optionEl.innerHTML = (lang.isValue(dropdownOption.text)) ?
+                    dropdownOption.text : dropdownOption;
+            optionEl = elDropdown.appendChild(optionEl);
+        }
 
-/**
- * Minimum width the Column can support (in pixels). Value is populated only if table
- * is fixedWidth, null otherwise.
- *
- * @property _minWidth
- * @type Number
- * @private
- */
-YAHOO.widget.Column.prototype._minWidth = null;
+        var options = elDropdown.options;
+        // Update dropdown's "selected" value
+        if(options.length) {
+            for(var i=options.length-1; i>-1; i--) {
+                if((this.get("paginator").rowsPerPage + "") === options[i].value) {
+                    options[i].selected = true;
+                }
+            }
+        }
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public member variables
-//
-/////////////////////////////////////////////////////////////////////////////
+        // Show the dropdown
+        elDropdown.style.display = "";
+        return;
+    }
+    YAHOO.log("Could not update Paginator dropdown " + elDropdown, "error", this.toString());
+},
 
 /**
- * Associated database field, or null.
- *
- * @property key
- * @type String
+ * @method formatPaginatorLinks
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.widget.Column.prototype.key = null;
+formatPaginatorLinks : function(elContainer, nCurrentPage, nPageLinksStart, nPageLinksLength, nTotalPages) {
+    if(elContainer && (elContainer.ownerDocument == document) &&
+            lang.isNumber(nCurrentPage) && lang.isNumber(nPageLinksStart) &&
+            lang.isNumber(nTotalPages)) {
+        // Set up markup for first/last/previous/next
+        var bIsFirstPage = (nCurrentPage == 1) ? true : false;
+        var bIsLastPage = (nCurrentPage == nTotalPages) ? true : false;
+        var sFirstLinkMarkup = (bIsFirstPage) ?
+                " <span class=\"" + DT.CLASS_DISABLED +
+                " " + DT.CLASS_FIRST + "\"><<</span> " :
+                " <a href=\"#\" class=\"" + DT.CLASS_FIRST + "\"><<</a> ";
+        var sPrevLinkMarkup = (bIsFirstPage) ?
+                " <span class=\"" + DT.CLASS_DISABLED +
+                " " + DT.CLASS_PREVIOUS + "\"><</span> " :
+                " <a href=\"#\" class=\"" + DT.CLASS_PREVIOUS + "\"><</a> " ;
+        var sNextLinkMarkup = (bIsLastPage) ?
+                " <span class=\"" + DT.CLASS_DISABLED +
+                " " + DT.CLASS_NEXT + "\">></span> " :
+                " <a href=\"#\" class=\"" + DT.CLASS_NEXT + "\">></a> " ;
+        var sLastLinkMarkup = (bIsLastPage) ?
+                " <span class=\"" + DT.CLASS_DISABLED +
+                " " + DT.CLASS_LAST +  "\">>></span> " :
+                " <a href=\"#\" class=\"" + DT.CLASS_LAST + "\">>></a> ";
 
-/**
- * Text or HTML for display as Column's label in the TH element.
- *
- * @property label
- * @type String
- */
-YAHOO.widget.Column.prototype.label = null;
+        // Start with first and previous
+        var sMarkup = sFirstLinkMarkup + sPrevLinkMarkup;
 
-/**
- * Column head cell ABBR for accessibility.
- *
- * @property abbr
- * @type String
- */
-YAHOO.widget.Column.prototype.abbr = null;
+        // Ok to show all links
+        var nMaxLinks = nTotalPages;
+        var nFirstLink = 1;
+        var nLastLink = nTotalPages;
 
-/**
- * Array of object literals that define children (nested headers) of a Column.
- *
- * @property children
- * @type Object[]
- */
-YAHOO.widget.Column.prototype.children = null;
+        if(nPageLinksLength > 0) {
+        // Calculate how many links to show
+            nMaxLinks = (nPageLinksStart+nPageLinksLength < nTotalPages) ?
+                    nPageLinksStart+nPageLinksLength-1 : nTotalPages;
 
-/**
- * Column width.
- *
- * @property width
- * @type String
- */
-YAHOO.widget.Column.prototype.width = null;
+            // Try to keep the current page in the middle
+            nFirstLink = (nCurrentPage - Math.floor(nMaxLinks/2) > 0) ? nCurrentPage - Math.floor(nMaxLinks/2) : 1;
+            nLastLink = (nCurrentPage + Math.floor(nMaxLinks/2) <= nTotalPages) ? nCurrentPage + Math.floor(nMaxLinks/2) : nTotalPages;
 
-/**
- * Custom CSS class or array of classes to be applied to every cell in the Column.
- *
- * @property className
- * @type String || String[]
- */
-YAHOO.widget.Column.prototype.className = null;
+            // Keep the last link in range
+            if(nFirstLink === 1) {
+                nLastLink = nMaxLinks;
+            }
+            // Keep the first link in range
+            else if(nLastLink === nTotalPages) {
+                nFirstLink = nTotalPages - nMaxLinks + 1;
+            }
 
-/**
- * Defines a format function.
- *
- * @property formatter
- * @type String || HTMLFunction
- */
-YAHOO.widget.Column.prototype.formatter = null;
+            // An even number of links can get funky
+            if(nLastLink - nFirstLink === nMaxLinks) {
+                nLastLink--;
+            }
+      }
 
-/**
- * Defines an editor function, otherwise Column is not editable.
- *
- * @property editor
- * @type String || HTMLFunction
- */
-YAHOO.widget.Column.prototype.editor = null;
-
-/**
- * Defines editor options for Column in an object literal of param:value pairs.
- *
- * @property editorOptions
- * @type Object
- */
-YAHOO.widget.Column.prototype.editorOptions = null;
-
-/**
- * True if Column is resizeable, false otherwise.
- *
- * @property resizeable
- * @type Boolean
- * @default false
- */
-YAHOO.widget.Column.prototype.resizeable = false;
-
-/**
- * True if Column is sortable, false otherwise.
- *
- * @property sortable
- * @type Boolean
- * @default false
- */
-YAHOO.widget.Column.prototype.sortable = false;
-
-/**
- * Default sort order for Column: "asc" or "desc".
- *
- * @property sortOptions.defaultOrder
- * @type String
- * @default null
- */
-/**
- * Custom sort handler.
- *
- * @property sortOptions.sortFunction
- * @type Function
- * @default null
- */
-YAHOO.widget.Column.prototype.sortOptions = null;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public methods
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Public accessor to the unique name of the Column instance.
- *
- * @method toString
- * @return {String} Column's unique name.
- */
-YAHOO.widget.Column.prototype.toString = function() {
-    return this._sName;
-};
-
-/**
- * Returns unique ID string.
- *
- * @method getId
- * @return {String} Unique ID string.
- */
-YAHOO.widget.Column.prototype.getId = function() {
-    return this._sId;
-};
-
-/**
- * Returns unique Column key.
- *
- * @method getKey
- * @return {String} Column key.
- */
-YAHOO.widget.Column.prototype.getKey = function() {
-    return this.key;
-};
-
-/**
- * Public accessor returns Column's current position index within its ColumnSet's keys array, if applicable.
- *
- * @method getKeyIndex
- * @return {Number} Position index, or null.
- */
-YAHOO.widget.Column.prototype.getKeyIndex = function() {
-    return this._nKeyIndex;
-};
-
-/**
- * Public accessor returns Column's parent instance if any, or null otherwise.
- *
- * @method getParent
- * @return {YAHOO.widget.Column} Column's parent instance.
- */
-YAHOO.widget.Column.prototype.getParent = function() {
-    return this._parent;
-};
-
-/**
- * Public accessor returns Column's calculated COLSPAN value.
- *
- * @method getColspan
- * @return {Number} Column's COLSPAN value.
- */
-YAHOO.widget.Column.prototype.getColspan = function() {
-    return this._colspan;
-};
-// Backward compatibility
-YAHOO.widget.Column.prototype.getColSpan = function() {
-    YAHOO.log("The method getColSpan() has been" +
-    " deprecated in favor of getColspan()", "warn", this.toString());
-    return this.getColspan();
-};
-
-/**
- * Public accessor returns Column's calculated ROWSPAN value.
- *
- * @method getRowspan
- * @return {Number} Column's ROWSPAN value.
- */
-YAHOO.widget.Column.prototype.getRowspan = function() {
-    return this._rowspan;
-};
-
-// Backward compatibility
-YAHOO.widget.Column.prototype.getIndex = function() {
-    YAHOO.log("The method getIndex() has been" +
-    " deprecated in favor of getKeyIndex()", "warn",
-    this.toString());
-    return this.getKeyIndex();
-};
-YAHOO.widget.Column.prototype.format = function() {
-    YAHOO.log("The method format() has been deprecated in favor of the " +
-    "DataTable method formatCell()", "error", this.toString());
-};
-YAHOO.widget.Column.formatCheckbox = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.log("The method YAHOO.widget.Column.formatCheckbox() has been" +
-    " deprecated in favor of YAHOO.widget.DataTable.formatCheckbox()", "warn",
-    "YAHOO.widget.Column.formatCheckbox");
-    YAHOO.widget.DataTable.formatCheckbox(elCell, oRecord, oColumn, oData);
-};
-YAHOO.widget.Column.formatCurrency = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.log("The method YAHOO.widget.Column.formatCurrency() has been" +
-    " deprecated in favor of YAHOO.widget.DataTable.formatCurrency()", "warn",
-    "YAHOO.widget.Column.formatCurrency");
-    YAHOO.widget.DataTable.formatCurrency(elCell, oRecord, oColumn, oData);
-};
-YAHOO.widget.Column.formatDate = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.log("The method YAHOO.widget.Column.formatDate() has been" +
-    " deprecated in favor of YAHOO.widget.DataTable.formatDate()", "warn",
-    "YAHOO.widget.Column.formatDate");
-    YAHOO.widget.DataTable.formatDate(elCell, oRecord, oColumn, oData);
-};
-YAHOO.widget.Column.formatEmail = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.log("The method YAHOO.widget.Column.formatEmail() has been" +
-    " deprecated in favor of YAHOO.widget.DataTable.formatEmail()", "warn",
-    "YAHOO.widget.Column.formatEmail");
-    YAHOO.widget.DataTable.formatEmail(elCell, oRecord, oColumn, oData);
-};
-YAHOO.widget.Column.formatLink = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.log("The method YAHOO.widget.Column.formatLink() has been" +
-    " deprecated in favor of YAHOO.widget.DataTable.formatLink()", "warn",
-    "YAHOO.widget.Column.formatLink");
-    YAHOO.widget.DataTable.formatLink(elCell, oRecord, oColumn, oData);
-};
-YAHOO.widget.Column.formatNumber = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.log("The method YAHOO.widget.Column.formatNumber() has been" +
-    " deprecated in favor of YAHOO.widget.DataTable.formatNumber()", "warn",
-    "YAHOO.widget.Column.formatNumber");
-    YAHOO.widget.DataTable.formatNumber(elCell, oRecord, oColumn, oData);
-};
-YAHOO.widget.Column.formatSelect = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.log("The method YAHOO.widget.Column.formatSelect() has been" +
-    " deprecated in favor of YAHOO.widget.DataTable.formatDropdown()", "warn",
-    "YAHOO.widget.Column.formatSelect");
-    YAHOO.widget.DataTable.formatDropdown(elCell, oRecord, oColumn, oData);
-};
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
-/**
- * Sort static utility to support Column sorting.
- *
- * @namespace YAHOO.util
- * @class Sort
- * @static
- */
-YAHOO.util.Sort = {
-    /////////////////////////////////////////////////////////////////////////////
-    //
-    // Public methods
-    //
-    /////////////////////////////////////////////////////////////////////////////
-
-    /**
-     * Comparator function for simple case-insensitive string sorting.
-     *
-     * @method compare
-     * @param a {Object} First sort argument.
-     * @param b {Object} Second sort argument.
-     * @param desc {Boolean} True if sort direction is descending, false if
-     * sort direction is ascending.
-     */
-    compare: function(a, b, desc) {
-        if((a === null) || (typeof a == "undefined")) {
-            if((b === null) || (typeof b == "undefined")) {
-                return 0;
+        // Generate markup for each page
+        for(var i=nFirstLink; i<=nLastLink; i++) {
+            if(i != nCurrentPage) {
+                sMarkup += " <a href=\"#\" class=\"" + DT.CLASS_PAGE + "\">" + i + "</a> ";
             }
             else {
-                return 1;
+                sMarkup += " <span class=\"" + DT.CLASS_SELECTED + "\">" + i + "</span>";
             }
         }
-        else if((b === null) || (typeof b == "undefined")) {
-            return -1;
-        }
-
-        if(a.constructor == String) {
-            a = a.toLowerCase();
-        }
-        if(b.constructor == String) {
-            b = b.toLowerCase();
-        }
-        if(a < b) {
-            return (desc) ? 1 : -1;
-        }
-        else if (a > b) {
-            return (desc) ? -1 : 1;
-        }
-        else {
-            return 0;
-        }
+        sMarkup += sNextLinkMarkup + sLastLinkMarkup;
+        elContainer.innerHTML = sMarkup;
+        return;
     }
-};
+    YAHOO.log("Could not format Paginator links", "error", this.toString());
+},
 
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
 /**
- * ColumnResizer subclasses DragDrop to support resizeable Columns.
- *
- * @namespace YAHOO.util
- * @class ColumnResizer
- * @extends YAHOO.util.DragDrop
- * @constructor
- * @param oDataTable {YAHOO.widget.DataTable} DataTable instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param elThead {HTMLElement} TH element reference.
- * @param sHandleElId {String} DOM ID of the handle element that causes the resize.
- * @param sGroup {String} Group name of related DragDrop items.
- * @param oConfig {Object} (Optional) Object literal of config values.
+ * @method _onPaginatorLinkClick
+ * @private
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.util.ColumnResizer = function(oDataTable, oColumn, elThead, sHandleId, sGroup, oConfig) {
-    if(oDataTable && oColumn && elThead && sHandleId) {
-        this.datatable = oDataTable;
-        this.column = oColumn;
-        this.cell = elThead;
-        this.init(sHandleId, sGroup, oConfig);
-        //this.initFrame();
-        this.setYConstraint(0,0);
-    }
-    else {
-        YAHOO.log("Column resizer could not be created due to invalid colElId","warn");
-    }
-};
+_onPaginatorLinkClick : function(e, oSelf) {
+    // Backward compatibility
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
 
-if(YAHOO.util.DD) {
-    YAHOO.extend(YAHOO.util.ColumnResizer, YAHOO.util.DD);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public DOM event handlers
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Handles mousedown events on the Column resizer.
- *
- * @method onMouseDown
- * @param e {string} The mousedown event
- */
-YAHOO.util.ColumnResizer.prototype.onMouseDown = function(e) {
-    this.startWidth = this.cell.offsetWidth;
-    this.startPos = YAHOO.util.Dom.getX(this.getDragEl());
-
-    if(this.datatable.fixedWidth) {
-        var cellLabel = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_LABEL,"span",this.cell)[0];
-        this.minWidth = cellLabel.offsetWidth + 6;
-        var sib = this.cell.nextSibling;
-        var sibCellLabel = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_LABEL,"span",sib)[0];
-        this.sibMinWidth = sibCellLabel.offsetWidth + 6;
-//!!
-        var left = ((this.startWidth - this.minWidth) < 0) ? 0 : (this.startWidth - this.minWidth);
-        var right = ((sib.offsetWidth - this.sibMinWidth) < 0) ? 0 : (sib.offsetWidth - this.sibMinWidth);
-        this.setXConstraint(left, right);
-        YAHOO.log("cellstartwidth:" + this.startWidth,"time");
-        YAHOO.log("cellminwidth:" + this.minWidth,"time");
-        YAHOO.log("sibstartwidth:" + sib.offsetWidth,"time");
-        YAHOO.log("sibminwidth:" + this.sibMinWidth,"time");
-        YAHOO.log("l:" + left + " AND r:" + right,"time");
+    if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
+        oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
     }
 
-};
-
-/**
- * Handles mouseup events on the Column resizer.
- *
- * @method onMouseUp
- * @param e {string} The mouseup event
- */
-YAHOO.util.ColumnResizer.prototype.onMouseUp = function(e) {
-    //TODO: replace the resizer where it belongs:
-    var resizeStyle = YAHOO.util.Dom.get(this.handleElId).style;
-    resizeStyle.left = "auto";
-    resizeStyle.right = 0;
-    resizeStyle.marginRight = "-6px";
-    resizeStyle.width = "6px";
-    //.yui-dt-headresizer {position:absolute;margin-right:-6px;right:0;bottom:0;width:6px;height:100%;cursor:w-resize;cursor:col-resize;}
-
-
-    //var cells = this.datatable._elTable.tHead.rows[this.datatable._elTable.tHead.rows.length-1].cells;
-    //for(var i=0; i<cells.length; i++) {
-        //cells[i].style.width = "5px";
-    //}
-
-    //TODO: set new ColumnSet width values
-    this.datatable.fireEvent("columnResizeEvent", {column:this.column,target:this.cell});
-};
-
-/**
- * Handles drag events on the Column resizer.
- *
- * @method onDrag
- * @param e {string} The drag event
- */
-YAHOO.util.ColumnResizer.prototype.onDrag = function(e) {
-    try {
-        var newPos = YAHOO.util.Dom.getX(this.getDragEl());
-        //YAHOO.log("newpos:"+newPos,"warn");//YAHOO.util.Event.getPageX(e);
-        var offsetX = newPos - this.startPos;
-        //YAHOO.log("offset:"+offsetX,"warn");
-        //YAHOO.log("startwidth:"+this.startWidth + " and offset:"+offsetX,"warn");
-        var newWidth = this.startWidth + offsetX;
-        //YAHOO.log("newwidth:"+newWidth,"warn");
-
-        if(newWidth < this.minWidth) {
-            newWidth = this.minWidth;
+    while(elTarget && (elTag != "table")) {
+        switch(elTag) {
+            case "body":
+                return;
+            case "a":
+                Ev.stopEvent(e);
+                //TODO: after the showPage call, figure out which link
+                //TODO: was clicked and reset focus to the new version of it
+                //TODO: support multiple custom classnames
+                switch(elTarget.className) {
+                    case DT.CLASS_PAGE:
+                        oSelf.showPage(parseInt(elTarget.innerHTML,10));
+                        return;
+                    case DT.CLASS_FIRST:
+                        oSelf.showPage(1);
+                        return;
+                    case DT.CLASS_LAST:
+                        oSelf.showPage(oSelf.get("paginator").totalPages);
+                        return;
+                    case DT.CLASS_PREVIOUS:
+                        oSelf.showPage(oSelf.get("paginator").currentPage - 1);
+                        return;
+                    case DT.CLASS_NEXT:
+                        oSelf.showPage(oSelf.get("paginator").currentPage + 1);
+                        return;
+                }
+                break;
+            default:
+                return;
         }
-
-        // Resize the Column
-        var oDataTable = this.datatable;
-        var elCell = this.cell;
-
-        //YAHOO.log("newwidth" + newWidth,"warn");
-        //YAHOO.log(newWidth + " AND "+ elColumn.offsetWidth + " AND " + elColumn.id,"warn");
-
-        // Resize the other Columns
-        if(oDataTable.fixedWidth) {
-            // Moving right or left?
-            var sib = elCell.nextSibling;
-            //var sibIndex = elCell.index + 1;
-            var sibnewwidth = sib.offsetWidth - offsetX;
-            if(sibnewwidth < this.sibMinWidth) {
-                sibnewwidth = this.sibMinWidth;
-            }
-
-            //TODO: how else to cycle through all the Columns without having to use an index property?
-            for(var i=0; i<oDataTable._oColumnSet.length; i++) {
-                //if((i != elCell.index) &&  (i!=sibIndex)) {
-                //    YAHOO.util.Dom.get(oDataTable._oColumnSet.keys[i].id).style.width = oDataTable._oColumnSet.keys[i].width + "px";
-                //}
-            }
-            sib.style.width = sibnewwidth;
-            elCell.style.width = newWidth + "px";
-            //oDataTable._oColumnSet.flat[sibIndex].width = sibnewwidth;
-            //oDataTable._oColumnSet.flat[elCell.index].width = newWidth;
-
+        elTarget = elTarget.parentNode;
+        if(elTarget) {
+            elTag = elTarget.nodeName.toLowerCase();
         }
         else {
-            elCell.style.width = newWidth + "px";
+            return;
         }
     }
-    catch(e) {
-    }
-};
+},
 
-
-
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
 /**
- * A RecordSet defines and manages a set of Records.
- *
- * @namespace YAHOO.widget
- * @class RecordSet
- * @param data {Object || Object[]} An object literal or an array of data.
- * @constructor
- */
-YAHOO.widget.RecordSet = function(data) {
-    // Internal variables
-    this._sName = "RecordSet instance" + YAHOO.widget.RecordSet._nCount;
-    YAHOO.widget.RecordSet._nCount++;
-    this._records = [];
-    this._length = 0;
-    
-    if(data) {
-        if(YAHOO.lang.isArray(data)) {
-            this.addRecords(data);
-        }
-        else if(data.constructor == Object) {
-            this.addRecord(data);
-        }
-    }
-
-    /**
-     * Fired when a new Record is added to the RecordSet.
-     *
-     * @event recordAddEvent
-     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
-     * @param oArgs.data {Object} Data added.
-     */
-    this.createEvent("recordAddEvent");
-
-    /**
-     * Fired when multiple Records are added to the RecordSet at once.
-     *
-     * @event recordsAddEvent
-     * @param oArgs.records {YAHOO.widget.Record[]} An array of Record instances.
-     * @param oArgs.data {Object[]} Data added.
-     */
-    this.createEvent("recordsAddEvent");
-
-    /**
-     * Fired when a Record is updated with new data.
-     *
-     * @event recordUpdateEvent
-     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
-     * @param oArgs.newData {Object} New data.
-     * @param oArgs.oldData {Object} Old data.
-     */
-    this.createEvent("recordUpdateEvent");
-    
-    /**
-     * Fired when a Record is deleted from the RecordSet.
-     *
-     * @event recordDeleteEvent
-     * @param oArgs.data {Object} A copy of the data held by the Record,
-     * or an array of data object literals if multiple Records were deleted at once.
-     * @param oArgs.index {Object} Index of the deleted Record.
-     */
-    this.createEvent("recordDeleteEvent");
-
-    /**
-     * Fired when multiple Records are deleted from the RecordSet at once.
-     *
-     * @event recordsDeleteEvent
-     * @param oArgs.data {Object[]} An array of data object literals copied
-     * from the Records.
-     * @param oArgs.index {Object} Index of the first deleted Record.
-     */
-    this.createEvent("recordsDeleteEvent");
-    
-    /**
-     * Fired when all Records are deleted from the RecordSet at once.
-     *
-     * @event resetEvent
-     */
-    this.createEvent("resetEvent");
-
-    /**
-     * Fired when a Record Key is updated with new data.
-     *
-     * @event keyUpdateEvent
-     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
-     * @param oArgs.key {String} The updated key.
-     * @param oArgs.newData {Object} New data.
-     * @param oArgs.oldData {Object} Old data.
-     *
-     */
-    this.createEvent("keyUpdateEvent");
-
-    YAHOO.log("RecordSet initialized", "info", this.toString());
-};
-
-if(YAHOO.util.EventProvider) {
-    YAHOO.augment(YAHOO.widget.RecordSet, YAHOO.util.EventProvider);
-}
-else {
-    YAHOO.log("Missing dependency: YAHOO.util.EventProvider","error",this.toString());
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Private member variables
-//
-/////////////////////////////////////////////////////////////////////////////
-/**
- * Internal class variable to name multiple Recordset instances.
- *
- * @property RecordSet._nCount
- * @type Number
+ * @method _onPaginatorDropdownChange
  * @private
- * @static
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.widget.RecordSet._nCount = 0;
+_onPaginatorDropdownChange : function(e, oSelf) {
+    // Backward compatibility
+    var elTarget = Ev.getTarget(e);
+    var newValue = elTarget[elTarget.selectedIndex].value;
 
-/**
- * Unique instance name.
- *
- * @property _sName
- * @type String
- * @private
- */
-YAHOO.widget.RecordSet.prototype._sName = null;
-
-/**
- * Internal counter of how many Records are in the RecordSet.
- *
- * @property _length
- * @type Number
- * @private
- */
-YAHOO.widget.RecordSet.prototype._length = null;
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Private methods
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Adds one Record to the RecordSet at the given index. If index is null,
- * then adds the Record to the end of the RecordSet.
- *
- * @method _addRecord
- * @param oData {Object} An object literal of data.
- * @param index {Number} (optional) Position index.
- * @return {YAHOO.widget.Record} A Record instance.
- * @private
- */
-YAHOO.widget.RecordSet.prototype._addRecord = function(oData, index) {
-    var oRecord = new YAHOO.widget.Record(oData);
-    
-    if(YAHOO.lang.isNumber(index) && (index > -1)) {
-        this._records.splice(index,0,oRecord);
+    var newRowsPerPage = lang.isValue(parseInt(newValue,10)) ? parseInt(newValue,10) : null;
+    if(newRowsPerPage !== null) {
+        var newStartRecordIndex = (oSelf.get("paginator").currentPage-1) * newRowsPerPage;
+        oSelf.updatePaginator({rowsPerPage:newRowsPerPage, startRecordIndex:newStartRecordIndex});
+        oSelf.render();
     }
     else {
-        index = this.getLength();
-        this._records.push(oRecord);
+        YAHOO.log("Could not paginate with " + newValue + " rows per page", "error", oSelf.toString());
     }
-    this._length++;
-    return oRecord;
-};
+},
 
 /**
- * Deletes Records from the RecordSet at the given index. If range is null,
- * then only one Record is deleted.
- *
- * @method _deleteRecord
- * @param index {Number} Position index.
- * @param range {Number} (optional) How many Records to delete
- * @private
+ * @method onEventEditCell
+ * @deprecated Use onEventShowCellEditor.
  */
-YAHOO.widget.RecordSet.prototype._deleteRecord = function(index, range) {
-    if(!YAHOO.lang.isNumber(range) || (range < 0)) {
-        range = 1;
-    }
-    this._records.splice(index, range);
-    this._length = this._length - range;
-};
+onEventEditCell : function(oArgs) {
+    // Backward compatibility
+    YAHOO.log("The method onEventEditCell() has been deprecated" +
+        " in favor of onEventShowCellEditor()", "warn", this.toString());
+    this.onEventShowCellEditor(oArgs);
+},
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public methods
-//
-/////////////////////////////////////////////////////////////////////////////
-
 /**
- * Public accessor to the unique name of the RecordSet instance.
- *
- * @method toString
- * @return {String} Unique name of the RecordSet instance.
+ * @method onDataReturnReplaceRows
+ * @deprecated Use onDataReturnInitializeTable.
  */
-YAHOO.widget.RecordSet.prototype.toString = function() {
-    return this._sName;
-};
+onDataReturnReplaceRows : function(sRequest, oResponse) {
+    // Backward compatibility
+    YAHOO.log("The method onDataReturnReplaceRows() has been deprecated" +
+            " in favor of onDataReturnInitializeTable()", "warn", this.toString());
+    this.onDataReturnInitializeTable(sRequest, oResponse);
+}
 
 /**
- * Returns the number of Records held in the RecordSet.
- *
- * @method getLength
- * @return {Number} Number of records in the RecordSet.
+ * @event headerRowMouseoverEvent
+ * @deprecated Use theadRowMouseoverEvent.
  */
-YAHOO.widget.RecordSet.prototype.getLength = function() {
-        return this._length;
-};
 
 /**
- * Returns Record by ID or RecordSet position index.
- *
- * @method getRecord
- * @param record {YAHOO.widget.Record | Number | String} Record instance,
- * RecordSet position index, or Record ID.
- * @return {YAHOO.widget.Record} Record object.
+ * @event headerRowMouseoutEvent
+ * @deprecated Use theadRowMouseoutEvent.
  */
-YAHOO.widget.RecordSet.prototype.getRecord = function(record) {
-    var i;
-    if(record instanceof YAHOO.widget.Record) {
-        for(i=0; i<this._records.length; i++) {
-            if(this._records[i]._sId === record._sId) {
-                return record;
-            }
-        }
-    }
-    else if(YAHOO.lang.isNumber(record)) {
-        if((record > -1) && (record < this.getLength())) {
-            return this._records[record];
-        }
-    }
-    else if(YAHOO.lang.isString(record)) {
-        for(i=0; i<this._records.length; i++) {
-            if(this._records[i]._sId === record) {
-                return this._records[i];
-            }
-        }
-    }
-    // Not a valid Record for this RecordSet
-    return null;
 
-};
-
 /**
- * Returns an array of Records from the RecordSet.
- *
- * @method getRecords
- * @param index {Number} (optional) Recordset position index of which Record to
- * start at.
- * @param range {Number} (optional) Number of Records to get.
- * @return {YAHOO.widget.Record[]} Array of Records starting at given index and
- * length equal to given range. If index is not given, all Records are returned.
+ * @event headerRowMousedownEvent
+ * @deprecated Use theadRowMousedownEvent.
  */
-YAHOO.widget.RecordSet.prototype.getRecords = function(index, range) {
-    if(!YAHOO.lang.isNumber(index)) {
-        return this._records;
-    }
-    if(!YAHOO.lang.isNumber(range)) {
-        return this._records.slice(index);
-    }
-    return this._records.slice(index, index+range);
-};
 
 /**
- * Returns current position index for the given Record.
- *
- * @method getRecordIndex
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @return {Number} Record's RecordSet position index.
+ * @event headerRowClickEvent
+ * @deprecated Use theadRowClickEvent.
  */
 
-YAHOO.widget.RecordSet.prototype.getRecordIndex = function(oRecord) {
-    if(oRecord) {
-        for(var i=this._records.length-1; i>-1; i--) {
-            if(oRecord.getId() === this._records[i].getId()) {
-                return i;
-            }
-        }
-    }
-    return null;
-
-};
-
 /**
- * Adds one Record to the RecordSet at the given index. If index is null,
- * then adds the Record to the end of the RecordSet.
- *
- * @method addRecord
- * @param oData {Object} An object literal of data.
- * @param index {Number} (optional) Position index.
- * @return {YAHOO.widget.Record} A Record instance.
+ * @event headerRowDblclickEvent
+ * @deprecated Use theadRowDblclickEvent.
  */
-YAHOO.widget.RecordSet.prototype.addRecord = function(oData, index) {
-    if(oData && (oData.constructor == Object)) {
-        var oRecord = this._addRecord(oData, index);
-        this.fireEvent("recordAddEvent",{record:oRecord,data:oData});
-        YAHOO.log("Added Record at index " + index +
-                " with data " + YAHOO.lang.dump(oData), "info", this.toString());
-        return oRecord;
-    }
-    else {
-        YAHOO.log("Could not add Record with data" +
-                YAHOO.lang.dump(oData), "info", this.toString());
-        return null;
-    }
-};
 
 /**
- * Adds multiple Records at once to the RecordSet at the given index with the
- * given data. If index is null, then the new Records are added to the end of
- * the RecordSet.
- *
- * @method addRecords
- * @param aData {Object[]} An array of object literal data.
- * @param index {Number} (optional) Position index.
- * @return {YAHOO.widget.Record[]} An array of Record instances.
+ * @event headerCellMouseoverEvent
+ * @deprecated Use theadCellMouseoverEvent.
  */
-YAHOO.widget.RecordSet.prototype.addRecords = function(aData, index) {
-    if(YAHOO.lang.isArray(aData)) {
-        var newRecords = [];
-        // Can't go backwards bc we need to preserve order
-        for(var i=0; i<aData.length; i++) {
-            if(aData[i] && (aData[i].constructor == Object)) {
-                var record = this._addRecord(aData[i], index);
-                newRecords.push(record);
-            }
-       }
-        this.fireEvent("recordsAddEvent",{records:newRecords,data:aData});
-        YAHOO.log("Added " + newRecords.length + " Record(s) at index " + index +
-                " with data " + YAHOO.lang.dump(aData), "info", this.toString());
-       return newRecords;
-    }
-    else if(aData && (aData.constructor == Object)) {
-        var oRecord = this._addRecord(aData);
-        this.fireEvent("recordsAddEvent",{records:[oRecord],data:aData});
-        YAHOO.log("Added 1 Record at index " + index +
-                " with data " + YAHOO.lang.dump(aData), "info", this.toString());
-        return oRecord;
-    }
-    else {
-        YAHOO.log("Could not add Records with data " +
-                YAHOO.lang.dump(aData), "info", this.toString());
-    }
-};
 
 /**
- * Updates given Record with given data.
- *
- * @method updateRecord
- * @param record {YAHOO.widget.Record | Number | String} A Record instance,
- * a RecordSet position index, or a Record ID.
- * @param oData {Object) Object literal of new data.
- * @return {YAHOO.widget.Record} Updated Record, or null.
+ * @event headerCellMouseoutEvent
+ * @deprecated Use theadCellMouseoutEvent.
  */
-YAHOO.widget.RecordSet.prototype.updateRecord = function(record, oData) {
-    var oRecord = this.getRecord(record);
-    if(oRecord && oData && (oData.constructor == Object)) {
-        // Copy data from the Record for the event that gets fired later
-        var oldData = {};
-        for(var key in oRecord._oData) {
-            oldData[key] = oRecord._oData[key];
-        }
-        oRecord._oData = oData;
-        this.fireEvent("recordUpdateEvent",{record:oRecord,newData:oData,oldData:oldData});
-        YAHOO.log("Record at index " + this.getRecordIndex(oRecord) +
-                " updated with data " + YAHOO.lang.dump(oData), "info", this.toString());
-        return oRecord;
-    }
-    else {
-        YAHOO.log("Could not update Record " + record, "error", this.toString());
-        return null;
-    }
-};
 
 /**
- * Updates given Record at given key with given data.
- *
- * @method updateKey
- * @param record {YAHOO.widget.Record | Number | String} A Record instance,
- * a RecordSet position index, or a Record ID.
- * @param sKey {String} Key name.
- * @param oData {Object) New data.
+ * @event headerCellMousedownEvent
+ * @deprecated Use theadCellMousedownEvent.
  */
-YAHOO.widget.RecordSet.prototype.updateKey = function(record, sKey, oData) {
-    var oRecord = this.getRecord(record);
-    if(oRecord) {
-        var oldData = null;
-        var keyValue = oRecord._oData[sKey];
-        // Copy data from the Record for the event that gets fired later
-        if(keyValue && keyValue.constructor == Object) {
-            oldData = {};
-            for(var key in keyValue) {
-                oldData[key] = keyValue[key];
-            }
-        }
-        // Copy by value
-        else {
-            oldData = keyValue;
-        }
 
-        oRecord._oData[sKey] = oData;
-        this.fireEvent("keyUpdateEvent",{record:oRecord,key:sKey,newData:oData,oldData:oldData});
-        YAHOO.log("Key \"" + sKey +
-                "\" for Record at index " + this.getRecordIndex(oRecord) +
-                " updated to \"" + YAHOO.lang.dump(oData) + "\"", "info", this.toString());
-    }
-    else {
-        YAHOO.log("Could not update key " + sKey + " for Record " + record, "error", this.toString());
-    }
-};
-
 /**
- * Replaces all Records in RecordSet with new data.
- *
- * @method replaceRecords
- * @param data {Object || Object[]} An object literal of data or an array of
- * object literal data.
- * @return {YAHOO.widget.Record || YAHOO.widget.Record[]} A Record instance or
- * an array of Records.
+ * @event headerCellClickEvent
+ * @deprecated Use theadCellClickEvent.
  */
-YAHOO.widget.RecordSet.prototype.replaceRecords = function(data) {
-    this.reset();
-    return this.addRecords(data);
-};
 
 /**
- * Sorts all Records by given function. Records keep their unique IDs but will
- * have new RecordSet position indexes.
- *
- * @method sortRecords
- * @param fnSort {Function} Reference to a sort function.
- * @param desc {Boolean} True if sort direction is descending, false if sort
- * direction is ascending.
- * @return {YAHOO.widget.Record[]} Sorted array of Records.
+ * @event headerCellDblclickEvent
+ * @deprecated Use theadCellDblclickEvent.
  */
-YAHOO.widget.RecordSet.prototype.sortRecords = function(fnSort, desc) {
-    return this._records.sort(function(a, b) {return fnSort(a, b, desc);});
-};
 
-
 /**
- * Removes the Record at the given position index from the RecordSet. If a range
- * is also provided, removes that many Records, starting from the index. Length
- * of RecordSet is correspondingly shortened.
- *
- * @method deleteRecord
- * @param index {Number} Record's RecordSet position index.
- * @param range {Number} (optional) How many Records to delete.
- * @return {Object} A copy of the data held by the deleted Record.
+ * @event headerLabelMouseoverEvent
+ * @deprecated Use theadLabelMouseoverEvent.
  */
-YAHOO.widget.RecordSet.prototype.deleteRecord = function(index) {
-    if(YAHOO.lang.isNumber(index) && (index > -1) && (index < this.getLength())) {
-        // Copy data from the Record for the event that gets fired later
-        var oRecordData = this.getRecord(index).getData();
-        var oData = {};
-        for(var key in oRecordData) {
-            oData[key] = oRecordData[key];
-        }
-        
-        this._deleteRecord(index);
-        this.fireEvent("recordDeleteEvent",{data:oData,index:index});
-        YAHOO.log("Record deleted at index " + index +
-                " and containing data " + YAHOO.lang.dump(oData), "info", this.toString());
-        return oData;
-    }
-    else {
-        YAHOO.log("Could not delete Record at index " + index, "error", this.toString());
-        return null;
-    }
-};
 
 /**
- * Removes the Record at the given position index from the RecordSet. If a range
- * is also provided, removes that many Records, starting from the index. Length
- * of RecordSet is correspondingly shortened.
- *
- * @method deleteRecords
- * @param index {Number} Record's RecordSet position index.
- * @param range {Number} (optional) How many Records to delete.
+ * @event headerLabelMouseoutEvent
+ * @deprecated Use theadLabelMouseoutEvent.
  */
-YAHOO.widget.RecordSet.prototype.deleteRecords = function(index, range) {
-    if(!YAHOO.lang.isNumber(range)) {
-        range = 1;
-    }
-    if(YAHOO.lang.isNumber(index) && (index > -1) && (index < this.getLength())) {
-        var recordsToDelete = this.getRecords(index, range);
-        // Copy data from each Record for the event that gets fired later
-        var deletedData = [];
-        for(var i=0; i<recordsToDelete.length; i++) {
-            var oData = {};
-            for(var key in recordsToDelete[i]) {
-                oData[key] = recordsToDelete[i][key];
-            }
-            deletedData.push(oData);
-        }
-        this._deleteRecord(index, range);
 
-        this.fireEvent("recordsDeleteEvent",{data:deletedData,index:index});
-        YAHOO.log(range + "Record(s) deleted at index " + index +
-                " and containing data " + YAHOO.lang.dump(deletedData), "info", this.toString());
-
-    }
-    else {
-        YAHOO.log("Could not delete Records at index " + index, "error", this.toString());
-    }
-};
-
 /**
- * Deletes all Records from the RecordSet.
- *
- * @method reset
+ * @event headerLabelMousedownEvent
+ * @deprecated Use theadLabelMousedownEvent.
  */
-YAHOO.widget.RecordSet.prototype.reset = function() {
-    this._records = [];
-    this._length = 0;
-    this.fireEvent("resetEvent");
-    YAHOO.log("All Records deleted from RecordSet", "info", this.toString());
-};
 
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
 /**
- * The Record class defines a DataTable record.
- *
- * @namespace YAHOO.widget
- * @class Record
- * @constructor
- * @param oConfigs {Object} (optional) Object literal of key/value pairs.
+ * @event headerLabelClickEvent
+ * @deprecated Use theadLabelClickEvent.
  */
-YAHOO.widget.Record = function(oLiteral) {
-    this._sId = YAHOO.widget.Record._nCount + "";
-    YAHOO.widget.Record._nCount++;
-    this._oData = {};
-    if(oLiteral && (oLiteral.constructor == Object)) {
-        for(var sKey in oLiteral) {
-            this._oData[sKey] = oLiteral[sKey];
-        }
-    }
-};
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Private member variables
-//
-/////////////////////////////////////////////////////////////////////////////
-
 /**
- * Internal class variable to give unique IDs to Record instances.
- *
- * @property Record._nCount
- * @type Number
- * @private
+ * @event headerLabelDbllickEvent
+ * @deprecated Use theadLabelDblclickEvent.
  */
-YAHOO.widget.Record._nCount = 0;
 
-/**
- * Immutable unique ID assigned at instantiation. Remains constant while a
- * Record's position index can change from sorting.
- *
- * @property _sId
- * @type String
- * @private
- */
-YAHOO.widget.Record.prototype._sId = null;
+});
 
 /**
- * Holds data for the Record in an object literal.
- *
- * @property _oData
- * @type Object
- * @private
+ * Alias for onDataReturnSetRows for backward compatibility
+ * @method onDataReturnSetRecords
+ * @deprecated Use onDataReturnSetRows
  */
-YAHOO.widget.Record.prototype._oData = null;
+DT.prototype.onDataReturnSetRecords = DT.prototype.onDataReturnSetRows;
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public member variables
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public methods
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Returns unique ID assigned at instantiation.
- *
- * @method getId
- * @return String
- */
-YAHOO.widget.Record.prototype.getId = function() {
-    return this._sId;
-};
-
-/**
- * Returns data for the Record for a key if given, or the entire object
- * literal otherwise.
- *
- * @method getData
- * @param sKey {String} (Optional) The key to retrieve a single data value.
- * @return Object
- */
-YAHOO.widget.Record.prototype.getData = function(sKey) {
-    if(YAHOO.lang.isString(sKey)) {
-        return this._oData[sKey];
-    }
-    else {
-        return this._oData;
-    }
-};
-
-
-YAHOO.register("datatable", YAHOO.widget.DataTable, {version: "2.4.1", build: "742"});
+})();
+YAHOO.register("datatable", YAHOO.widget.DataTable, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/datatable/datatable-beta-min.js
===================================================================
--- trunk/root/static/yui/datatable/datatable-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/datatable/datatable-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,21 +1,28 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-YAHOO.widget.DataTable=function(D,C,A,B){this._nIndex=YAHOO.widget.DataTable._nCount;this._sName="instance"+this._nIndex;this.id="yui-dt"+this._nIndex;this._initContainerEl(D);if(!this._elContainer){return ;}this._initConfigs(B);this._initColumnSet(C);if(!this._oColumnSet){return ;}this._initRecordSet();if(!this._oRecordSet){return ;}this._initDataSource(A);if(!this._oDataSource){return ;}if(this._oDataSource.dataType==YAHOO.util.DataSource.TYPE_HTMLTABLE){this._oDataSource.sendRequest(this.get("initialRequest"),this._onDataReturnEnhanceTable,this);}else{this._initTableEl();if(!this._elTable||!this._elThead||!this._elTbody){return ;}YAHOO.widget.DataTable.superclass.constructor.call(this,this._elContainer,this._oConfigs);if(this._oConfigs&&this._oConfigs.paginator){this.updatePaginator(this._oConfigs.paginator);}this._oDataSource.sendRequest(this.get("initialRequest"),this.onDataReturnInitializeTable,this);}this._initCellEditorEl();this._initColumnSort();this._initDomEvents!
 ();YAHOO.widget.DataTable._nCount++;};if(YAHOO.util.Element){YAHOO.lang.extend(YAHOO.widget.DataTable,YAHOO.util.Element);}else{}YAHOO.widget.DataTable.prototype.initAttributes=function(A){A=A||{};YAHOO.widget.DataTable.superclass.initAttributes.call(this,A);this.setAttributeConfig("summary",{value:null,validator:YAHOO.lang.isString,method:function(B){this._elTable.summary=B;}});this.setAttributeConfig("selectionMode",{value:"standard",validator:YAHOO.lang.isString});this.setAttributeConfig("initialRequest",{value:"",validator:YAHOO.lang.isString});this.setAttributeConfig("sortedBy",{value:null,validator:function(B){return(B&&(B.constructor==Object)&&B.key);},method:function(B){var C=this.get("sortedBy");if(C&&(C.constructor==Object)&&C.key){var E=this._oColumnSet.getColumn(C.key);var D=this.getThEl(E);YAHOO.util.Dom.removeClass(D,YAHOO.widget.DataTable.CLASS_ASC);YAHOO.util.Dom.removeClass(D,YAHOO.widget.DataTable.CLASS_DESC);}var F=(B.column)?B.column:this._oColumnSet.get!
 Column(B.key);if(F){var G=(B.dir&&(B.dir!="asc"))?YAHOO.widget!
 .DataTab
le.CLASS_DESC:YAHOO.widget.DataTable.CLASS_ASC;YAHOO.util.Dom.addClass(this.id+"-col"+F.getId(),G);}}});this.setAttributeConfig("paginator",{value:{rowsPerPage:500,currentPage:1,startRecordIndex:0,totalRecords:0,totalPages:0,rowsThisPage:0,pageLinks:0,pageLinksStart:1,dropdownOptions:null,containers:[],dropdowns:[],links:[]},validator:function(B){if(B&&(B.constructor==Object)){if((B.rowsPerPage!==undefined)&&(B.currentPage!==undefined)&&(B.startRecordIndex!==undefined)&&(B.totalRecords!==undefined)&&(B.totalPages!==undefined)&&(B.rowsThisPage!==undefined)&&(B.pageLinks!==undefined)&&(B.pageLinksStart!==undefined)&&(B.dropdownOptions!==undefined)&&(B.containers!==undefined)&&(B.dropdowns!==undefined)&&(B.links!==undefined)){if(YAHOO.lang.isNumber(B.rowsPerPage)&&YAHOO.lang.isNumber(B.currentPage)&&YAHOO.lang.isNumber(B.startRecordIndex)&&YAHOO.lang.isNumber(B.totalRecords)&&YAHOO.lang.isNumber(B.totalPages)&&YAHOO.lang.isNumber(B.rowsThisPage)&&YAHOO.lang.isNumber(B.pageLinks!
 )&&YAHOO.lang.isNumber(B.pageLinksStart)&&YAHOO.lang.isArray(B.dropdownOptions)&&YAHOO.lang.isArray(B.containers)&&YAHOO.lang.isArray(B.dropdowns)&&YAHOO.lang.isArray(B.links)){return true;}}}return false;}});this.setAttributeConfig("paginated",{value:false,validator:YAHOO.lang.isBoolean,method:function(B){var F=this.get("paginator");var E=F.containers;var D;if(B){if(E.length===0){var J=document.createElement("span");J.id=this.id+"-paginator0";YAHOO.util.Dom.addClass(J,YAHOO.widget.DataTable.CLASS_PAGINATOR);J=this._elContainer.insertBefore(J,this._elTable);E.push(J);var H=document.createElement("span");H.id=this.id+"-paginator1";YAHOO.util.Dom.addClass(H,YAHOO.widget.DataTable.CLASS_PAGINATOR);H=this._elContainer.insertBefore(H,this._elTable.nextSibling);E.push(H);this._configs.paginator.value.containers=[J,H];}else{for(D=0;D<E.length;D++){E[D].style.display="";}}if(F.pageLinks>-1){var I=F.links;if(I.length===0){for(D=0;D<E.length;D++){var G=document.createElement("span");!
 G.id="yui-dt-pagselect"+D;G=E[D].appendChild(G);YAHOO.util.Eve!
 nt.addLi
stener(G,"click",this._onPaginatorLinkClick,this);this._configs.paginator.value.links.push(G);}}}var K=F.dropdownOptions||[];for(D=0;D<E.length;D++){var C=document.createElement("select");YAHOO.util.Dom.addClass(C,YAHOO.widget.DataTable.CLASS_DROPDOWN);C=E[D].appendChild(C);C.id="yui-dt-pagselect"+D;YAHOO.util.Event.addListener(C,"change",this._onPaginatorDropdownChange,this);this._configs.paginator.value.dropdowns.push(C);if(!F.dropdownOptions){C.style.display="none";}}}else{if(E.length>0){for(D=0;D<E.length;D++){E[D].style.display="none";}}}}});this.setAttributeConfig("caption",{value:null,validator:YAHOO.lang.isString,method:function(B){if(!this._elCaption){if(!this._elTable.firstChild){this._elCaption=this._elTable.appendChild(document.createElement("caption"));}else{this._elCaption=this._elTable.insertBefore(document.createElement("caption"),this._elTable.firstChild);}}this._elCaption.innerHTML=B;}});this.setAttributeConfig("scrollable",{value:false,validator:function(B!
 ){return(YAHOO.lang.isBoolean(B)&&!YAHOO.lang.isString(this.get("caption")));},method:function(B){if(B){YAHOO.util.Dom.addClass(this._elContainer,YAHOO.widget.DataTable.CLASS_SCROLLABLE);YAHOO.util.Dom.addClass(this._elTbody,YAHOO.widget.DataTable.CLASS_SCROLLBODY);}else{YAHOO.util.Dom.removeClass(this._elContainer,YAHOO.widget.DataTable.CLASS_SCROLLABLE);YAHOO.util.Dom.removeClass(this._elTbody,YAHOO.widget.DataTable.CLASS_SCROLLBODY);}}});};YAHOO.widget.DataTable.CLASS_TABLE="yui-dt-table";YAHOO.widget.DataTable.CLASS_HEADER="yui-dt-header";YAHOO.widget.DataTable.CLASS_BODY="yui-dt-body";YAHOO.widget.DataTable.CLASS_SCROLLBODY="yui-dt-scrollbody";YAHOO.widget.DataTable.CLASS_LABEL="yui-dt-label";YAHOO.widget.DataTable.CLASS_RESIZER="yui-dt-resizer";YAHOO.widget.DataTable.CLASS_EDITOR="yui-dt-editor";YAHOO.widget.DataTable.CLASS_PAGINATOR="yui-dt-paginator";YAHOO.widget.DataTable.CLASS_PAGE="yui-dt-page";
-YAHOO.widget.DataTable.CLASS_DEFAULT="yui-dt-default";YAHOO.widget.DataTable.CLASS_PREVIOUS="yui-dt-previous";YAHOO.widget.DataTable.CLASS_NEXT="yui-dt-next";YAHOO.widget.DataTable.CLASS_FIRST="yui-dt-first";YAHOO.widget.DataTable.CLASS_LAST="yui-dt-last";YAHOO.widget.DataTable.CLASS_EVEN="yui-dt-even";YAHOO.widget.DataTable.CLASS_ODD="yui-dt-odd";YAHOO.widget.DataTable.CLASS_SELECTED="yui-dt-selected";YAHOO.widget.DataTable.CLASS_HIGHLIGHTED="yui-dt-highlighted";YAHOO.widget.DataTable.CLASS_DISABLED="yui-dt-disabled";YAHOO.widget.DataTable.CLASS_EMPTY="yui-dt-empty";YAHOO.widget.DataTable.CLASS_LOADING="yui-dt-loading";YAHOO.widget.DataTable.CLASS_ERROR="yui-dt-error";YAHOO.widget.DataTable.CLASS_EDITABLE="yui-dt-editable";YAHOO.widget.DataTable.CLASS_SCROLLABLE="yui-dt-scrollable";YAHOO.widget.DataTable.CLASS_SORTABLE="yui-dt-sortable";YAHOO.widget.DataTable.CLASS_ASC="yui-dt-asc";YAHOO.widget.DataTable.CLASS_DESC="yui-dt-desc";YAHOO.widget.DataTable.CLASS_BUTTON="yui-dt-!
 button";YAHOO.widget.DataTable.CLASS_CHECKBOX="yui-dt-checkbox";YAHOO.widget.DataTable.CLASS_DROPDOWN="yui-dt-dropdown";YAHOO.widget.DataTable.CLASS_RADIO="yui-dt-radio";YAHOO.widget.DataTable.MSG_EMPTY="No records found.";YAHOO.widget.DataTable.MSG_LOADING="Loading data...";YAHOO.widget.DataTable.MSG_ERROR="Data error.";YAHOO.widget.DataTable._nCount=0;YAHOO.widget.DataTable.prototype._nIndex=null;YAHOO.widget.DataTable.prototype._nTrCount=0;YAHOO.widget.DataTable.prototype._sName=null;YAHOO.widget.DataTable.prototype._elContainer=null;YAHOO.widget.DataTable.prototype._elCaption=null;YAHOO.widget.DataTable.prototype._elTable=null;YAHOO.widget.DataTable.prototype._elThead=null;YAHOO.widget.DataTable.prototype._elTbody=null;YAHOO.widget.DataTable.prototype._elMsgTbody=null;YAHOO.widget.DataTable.prototype._elMsgTbodyRow=null;YAHOO.widget.DataTable.prototype._elMsgTbodyCell=null;YAHOO.widget.DataTable.prototype._oDataSource=null;YAHOO.widget.DataTable.prototype._oColumnSet=nu!
 ll;YAHOO.widget.DataTable.prototype._oRecordSet=null;YAHOO.wid!
 get.Data
Table.prototype._sFirstLabelLinkId=null;YAHOO.widget.DataTable.prototype._sFirstTrId=null;YAHOO.widget.DataTable.prototype._sLastTrId=null;YAHOO.widget.DataTable.prototype._focusEl=function(A){A=A||this._elTable;setTimeout(function(){A.focus();},0);};YAHOO.widget.DataTable.prototype._initContainerEl=function(A){this._elContainer=null;A=YAHOO.util.Dom.get(A);if(A&&A.tagName&&(A.tagName.toLowerCase()=="div")){this._elContainer=A;}};YAHOO.widget.DataTable.prototype._initConfigs=function(A){if(A){if(A.constructor!=Object){A=null;}else{if(YAHOO.lang.isBoolean(A.paginator)){}}this._oConfigs=A;}};YAHOO.widget.DataTable.prototype._initColumnSet=function(A){this._oColumnSet=null;if(YAHOO.lang.isArray(A)){this._oColumnSet=new YAHOO.widget.ColumnSet(A);}else{if(A instanceof YAHOO.widget.ColumnSet){this._oColumnSet=A;}}};YAHOO.widget.DataTable.prototype._initDataSource=function(A){this._oDataSource=null;if(A&&(A instanceof YAHOO.util.DataSource)){this._oDataSource=A;}else{var B=null;var!
  F=this._elContainer;var C;if(F.hasChildNodes()){var E=F.childNodes;for(C=0;C<E.length;C++){if(E[C].tagName&&E[C].tagName.toLowerCase()=="table"){B=E[C];break;}}if(B){var D=[];for(C=0;C<this._oColumnSet.keys.length;C++){D.push({key:this._oColumnSet.keys[C].key});}this._oDataSource=new YAHOO.util.DataSource(B);this._oDataSource.responseType=YAHOO.util.DataSource.TYPE_HTMLTABLE;this._oDataSource.responseSchema={fields:D};}}}};YAHOO.widget.DataTable.prototype._initRecordSet=function(){if(this._oRecordSet){this._oRecordSet.reset();}else{this._oRecordSet=new YAHOO.widget.RecordSet();}};YAHOO.widget.DataTable.prototype._initTableEl=function(){YAHOO.util.Event.purgeElement(this._elContainer,true);this._elContainer.innerHTML="";this._elTable=this._elContainer.appendChild(document.createElement("table"));var C=this._elTable;C.tabIndex=0;C.id=this.id+"-table";YAHOO.util.Dom.addClass(C,YAHOO.widget.DataTable.CLASS_TABLE);this._initTheadEl(C,this._oColumnSet);var A=document.createEleme!
 nt("tbody");var B=A.appendChild(document.createElement("tr"));!
 YAHOO.ut
il.Dom.addClass(B,YAHOO.widget.DataTable.CLASS_FIRST);YAHOO.util.Dom.addClass(B,YAHOO.widget.DataTable.CLASS_LAST);this._elMsgRow=B;var D=B.appendChild(document.createElement("td"));D.colSpan=this._oColumnSet.keys.length;YAHOO.util.Dom.addClass(D,YAHOO.widget.DataTable.CLASS_FIRST);YAHOO.util.Dom.addClass(D,YAHOO.widget.DataTable.CLASS_LAST);this._elMsgTd=D;this._elMsgTbody=C.appendChild(A);this.showTableMessage(YAHOO.widget.DataTable.MSG_LOADING,YAHOO.widget.DataTable.CLASS_LOADING);this._elTbody=C.appendChild(document.createElement("tbody"));YAHOO.util.Dom.addClass(this._elTbody,YAHOO.widget.DataTable.CLASS_BODY);};YAHOO.widget.DataTable.prototype._initTheadEl=function(){var M,F,A;var Q=this._oColumnSet;this._sFirstLabelLinkId=null;var N=document.createElement("thead");var C=Q.tree;for(M=0;M<C.length;M++){var J=N.appendChild(document.createElement("tr"));J.id=this.id+"-hdrow"+M;var E;for(var K=0;K<C[M].length;K++){F=C[M][K];E=J.appendChild(document.createElement("th"));E.i!
 d=this.id+"-col"+F.getId();this._initThEl(E,F,M,K);}if(M===0){YAHOO.util.Dom.addClass(J,YAHOO.widget.DataTable.CLASS_FIRST);}if(M===(C.length-1)){YAHOO.util.Dom.addClass(J,YAHOO.widget.DataTable.CLASS_LAST);}}this._elThead=this._elTable.appendChild(N);var I=Q.headers[0];var D=Q.headers[Q.headers.length-1];for(M=0;M<I.length;M++){YAHOO.util.Dom.addClass(YAHOO.util.Dom.get(this.id+"-col"+I[M]),YAHOO.widget.DataTable.CLASS_FIRST);}for(M=0;M<D.length;M++){YAHOO.util.Dom.addClass(YAHOO.util.Dom.get(this.id+"-col"+D[M]),YAHOO.widget.DataTable.CLASS_LAST);}var H=(YAHOO.util.DD)?true:false;var P=false;for(M=0;M<this._oColumnSet.keys.length;M++){F=this._oColumnSet.keys[M];var R=F.getKey();var O=YAHOO.util.Dom.get(this.id+"-col"+F.getId());if(F.resizeable){if(H){if(!this.fixedWidth||(this.fixedWidth&&(F.getKeyIndex()!=this._oColumnSet.keys.length-1))){var S=YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_HEADER,"div",O)[0];
-var B=S.appendChild(document.createElement("span"));B.id=this.id+"-resizer-"+R;YAHOO.util.Dom.addClass(B,YAHOO.widget.DataTable.CLASS_RESIZER);F.ddResizer=new YAHOO.util.ColumnResizer(this,F,O,B.id,B.id);var L=function(T){YAHOO.util.Event.stopPropagation(T);};YAHOO.util.Event.addListener(B,"click",L);}if(this.fixedWidth){var G=(YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_LABEL,"span",O))[0];G.style.overflow="hidden";}}else{P=true;}}}if(P){}};YAHOO.widget.DataTable.prototype._initThEl=function(L,J,N,C){var K=this._nIndex;var G=J.getKey();var B=J.getId();L.yuiColumnKey=G;L.yuiColumnId=B;if(J.abbr){L.abbr=J.abbr;}if(J.width){L.style.width=J.width;}var A;if(YAHOO.lang.isString(J.className)){A=[J.className];}else{if(YAHOO.lang.isArray(J.className)){A=J.className;}}if(A){for(var E=0;E<A.length;E++){YAHOO.util.Dom.addClass(L,A[E]);}}YAHOO.util.Dom.addClass(L,"yui-dt-col-"+G);L.innerHTML="";L.rowSpan=J.getRowspan();L.colSpan=J.getColspan();var I=L.appendChild!
 (document.createElement("div"));I.id=this.id+"-container"+B;YAHOO.util.Dom.addClass(I,YAHOO.widget.DataTable.CLASS_HEADER);var D=I.appendChild(document.createElement("span"));D.id=this.id+"-label"+B;YAHOO.util.Dom.addClass(D,YAHOO.widget.DataTable.CLASS_LABEL);var M=YAHOO.lang.isValue(J.label)?J.label:G;if(J.sortable){YAHOO.util.Dom.addClass(L,YAHOO.widget.DataTable.CLASS_SORTABLE);var H=this.id+"-labellink"+B;var F="?key="+G;D.innerHTML="<a id=\""+H+"\" href=\""+F+"\" title=\"Click to sort\" class=\""+YAHOO.widget.DataTable.CLASS_SORTABLE+"\">"+M+"</a>";if(!this._sFirstLabelLinkId){this._sFirstLabelLinkId=H;}}else{D.innerHTML=M;}};YAHOO.widget.DataTable.prototype._initCellEditorEl=function(){var A=document.createElement("div");A.id=this.id+"-celleditor";A.style.display="none";YAHOO.util.Dom.addClass(A,YAHOO.widget.DataTable.CLASS_EDITOR);A=document.body.appendChild(A);var B={};B.container=A;B.value=null;B.isActive=false;this._oCellEditor=B;this.subscribe("editorKeydownEven!
 t",function(C){var D=C.event;var E=YAHOO.util.Event.getTarget(!
 D);if((D
.keyCode==27)){this.cancelCellEditor();}});};YAHOO.widget.DataTable.prototype._initColumnSort=function(){this.subscribe("headerCellClickEvent",this.onEventSortColumn);};YAHOO.widget.DataTable.prototype._initDomEvents=function(){var B=this._elTable;var C=this._elThead;var A=this._elTbody;var D=this._elContainer;YAHOO.util.Event.addListener(document,"click",this._onDocumentClick,this);YAHOO.util.Event.addListener(document,"keydown",this._onDocumentKeydown,this);YAHOO.util.Event.addListener(B,"focus",this._onTableFocus,this);YAHOO.util.Event.addListener(B,"mouseover",this._onTableMouseover,this);YAHOO.util.Event.addListener(B,"mouseout",this._onTableMouseout,this);YAHOO.util.Event.addListener(B,"mousedown",this._onTableMousedown,this);YAHOO.util.Event.addListener(B,"keydown",this._onTableKeydown,this);YAHOO.util.Event.addListener(B,"keypress",this._onTableKeypress,this);YAHOO.util.Event.addListener(B,"dblclick",this._onTableDblclick,this);YAHOO.util.Event.addListener(C,"click",!
 this._onTheadClick,this);YAHOO.util.Event.addListener(A,"click",this._onTbodyClick,this);YAHOO.util.Event.addListener(D,"scroll",this._onScroll,this);YAHOO.util.Event.addListener(A,"scroll",this._onScroll,this);};YAHOO.widget.DataTable.prototype._addTrEl=function(N,H){this.hideTableMessage();var B=(!YAHOO.lang.isNumber(H)||(H<0)||(H>=(this._elTbody.rows.length)))?true:false;var K=this._oColumnSet;var J=this._oRecordSet;var C=this.get("sortedBy");var L=null;var G,I;if(C){L=(C.column)?C.column.getKeyIndex():this._oColumnSet.getColumn(C.key).getKeyIndex();G=C.dir;I=(G==="desc")?YAHOO.widget.DataTable.CLASS_DESC:YAHOO.widget.DataTable.CLASS_ASC;}var A=(B)?this._elTbody.appendChild(document.createElement("tr")):this._elTbody.insertBefore(document.createElement("tr"),this._elTbody.rows[H]);A.id=this.id+"-bdrow"+this._nTrCount;this._nTrCount++;A.yuiRecordId=N.getId();for(var E=0;E<K.keys.length;E++){var F=K.keys[E];var M=A.appendChild(document.createElement("td"));M.id=A.id+"-cell!
 "+E;M.yuiColumnKey=F.getKey();M.yuiColumnId=F.getId();for(var !
 D=0;D<K.
headers[E].length;D++){M.headers+=this.id+"-col"+K.headers[E][D]+" ";}M.yuiCellIndex=E;this.formatCell(M,N,F);if(E===0){YAHOO.util.Dom.addClass(M,YAHOO.widget.DataTable.CLASS_FIRST);}else{if(E===this._oColumnSet.keys.length-1){YAHOO.util.Dom.addClass(M,YAHOO.widget.DataTable.CLASS_LAST);}}YAHOO.util.Dom.removeClass(M,YAHOO.widget.DataTable.CLASS_ASC);YAHOO.util.Dom.removeClass(M,YAHOO.widget.DataTable.CLASS_DESC);if(E===L){I=(G==="desc")?YAHOO.widget.DataTable.CLASS_DESC:YAHOO.widget.DataTable.CLASS_ASC;YAHOO.util.Dom.addClass(M,I);}if(this.fixedWidth){M.style.overflow="hidden";}}return A.id;};YAHOO.widget.DataTable.prototype._updateTrEl=function(A,I){this.hideTableMessage();var B=this.get("sortedBy");var G=null;var E,F;if(B){G=(B.column)?B.column.getKeyIndex():this._oColumnSet.getColumn(B.key).getKeyIndex();E=B.dir;F=(E==="desc")?YAHOO.widget.DataTable.CLASS_DESC:YAHOO.widget.DataTable.CLASS_ASC;}for(var C=0;C<A.cells.length;C++){var D=this._oColumnSet.keys[C];var H=A.cells!
 [C];this.formatCell(H,I,D);YAHOO.util.Dom.removeClass(H,YAHOO.widget.DataTable.CLASS_ASC);YAHOO.util.Dom.removeClass(H,YAHOO.widget.DataTable.CLASS_DESC);if(C===G){YAHOO.util.Dom.addClass(H,F);}}A.yuiRecordId=I.getId();return A.id;};YAHOO.widget.DataTable.prototype._deleteTrEl=function(A){var B;if(!YAHOO.lang.isNumber(A)){B=YAHOO.util.Dom.get(A).sectionRowIndex;}else{B=A;}if(YAHOO.lang.isNumber(B)&&(B>-2)&&(B<this._elTbody.rows.length)){this._elTbody.deleteRow(B);return true;}else{return false;}};YAHOO.widget.DataTable.prototype._setFirstRow=function(){var A=this.getFirstTrEl();if(A){if(this._sFirstTrId){YAHOO.util.Dom.removeClass(this._sFirstTrId,YAHOO.widget.DataTable.CLASS_FIRST);}YAHOO.util.Dom.addClass(A,YAHOO.widget.DataTable.CLASS_FIRST);this._sFirstTrId=A.id;}else{this._sFirstTrId=null;}};YAHOO.widget.DataTable.prototype._setLastRow=function(){var A=this.getLastTrEl();if(A){if(this._sLastTrId){YAHOO.util.Dom.removeClass(this._sLastTrId,YAHOO.widget.DataTable.CLASS_L!
 AST);
-}YAHOO.util.Dom.addClass(A,YAHOO.widget.DataTable.CLASS_LAST);this._sLastTrId=A.id;}else{this._sLastTrId=null;}};YAHOO.widget.DataTable.prototype._setRowStripes=function(G,C){var E=this._elTbody.rows;var F=0;var A=E.length;if((G!==null)&&(G!==undefined)){var B=this.getTrEl(G);if(B){F=B.sectionRowIndex;if(YAHOO.lang.isNumber(C)&&(C>1)){A=F+C;}}}for(var D=F;D<A;D++){if(D%2){YAHOO.util.Dom.removeClass(E[D],YAHOO.widget.DataTable.CLASS_EVEN);YAHOO.util.Dom.addClass(E[D],YAHOO.widget.DataTable.CLASS_ODD);}else{YAHOO.util.Dom.removeClass(E[D],YAHOO.widget.DataTable.CLASS_ODD);YAHOO.util.Dom.addClass(E[D],YAHOO.widget.DataTable.CLASS_EVEN);}}};YAHOO.widget.DataTable.prototype._onScroll=function(C,B){var D=YAHOO.util.Event.getTarget(C);var A=D.tagName.toLowerCase();if(B._oCellEditor.isActive){B.fireEvent("editorBlurEvent",{editor:B._oCellEditor});B.cancelCellEditor();}B.fireEvent("tableScrollEvent",{event:C,target:D});};YAHOO.widget.DataTable.prototype._onDocumentClick=function(C,B!
 ){var D=YAHOO.util.Event.getTarget(C);var A=D.tagName.toLowerCase();if(!YAHOO.util.Dom.isAncestor(B._elTable,D)){B.fireEvent("tableBlurEvent");if(B._oCellEditor&&B._oCellEditor.isActive){if(!YAHOO.util.Dom.isAncestor(B._oCellEditor.container,D)&&(B._oCellEditor.container.id!==D.id)){B.fireEvent("editorBlurEvent",{editor:B._oCellEditor});}}}};YAHOO.widget.DataTable.prototype._onDocumentKeydown=function(C,B){var D=YAHOO.util.Event.getTarget(C);var A=D.tagName.toLowerCase();if(B._oCellEditor&&B._oCellEditor.isActive&&YAHOO.util.Dom.isAncestor(B._oCellEditor.container,D)){B.fireEvent("editorKeydownEvent",{editor:B._oCellEditor,event:C});}};YAHOO.widget.DataTable.prototype._onTableMouseover=function(B,A){A.fireEvent("tableFocusEvent");};YAHOO.widget.DataTable.prototype._onTableMouseover=function(C,B){var D=YAHOO.util.Event.getTarget(C);var A=D.tagName.toLowerCase();while(D&&(A!="table")){switch(A){case"body":break;case"a":break;case"td":B.fireEvent("cellMouseoverEvent",{target:D!
 ,event:C});break;case"span":if(YAHOO.util.Dom.hasClass(D,YAHOO!
 .widget.
DataTable.CLASS_LABEL)){B.fireEvent("headerLabelMouseoverEvent",{target:D,event:C});}break;case"th":B.fireEvent("headerCellMouseoverEvent",{target:D,event:C});break;case"tr":if(D.parentNode.tagName.toLowerCase()=="thead"){B.fireEvent("headerRowMouseoverEvent",{target:D,event:C});}else{B.fireEvent("rowMouseoverEvent",{target:D,event:C});}break;default:break;}D=D.parentNode;if(D){A=D.tagName.toLowerCase();}}B.fireEvent("tableMouseoverEvent",{target:(D||B._elTable),event:C});};YAHOO.widget.DataTable.prototype._onTableMouseout=function(C,B){var D=YAHOO.util.Event.getTarget(C);var A=D.tagName.toLowerCase();while(D&&(A!="table")){switch(A){case"body":break;case"a":break;case"td":B.fireEvent("cellMouseoutEvent",{target:D,event:C});break;case"span":if(YAHOO.util.Dom.hasClass(D,YAHOO.widget.DataTable.CLASS_LABEL)){B.fireEvent("headerLabelMouseoutEvent",{target:D,event:C});}break;case"th":B.fireEvent("headerCellMouseoutEvent",{target:D,event:C});break;case"tr":if(D.parentNode.tagName.!
 toLowerCase()=="thead"){B.fireEvent("headerRowMouseoutEvent",{target:D,event:C});}else{B.fireEvent("rowMouseoutEvent",{target:D,event:C});}break;default:break;}D=D.parentNode;if(D){A=D.tagName.toLowerCase();}}B.fireEvent("tableMouseoutEvent",{target:(D||B._elTable),event:C});};YAHOO.widget.DataTable.prototype._onTableMousedown=function(C,B){var D=YAHOO.util.Event.getTarget(C);var A=D.tagName.toLowerCase();while(D&&(A!="table")){switch(A){case"body":break;case"a":break;case"td":B.fireEvent("cellMousedownEvent",{target:D,event:C});break;case"span":if(YAHOO.util.Dom.hasClass(D,YAHOO.widget.DataTable.CLASS_LABEL)){B.fireEvent("headerLabelMousedownEvent",{target:D,event:C});}break;case"th":B.fireEvent("headerCellMousedownEvent",{target:D,event:C});break;case"tr":if(D.parentNode.tagName.toLowerCase()=="thead"){B.fireEvent("headerRowMousedownEvent",{target:D,event:C});}else{B.fireEvent("rowMousedownEvent",{target:D,event:C});}break;default:break;}D=D.parentNode;if(D){A=D.tagName.t!
 oLowerCase();}}B.fireEvent("tableMousedownEvent",{target:(D||B!
 ._elTabl
e),event:C});};YAHOO.widget.DataTable.prototype._onTableDblclick=function(C,B){var D=YAHOO.util.Event.getTarget(C);var A=D.tagName.toLowerCase();while(D&&(A!="table")){switch(A){case"body":break;case"td":B.fireEvent("cellDblclickEvent",{target:D,event:C});break;case"span":if(YAHOO.util.Dom.hasClass(D,YAHOO.widget.DataTable.CLASS_LABEL)){B.fireEvent("headerLabelDblclickEvent",{target:D,event:C});}break;case"th":B.fireEvent("headerCellDblclickEvent",{target:D,event:C});break;case"tr":if(D.parentNode.tagName.toLowerCase()=="thead"){B.fireEvent("headerRowDblclickEvent",{target:D,event:C});}else{B.fireEvent("rowDblclickEvent",{target:D,event:C});}break;default:break;}D=D.parentNode;if(D){A=D.tagName.toLowerCase();}}B.fireEvent("tableDblclickEvent",{target:(D||B._elTable),event:C});};YAHOO.widget.DataTable.prototype._onTableKeydown=function(W,H){var G=W.shiftKey;var X=YAHOO.util.Event.getTarget(W);if(YAHOO.util.Dom.isAncestor(H._elThead,X)){return ;}var O=YAHOO.util.Event.getCharC!
 ode(W);if(O===9){if(!G&&(X.id===H._elTable.id)&&H._sFirstLabelLinkId){YAHOO.util.Event.stopEvent(W);H._focusEl(YAHOO.util.Dom.get(H._sFirstLabelLinkId));}return ;}if((O>36)&&(O<41)){YAHOO.util.Event.stopEvent(W);var F=H._elTbody.rows;var P=H.get("selectionMode");var S,T,K,Q,R,I,Y,U,D,J,L,C,A,N,E,B,M,V;if((P=="standard")||(P=="single")){D=H.getLastSelectedRecord();if(!D){return ;}else{D=H.getRecord(D);J=H.getRecordIndex(D);N=H.getTrEl(D);L=H.getTrIndex(N);if(L===null){return ;}}K=H._oAnchorRecord;if(!K){K=H._oAnchorRecord=D;}Q=H.getRecordIndex(K);R=H.getTrIndex(K);if(R===null){if(Q<H.getRecordIndex(H.getFirstTrEl())){R=0;}else{R=H.getRecordIndex(H.getLastTrEl());}}if(G&&(P!="single")){if(Q>L){M=1;}else{if(Q<L){M=-1;}else{M=0;}}if(O==40){if(M<=0){if(L<F.length-1){H.selectRow(F[L+1]);}}else{H.unselectRow(F[L]);}}else{if(O==38){if(M>=0){if(L>0){H.selectRow(F[L-1]);}}else{H.unselectRow(F[L]);}}else{if(O==39){}else{if(O==37){}}}}}else{if(O==40){H.unselectAllRows();
-if(L<F.length-1){V=F[L+1];H.selectRow(V);}else{V=F[L];H.selectRow(V);}H._oAnchorRecord=H.getRecord(V);}else{if(O==38){H.unselectAllRows();if(L>0){V=F[L-1];H.selectRow(V);}else{V=F[L];H.selectRow(V);}H._oAnchorRecord=H.getRecord(V);}else{if(O==39){}else{if(O==37){}}}}}}else{U=H.getLastSelectedCell();if(!U){return ;}else{D=H.getRecord(U.recordId);J=H.getRecordIndex(D);N=H.getTrEl(D);L=H.getTrIndex(N);if(L===null){return ;}else{C=H.getColumnById(U.columnId);A=C.getKeyIndex();}}T=H._oAnchorCell;if(!T){T=H._oAnchorCell=U;}K=H._oAnchorCell.record;Q=H._oRecordSet.getRecordIndex(K);R=H.getTrIndex(K);if(R===null){if(Q<H.getRecordIndex(H.getFirstTrEl())){R=0;}else{R=H.getRecordIndex(H.getLastTrEl());}}I=H._oAnchorCell.column;Y=I.getKeyIndex();if(G&&(P=="cellblock")){if(O==40){if(Q>J){M=1;}else{if(Q<J){M=-1;}else{M=0;}}if(M<=0){if(L<F.length-1){E=Y;B=A;if(E>B){for(S=E;S>=B;S--){V=F[L+1].cells[S];H.selectCell(V);}}else{for(S=E;S<=B;S++){V=F[L+1].cells[S];H.selectCell(V);}}}}else{E=Math!
 .min(Y,A);B=Math.max(Y,A);for(S=E;S<=B;S++){H.unselectCell(F[L].cells[S]);}}}else{if(O==38){if(Q>J){M=1;}else{if(Q<J){M=-1;}else{M=0;}}if(M>=0){if(L>0){E=Y;B=A;if(E>B){for(S=E;S>=B;S--){V=F[L-1].cells[S];H.selectCell(V);}}else{for(S=E;S<=B;S++){V=F[L-1].cells[S];H.selectCell(V);}}}}else{E=Math.min(Y,A);B=Math.max(Y,A);for(S=E;S<=B;S++){H.unselectCell(F[L].cells[S]);}}}else{if(O==39){if(Y>A){M=1;}else{if(Y<A){M=-1;}else{M=0;}}if(M<=0){if(A<F[L].cells.length-1){E=R;B=L;if(E>B){for(S=E;S>=B;S--){V=F[S].cells[A+1];H.selectCell(V);}}else{for(S=E;S<=B;S++){V=F[S].cells[A+1];H.selectCell(V);}}}}else{E=Math.min(R,L);B=Math.max(R,L);for(S=E;S<=B;S++){H.unselectCell(F[S].cells[A]);}}}else{if(O==37){if(Y>A){M=1;}else{if(Y<A){M=-1;}else{M=0;}}if(M>=0){if(A>0){E=R;B=L;if(E>B){for(S=E;S>=B;S--){V=F[S].cells[A-1];H.selectCell(V);}}else{for(S=E;S<=B;S++){V=F[S].cells[A-1];H.selectCell(V);}}}}else{E=Math.min(R,L);B=Math.max(R,L);for(S=E;S<=B;S++){H.unselectCell(F[S].cells[A]);}}}}}}}else{if!
 (G&&(P=="cellrange")){if(Q>J){M=1;}else{if(Q<J){M=-1;}else{M=0!
 ;}}if(O=
=40){if(M<=0){for(S=A+1;S<F[L].cells.length;S++){V=F[L].cells[S];H.selectCell(V);}if(L<F.length-1){for(S=0;S<=A;S++){V=F[L+1].cells[S];H.selectCell(V);}}}else{for(S=A;S<F[L].cells.length;S++){H.unselectCell(F[L].cells[S]);}for(S=0;S<A;S++){H.unselectCell(F[L+1].cells[S]);}}}else{if(O==38){if(M>=0){for(S=A-1;S>-1;S--){V=F[L].cells[S];H.selectCell(V);}if(L>0){for(S=F[L].cells.length-1;S>=A;S--){V=F[L-1].cells[S];H.selectCell(V);}}}else{for(S=A;S>-1;S--){H.unselectCell(F[L].cells[S]);}for(S=F[L].cells.length-1;S>A;S--){H.unselectCell(F[L-1].cells[S]);}}}else{if(O==39){if(M<0){if(A<F[L].cells.length-1){V=F[L].cells[A+1];H.selectCell(V);}else{if(L<F.length-1){V=F[L+1].cells[0];H.selectCell(V);}}}else{if(M>0){H.unselectCell(F[L].cells[A]);if(A<F[L].cells.length-1){}else{}}else{if(Y<=A){if(A<F[L].cells.length-1){V=F[L].cells[A+1];H.selectCell(V);}else{if(L<F.length-1){V=F[L+1].cells[0];H.selectCell(V);}}}else{H.unselectCell(F[L].cells[A]);}}}}else{if(O==37){if(M<0){H.unselectCell(F!
 [L].cells[A]);if(A>0){}else{}}else{if(M>0){if(A>0){V=F[L].cells[A-1];H.selectCell(V);}else{if(L>0){V=F[L-1].cells[F[L-1].cells.length-1];H.selectCell(V);}}}else{if(Y>=A){if(A>0){V=F[L].cells[A-1];H.selectCell(V);}else{if(L>0){V=F[L-1].cells[F[L-1].cells.length-1];H.selectCell(V);}}}else{H.unselectCell(F[L].cells[A]);if(A>0){}else{}}}}}}}}}else{if((P=="cellblock")||(P=="cellrange")||(P=="singlecell")){if(O==40){H.unselectAllCells();if(L<F.length-1){V=F[L+1].cells[A];H.selectCell(V);}else{V=F[L].cells[A];H.selectCell(V);}H._oAnchorCell={record:H.getRecord(V),column:H.getColumn(V)};}else{if(O==38){H.unselectAllCells();if(L>0){V=F[L-1].cells[A];H.selectCell(V);}else{V=F[L].cells[A];H.selectCell(V);}H._oAnchorCell={record:H.getRecord(V),column:H.getColumn(V)};}else{if(O==39){H.unselectAllCells();if(A<F[L].cells.length-1){V=F[L].cells[A+1];H.selectCell(V);}else{V=F[L].cells[A];H.selectCell(V);}H._oAnchorCell={record:H.getRecord(V),column:H.getColumn(V)};}else{if(O==37){H.unselect!
 AllCells();if(A>0){V=F[L].cells[A-1];H.selectCell(V);}else{V=F!
 [L].cell
s[A];H.selectCell(V);}H._oAnchorCell={record:H.getRecord(V),column:H.getColumn(V)};}}}}}}}}}else{return ;}};YAHOO.widget.DataTable.prototype._onTableKeypress=function(D,C){var B=(navigator.userAgent.toLowerCase().indexOf("mac")!=-1);if(B){var A=YAHOO.util.Event.getCharCode(D);if(A==40){YAHOO.util.Event.stopEvent(D);}else{if(A==38){YAHOO.util.Event.stopEvent(D);}}}};YAHOO.widget.DataTable.prototype._onTheadClick=function(C,B){var D=YAHOO.util.Event.getTarget(C);var A=D.tagName.toLowerCase();if(B._oCellEditor&&B._oCellEditor.isActive){B.fireEvent("editorBlurEvent",{editor:B._oCellEditor});}while(D&&(A!="thead")){switch(A){case"body":break;case"span":if(YAHOO.util.Dom.hasClass(D,YAHOO.widget.DataTable.CLASS_LABEL)){B.fireEvent("headerLabelClickEvent",{target:D,event:C});}break;case"th":B.fireEvent("headerCellClickEvent",{target:D,event:C});break;case"tr":B.fireEvent("headerRowClickEvent",{target:D,event:C});break;default:break;}D=D.parentNode;if(D){A=D.tagName.toLowerCase();}}B!
 .fireEvent("tableClickEvent",{target:(D||B._elTable),event:C});};YAHOO.widget.DataTable.prototype._onTbodyClick=function(C,B){var D=YAHOO.util.Event.getTarget(C);var A=D.tagName.toLowerCase();if(B._oCellEditor&&B._oCellEditor.isActive){B.fireEvent("editorBlurEvent",{editor:B._oCellEditor});}while(D&&(A!="table")){switch(A){case"body":break;case"input":if(D.type.toLowerCase()=="checkbox"){B.fireEvent("checkboxClickEvent",{target:D,event:C});}else{if(D.type.toLowerCase()=="radio"){B.fireEvent("radioClickEvent",{target:D,event:C});}}B.fireEvent("tableClickEvent",{target:(D||B._elTable),event:C});return ;case"a":B.fireEvent("linkClickEvent",{target:D,event:C});B.fireEvent("tableClickEvent",{target:(D||B._elTable),event:C});return ;case"button":B.fireEvent("buttonClickEvent",{target:D,event:C});B.fireEvent("tableClickEvent",{target:(D||B._elTable),event:C});return ;case"td":B.fireEvent("cellClickEvent",{target:D,event:C});
-break;case"tr":B.fireEvent("rowClickEvent",{target:D,event:C});break;default:break;}D=D.parentNode;if(D){A=D.tagName.toLowerCase();}}B.fireEvent("tableClickEvent",{target:(D||B._elTable),event:C});};YAHOO.widget.DataTable.prototype._onPaginatorLinkClick=function(C,B){var D=YAHOO.util.Event.getTarget(C);var A=D.tagName.toLowerCase();if(B._oCellEditor&&B._oCellEditor.isActive){B.fireEvent("editorBlurEvent",{editor:B._oCellEditor});}while(D&&(A!="table")){switch(A){case"body":return ;case"a":YAHOO.util.Event.stopEvent(C);switch(D.className){case YAHOO.widget.DataTable.CLASS_PAGE:B.showPage(parseInt(D.innerHTML,10));return ;case YAHOO.widget.DataTable.CLASS_FIRST:B.showPage(1);return ;case YAHOO.widget.DataTable.CLASS_LAST:B.showPage(B.get("paginator").totalPages);return ;case YAHOO.widget.DataTable.CLASS_PREVIOUS:B.showPage(B.get("paginator").currentPage-1);return ;case YAHOO.widget.DataTable.CLASS_NEXT:B.showPage(B.get("paginator").currentPage+1);return ;}break;default:return!
  ;}D=D.parentNode;if(D){A=D.tagName.toLowerCase();}else{return ;}}};YAHOO.widget.DataTable.prototype._onPaginatorDropdownChange=function(E,B){var F=YAHOO.util.Event.getTarget(E);var D=F[F.selectedIndex].value;var A=YAHOO.lang.isValue(parseInt(D,10))?parseInt(D,10):null;if(A!==null){var C=(B.get("paginator").currentPage-1)*A;B.updatePaginator({rowsPerPage:A,startRecordIndex:C});B.refreshView();}else{}};YAHOO.widget.DataTable.prototype._onDropdownChange=function(B,A){var C=YAHOO.util.Event.getTarget(B);A.fireEvent("dropdownChangeEvent",{event:B,target:C});};YAHOO.widget.DataTable.prototype.toString=function(){return"DataTable "+this._sName;};YAHOO.widget.DataTable.prototype.getDataSource=function(){return this._oDataSource;};YAHOO.widget.DataTable.prototype.getColumnSet=function(){return this._oColumnSet;};YAHOO.widget.DataTable.prototype.getRecordSet=function(){return this._oRecordSet;};YAHOO.widget.DataTable.prototype.getCellEditor=function(){return this._oCellEditor;};YAHO!
 O.widget.DataTable.prototype.getTableEl=function(){return this!
 ._elTabl
e;};YAHOO.widget.DataTable.prototype.getTheadEl=function(){return this._elThead;};YAHOO.widget.DataTable.prototype.getTbodyEl=function(){return this._elTbody;};YAHOO.widget.DataTable.prototype.getBody=function(){return this.getTbodyEl();};YAHOO.widget.DataTable.prototype.getMsgTbodyEl=function(){return this._elMsgTbody;};YAHOO.widget.DataTable.prototype.getMsgTdEl=function(){return this._elMsgTd;};YAHOO.widget.DataTable.prototype.getTrEl=function(E){var D=this._elTbody.rows;if(E instanceof YAHOO.widget.Record){var C=this.getTrIndex(E);if(C!==null){return D[C];}else{return null;}}else{if(YAHOO.lang.isNumber(E)&&(E>-1)&&(E<D.length)){return D[E];}else{var A;var B=YAHOO.util.Dom.get(E);if(B&&(B.ownerDocument==document)){if(B.tagName.toLowerCase()!="tr"){A=YAHOO.util.Dom.getAncestorByTagName(B,"tr");}else{A=B;}if(A&&(A.parentNode==this._elTbody)){return A;}}}}return null;};YAHOO.widget.DataTable.prototype.getRow=function(A){return this.getTrEl(A);};YAHOO.widget.DataTable.prototy!
 pe.getFirstTrEl=function(){return this._elTbody.rows[0]||null;};YAHOO.widget.DataTable.prototype.getLastTrEl=function(){var A=this._elTbody.rows;if(A.length>0){return A[A.length-1]||null;}};YAHOO.widget.DataTable.prototype.getTdEl=function(A){var E;var C=YAHOO.util.Dom.get(A);if(C&&(C.ownerDocument==document)){if(C.tagName.toLowerCase()!="td"){E=YAHOO.util.Dom.getAncestorByTagName(C,"td");}else{E=C;}if(E&&(E.parentNode.parentNode==this._elTbody)){return E;}}else{if(A.record&&A.column&&A.column.getKeyIndex){var D=A.record;var B=this.getTrEl(D);if(B&&B.cells&&B.cells.length>0){return B.cells[A.column.getKeyIndex()]||null;}}}return null;};YAHOO.widget.DataTable.prototype.getThEl=function(D){var A;if(D instanceof YAHOO.widget.Column){var C=D;A=YAHOO.util.Dom.get(this.id+"-col"+C.getId());if(A){return A;}}else{var B=YAHOO.util.Dom.get(D);if(B&&(B.ownerDocument==document)){if(B.tagName.toLowerCase()!="th"){A=YAHOO.util.Dom.getAncestorByTagName(B,"th");}else{A=B;}if(A&&(A.parentNo!
 de.parentNode==this._elThead)){return A;}}}return null;};YAHOO!
 .widget.
DataTable.prototype.getTrIndex=function(D){var C;if(D instanceof YAHOO.widget.Record){C=this._oRecordSet.getRecordIndex(D);if(C===null){return null;}}else{if(YAHOO.lang.isNumber(D)){C=D;}}if(YAHOO.lang.isNumber(C)){if((C>-1)&&(C<this._oRecordSet.getLength())){if(this.get("paginated")){var B=this.get("paginator").startRecordIndex;var E=B+this.get("paginator").rowsPerPage-1;if((C>=B)&&(C<=E)){return C-B;}else{return null;}}else{return C;}}else{return null;}}else{var A=this.getTrEl(D);if(A&&(A.ownerDocument==document)&&(A.parentNode==this._elTbody)){return A.sectionRowIndex;}}return null;};YAHOO.widget.DataTable.prototype.initializeTable=function(B){this._oRecordSet.reset();var A=this._oRecordSet.addRecords(B);this._unselectAllTrEls();this._unselectAllTdEls();this._aSelections=null;this._oAnchorRecord=null;this._oAnchorCell=null;this.refreshView();this.fireEvent("initEvent");};YAHOO.widget.DataTable.prototype.refreshView=function(){var H,G,F,E,J;var K=this.updatePaginator();if(!
 this.get("paginated")){var A=K.rowsPerPage;var D=(K.currentPage-1)*A;J=this._oRecordSet.getRecords(D,A);this.formatPaginators();}else{J=this._oRecordSet.getRecords();}var B=this._elTbody;var O=B.rows;if(YAHOO.lang.isArray(J)&&(J.length>0)){this.hideTableMessage();var N=this.getSelectedRows();var I=this.getSelectedCells();var C=(N.length>0)||(I.length>0);while(B.hasChildNodes()&&(O.length>J.length)){B.deleteRow(-1);}if(C){this._unselectAllTrEls();this._unselectAllTdEls();}for(H=0;H<O.length;H++){this._updateTrEl(O[H],J[H]);}for(H=O.length;H<J.length;H++){this._addTrEl(J[H]);}if(C){for(G=0;G<O.length;G++){var L=O[G];var M=this.get("selectionMode");if((M=="standard")||(M=="single")){for(F=0;F<N.length;F++){if(N[F]===L.yuiRecordId){YAHOO.util.Dom.addClass(L,YAHOO.widget.DataTable.CLASS_SELECTED);if(G===O.length-1){this._oAnchorRecord=this.getRecord(L.yuiRecordId);}}}}else{for(F=0;F<L.cells.length;F++){var P=L.cells[F];
-for(E=0;E<I.length;E++){if((I[E].recordId===L.yuiRecordId)&&(I[E].columnId===P.yuiColumnId)){YAHOO.util.Dom.addClass(P,YAHOO.widget.DataTable.CLASS_SELECTED);if(F===L.cells.length-1){this._oAnchorCell={record:this.getRecord(L.yuiRecordId),column:this.getColumnById(P.yuiColumnId)};}}}}}}}this._setFirstRow();this._setLastRow();this._setRowStripes();this.fireEvent("refreshEvent");}else{while(B.hasChildNodes()){B.deleteRow(-1);}this.showTableMessage(YAHOO.widget.DataTable.MSG_EMPTY,YAHOO.widget.DataTable.CLASS_EMPTY);}};YAHOO.widget.DataTable.prototype.destroy=function(){YAHOO.util.Event.purgeElement(this._oCellEditor.container,true);document.body.removeChild(this._oCellEditor.container);var A=this.toString();var B=this._elContainer;this._oRecordSet.unsubscribeAll();this.unsubscribeAll();YAHOO.util.Event.purgeElement(B,true);B.innerHTML="";for(var C in this){if(YAHOO.lang.hasOwnProperty(this,C)){this[C]=null;}}};YAHOO.widget.DataTable.prototype.showTableMessage=function(B,A){va!
 r C=this._elMsgTd;if(YAHOO.lang.isString(B)){C.innerHTML=B;}if(YAHOO.lang.isString(A)){YAHOO.util.Dom.addClass(C,A);}this._elMsgTbody.style.display="";this.fireEvent("tableMsgShowEvent",{html:B,className:A});};YAHOO.widget.DataTable.prototype.hideTableMessage=function(){if(this._elMsgTbody.style.display!="none"){this._elMsgTbody.style.display="none";this.fireEvent("tableMsgHideEvent");}};YAHOO.widget.DataTable.prototype.focus=function(){this._focusEl(this._elTable);};YAHOO.widget.DataTable.prototype.getRecordIndex=function(C){var B;if(!YAHOO.lang.isNumber(C)){if(C instanceof YAHOO.widget.Record){return this._oRecordSet.getRecordIndex(C);}else{var A=this.getTrEl(C);if(A){B=A.sectionRowIndex;}}}else{B=C;}if(YAHOO.lang.isNumber(B)){if(this.get("paginated")){return this.get("paginator").startRecordIndex+B;}else{return B;}}return null;};YAHOO.widget.DataTable.prototype.getRecord=function(C){var B=this._oRecordSet.getRecord(C);if(!B){var A=this.getTrEl(C);if(A){B=this._oRecordSet!
 .getRecord(A.yuiRecordId);}}if(B instanceof YAHOO.widget.Recor!
 d){retur
n this._oRecordSet.getRecord(B);}else{return null;}};YAHOO.widget.DataTable.prototype.getColumn=function(A){var C=this._oColumnSet.getColumn(A);if(!C){var B=this.getTdEl(A);if(B){C=this._oColumnSet.getColumnById(B.yuiColumnId);}else{B=this.getThEl(A);if(B){C=this._oColumnSet.getColumnById(B.yuiColumnId);}}}if(!C){}return C;};YAHOO.widget.DataTable.prototype.getColumnById=function(A){return this._oColumnSet.getColumnById(A);};YAHOO.widget.DataTable.prototype.sortColumn=function(C){if(C&&(C instanceof YAHOO.widget.Column)){if(!C.sortable){YAHOO.util.Dom.addClass(this.getThEl(C),YAHOO.widget.DataTable.CLASS_SORTABLE);}var A=(C.sortOptions&&C.sortOptions.defaultOrder)?C.sortOptions.defaultOrder:"asc";var E=this.get("sortedBy");if(E&&(E.key===C.key)){if(E.dir){A=(E.dir=="asc")?"desc":"asc";}else{A=(A=="asc")?"desc":"asc";}}var B=(C.sortOptions&&YAHOO.lang.isFunction(C.sortOptions.sortFunction))?C.sortOptions.sortFunction:function(G,F,I){var H=YAHOO.util.Sort.compare(G.getData(C.k!
 ey),F.getData(C.key),I);if(H===0){return YAHOO.util.Sort.compare(G.getId(),F.getId(),I);}else{return H;}};var D=(A=="desc")?true:false;this._oRecordSet.sortRecords(B,D);this.set("sortedBy",{key:C.key,dir:A,column:C});this.updatePaginator({currentPage:1});this.refreshView();this.fireEvent("columnSortEvent",{column:C,dir:A});}else{}};YAHOO.widget.DataTable.prototype.addRow=function(F,B){if(F&&(F.constructor==Object)){var D=this._oRecordSet.addRecord(F,B);if(D){var C=this.getTrIndex(D);if(YAHOO.lang.isNumber(C)){if(this.get("paginated")){this.refreshView();}else{var E=this._addTrEl(D,C);if(E){var A=(YAHOO.lang.isNumber(C)&&(C==this._elTbody.rows.length-1))?true:false;if(A){if((this._elTbody.rows.length-1)%2){YAHOO.util.Dom.addClass(E,YAHOO.widget.DataTable.CLASS_ODD);}else{YAHOO.util.Dom.addClass(E,YAHOO.widget.DataTable.CLASS_EVEN);}}else{this._setRowStripes(C);}if(A){this._setLastRow();}else{if(YAHOO.lang.isNumber(B)&&(C===0)){this._setFirstRow();}}}}}else{this.updatePaginat!
 or();}this.fireEvent("rowAddEvent",{record:D});C=(YAHOO.lang.i!
 sValue(C
))?C:"n/a";return ;}}};YAHOO.widget.DataTable.prototype.addRows=function(B,A){if(YAHOO.lang.isArray(B)){var C;if(YAHOO.lang.isNumber(A)){for(C=B.length-1;C>-1;C--){this.addRow(B[C],A);}}else{for(C=0;C<B.length;C++){this.addRow(B[C]);}}}else{}};YAHOO.widget.DataTable.prototype.updateRow=function(G,H){var A,F,E,B;if((G instanceof YAHOO.widget.Record)||(YAHOO.lang.isNumber(G))){A=this._oRecordSet.getRecord(G);B=this.getTrEl(A);}else{B=this.getTrEl(G);if(B){A=this.getRecord(B);}}if(A){var C=A.getData();F={};for(var D in C){F[D]=C[D];}E=this._oRecordSet.updateRecord(A,H);}else{return ;}if(B){this._updateTrEl(B,E);}this.fireEvent("rowUpdateEvent",{record:E,oldData:F});};YAHOO.widget.DataTable.prototype.deleteRow=function(K){var L=null;if(YAHOO.lang.isNumber(K)){L=this._oRecordSet.getRecord(K);}else{var B=YAHOO.util.Dom.get(K);B=this.getTrEl(B);if(B){L=this.getRecord(B);}}if(L){var H=L.getId();var I=this._aSelections||[];for(var F=I.length-1;F>-1;F--){if((YAHOO.lang.isNumber(I[F])&!
 &(I[F]===H))||((I[F].constructor==Object)&&(I[F].recordId===H))){I.splice(F,1);}}var A=this.getRecordIndex(L);var J=L.getData();var D={};for(var E in J){D[E]=J[E];}var C=this.getTrIndex(L);this._oRecordSet.deleteRecord(A);if(YAHOO.lang.isNumber(C)){var G=(C==this.getLastTrEl().sectionRowIndex)?true:false;this._deleteTrEl(C);if(this._elTbody.rows.length===0){this.showTableMessage(YAHOO.widget.DataTable.MSG_EMPTY,YAHOO.widget.DataTable.CLASS_EMPTY);}else{if(C===0){this._setFirstRow();}if(G){this._setLastRow();}if(C!=this._elTbody.rows.length){this._setRowStripes(C);}}}this.fireEvent("rowDeleteEvent",{recordIndex:A,oldData:D,trElIndex:C});}else{}};YAHOO.widget.DataTable.prototype.deleteRows=function(G,C){var E=null;if(YAHOO.lang.isNumber(G)){E=G;}else{var A=YAHOO.util.Dom.get(G);A=this.getTrEl(A);if(A){E=this.getRecordIndex(A);}}if(E!==null){if(C&&YAHOO.lang.isNumber(C)){var F=(C>0)?E+C-1:E;var D=(C>0)?E:E+C+1;
-for(var B=F;B>D-1;B--){this.deleteRow(B);}}else{this.deleteRow(E);}}else{}};YAHOO.widget.DataTable.prototype.formatCell=function(F,D,G){if(!(D instanceof YAHOO.widget.Record)){D=this.getRecord(F);}if(!(G instanceof YAHOO.widget.Column)){G=this._oColumnSet.getColumn(F.yuiColumnKey);}if(D&&G){var E=G.key;var H=D.getData(E);var B;if(YAHOO.lang.isString(G.formatter)){switch(G.formatter){case"button":B=YAHOO.widget.DataTable.formatButton;break;case"checkbox":B=YAHOO.widget.DataTable.formatCheckbox;break;case"currency":B=YAHOO.widget.DataTable.formatCurrency;break;case"date":B=YAHOO.widget.DataTable.formatDate;break;case"dropdown":B=YAHOO.widget.DataTable.formatDropdown;break;case"email":B=YAHOO.widget.DataTable.formatEmail;break;case"link":B=YAHOO.widget.DataTable.formatLink;break;case"number":B=YAHOO.widget.DataTable.formatNumber;break;case"radio":B=YAHOO.widget.DataTable.formatRadio;break;case"text":B=YAHOO.widget.DataTable.formatText;break;case"textarea":B=YAHOO.widget.DataTa!
 ble.formatTextarea;break;case"textbox":B=YAHOO.widget.DataTable.formatTextbox;break;case"html":break;default:B=null;}}else{if(YAHOO.lang.isFunction(G.formatter)){B=G.formatter;}}if(B){B.call(this,F,D,G,H);}else{F.innerHTML=(YAHOO.lang.isValue(H))?H.toString():"";}var C=null;if(YAHOO.lang.isString(G.className)){C=[G.className];}else{if(YAHOO.lang.isArray(G.className)){C=G.className;}}if(C){for(var A=0;A<C.length;A++){YAHOO.util.Dom.addClass(F,C[A]);}}YAHOO.util.Dom.addClass(F,"yui-dt-col-"+E);if(G.editor){YAHOO.util.Dom.addClass(F,YAHOO.widget.DataTable.CLASS_EDITABLE);}this.fireEvent("cellFormatEvent",{record:D,column:G,key:E,el:F});}else{}};YAHOO.widget.DataTable.formatButton=function(A,B,C,E){var D=YAHOO.lang.isValue(E)?E:"Click";A.innerHTML="<button type=\"button\" class=\""+YAHOO.widget.DataTable.CLASS_BUTTON+"\">"+D+"</button>";};YAHOO.widget.DataTable.formatCheckbox=function(A,B,C,E){var D=E;D=(D)?" checked":"";A.innerHTML="<input type=\"checkbox\""+D+" class=\""+YAHO!
 O.widget.DataTable.CLASS_CHECKBOX+"\">";};YAHOO.widget.DataTab!
 le.forma
tCurrency=function(C,E,F,G){if(YAHOO.lang.isNumber(G)){var B=G;var A;B=Math.round(B*100)/100;A="$"+B;var D=A.indexOf(".");if(D<0){A+=".00";}else{while(D>A.length-3){A+="0";}}C.innerHTML=A;}else{C.innerHTML=YAHOO.lang.isValue(G)?G:"";}};YAHOO.widget.DataTable.formatDate=function(A,C,D,E){var B=E;if(B instanceof Date){A.innerHTML=(B.getMonth()+1)+"/"+B.getDate()+"/"+B.getFullYear();}else{A.innerHTML=YAHOO.lang.isValue(E)?E:"";}};YAHOO.widget.DataTable.formatDropdown=function(C,J,H,A){var I=(YAHOO.lang.isValue(A))?A:J.getData(H.key);var K=(YAHOO.lang.isArray(H.dropdownOptions))?H.dropdownOptions:null;var B;var G=C.getElementsByTagName("select");if(G.length===0){B=document.createElement("select");YAHOO.util.Dom.addClass(B,YAHOO.widget.DataTable.CLASS_DROPDOWN);B=C.appendChild(B);YAHOO.util.Event.addListener(B,"change",this._onDropdownChange,this);}B=G[0];if(B){B.innerHTML="";if(K){for(var E=0;E<K.length;E++){var F=K[E];var D=document.createElement("option");D.value=(YAHOO.lang.i!
 sValue(F.value))?F.value:F;D.innerHTML=(YAHOO.lang.isValue(F.text))?F.text:F;D=B.appendChild(D);}}else{B.innerHTML="<option value=\""+I+"\">"+I+"</option>";}}else{C.innerHTML=YAHOO.lang.isValue(A)?A:"";}};YAHOO.widget.DataTable.formatEmail=function(A,B,C,D){if(YAHOO.lang.isString(D)){A.innerHTML="<a href=\"mailto:"+D+"\">"+D+"</a>";}else{A.innerHTML=YAHOO.lang.isValue(D)?D:"";}};YAHOO.widget.DataTable.formatLink=function(A,B,C,D){if(YAHOO.lang.isString(D)){A.innerHTML="<a href=\""+D+"\">"+D+"</a>";}else{A.innerHTML=YAHOO.lang.isValue(D)?D:"";}};YAHOO.widget.DataTable.formatNumber=function(A,B,C,D){if(YAHOO.lang.isNumber(D)){A.innerHTML=D;}else{A.innerHTML=YAHOO.lang.isValue(D)?D:"";}};YAHOO.widget.DataTable.formatRadio=function(A,B,C,E){var D=E;D=(D)?" checked":"";A.innerHTML="<input type=\"radio\""+D+" name=\""+C.getKey()+"-radio\" class=\""+YAHOO.widget.DataTable.CLASS_RADIO+"\">";};YAHOO.widget.DataTable.formatText=function(A,B,D,E){var C=(YAHOO.lang.isValue(B.getData(D.!
 key)))?B.getData(D.key):"";A.innerHTML=C.toString().replace(/&!
 /g,"&#38
;").replace(/</g,"<").replace(/>/g,">");};YAHOO.widget.DataTable.formatTextarea=function(B,C,E,F){var D=(YAHOO.lang.isValue(C.getData(E.key)))?C.getData(E.key):"";var A="<textarea>"+D+"</textarea>";B.innerHTML=A;};YAHOO.widget.DataTable.formatTextbox=function(B,C,E,F){var D=(YAHOO.lang.isValue(C.getData(E.key)))?C.getData(E.key):"";var A="<input type=\"text\" value=\""+D+"\">";B.innerHTML=A;};YAHOO.widget.DataTable.prototype.updatePaginator=function(B){var D=this.get("paginator");var A=D.currentPage;for(var C in B){if(YAHOO.lang.hasOwnProperty(D,C)){D[C]=B[C];}}D.totalRecords=this._oRecordSet.getLength();D.rowsThisPage=Math.min(D.rowsPerPage,D.totalRecords);D.totalPages=Math.ceil(D.totalRecords/D.rowsThisPage);if(isNaN(D.totalPages)){D.totalPages=0;}if(D.currentPage>D.totalPages){if(D.totalPages<1){D.currentPage=1;}else{D.currentPage=D.totalPages;}}if(D.currentPage!==A){D.startRecordIndex=(D.currentPage-1)*D.rowsPerPage;}this.set("paginator",D);return this.get("pagin!
 ator");};YAHOO.widget.DataTable.prototype.showPage=function(A){if(!YAHOO.lang.isNumber(A)||(A<1)||(A>this.get("paginator").totalPages)){A=1;}this.updatePaginator({currentPage:A});this.refreshView();};YAHOO.widget.DataTable.prototype.formatPaginators=function(){var B=this.get("paginator");var A;var C=false;if(B.pageLinks>-1){for(A=0;A<B.links.length;A++){this.formatPaginatorLinks(B.links[A],B.currentPage,B.pageLinksStart,B.pageLinks,B.totalPages);}}for(A=0;A<B.dropdowns.length;A++){if(B.dropdownOptions){C=true;this.formatPaginatorDropdown(B.dropdowns[A],B.dropdownOptions);}else{B.dropdowns[A].style.display="none";}}if(C&&navigator.userAgent.toLowerCase().indexOf("opera")!=-1){document.body.style+="";}};YAHOO.widget.DataTable.prototype.formatPaginatorDropdown=function(F,E){if(F&&(F.ownerDocument==document)){while(F.firstChild){F.removeChild(F.firstChild);}for(var C=0;C<E.length;C++){var G=E[C];var A=document.createElement("option");
-A.value=(YAHOO.lang.isValue(G.value))?G.value:G;A.innerHTML=(YAHOO.lang.isValue(G.text))?G.text:G;A=F.appendChild(A);}var B=F.options;if(B.length){for(var D=B.length-1;D>-1;D--){if((this.get("paginator").rowsPerPage+"")===B[D].value){B[D].selected=true;}}}F.style.display="";return ;}};YAHOO.widget.DataTable.prototype.formatPaginatorLinks=function(E,A,N,D,K){if(E&&(E.ownerDocument==document)&&YAHOO.lang.isNumber(A)&&YAHOO.lang.isNumber(N)&&YAHOO.lang.isNumber(K)){var G=(A==1)?true:false;var B=(A==K)?true:false;var I=(G)?" <span class=\""+YAHOO.widget.DataTable.CLASS_DISABLED+" "+YAHOO.widget.DataTable.CLASS_FIRST+"\"><<</span> ":" <a href=\"#\" class=\""+YAHOO.widget.DataTable.CLASS_FIRST+"\"><<</a> ";var L=(G)?" <span class=\""+YAHOO.widget.DataTable.CLASS_DISABLED+" "+YAHOO.widget.DataTable.CLASS_PREVIOUS+"\"><</span> ":" <a href=\"#\" class=\""+YAHOO.widget.DataTable.CLASS_PREVIOUS+"\"><</a> ";var O=(B)?" <span class=\""+YAHOO.widget.DataTable.CLASS_DISA!
 BLED+" "+YAHOO.widget.DataTable.CLASS_NEXT+"\">></span> ":" <a href=\"#\" class=\""+YAHOO.widget.DataTable.CLASS_NEXT+"\">></a> ";var C=(B)?" <span class=\""+YAHOO.widget.DataTable.CLASS_DISABLED+" "+YAHOO.widget.DataTable.CLASS_LAST+"\">>></span> ":" <a href=\"#\" class=\""+YAHOO.widget.DataTable.CLASS_LAST+"\">>></a> ";var H=I+L;var P=K;var J=1;var M=K;if(D>0){P=(N+D<K)?N+D-1:K;J=(A-Math.floor(P/2)>0)?A-Math.floor(P/2):1;M=(A+Math.floor(P/2)<=K)?A+Math.floor(P/2):K;if(J===1){M=P;}else{if(M===K){J=K-P+1;}}if(M-J===P){M--;}}for(var F=J;F<=M;F++){if(F!=A){H+=" <a href=\"#\" class=\""+YAHOO.widget.DataTable.CLASS_PAGE+"\">"+F+"</a> ";}else{H+=" <span class=\""+YAHOO.widget.DataTable.CLASS_SELECTED+"\">"+F+"</span>";}}H+=O+C;E.innerHTML=H;return ;}};YAHOO.widget.DataTable.prototype._sLastHighlightedTdElId=null;YAHOO.widget.DataTable.prototype._sLastHighlightedTrElId=null;YAHOO.widget.DataTable.prototype._aSelections=null;YAHOO.widget.DataTable.prototype._oAnc!
 horRecord=null;YAHOO.widget.DataTable.prototype._oAnchorCell=n!
 ull;YAHO
O.widget.DataTable.prototype._unselectAllTrEls=function(){var A=YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"tr",this._elTbody);YAHOO.util.Dom.removeClass(A,YAHOO.widget.DataTable.CLASS_SELECTED);};YAHOO.widget.DataTable.prototype.getSelectedTrEls=function(){return YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"tr",this._elTbody);};YAHOO.widget.DataTable.prototype.selectRow=function(F){var E,A;if(F instanceof YAHOO.widget.Record){E=this._oRecordSet.getRecord(F);A=this.getTrEl(E);}else{if(YAHOO.lang.isNumber(F)){E=this.getRecord(F);A=this.getTrEl(E);}else{A=this.getTrEl(F);E=this.getRecord(A);}}if(E){var D=this._aSelections||[];var C=E.getId();if(D.indexOf&&(D.indexOf(C)>-1)){D.splice(D.indexOf(C),1);}else{for(var B=D.length-1;B>-1;B--){if(D[B]===C){D.splice(B,1);break;}}}D.push(C);this._aSelections=D;if(!this._oAnchorRecord){this._oAnchorRecord=E;}if(A){YAHOO.util.Dom.addClass(A,YAHOO.widget.DataTable.CLASS_SELECT!
 ED);}this.fireEvent("rowSelectEvent",{record:E,el:A});}};YAHOO.widget.DataTable.prototype.select=function(B){if(!YAHOO.lang.isArray(B)){B=[B];}for(var A=0;A<B.length;A++){this.selectRow(B[A]);}};YAHOO.widget.DataTable.prototype.unselectRow=function(G){var A=this.getTrEl(G);var F;if(G instanceof YAHOO.widget.Record){F=this._oRecordSet.getRecord(G);}else{if(YAHOO.lang.isNumber(G)){F=this.getRecord(G);}else{F=this.getRecord(A);}}if(F){var E=this._aSelections||[];var C=F.getId();var D=false;if(E.indexOf&&(E.indexOf(C)>-1)){E.splice(E.indexOf(C),1);}else{for(var B=E.length-1;B>-1;B--){if(E[B]===C){E.splice(B,1);break;}}}if(D){this._aSelections=E;YAHOO.util.Dom.removeClass(A,YAHOO.widget.DataTable.CLASS_SELECTED);this.fireEvent("rowUnselectEvent",{record:F,el:A});return ;}YAHOO.util.Dom.removeClass(A,YAHOO.widget.DataTable.CLASS_SELECTED);this.fireEvent("rowUnselectEvent",{record:F,el:A});}};YAHOO.widget.DataTable.prototype.unselectAllRows=function(){var B=this._aSelections||[];f!
 or(var A=B.length-1;A>-1;A--){if(YAHOO.lang.isString(B[A])){B.!
 splice(A
,1);}}this._aSelections=B;this._unselectAllTrEls();this.fireEvent("unselectAllRowsEvent");};YAHOO.widget.DataTable.prototype._unselectAllTdEls=function(){var A=YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"td",this._elTbody);YAHOO.util.Dom.removeClass(A,YAHOO.widget.DataTable.CLASS_SELECTED);};YAHOO.widget.DataTable.prototype.getSelectedTdEls=function(){return YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"td",this._elTbody);};YAHOO.widget.DataTable.prototype.selectCell=function(A){var G=this.getTdEl(A);if(G){var F=this.getRecord(G);var E=G.yuiColumnId;if(F&&E){var D=this._aSelections||[];var C=F.getId();for(var B=D.length-1;B>-1;B--){if((D[B].recordId===C)&&(D[B].columnId===E)){D.splice(B,1);break;}}D.push({recordId:C,columnId:E});this._aSelections=D;if(!this._oAnchorCell){this._oAnchorCell={record:F,column:this.getColumnById(E)};}YAHOO.util.Dom.addClass(G,YAHOO.widget.DataTable.CLASS_SELECTED);this.fireEvent("cel!
 lSelectEvent",{record:F,column:this.getColumnById(E),key:G.yuiColumnKey,el:G});return ;}}};YAHOO.widget.DataTable.prototype.unselectCell=function(A){var F=this.getTdEl(A);if(F){var E=this.getRecord(F);var D=F.yuiColumnId;if(E&&D){var C=this._aSelections||[];var G=E.getId();for(var B=C.length-1;B>-1;B--){if((C[B].recordId===G)&&(C[B].columnId===D)){C.splice(B,1);this._aSelections=C;YAHOO.util.Dom.removeClass(F,YAHOO.widget.DataTable.CLASS_SELECTED);this.fireEvent("cellUnselectEvent",{record:E,column:this.getColumnById(D),key:F.yuiColumnKey,el:F});return ;}}}}};YAHOO.widget.DataTable.prototype.unselectAllCells=function(){var B=this._aSelections||[];for(var A=B.length-1;A>-1;A--){if(B[A].constructor==Object){B.splice(A,1);}}this._aSelections=B;this._unselectAllTdEls();this.fireEvent("unselectAllCellsEvent");};YAHOO.widget.DataTable.prototype.isSelected=function(G){var F,B,A;var C=this.getTrEl(G)||this.getTdEl(G);
-if(C){return YAHOO.util.Dom.hasClass(C,YAHOO.widget.DataTable.CLASS_SELECTED);}else{var E=this._aSelections;if(E&&E.length>1){if(G instanceof YAHOO.widget.Record){F=G;}else{if(YAHOO.lang.isNumber(G)){F=this.getRecord(G);}}if(F){B=F.getId();if(E.indexOf&&(E.indexOf(B)>-1)){return true;}else{for(A=E.length-1;A>-1;A--){if(E[A]===B){return true;}}}}else{if(G.record&&G.column){B=G.record.getId();var D=G.column.getId();for(A=E.length-1;A>-1;A--){if((E[A].recordId===B)&&(E[A].columnId===D)){return true;}}}}}}return false;};YAHOO.widget.DataTable.prototype.getSelectedRows=function(){var A=[];var C=this._aSelections||[];for(var B=0;B<C.length;B++){if(YAHOO.lang.isString(C[B])){A.push(C[B]);}}return A;};YAHOO.widget.DataTable.prototype.getSelectedCells=function(){var B=[];var C=this._aSelections||[];for(var A=0;A<C.length;A++){if(C[A]&&(C[A].constructor==Object)){B.push(C[A]);}}return B;};YAHOO.widget.DataTable.prototype.getLastSelectedRecord=function(){var B=this._aSelections;if(B.l!
 ength>0){for(var A=B.length-1;A>-1;A--){if(YAHOO.lang.isString(B[A])){return B[A];}}}};YAHOO.widget.DataTable.prototype.getLastSelectedCell=function(){var B=this._aSelections;if(B.length>0){for(var A=B.length-1;A>-1;A--){if(B[A].recordId&&B[A].columnId){return B[A];}}}};YAHOO.widget.DataTable.prototype.highlightRow=function(C){var A=this.getTrEl(C);if(A){if(this._sLastHighlightedTrElId){YAHOO.util.Dom.removeClass(this._sLastHighlightedTrElId,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);}var B=this.getRecord(A);YAHOO.util.Dom.addClass(A,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);this._sLastHighlightedTrElId=A.id;this.fireEvent("rowHighlightEvent",{record:B,el:A});return ;}};YAHOO.widget.DataTable.prototype.unhighlightRow=function(C){var A=this.getTrEl(C);if(A){var B=this.getRecord(A);YAHOO.util.Dom.removeClass(A,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);this.fireEvent("rowUnhighlightEvent",{record:B,el:A});return ;}};YAHOO.widget.DataTable.prototype.highlightCell=function(A){var!
  D=this.getTdEl(A);if(D){if(this._sLastHighlightedTdElId){YAHO!
 O.util.D
om.removeClass(this._sLastHighlightedTdElId,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);}var C=this.getRecord(D);var B=D.yuiColumnId;YAHOO.util.Dom.addClass(D,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);this._sLastHighlightedTdElId=D.id;this.fireEvent("cellHighlightEvent",{record:C,column:this.getColumnById(B),key:D.yuiColumnKey,el:D});return ;}};YAHOO.widget.DataTable.prototype.unhighlightCell=function(A){var C=this.getTdEl(A);if(C){var B=this.getRecord(C);YAHOO.util.Dom.removeClass(C,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);this.fireEvent("cellUnhighlightEvent",{record:B,column:this.getColumnById(C.yuiColumnId),key:C.yuiColumnKey,el:C});return ;}};YAHOO.widget.DataTable.prototype.showCellEditor=function(E,C,G){E=YAHOO.util.Dom.get(E);if(E&&(E.ownerDocument===document)){if(!C||!(C instanceof YAHOO.widget.Record)){C=this.getRecord(E);}if(!G||!(G instanceof YAHOO.widget.Column)){G=this.getColumn(E);}if(C&&G){var D=this._oCellEditor;if(D.isActive){this.cancelCellEditor();}if(!G.e!
 ditor){return ;}D.cell=E;D.record=C;D.column=G;D.validator=(G.editorOptions&&YAHOO.lang.isFunction(G.editorOptions.validator))?G.editorOptions.validator:null;D.value=C.getData(G.key);var F=D.container;var A=YAHOO.util.Dom.getX(E);var H=YAHOO.util.Dom.getY(E);if(isNaN(A)||isNaN(H)){A=E.offsetLeft+YAHOO.util.Dom.getX(this._elTable)-this._elTbody.scrollLeft;H=E.offsetTop+YAHOO.util.Dom.getY(this._elTable)-this._elTbody.scrollTop+this._elThead.offsetHeight;}F.style.left=A+"px";F.style.top=H+"px";F.style.display="";var B;if(YAHOO.lang.isString(G.editor)){switch(G.editor){case"checkbox":B=YAHOO.widget.DataTable.editCheckbox;break;case"date":B=YAHOO.widget.DataTable.editDate;break;case"dropdown":B=YAHOO.widget.DataTable.editDropdown;break;case"radio":B=YAHOO.widget.DataTable.editRadio;break;case"textarea":B=YAHOO.widget.DataTable.editTextarea;break;case"textbox":B=YAHOO.widget.DataTable.editTextbox;break;default:B=null;}}else{if(YAHOO.lang.isFunction(G.editor)){B=G.editor;}}if(B){!
 B(this._oCellEditor,this);if(!G.editorOptions||!G.editorOption!
 s.disabl
eBtns){this.showCellEditorBtns(F);}this.doBeforeShowCellEditor(this._oCellEditor);D.isActive=true;this.fireEvent("editorShowEvent",{editor:D});return ;}}}};YAHOO.widget.DataTable.prototype.doBeforeShowCellEditor=function(A){};YAHOO.widget.DataTable.prototype.showCellEditorBtns=function(C){var D=C.appendChild(document.createElement("div"));YAHOO.util.Dom.addClass(D,YAHOO.widget.DataTable.CLASS_BUTTON);var B=D.appendChild(document.createElement("button"));YAHOO.util.Dom.addClass(B,YAHOO.widget.DataTable.CLASS_DEFAULT);B.innerHTML="OK";YAHOO.util.Event.addListener(B,"click",this.saveCellEditor,this,true);var A=D.appendChild(document.createElement("button"));A.innerHTML="Cancel";YAHOO.util.Event.addListener(A,"click",this.cancelCellEditor,this,true);};YAHOO.widget.DataTable.prototype.resetCellEditor=function(){var A=this._oCellEditor.container;A.style.display="none";YAHOO.util.Event.purgeElement(A,true);A.innerHTML="";this._oCellEditor.value=null;this._oCellEditor.isActive=false!
 ;};YAHOO.widget.DataTable.prototype.saveCellEditor=function(){if(this._oCellEditor.isActive){var A=this._oCellEditor.value;var B=this._oCellEditor.record.getData(this._oCellEditor.column.key);if(this._oCellEditor.validator){this._oCellEditor.value=this._oCellEditor.validator.call(this,A,B,this._oCellEditor);if(this._oCellEditor.value===null){this.resetCellEditor();this.fireEvent("editorRevertEvent",{editor:this._oCellEditor,oldData:B,newData:A});return ;}}this._oRecordSet.updateKey(this._oCellEditor.record,this._oCellEditor.column.key,this._oCellEditor.value);this.formatCell(this._oCellEditor.cell);this.resetCellEditor();this.fireEvent("editorSaveEvent",{editor:this._oCellEditor,oldData:B,newData:A});}else{}};YAHOO.widget.DataTable.prototype.cancelCellEditor=function(){if(this._oCellEditor.isActive){this.resetCellEditor();this.fireEvent("editorCancelEvent",{editor:this._oCellEditor});}else{}};YAHOO.widget.DataTable.editCheckbox=function(J,I){var K=J.cell;
-var O=J.record;var G=J.column;var A=J.container;var D=O.getData(G.key);if(!YAHOO.lang.isArray(D)){D=[D];}if(G.editorOptions&&YAHOO.lang.isArray(G.editorOptions.checkboxOptions)){var N=G.editorOptions.checkboxOptions;var F,L,E,C,B;for(C=0;C<N.length;C++){F=YAHOO.lang.isValue(N[C].label)?N[C].label:N[C];L=I.id+"-editor-checkbox"+C;A.innerHTML+="<input type=\"checkbox\" name=\""+I.id+"-editor-checkbox\" value=\""+F+"\" id=\""+L+"\">";E=A.appendChild(document.createElement("label"));E.htmlFor=L;E.innerHTML=F;}var H=[];var M;for(C=0;C<N.length;C++){M=YAHOO.util.Dom.get(I.id+"-editor-checkbox"+C);H.push(M);for(B=0;B<D.length;B++){if(M.value===D[B]){M.checked=true;}}if(C===0){I._focusEl(M);}}for(C=0;C<N.length;C++){M=YAHOO.util.Dom.get(I.id+"-editor-checkbox"+C);YAHOO.util.Event.addListener(M,"click",function(){var Q=[];for(var P=0;P<H.length;P++){if(H[P].checked){Q.push(H[P].value);}}I._oCellEditor.value=Q;I.fireEvent("editorUpdateEvent",{editor:I._oCellEditor});});}}};YAHOO.widg!
 et.DataTable.editDate=function(F,E){var G=F.cell;var J=F.record;var C=F.column;var A=F.container;var H=J.getData(C.key);if(YAHOO.widget.Calendar){var D=(H.getMonth()+1)+"/"+H.getDate()+"/"+H.getFullYear();var I=A.appendChild(document.createElement("div"));I.id=E.id+"-col"+C.getId()+"-dateContainer";var B=new YAHOO.widget.Calendar(E.id+"-col"+C.getId()+"-date",I.id,{selected:D,pagedate:H});B.render();I.style.cssFloat="none";B.selectEvent.subscribe(function(L,K,M){E._oCellEditor.value=new Date(K[0][0][0],K[0][0][1]-1,K[0][0][2]);E.fireEvent("editorUpdateEvent",{editor:E._oCellEditor});});}else{}};YAHOO.widget.DataTable.editDropdown=function(G,F){var H=G.cell;var L=G.record;var D=G.column;var B=G.container;var I=L.getData(D.key);var K=B.appendChild(document.createElement("select"));var J=(D.editorOptions&&YAHOO.lang.isArray(D.editorOptions.dropdownOptions))?D.editorOptions.dropdownOptions:[];for(var C=0;C<J.length;C++){var E=J[C];var A=document.createElement("option");A.value=!
 (YAHOO.lang.isValue(E.value))?E.value:E;A.innerHTML=(YAHOO.lan!
 g.isValu
e(E.text))?E.text:E;A=K.appendChild(A);if(I===K.options[C].value){K.options[C].selected=true;}}YAHOO.util.Event.addListener(K,"change",function(){F._oCellEditor.value=K[K.selectedIndex].value;F.fireEvent("editorUpdateEvent",{editor:F._oCellEditor});});F._focusEl(K);};YAHOO.widget.DataTable.editRadio=function(H,F){var I=H.cell;var M=H.record;var E=H.column;var A=H.container;var J=M.getData(E.key);if(E.editorOptions&&YAHOO.lang.isArray(E.editorOptions.radioOptions)){var G=E.editorOptions.radioOptions;var B,K,D,C;for(C=0;C<G.length;C++){B=YAHOO.lang.isValue(G[C].label)?G[C].label:G[C];K=F.id+"-editor-radio"+C;A.innerHTML+="<input type=\"radio\" name=\""+F.id+"-editor-radio\" value=\""+B+"\" id=\""+K+"\">";D=A.appendChild(document.createElement("label"));D.htmlFor=K;D.innerHTML=B;}for(C=0;C<G.length;C++){var L=YAHOO.util.Dom.get(F.id+"-editor-radio"+C);if(J===L.value){L.checked=true;F._focusEl(L);}YAHOO.util.Event.addListener(L,"click",function(){F._oCellEditor.value=this.value;!
 F.fireEvent("editorUpdateEvent",{editor:F._oCellEditor});});}}};YAHOO.widget.DataTable.editTextarea=function(H,B){var E=H.cell;var C=H.record;var G=H.column;var F=H.container;var D=C.getData(G.key);var A=F.appendChild(document.createElement("textarea"));A.style.width=E.offsetWidth+"px";A.style.height="3em";A.value=YAHOO.lang.isValue(D)?D:"";YAHOO.util.Event.addListener(A,"keyup",function(){B._oCellEditor.value=A.value;B.fireEvent("editorUpdateEvent",{editor:B._oCellEditor});});A.focus();A.select();};YAHOO.widget.DataTable.editTextbox=function(G,A){var D=G.cell;var B=G.record;var F=G.column;var E=G.container;var C=YAHOO.lang.isValue(B.getData(F.key))?B.getData(F.key):"";var H=E.appendChild(document.createElement("input"));H.type="text";H.style.width=D.offsetWidth+"px";H.value=C;YAHOO.util.Event.addListener(H,"keyup",function(){A._oCellEditor.value=H.value;A.fireEvent("editorUpdateEvent",{editor:A._oCellEditor});});H.focus();H.select();};YAHOO.widget.DataTable.validateNumber=!
 function(B){var A=B*1;if(YAHOO.lang.isNumber(A)){return A;}els!
 e{return
 null;}};YAHOO.widget.DataTable.prototype.doBeforeLoadData=function(A,B){return true;};YAHOO.widget.DataTable.prototype.onEventSortColumn=function(C){var A=C.event;var E=C.target;YAHOO.util.Event.stopEvent(A);var B=this.getThEl(E)||this.getTdEl(E);if(B&&B.yuiColumnKey){var D=this.getColumn(B.yuiColumnKey);if(D.sortable){this.sortColumn(D);}else{}}else{}};YAHOO.widget.DataTable.prototype.onEventSelectRow=function(D){var M=this.get("selectionMode");if((M=="singlecell")||(M=="cellblock")||(M=="cellrange")){return ;}var N=D.event;var C=D.target;var P=N.shiftKey;var G=N.ctrlKey||((navigator.userAgent.toLowerCase().indexOf("mac")!=-1)&&N.metaKey);var H;var F=this.getTrEl(C);if(F){var L,I;var J=this._elTbody.rows;var O=this.getRecord(F);var E=this._oRecordSet.getRecordIndex(O);var K=this.getTrIndex(F);var A=this._oAnchorRecord;if(A){L=this._oRecordSet.getRecordIndex(A);I=this.getTrIndex(A);if(I===null){if(L<this.getRecordIndex(this.getFirstTrEl())){I=0;}else{I=this.getRecordIndex(t!
 his.getLastTrEl());}}}if((M!="single")&&P&&G){if(A){if(this.isSelected(A)){if(L<E){for(H=L+1;H<=E;H++){if(!this.isSelected(H)){this.selectRow(H);}}}else{for(H=L-1;H>=E;H--){if(!this.isSelected(H)){this.selectRow(H);}}}}else{if(L<E){for(H=L+1;H<=E-1;H++){if(this.isSelected(H)){this.unselectRow(H);}}}else{for(H=E+1;H<=L-1;H++){if(this.isSelected(H)){this.unselectRow(H);}}}this.selectRow(O);}}else{this._oAnchorRecord=O;if(this.isSelected(O)){this.unselectRow(O);}else{this.selectRow(O);}}}else{if((M!="single")&&P){this.unselectAllRows();if(A){if(L<E){for(H=L;H<=E;H++){this.selectRow(H);}}else{for(H=L;H>=E;H--){this.selectRow(H);}}}else{this._oAnchorRecord=O;this.selectRow(O);}}else{if((M!="single")&&G){this._oAnchorRecord=O;if(this.isSelected(O)){this.unselectRow(O);}else{this.selectRow(O);}}else{if(M=="single"){this.unselectAllRows();this.selectRow(O);}else{this._oAnchorRecord=O;this.unselectAllRows();this.selectRow(O);
-}}}}var B;if(window.getSelection){B=window.getSelection();}else{if(document.getSelection){B=document.getSelection();}else{if(document.selection){B=document.selection;}}}if(B){if(B.empty){B.empty();}else{if(B.removeAllRanges){B.removeAllRanges();}else{if(B.collapse){B.collapse();}}}}}else{}};YAHOO.widget.DataTable.prototype.onEventSelectCell=function(W){var Q=this.get("selectionMode");if((Q=="standard")||(Q=="single")){return ;}var L=W.event;var X=W.target;var G=L.shiftKey;var C=L.ctrlKey||((navigator.userAgent.toLowerCase().indexOf("mac")!=-1)&&L.metaKey);var U,T,Z,D,A;var B=this.getTdEl(X);if(B){var R,S,I,Y;var K=this.getTrEl(B);var E=this._elTbody.rows;var N=this.getRecord(K);var a=this._oRecordSet.getRecordIndex(N);var M=this.getColumn(B);var P=M.getKeyIndex();var J=this.getTrIndex(K);var F={record:N,column:M};var H=(this._oAnchorCell)?this._oAnchorCell.record:null;if(H){R=this._oRecordSet.getRecordIndex(H);I=this._oAnchorCell.column;Y=I.getKeyIndex();S=this.getTrIndex(H!
 );if(S===null){if(R<this.getRecordIndex(this.getFirstTrEl())){S=0;}else{S=this.getRecordIndex(this.getLastTrEl());}}}var V={record:H,column:I};if((Q!="singlecell")&&G&&C){if(H&&I){if(this.isSelected(this._oAnchorCell)){if(R===a){if(Y<P){for(U=Y+1;U<=P;U++){this.selectCell(E[J].cells[U]);}}else{if(P<Y){for(U=P;U<Y;U++){this.selectCell(E[J].cells[U]);}}}}else{if(R<a){if(Q=="cellrange"){for(U=Y+1;U<E[S].cells.length;U++){this.selectCell(E[S].cells[U]);}for(U=S+1;U<J;U++){for(T=0;T<E[U].cells.length;T++){this.selectCell(E[U].cells[T]);}}for(U=0;U<=P;U++){this.selectCell(E[J].cells[U]);}}else{if(Q=="cellblock"){D=Math.min(Y,P);A=Math.max(Y,P);for(U=S;U<=J;U++){for(T=D;T<=A;T++){this.selectCell(E[U].cells[T]);}}}}}else{if(Q=="cellrange"){for(U=P;U<E[J].cells.length;U++){this.selectCell(E[J].cells[U]);}for(U=J+1;U<S;U++){for(T=0;T<E[U].cells.length;T++){this.selectCell(E[U].cells[T]);}}for(U=0;U<Y;U++){this.selectCell(E[S].cells[U]);}}else{if(Q=="cellblock"){D=Math.min(S,P);A=Math!
 .max(S,P);for(U=S;U>=J;U--){for(T=A;T>=D;T--){this.selectCell(!
 E[U].cel
ls[T]);}}}}}}}else{if(R===a){if(Y<P){for(U=Y+1;U<P;U++){this.unselectCell(E[J].cells[U]);}}else{if(P<Y){for(U=P+1;U<Y;U++){this.unselectCell(E[J].cells[U]);}}}}if(R<a){for(U=S;U<=J;U++){Z=E[U];for(T=0;T<Z.cells.length;T++){if(Z.sectionRowIndex===S){if(T>Y){this.unselectCell(Z.cells[T]);}}else{if(Z.sectionRowIndex===J){if(T<P){this.unselectCell(Z.cells[T]);}}else{this.unselectCell(Z.cells[T]);}}}}}else{for(U=J;U<=S;U++){Z=E[U];for(T=0;T<Z.cells.length;T++){if(Z.sectionRowIndex==J){if(T>P){this.unselectCell(Z.cells[T]);}}else{if(Z.sectionRowIndex==S){if(T<Y){this.unselectCell(Z.cells[T]);}}else{this.unselectCell(Z.cells[T]);}}}}}this.selectCell(B);}}else{this._oAnchorCell=F;if(this.isSelected(F)){this.unselectCell(F);}else{this.selectCell(F);}}}else{if((Q!="singlecell")&&G){this.unselectAllCells();if(V){if(R===a){if(Y<P){for(U=Y;U<=P;U++){this.selectCell(E[J].cells[U]);}}else{if(P<Y){for(U=P;U<=Y;U++){this.selectCell(E[J].cells[U]);}}}}else{if(R<a){if(Q=="cellrange"){for(U=S;U!
 <=J;U++){Z=E[U];for(T=0;T<Z.cells.length;T++){if(Z.sectionRowIndex==S){if(T>=Y){this.selectCell(Z.cells[T]);}}else{if(Z.sectionRowIndex==J){if(T<=P){this.selectCell(Z.cells[T]);}}else{this.selectCell(Z.cells[T]);}}}}}else{if(Q=="cellblock"){D=Math.min(Y,P);A=Math.max(Y,P);for(U=S;U<=J;U++){for(T=D;T<=A;T++){this.selectCell(E[U].cells[T]);}}}}}else{if(Q=="cellrange"){for(U=J;U<=S;U++){Z=E[U];for(T=0;T<Z.cells.length;T++){if(Z.sectionRowIndex==J){if(T>=P){this.selectCell(Z.cells[T]);}}else{if(Z.sectionRowIndex==S){if(T<=Y){this.selectCell(Z.cells[T]);}}else{this.selectCell(Z.cells[T]);}}}}}else{if(Q=="cellblock"){D=Math.min(Y,P);A=Math.max(Y,P);for(U=J;U<=S;U++){for(T=D;T<=A;T++){this.selectCell(E[U].cells[T]);}}}}}}}else{this._oAnchorCell=F;this.selectCell(F);}}else{if((Q!="singlecell")&&C){this._oAnchorCell=F;if(this.isSelected(F)){this.unselectCell(F);}else{this.selectCell(F);}}else{this._oAnchorCell=F;this.unselectAllCells();this.selectCell(F);}}}var O;if(window.getSelect!
 ion){O=window.getSelection();}else{if(document.getSelection){O!
 =documen
t.getSelection();}else{if(document.selection){O=document.selection;}}}if(O){if(O.empty){O.empty();}else{if(O.removeAllRanges){O.removeAllRanges();}else{if(O.collapse){O.collapse();}}}}}else{}};YAHOO.widget.DataTable.prototype.onEventHighlightRow=function(B){var A=B.event;var C=B.target;this.highlightRow(C);};YAHOO.widget.DataTable.prototype.onEventUnhighlightRow=function(B){var A=B.event;var C=B.target;this.unhighlightRow(C);};YAHOO.widget.DataTable.prototype.onEventHighlightCell=function(B){var A=B.event;var C=B.target;this.highlightCell(C);};YAHOO.widget.DataTable.prototype.onEventUnhighlightCell=function(B){var A=B.event;var C=B.target;this.unhighlightCell(C);};YAHOO.widget.DataTable.prototype.onEventFormatCell=function(C){var A=C.event;var F=C.target;var B=F.tagName.toLowerCase();var D=this.getTdEl(F);if(D&&D.yuiColumnKey){var E=this.getColumn(D.yuiColumnKey);this.formatCell(D,this.getRecord(D),E);}else{}};YAHOO.widget.DataTable.prototype.onEventShowCellEditor=function(C!
 ){var A=C.event;var E=C.target;var B=E.tagName.toLowerCase();var D=this.getTdEl(E);if(D){this.showCellEditor(D);}else{}};YAHOO.widget.DataTable.prototype.onEventEditCell=function(A){this.onEventShowCellEditor(A);};YAHOO.widget.DataTable.prototype.onEventSaveCellEditor=function(A){this.saveCellEditor();};YAHOO.widget.DataTable.prototype._onDataReturnEnhanceTable=function(B,C){var A=this.doBeforeLoadData(B,C);if(A&&C&&!C.error&&YAHOO.lang.isArray(C.results)){this._oRecordSet.addRecords(C.results);this._initTableEl();if(!this._elTable||!this._elThead||!this._elTbody){return ;}YAHOO.widget.DataTable.superclass.constructor.call(this,this._elContainer,this._oConfigs);if(this._oConfigs.paginator){this.updatePaginator(this._oConfigs.paginator);}this.refreshView();}else{if(A&&C.error){this.showTableMessage(YAHOO.widget.DataTable.MSG_ERROR,YAHOO.widget.DataTable.CLASS_ERROR);}else{if(A){this.showTableMessage(YAHOO.widget.DataTable.MSG_EMPTY,YAHOO.widget.DataTable.CLASS_EMPTY);
-}}}};YAHOO.widget.DataTable.prototype.onDataReturnInitializeTable=function(B,C){this.fireEvent("dataReturnEvent",{request:B,response:C});var A=this.doBeforeLoadData(B,C);if(A&&C&&!C.error&&YAHOO.lang.isArray(C.results)){this.initializeTable(C.results);}else{if(A&&C.error){this.showTableMessage(YAHOO.widget.DataTable.MSG_ERROR,YAHOO.widget.DataTable.CLASS_ERROR);}else{if(A){this.showTableMessage(YAHOO.widget.DataTable.MSG_EMPTY,YAHOO.widget.DataTable.CLASS_EMPTY);}}}};YAHOO.widget.DataTable.prototype.onDataReturnReplaceRows=function(A,B){this.onDataReturnInitializeTable(A,B);};YAHOO.widget.DataTable.prototype.onDataReturnAppendRows=function(B,C){this.fireEvent("dataReturnEvent",{request:B,response:C});var A=this.doBeforeLoadData(B,C);if(A&&C&&!C.error&&YAHOO.lang.isArray(C.results)){this.addRows(C.results);}else{if(A&&C.error){this.showTableMessage(YAHOO.widget.DataTable.MSG_ERROR,YAHOO.widget.DataTable.CLASS_ERROR);}}};YAHOO.widget.DataTable.prototype.onDataReturnInsertRows!
 =function(B,C){this.fireEvent("dataReturnEvent",{request:B,response:C});var A=this.doBeforeLoadData(B,C);if(A&&C&&!C.error&&YAHOO.lang.isArray(C.results)){this.addRows(C.results,0);}else{if(A&&C.error){this.showTableMessage(YAHOO.widget.DataTable.MSG_ERROR,YAHOO.widget.DataTable.CLASS_ERROR);}}};YAHOO.widget.ColumnSet=function(F){this._sName="instance"+YAHOO.widget.ColumnSet._nCount;var K=[];var A=[];var I=[];var E=[];var C=-1;var H=this;var B=function(N,T){C++;if(!K[C]){K[C]=[];}for(var P=0;P<N.length;P++){var L=N[P];var R=new YAHOO.widget.Column(L);R._sId=YAHOO.widget.Column._nCount+"";R._sName="Column instance"+YAHOO.widget.Column._nCount;if(!YAHOO.lang.isValue(R.key)){R.key="yui-dt-col"+YAHOO.widget.Column._nCount;}YAHOO.widget.Column._nCount++;A.push(R);if(T){R.parent=T;}if(YAHOO.lang.isArray(L.children)){R.children=L.children;var S=0;var Q=function(W){var X=W.children;for(var V=0;V<X.length;V++){if(YAHOO.lang.isArray(X[V].children)){Q(X[V]);}else{S++;}}};Q(L);R._colsp!
 an=S;var U=L.children;for(var O=0;O<U.length;O++){var M=U[O];i!
 f(R.clas
sName&&(M.className===undefined)){M.className=R.className;}if(R.editor&&(M.editor===undefined)){M.editor=R.editor;}if(R.editorOptions&&(M.editorOptions===undefined)){M.editorOptions=R.editorOptions;}if(R.formatter&&(M.formatter===undefined)){M.formatter=R.formatter;}if(R.resizeable&&(M.resizeable===undefined)){M.resizeable=R.resizeable;}if(R.sortable&&(M.sortable===undefined)){M.sortable=R.sortable;}if(R.width&&(M.width===undefined)){M.width=R.width;}if(R.type&&(M.type===undefined)){M.type=R.type;}if(R.type&&!R.formatter){R.formatter=R.type;}if(R.text&&!YAHOO.lang.isValue(R.label)){R.label=R.text;}if(R.parser){}if(R.sortOptions&&((R.sortOptions.ascFunction)||(R.sortOptions.descFunction))){}}if(!K[C+1]){K[C+1]=[];}B(U,R);}else{R._nKeyIndex=I.length;R._colspan=1;I.push(R);}K[C].push(R);}C--;};if(YAHOO.lang.isArray(F)){B(F);}var D=function(M){var N=1;var P;var O;var Q=function(U,T){T=T||1;for(var V=0;V<U.length;V++){var S=U[V];if(YAHOO.lang.isArray(S.children)){T++;Q(S.children!
 ,T);T--;}else{if(T>N){N=T;}}}};for(var L=0;L<M.length;L++){P=M[L];Q(P);for(var R=0;R<P.length;R++){O=P[R];if(!YAHOO.lang.isArray(O.children)){O._rowspan=N;}else{O._rowspan=1;}}N=1;}};D(K);var J=function(L,M){E[L].push(M._sId);if(M.parent){J(L,M.parent);}};for(var G=0;G<I.length;G++){E[G]=[];J(G,I[G]);E[G]=E[G].reverse();}this.tree=K;this.flat=A;this.keys=I;this.headers=E;YAHOO.widget.ColumnSet._nCount++;};YAHOO.widget.ColumnSet._nCount=0;YAHOO.widget.ColumnSet.prototype._sName=null;YAHOO.widget.ColumnSet.prototype.tree=null;YAHOO.widget.ColumnSet.prototype.flat=null;YAHOO.widget.ColumnSet.prototype.keys=null;YAHOO.widget.ColumnSet.prototype.headers=null;YAHOO.widget.ColumnSet.prototype.toString=function(){return"ColumnSet "+this._sName;};YAHOO.widget.ColumnSet.prototype.getColumnById=function(C){if(YAHOO.lang.isString(C)){var A=this.flat;for(var B=A.length-1;B>-1;B--){if(A[B]._sId===C){return A[B];}}}return null;};YAHOO.widget.ColumnSet.prototype.getColumn=function(C){if(YA!
 HOO.lang.isNumber(C)&&this.keys[C]){return this.keys[C];}else{!
 if(YAHOO
.lang.isString(C)){var A=this.flat;var D=[];for(var B=0;B<A.length;B++){if(A[B].key===C){D.push(A[B]);}}if(D.length===1){return D[0];}else{if(D.length>1){return D;}}}}return null;};YAHOO.widget.Column=function(B){if(B&&(B.constructor==Object)){for(var A in B){if(A){this[A]=B[A];}}}};YAHOO.widget.Column._nCount=0;YAHOO.widget.Column.prototype._sName=null;YAHOO.widget.Column.prototype._sId=null;YAHOO.widget.Column.prototype._nKeyIndex=null;YAHOO.widget.Column.prototype._colspan=1;YAHOO.widget.Column.prototype._rowspan=1;YAHOO.widget.Column.prototype._parent=null;YAHOO.widget.Column.prototype._width=null;YAHOO.widget.Column.prototype._minWidth=null;YAHOO.widget.Column.prototype.key=null;YAHOO.widget.Column.prototype.label=null;YAHOO.widget.Column.prototype.abbr=null;YAHOO.widget.Column.prototype.children=null;YAHOO.widget.Column.prototype.width=null;YAHOO.widget.Column.prototype.className=null;YAHOO.widget.Column.prototype.formatter=null;YAHOO.widget.Column.prototype.editor=nul!
 l;YAHOO.widget.Column.prototype.editorOptions=null;YAHOO.widget.Column.prototype.resizeable=false;YAHOO.widget.Column.prototype.sortable=false;YAHOO.widget.Column.prototype.sortOptions=null;YAHOO.widget.Column.prototype.toString=function(){return this._sName;};YAHOO.widget.Column.prototype.getId=function(){return this._sId;};YAHOO.widget.Column.prototype.getKey=function(){return this.key;};YAHOO.widget.Column.prototype.getKeyIndex=function(){return this._nKeyIndex;};YAHOO.widget.Column.prototype.getParent=function(){return this._parent;};YAHOO.widget.Column.prototype.getColspan=function(){return this._colspan;};YAHOO.widget.Column.prototype.getColSpan=function(){return this.getColspan();};YAHOO.widget.Column.prototype.getRowspan=function(){return this._rowspan;};YAHOO.widget.Column.prototype.getIndex=function(){return this.getKeyIndex();};YAHOO.widget.Column.prototype.format=function(){};YAHOO.widget.Column.formatCheckbox=function(B,A,C,D){YAHOO.widget.DataTable.formatCheck!
 box(B,A,C,D);
-};YAHOO.widget.Column.formatCurrency=function(B,A,C,D){YAHOO.widget.DataTable.formatCurrency(B,A,C,D);};YAHOO.widget.Column.formatDate=function(B,A,C,D){YAHOO.widget.DataTable.formatDate(B,A,C,D);};YAHOO.widget.Column.formatEmail=function(B,A,C,D){YAHOO.widget.DataTable.formatEmail(B,A,C,D);};YAHOO.widget.Column.formatLink=function(B,A,C,D){YAHOO.widget.DataTable.formatLink(B,A,C,D);};YAHOO.widget.Column.formatNumber=function(B,A,C,D){YAHOO.widget.DataTable.formatNumber(B,A,C,D);};YAHOO.widget.Column.formatSelect=function(B,A,C,D){YAHOO.widget.DataTable.formatDropdown(B,A,C,D);};YAHOO.util.Sort={compare:function(B,A,C){if((B===null)||(typeof B=="undefined")){if((A===null)||(typeof A=="undefined")){return 0;}else{return 1;}}else{if((A===null)||(typeof A=="undefined")){return -1;}}if(B.constructor==String){B=B.toLowerCase();}if(A.constructor==String){A=A.toLowerCase();}if(B<A){return(C)?1:-1;}else{if(B>A){return(C)?-1:1;}else{return 0;}}}};YAHOO.util.ColumnResizer=function(F,!
 E,D,B,A,C){if(F&&E&&D&&B){this.datatable=F;this.column=E;this.cell=D;this.init(B,A,C);this.setYConstraint(0,0);}else{}};if(YAHOO.util.DD){YAHOO.extend(YAHOO.util.ColumnResizer,YAHOO.util.DD);}YAHOO.util.ColumnResizer.prototype.onMouseDown=function(F){this.startWidth=this.cell.offsetWidth;this.startPos=YAHOO.util.Dom.getX(this.getDragEl());if(this.datatable.fixedWidth){var B=YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_LABEL,"span",this.cell)[0];this.minWidth=B.offsetWidth+6;var A=this.cell.nextSibling;var D=YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_LABEL,"span",A)[0];this.sibMinWidth=D.offsetWidth+6;var E=((this.startWidth-this.minWidth)<0)?0:(this.startWidth-this.minWidth);var C=((A.offsetWidth-this.sibMinWidth)<0)?0:(A.offsetWidth-this.sibMinWidth);this.setXConstraint(E,C);}};YAHOO.util.ColumnResizer.prototype.onMouseUp=function(B){var A=YAHOO.util.Dom.get(this.handleElId).style;A.left="auto";A.right=0;A.marginRight="-6px";A.!
 width="6px";this.datatable.fireEvent("columnResizeEvent",{colu!
 mn:this.
column,target:this.cell});};YAHOO.util.ColumnResizer.prototype.onDrag=function(F){try{var G=YAHOO.util.Dom.getX(this.getDragEl());var E=G-this.startPos;var D=this.startWidth+E;if(D<this.minWidth){D=this.minWidth;}var I=this.datatable;var H=this.cell;if(I.fixedWidth){var B=H.nextSibling;var A=B.offsetWidth-E;if(A<this.sibMinWidth){A=this.sibMinWidth;}for(var C=0;C<I._oColumnSet.length;C++){}B.style.width=A;H.style.width=D+"px";}else{H.style.width=D+"px";}}catch(F){}};YAHOO.widget.RecordSet=function(A){this._sName="RecordSet instance"+YAHOO.widget.RecordSet._nCount;YAHOO.widget.RecordSet._nCount++;this._records=[];this._length=0;if(A){if(YAHOO.lang.isArray(A)){this.addRecords(A);}else{if(A.constructor==Object){this.addRecord(A);}}}this.createEvent("recordAddEvent");this.createEvent("recordsAddEvent");this.createEvent("recordUpdateEvent");this.createEvent("recordDeleteEvent");this.createEvent("recordsDeleteEvent");this.createEvent("resetEvent");this.createEvent("keyUpdateEvent"!
 );};if(YAHOO.util.EventProvider){YAHOO.augment(YAHOO.widget.RecordSet,YAHOO.util.EventProvider);}else{}YAHOO.widget.RecordSet._nCount=0;YAHOO.widget.RecordSet.prototype._sName=null;YAHOO.widget.RecordSet.prototype._length=null;YAHOO.widget.RecordSet.prototype._addRecord=function(C,A){var B=new YAHOO.widget.Record(C);if(YAHOO.lang.isNumber(A)&&(A>-1)){this._records.splice(A,0,B);}else{A=this.getLength();this._records.push(B);}this._length++;return B;};YAHOO.widget.RecordSet.prototype._deleteRecord=function(B,A){if(!YAHOO.lang.isNumber(A)||(A<0)){A=1;}this._records.splice(B,A);this._length=this._length-A;};YAHOO.widget.RecordSet.prototype.toString=function(){return this._sName;};YAHOO.widget.RecordSet.prototype.getLength=function(){return this._length;};YAHOO.widget.RecordSet.prototype.getRecord=function(A){var B;if(A instanceof YAHOO.widget.Record){for(B=0;B<this._records.length;B++){if(this._records[B]._sId===A._sId){return A;}}}else{if(YAHOO.lang.isNumber(A)){if((A>-1)&&(A!
 <this.getLength())){return this._records[A];}}else{if(YAHOO.la!
 ng.isStr
ing(A)){for(B=0;B<this._records.length;B++){if(this._records[B]._sId===A){return this._records[B];}}}}}return null;};YAHOO.widget.RecordSet.prototype.getRecords=function(B,A){if(!YAHOO.lang.isNumber(B)){return this._records;}if(!YAHOO.lang.isNumber(A)){return this._records.slice(B);}return this._records.slice(B,B+A);};YAHOO.widget.RecordSet.prototype.getRecordIndex=function(B){if(B){for(var A=this._records.length-1;A>-1;A--){if(B.getId()===this._records[A].getId()){return A;}}}return null;};YAHOO.widget.RecordSet.prototype.addRecord=function(C,A){if(C&&(C.constructor==Object)){var B=this._addRecord(C,A);this.fireEvent("recordAddEvent",{record:B,data:C});return B;}else{return null;}};YAHOO.widget.RecordSet.prototype.addRecords=function(C,B){if(YAHOO.lang.isArray(C)){var F=[];for(var D=0;D<C.length;D++){if(C[D]&&(C[D].constructor==Object)){var A=this._addRecord(C[D],B);F.push(A);}}this.fireEvent("recordsAddEvent",{records:F,data:C});return F;}else{if(C&&(C.constructor==Object)!
 ){var E=this._addRecord(C);this.fireEvent("recordsAddEvent",{records:[E],data:C});return E;}else{}}};YAHOO.widget.RecordSet.prototype.updateRecord=function(A,E){var C=this.getRecord(A);if(C&&E&&(E.constructor==Object)){var D={};for(var B in C._oData){D[B]=C._oData[B];}C._oData=E;this.fireEvent("recordUpdateEvent",{record:C,newData:E,oldData:D});return C;}else{return null;}};YAHOO.widget.RecordSet.prototype.updateKey=function(A,D,G){var C=this.getRecord(A);if(C){var F=null;var E=C._oData[D];if(E&&E.constructor==Object){F={};for(var B in E){F[B]=E[B];}}else{F=E;}C._oData[D]=G;this.fireEvent("keyUpdateEvent",{record:C,key:D,newData:G,oldData:F});}else{}};YAHOO.widget.RecordSet.prototype.replaceRecords=function(A){this.reset();return this.addRecords(A);};YAHOO.widget.RecordSet.prototype.sortRecords=function(A,B){return this._records.sort(function(D,C){return A(D,C,B);});};YAHOO.widget.RecordSet.prototype.deleteRecord=function(B){if(YAHOO.lang.isNumber(B)&&(B>-1)&&(B<this.getLen!
 gth())){var A=this.getRecord(B).getData();
-var D={};for(var C in A){D[C]=A[C];}this._deleteRecord(B);this.fireEvent("recordDeleteEvent",{data:D,index:B});return D;}else{return null;}};YAHOO.widget.RecordSet.prototype.deleteRecords=function(C,A){if(!YAHOO.lang.isNumber(A)){A=1;}if(YAHOO.lang.isNumber(C)&&(C>-1)&&(C<this.getLength())){var F=this.getRecords(C,A);var B=[];for(var E=0;E<F.length;E++){var G={};for(var D in F[E]){G[D]=F[E][D];}B.push(G);}this._deleteRecord(C,A);this.fireEvent("recordsDeleteEvent",{data:B,index:C});}else{}};YAHOO.widget.RecordSet.prototype.reset=function(){this._records=[];this._length=0;this.fireEvent("resetEvent");};YAHOO.widget.Record=function(A){this._sId=YAHOO.widget.Record._nCount+"";YAHOO.widget.Record._nCount++;this._oData={};if(A&&(A.constructor==Object)){for(var B in A){this._oData[B]=A[B];}}};YAHOO.widget.Record._nCount=0;YAHOO.widget.Record.prototype._sId=null;YAHOO.widget.Record.prototype._oData=null;YAHOO.widget.Record.prototype.getId=function(){return this._sId;};YAHOO.widget!
 .Record.prototype.getData=function(A){if(YAHOO.lang.isString(A)){return this._oData[A];}else{return this._oData;}};YAHOO.register("datatable",YAHOO.widget.DataTable,{version:"2.4.1",build:"742"});
\ No newline at end of file
+YAHOO.util.Chain=function(){this.q=[].slice.call(arguments);this.createEvent("end");};YAHOO.util.Chain.prototype={id:0,run:function(){var F=this.q[0],C;if(!F){this.fireEvent("end");return this;}else{if(this.id){return this;}}C=F.method||F;if(typeof C==="function"){var E=F.scope||{},B=F.argument||[],A=F.timeout||0,D=this;if(!(B instanceof Array)){B=[B];}if(A<0){this.id=A;if(F.until){for(;!F.until();){C.apply(E,B);}}else{if(F.iterations){for(;F.iterations-->0;){C.apply(E,B);}}else{C.apply(E,B);}}this.q.shift();this.id=0;return this.run();}else{if(F.until){if(F.until()){this.q.shift();return this.run();}}else{if(!F.iterations||!--F.iterations){this.q.shift();}}this.id=setTimeout(function(){C.apply(E,B);if(D.id){D.id=0;D.run();}},A);}}return this;},add:function(A){this.q.push(A);return this;},pause:function(){clearTimeout(this.id);this.id=0;return this;},stop:function(){this.pause();this.q=[];return this;}};YAHOO.lang.augmentProto(YAHOO.util.Chain,YAHOO.util.EventProvider);YAHO!
 O.widget.ColumnSet=function(A){this._sId="yui-cs"+YAHOO.widget.ColumnSet._nCount;A=YAHOO.widget.DataTable._cloneObject(A);this._init(A);YAHOO.widget.ColumnSet._nCount++;};YAHOO.widget.ColumnSet._nCount=0;YAHOO.widget.ColumnSet.prototype={_sId:null,_aDefinitions:null,tree:null,flat:null,keys:null,headers:null,_init:function(I){var J=[];var A=[];var G=[];var E=[];var C=-1;var B=function(M,S){C++;if(!J[C]){J[C]=[];}for(var O=0;O<M.length;O++){var K=M[O];var Q=new YAHOO.widget.Column(K);K.yuiColumnId=Q._sId=YAHOO.widget.Column._nCount+"";if(!YAHOO.lang.isValue(Q.key)){Q.key="yui-dt-col"+YAHOO.widget.Column._nCount;}YAHOO.widget.Column._nCount++;A.push(Q);if(S){Q.parent=S;}if(YAHOO.lang.isArray(K.children)){Q.children=K.children;var R=0;var P=function(V){var W=V.children;for(var U=0;U<W.length;U++){if(YAHOO.lang.isArray(W[U].children)){P(W[U]);}else{R++;}}};P(K);Q._nColspan=R;var T=K.children;for(var N=0;N<T.length;N++){var L=T[N];if(Q.className&&(L.className===undefined)){L.cla!
 ssName=Q.className;}if(Q.editor&&(L.editor===undefined)){L.edi!
 tor=Q.ed
itor;}if(Q.editorOptions&&(L.editorOptions===undefined)){L.editorOptions=Q.editorOptions;}if(Q.formatter&&(L.formatter===undefined)){L.formatter=Q.formatter;}if(Q.resizeable&&(L.resizeable===undefined)){L.resizeable=Q.resizeable;}if(Q.sortable&&(L.sortable===undefined)){L.sortable=Q.sortable;}if(Q.width&&(L.width===undefined)){L.width=Q.width;}if(Q.type&&(L.type===undefined)){L.type=Q.type;}if(Q.type&&!Q.formatter){Q.formatter=Q.type;}if(Q.text&&!YAHOO.lang.isValue(Q.label)){Q.label=Q.text;}if(Q.parser){}if(Q.sortOptions&&((Q.sortOptions.ascFunction)||(Q.sortOptions.descFunction))){}}if(!J[C+1]){J[C+1]=[];}B(T,Q);}else{Q._nKeyIndex=G.length;Q._nColspan=1;G.push(Q);}J[C].push(Q);}C--;};if(YAHOO.lang.isArray(I)){B(I);this._aDefinitions=I;}else{return null;}var F;var D=function(L){var M=1;var O;var N;var P=function(T,S){S=S||1;for(var U=0;U<T.length;U++){var R=T[U];if(YAHOO.lang.isArray(R.children)){S++;P(R.children,S);S--;}else{if(S>M){M=S;}}}};for(var K=0;K<L.length;K++){O=L[!
 K];P(O);for(var Q=0;Q<O.length;Q++){N=O[Q];if(!YAHOO.lang.isArray(N.children)){N._nRowspan=M;}else{N._nRowspan=1;}}M=1;}};D(J);for(F=0;F<J[0].length;F++){J[0][F]._nTreeIndex=F;}var H=function(K,L){E[K].push(L._sId);if(L.parent){H(K,L.parent);}};for(F=0;F<G.length;F++){E[F]=[];H(F,G[F]);E[F]=E[F].reverse();}this.tree=J;this.flat=A;this.keys=G;this.headers=E;},getId:function(){return this._sId;},toString:function(){return"ColumnSet instance "+this._sId;},getDefinitions:function(){var A=this._aDefinitions;var B=function(D,F){for(var C=0;C<D.length;C++){var E=D[C];var G=F.getColumnById(E.yuiColumnId);if(G){E.abbr=G.abbr;E.className=G.className;E.editor=G.editor;E.editorOptions=G.editorOptions;E.formatter=G.formatter;E.hidden=G.hidden;E.key=G.key;E.label=G.label;E.minWidth=G.minWidth;E.resizeable=G.resizeable;E.selected=G.selected;E.sortable=G.sortable;E.sortOptions=G.sortOptions;E.width=G.width;}if(YAHOO.lang.isArray(E.children)){B(E.children,F);}}};B(A,this);this._aDefinitions!
 =A;return A;},getColumnById:function(C){if(YAHOO.lang.isString!
 (C)){var
 A=this.flat;for(var B=A.length-1;B>-1;B--){if(A[B]._sId===C){return A[B];}}}return null;},getColumn:function(C){if(YAHOO.lang.isNumber(C)&&this.keys[C]){return this.keys[C];}else{if(YAHOO.lang.isString(C)){var A=this.flat;var D=[];for(var B=0;B<A.length;B++){if(A[B].key===C){D.push(A[B]);}}if(D.length===1){return D[0];}else{if(D.length>1){return D;}}}}return null;},getDescendants:function(D){var B=this;var C=[];var A;var E=function(F){C.push(F);if(F.children){for(A=0;A<F.children.length;A++){E(B.getColumn(F.children[A].key));}}};E(D);return C;}};YAHOO.widget.Column=function(B){if(B&&(B.constructor==Object)){for(var A in B){if(A){this[A]=B[A];}}}if(this.width&&!YAHOO.lang.isNumber(this.width)){this.width=null;}};YAHOO.lang.augmentObject(YAHOO.widget.Column,{_nCount:0,formatCheckbox:function(B,A,C,D){YAHOO.widget.DataTable.formatCheckbox(B,A,C,D);},formatCurrency:function(B,A,C,D){YAHOO.widget.DataTable.formatCurrency(B,A,C,D);},formatDate:function(B,A,C,D){YAHOO.widget.DataT!
 able.formatDate(B,A,C,D);},formatEmail:function(B,A,C,D){YAHOO.widget.DataTable.formatEmail(B,A,C,D);},formatLink:function(B,A,C,D){YAHOO.widget.DataTable.formatLink(B,A,C,D);},formatNumber:function(B,A,C,D){YAHOO.widget.DataTable.formatNumber(B,A,C,D);},formatSelect:function(B,A,C,D){YAHOO.widget.DataTable.formatDropdown(B,A,C,D);}});YAHOO.widget.Column.prototype={_sId:null,_oDefinition:null,_nKeyIndex:null,_nTreeIndex:null,_nColspan:1,_nRowspan:1,_oParent:null,_elTh:null,_elResizer:null,_dd:null,_ddResizer:null,key:null,label:null,abbr:null,children:null,width:null,minWidth:10,hidden:false,selected:false,className:null,formatter:null,editor:null,editorOptions:null,resizeable:false,sortable:false,sortOptions:null,getId:function(){return this._sId;},toString:function(){return"Column instance "+this._sId;},getDefinition:function(){var A=this._oDefinition;A.abbr=this.abbr;A.className=this.className;A.editor=this.editor;
+A.editorOptions=this.editorOptions;A.formatter=this.formatter;A.key=this.key;A.label=this.label;A.minWidth=this.minWidth;A.resizeable=this.resizeable;A.sortable=this.sortable;A.sortOptions=this.sortOptions;A.width=this.width;return A;},getKey:function(){return this.key;},getKeyIndex:function(){return this._nKeyIndex;},getTreeIndex:function(){return this._nTreeIndex;},getParent:function(){return this._oParent;},getColspan:function(){return this._nColspan;},getColSpan:function(){return this.getColspan();},getRowspan:function(){return this._nRowspan;},getThEl:function(){return this._elTh;},getResizerEl:function(){return this._elResizer;},getColEl:function(){return this.getThEl();},getIndex:function(){return this.getKeyIndex();},format:function(){}};YAHOO.util.Sort={compare:function(B,A,C){if((B===null)||(typeof B=="undefined")){if((A===null)||(typeof A=="undefined")){return 0;}else{return 1;}}else{if((A===null)||(typeof A=="undefined")){return -1;}}if(B.constructor==String){B=!
 B.toLowerCase();}if(A.constructor==String){A=A.toLowerCase();}if(B<A){return(C)?1:-1;}else{if(B>A){return(C)?-1:1;}else{return 0;}}}};YAHOO.widget.ColumnDD=function(D,A,C,B){if(D&&A&&C&&B){this.datatable=D;this.table=D.getTheadEl().parentNode;this.column=A;this.headCell=C;this.pointer=B;this.newIndex=null;this.init(C);this.initFrame();this.invalidHandleTypes={};this.setPadding(10,0,(this.datatable.getTheadEl().offsetHeight+10),0);}else{}};if(YAHOO.util.DDProxy){YAHOO.extend(YAHOO.widget.ColumnDD,YAHOO.util.DDProxy,{initConstraints:function(){var G=YAHOO.util.Dom.getRegion(this.table),D=this.getEl(),F=YAHOO.util.Dom.getXY(D),C=parseInt(YAHOO.util.Dom.getStyle(D,"width"),10),A=parseInt(YAHOO.util.Dom.getStyle(D,"height"),10),E=((F[0]-G.left)+15),B=((G.right-F[0]-C)+15);this.setXConstraint(E,B);this.setYConstraint(10,10);YAHOO.util.Event.on(window,"resize",function(){this.initConstraints();},this,true);},_resizeProxy:function(){this.constructor.superclass._resizeProxy.apply(th!
 is,arguments);var A=this.getDragEl(),B=this.getEl();YAHOO.util!
 .Dom.set
Style(this.pointer,"height",(this.table.parentNode.offsetHeight+10)+"px");YAHOO.util.Dom.setStyle(this.pointer,"display","block");var C=YAHOO.util.Dom.getXY(B);YAHOO.util.Dom.setXY(this.pointer,[C[0],(C[1]-5)]);YAHOO.util.Dom.setStyle(A,"height",this.datatable.getContainerEl().offsetHeight+"px");YAHOO.util.Dom.setStyle(A,"width",(parseInt(YAHOO.util.Dom.getStyle(A,"width"),10)+4)+"px");YAHOO.util.Dom.setXY(this.dragEl,C);},onMouseDown:function(){this.initConstraints();this.resetConstraints();},clickValidator:function(B){if(!this.column.hidden){var A=YAHOO.util.Event.getTarget(B);return(this.isValidHandleChild(A)&&(this.id==this.handleElId||this.DDM.handleWasClicked(A,this.id)));}},onDragOver:function(G,A){var E=this.datatable.getColumn(A);if(E){var C=YAHOO.util.Event.getPageX(G),H=YAHOO.util.Dom.getX(A),I=H+((YAHOO.util.Dom.get(A).offsetWidth)/2),F=this.column.getTreeIndex(),B=E.getTreeIndex(),J=B;if(C<I){YAHOO.util.Dom.setX(this.pointer,H);}else{var D=parseInt(E.getThEl().o!
 ffsetWidth,10);YAHOO.util.Dom.setX(this.pointer,(H+D));J++;}if(B>F){J--;}if(J<0){J=0;}else{if(J>this.datatable.getColumnSet().tree[0].length){J=this.datatable.getColumnSet().tree[0].length;}}this.newIndex=J;}},onDragDrop:function(){if(YAHOO.lang.isNumber(this.newIndex)&&(this.newIndex!==this.column.getTreeIndex())){var C=this.datatable;C._oChainRender.stop();var B=C._oColumnSet.getDefinitions();var A=B.splice(this.column.getTreeIndex(),1)[0];B.splice(this.newIndex,0,A);C._initColumnSet(B);C._initTheadEls();C.render();C.fireEvent("columnReorderEvent");}},endDrag:function(){this.newIndex=null;YAHOO.util.Dom.setStyle(this.pointer,"display","none");}});}YAHOO.util.ColumnResizer=function(E,C,D,A,B){if(E&&C&&D&&A){this.datatable=E;this.column=C;this.headCell=D;this.headCellLiner=D.firstChild;this.init(A,A,{dragOnly:true,dragElId:B.id});this.initFrame();}else{}};if(YAHOO.util.DD){YAHOO.extend(YAHOO.util.ColumnResizer,YAHOO.util.DDProxy,{resetResizerEl:function(){var A=YAHOO.util.D!
 om.get(this.handleElId).style;A.left="auto";A.right=0;A.top="a!
 uto";A.b
ottom=0;},onMouseUp:function(C){this.resetResizerEl();var A=this.headCell.firstChild;var B=A.offsetWidth-(parseInt(YAHOO.util.Dom.getStyle(A,"paddingLeft"),10)|0)-(parseInt(YAHOO.util.Dom.getStyle(A,"paddingRight"),10)|0);this.datatable.fireEvent("columnResizeEvent",{column:this.column,target:this.headCell,width:B});},onMouseDown:function(A){this.startWidth=this.headCell.firstChild.offsetWidth;this.startX=YAHOO.util.Event.getXY(A)[0];this.nLinerPadding=(parseInt(YAHOO.util.Dom.getStyle(this.headCellLiner,"paddingLeft"),10)|0)+(parseInt(YAHOO.util.Dom.getStyle(this.headCellLiner,"paddingRight"),10)|0);},clickValidator:function(B){if(!this.column.hidden){var A=YAHOO.util.Event.getTarget(B);return(this.isValidHandleChild(A)&&(this.id==this.handleElId||this.DDM.handleWasClicked(A,this.id)));}},onDrag:function(C){var D=YAHOO.util.Event.getXY(C)[0];if(D>YAHOO.util.Dom.getX(this.headCellLiner)){var A=D-this.startX;var B=this.startWidth+A-this.nLinerPadding;this.datatable.setColumnW!
 idth(this.column,B);}}});}YAHOO.widget.RecordSet=function(A){this._sId="yui-rs"+YAHOO.widget.RecordSet._nCount;YAHOO.widget.RecordSet._nCount++;this._records=[];if(A){if(YAHOO.lang.isArray(A)){this.addRecords(A);}else{if(A.constructor==Object){this.addRecord(A);}}}this.createEvent("recordAddEvent");this.createEvent("recordsAddEvent");this.createEvent("recordSetEvent");this.createEvent("recordsSetEvent");this.createEvent("recordUpdateEvent");this.createEvent("recordDeleteEvent");this.createEvent("recordsDeleteEvent");this.createEvent("resetEvent");this.createEvent("keyUpdateEvent");this.createEvent("recordValueUpdateEvent");};YAHOO.widget.RecordSet._nCount=0;YAHOO.widget.RecordSet.prototype={_sId:null,_addRecord:function(C,A){var B=new YAHOO.widget.Record(C);if(YAHOO.lang.isNumber(A)&&(A>-1)){this._records.splice(A,0,B);}else{this._records[this._records.length]=B;}return B;},_setRecord:function(B,A){if(!YAHOO.lang.isNumber(A)||A<0){A=this._records.length;
+}return(this._records[A]=new YAHOO.widget.Record(B));},_deleteRecord:function(B,A){if(!YAHOO.lang.isNumber(A)||(A<0)){A=1;}this._records.splice(B,A);},getId:function(){return this._sId;},toString:function(){return"RecordSet instance "+this._sId;},getLength:function(){return this._records.length;},getRecord:function(A){var B;if(A instanceof YAHOO.widget.Record){for(B=0;B<this._records.length;B++){if(this._records[B]&&(this._records[B]._sId===A._sId)){return A;}}}else{if(YAHOO.lang.isNumber(A)){if((A>-1)&&(A<this.getLength())){return this._records[A];}}else{if(YAHOO.lang.isString(A)){for(B=0;B<this._records.length;B++){if(this._records[B]&&(this._records[B]._sId===A)){return this._records[B];}}}}}return null;},getRecords:function(B,A){if(!YAHOO.lang.isNumber(B)){return this._records;}if(!YAHOO.lang.isNumber(A)){return this._records.slice(B);}return this._records.slice(B,B+A);},hasRecords:function(B,A){var D=this.getRecords(B,A);for(var C=0;C<A;++C){if(typeof D[C]==="undefined!
 "){return false;}}return true;},getRecordIndex:function(B){if(B){for(var A=this._records.length-1;A>-1;A--){if(this._records[A]&&B.getId()===this._records[A].getId()){return A;}}}return null;},addRecord:function(C,A){if(C&&(C.constructor==Object)){var B=this._addRecord(C,A);this.fireEvent("recordAddEvent",{record:B,data:C});return B;}else{return null;}},addRecords:function(C,B){if(YAHOO.lang.isArray(C)){var F=[];for(var D=0;D<C.length;D++){if(C[D]&&(C[D].constructor==Object)){var A=this._addRecord(C[D],B);F.push(A);}}this.fireEvent("recordsAddEvent",{records:F,data:C});return F;}else{if(C&&(C.constructor==Object)){var E=this._addRecord(C);this.fireEvent("recordsAddEvent",{records:[E],data:C});return E;}else{return null;}}},setRecord:function(C,A){if(C&&(C.constructor==Object)){var B=this._setRecord(C,A);this.fireEvent("recordSetEvent",{record:B,data:C});return B;}else{return null;}},setRecords:function(E,D){var H=YAHOO.widget.Record,B=YAHOO.lang.isArray(E)?E:[E],G=[],F=0,A=!
 B.length,C=0;D=parseInt(D,10)|0;for(;F<A;++F){if(typeof B[F]==!
 ="object
"&&B[F]){G[C++]=this._records[D+F]=new H(B[F]);}}this.fireEvent("recordsSet",{records:G,data:E});if(B.length&&!G.length){}return G.length>1?G:G[0];},updateRecord:function(A,E){var C=this.getRecord(A);if(C&&E&&(E.constructor==Object)){var D={};for(var B in C._oData){D[B]=C._oData[B];}C._oData=E;this.fireEvent("recordUpdateEvent",{record:C,newData:E,oldData:D});return C;}else{return null;}},updateKey:function(A,B,C){this.updateRecordValue(A,B,C);},updateRecordValue:function(A,D,G){var C=this.getRecord(A);if(C){var F=null;var E=C._oData[D];if(E&&E.constructor==Object){F={};for(var B in E){F[B]=E[B];}}else{F=E;}C._oData[D]=G;this.fireEvent("keyUpdateEvent",{record:C,key:D,newData:G,oldData:F});this.fireEvent("recordValueUpdateEvent",{record:C,key:D,newData:G,oldData:F});}else{}},replaceRecords:function(A){this.reset();return this.addRecords(A);},sortRecords:function(A,B){return this._records.sort(function(D,C){return A(D,C,B);});},reverseRecords:function(){return this._records.r!
 everse();},deleteRecord:function(A){if(YAHOO.lang.isNumber(A)&&(A>-1)&&(A<this.getLength())){var B=YAHOO.widget.DataTable._cloneObject(this.getRecord(A).getData());this._deleteRecord(A);this.fireEvent("recordDeleteEvent",{data:B,index:A});return B;}else{return null;}},deleteRecords:function(C,A){if(!YAHOO.lang.isNumber(A)){A=1;}if(YAHOO.lang.isNumber(C)&&(C>-1)&&(C<this.getLength())){var E=this.getRecords(C,A);var B=[];for(var D=0;D<E.length;D++){B[B.length]=YAHOO.widget.DataTable._cloneObject(E[D]);}this._deleteRecord(C,A);this.fireEvent("recordsDeleteEvent",{data:B,index:C});return B;}else{return null;}},reset:function(){this._records=[];this.fireEvent("resetEvent");}};YAHOO.augment(YAHOO.widget.RecordSet,YAHOO.util.EventProvider);YAHOO.widget.Record=function(A){this._sId="yui-rec"+YAHOO.widget.Record._nCount;YAHOO.widget.Record._nCount++;this._oData={};if(A&&(A.constructor==Object)){for(var B in A){this._oData[B]=A[B];}}};YAHOO.widget.Record._nCount=0;YAHOO.widget.Record!
 .prototype={_sId:null,_oData:null,getId:function(){return this!
 ._sId;},
getData:function(A){if(YAHOO.lang.isString(A)){return this._oData[A];}else{return this._oData;}},setData:function(A,B){this._oData[A]=B;}};YAHOO.widget.Paginator=function(D){var H=YAHOO.widget.Paginator.VALUE_UNLIMITED,G=YAHOO.lang,E,A,B,C;D=G.isObject(D)?D:{};this.initConfig();this.initEvents();this.set("rowsPerPage",D.rowsPerPage,true);if(G.isNumber(D.totalRecords)){this.set("totalRecords",D.totalRecords,true);}this.initUIComponents();for(E in D){if(G.hasOwnProperty(D,E)){this.set(E,D[E],true);}}A=this.get("initialPage");B=this.get("totalRecords");C=this.get("rowsPerPage");if(A>1&&C!==H){var F=(A-1)*C;if(B===H||F<B){this.set("recordOffset",F,true);}}};YAHOO.lang.augmentObject(YAHOO.widget.Paginator,{id:0,ID_BASE:"yui-pg",VALUE_UNLIMITED:-1,TEMPLATE_DEFAULT:"{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}",TEMPLATE_ROWS_PER_PAGE:"{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"},true);YAHOO.widg!
 et.Paginator.prototype={_containers:[],initConfig:function(){var B=YAHOO.widget.Paginator.VALUE_UNLIMITED,A=YAHOO.lang;this.setAttributeConfig("rowsPerPage",{value:0,validator:A.isNumber});this.setAttributeConfig("containers",{value:null,writeOnce:true,validator:function(E){if(!A.isArray(E)){E=[E];}for(var D=0,C=E.length;D<C;++D){if(A.isString(E[D])||(A.isObject(E[D])&&E[D].nodeType===1)){continue;}return false;}return true;},method:function(C){C=YAHOO.util.Dom.get(C);if(!A.isArray(C)){C=[C];}this._containers=C;}});this.setAttributeConfig("totalRecords",{value:0,validator:A.isNumber});this.setAttributeConfig("recordOffset",{value:0,validator:function(D){var C=this.get("totalRecords");if(A.isNumber(D)){return C===B||C>D;}return false;}});this.setAttributeConfig("initialPage",{value:1,validator:A.isNumber});this.setAttributeConfig("template",{value:YAHOO.widget.Paginator.TEMPLATE_DEFAULT,validator:A.isString});
+this.setAttributeConfig("containerClass",{value:"yui-pg-container",validator:A.isString});this.setAttributeConfig("alwaysVisible",{value:true,validator:A.isBoolean});this.setAttributeConfig("updateOnChange",{value:false,validator:A.isBoolean});this.setAttributeConfig("id",{value:YAHOO.widget.Paginator.id++,readOnly:true});this.setAttributeConfig("rendered",{value:false,readOnly:true});},initUIComponents:function(){var C=YAHOO.widget.Paginator.ui;for(var B in C){var A=C[B];if(YAHOO.lang.isObject(A)&&YAHOO.lang.isFunction(A.init)){A.init(this);}}},initEvents:function(){this.createEvent("recordOffsetChange");this.createEvent("totalRecordsChange");this.createEvent("rowsPerPageChange");this.createEvent("alwaysVisibleChange");this.createEvent("rendered");this.createEvent("changeRequest");this.createEvent("beforeDestroy");this.subscribe("totalRecordsChange",this.updateVisibility,this,true);this.subscribe("alwaysVisibleChange",this.updateVisibility,this,true);},render:function(){if!
 (this.get("rendered")){return ;}var M=this.get("totalRecords");if(M!==YAHOO.widget.Paginator.VALUE_UNLIMITED&&M<this.get("rowsPerPage")&&!this.get("alwaysVisible")){return ;}var F=YAHOO.util.Dom,N=this.get("template"),P=this.get("containerClass");N=N.replace(/\{([a-z0-9_ \-]+)\}/gi,'<span class="yui-pg-ui $1"></span>');for(var H=0,J=this._containers.length;H<J;++H){var L=this._containers[H],G=YAHOO.widget.Paginator.ID_BASE+this.get("id")+"-"+H;if(!L){continue;}L.style.display="none";F.addClass(L,P);L.innerHTML=N;var E=F.getElementsByClassName("yui-pg-ui","span",L);for(var D=0,O=E.length;D<O;++D){var C=E[D],B=C.parentNode,A=C.className.replace(/\s*yui-pg-ui\s+/g,""),K=YAHOO.widget.Paginator.ui[A];if(YAHOO.lang.isFunction(K)){var I=new K(this);if(YAHOO.lang.isFunction(I.render)){B.replaceChild(I.render(G),C);}}}L.style.display="";}if(this._containers.length){this.setAttributeConfig("rendered",{value:true});this.fireEvent("rendered",this.getState());}},destroy:function(){this.!
 fireEvent("beforeDestroy");for(var B=0,A=this._containers.leng!
 th;B<A;+
+B){this._containers[B].innerHTML="";}this.setAttributeConfig("rendered",{value:false});},updateVisibility:function(F){var B=this.get("alwaysVisible");if(F.type==="alwaysVisibleChange"||!B){var H=this.get("totalRecords"),G=true,D=this.get("rowsPerPage"),E=this.get("rowsPerPageOptions"),C,A;if(YAHOO.lang.isArray(E)){for(C=0,A=E.length;C<A;++C){D=Math.min(D,E[C]);}}if(H!==YAHOO.widget.Paginator.VALUE_UNLIMITED&&H<=D){G=false;}G=G||B;for(C=0,A=this._containers.length;C<A;++C){YAHOO.util.Dom.setStyle(this._containers[C],"display",G?"":"none");}}},getContainerNodes:function(){return this._containers;},getTotalPages:function(){var A=this.get("totalRecords");var B=this.get("rowsPerPage");if(!B){return null;}if(A===YAHOO.widget.Paginator.VALUE_UNLIMITED){return YAHOO.widget.Paginator.VALUE_UNLIMITED;}return Math.ceil(A/B);},hasPage:function(B){if(!YAHOO.lang.isNumber(B)||B<1){return false;}var A=this.getTotalPages();return(A===YAHOO.widget.Paginator.VALUE_UNLIMITED||A>=B);},getCurre!
 ntPage:function(){var A=this.get("rowsPerPage");if(!A||!this.get("totalRecords")){return 0;}return Math.floor(this.get("recordOffset")/A)+1;},hasNextPage:function(){var A=this.getCurrentPage(),B=this.getTotalPages();return A&&(B===YAHOO.widget.Paginator.VALUE_UNLIMITED||A<B);},getNextPage:function(){return this.hasNextPage()?this.getCurrentPage()+1:null;},hasPreviousPage:function(){return(this.getCurrentPage()>1);},getPreviousPage:function(){return(this.hasPreviousPage()?this.getCurrentPage()-1:1);},getPageRecords:function(D){if(!YAHOO.lang.isNumber(D)){D=this.getCurrentPage();}var C=this.get("rowsPerPage"),B=this.get("totalRecords"),E,A;if(!D||!C){return null;}E=(D-1)*C;if(B!==YAHOO.widget.Paginator.VALUE_UNLIMITED){if(E>=B){return null;}A=Math.min(E+C,B)-1;}else{A=E+C-1;}return[E,A];},setPage:function(B,A){if(this.hasPage(B)&&B!==this.getCurrentPage()){if(this.get("updateOnChange")||A){this.set("recordOffset",(B-1)*this.get("rowsPerPage"));}else{this.fireEvent("changeRequ!
 est",this.getState({"page":B}));}}},getRowsPerPage:function(){!
 return t
his.get("rowsPerPage");},setRowsPerPage:function(B,A){if(YAHOO.lang.isNumber(B)&&B>0&&B!==this.get("rowsPerPage")){if(this.get("updateOnChange")||A){this.set("rowsPerPage",B);}else{this.fireEvent("changeRequest",this.getState({"rowsPerPage":B}));}}},getTotalRecords:function(){return this.get("totalRecords");},setTotalRecords:function(B,A){if(YAHOO.lang.isNumber(B)&&B>=0&&B!==this.get("totalRecords")){if(this.get("updateOnChange")||A){this.set("totalRecords",B);}else{this.fireEvent("changeRequest",this.getState({"totalRecords":B}));}}},getStartIndex:function(){return this.get("recordOffset");},setStartIndex:function(B,A){if(YAHOO.lang.isNumber(B)&&B>=0&&B!==this.get("recordOffset")){if(this.get("updateOnChange")||A){this.set("recordOffset",B);}else{this.fireEvent("changeRequest",this.getState({"recordOffset":B}));}}},getState:function(C){var F=YAHOO.widget.Paginator.VALUE_UNLIMITED,A=YAHOO.lang;var B={paginator:this,page:this.getCurrentPage(),totalRecords:this.get("totalRecor!
 ds"),recordOffset:this.get("recordOffset"),rowsPerPage:this.get("rowsPerPage"),records:this.getPageRecords()};if(!C){return B;}var E=B.recordOffset;var D={paginator:this,before:B,rowsPerPage:C.rowsPerPage||B.rowsPerPage,totalRecords:(A.isNumber(C.totalRecords)?Math.max(C.totalRecords,F):B.totalRecords)};if(D.totalRecords===0){E=0;D.page=0;}else{if(!A.isNumber(C.recordOffset)&&A.isNumber(C.page)){E=(C.page-1)*D.rowsPerPage;if(D.totalRecords===F){D.page=C.page;}else{D.page=Math.min(C.page,Math.ceil(D.totalRecords/D.rowsPerPage));E=Math.min(E,D.totalRecords-1);}}else{E=Math.min(E,D.totalRecords-1);D.page=Math.floor(E/D.rowsPerPage)+1;}}D.recordOffset=D.recordOffset||E-(E%D.rowsPerPage);D.records=[D.recordOffset,D.recordOffset+D.rowsPerPage-1];if(D.totalRecords!==F&&D.recordOffset<D.totalRecords&&D.records[1]>D.totalRecords-1){D.records[1]=D.totalRecords-1;}return D;}};YAHOO.lang.augmentProto(YAHOO.widget.Paginator,YAHOO.util.AttributeProvider);
+(function(){YAHOO.widget.Paginator.ui={};var C=YAHOO.widget.Paginator,B=C.ui,A=YAHOO.lang;B.FirstPageLink=function(D){this.paginator=D;D.createEvent("firstPageLinkLabelChange");D.createEvent("firstPageLinkClassChange");D.subscribe("recordOffsetChange",this.update,this,true);D.subscribe("beforeDestroy",this.destroy,this,true);D.subscribe("firstPageLinkLabelChange",this.update,this,true);D.subscribe("firstPageLinkClassChange",this.update,this,true);};B.FirstPageLink.init=function(D){D.setAttributeConfig("firstPageLinkLabel",{value:"<< first",validator:A.isString});D.setAttributeConfig("firstPageLinkClass",{value:"yui-pg-first",validator:A.isString});};B.FirstPageLink.prototype={current:null,link:null,span:null,render:function(E){var F=this.paginator,G=F.get("firstPageLinkClass"),D=F.get("firstPageLinkLabel");this.link=document.createElement("a");this.span=document.createElement("span");this.link.id=E+"-first-link";this.link.href="#";this.link.className=G;this.link.!
 innerHTML=D;YAHOO.util.Event.on(this.link,"click",this.onClick,this,true);this.span.id=E+"-first-span";this.span.className=G;this.span.innerHTML=D;this.current=F.get("recordOffset")<1?this.span:this.link;return this.current;},update:function(E){if(E&&E.prevValue===E.newValue){return ;}var D=this.current?this.current.parentNode:null;if(this.paginator.get("recordOffset")<1){if(D&&this.current===this.link){D.replaceChild(this.span,this.current);this.current=this.span;}}else{if(D&&this.current===this.span){D.replaceChild(this.link,this.current);this.current=this.link;}}},destroy:function(){YAHOO.util.Event.purgeElement(this.link);},onClick:function(D){YAHOO.util.Event.stopEvent(D);this.paginator.setPage(1);}};B.LastPageLink=function(D){this.paginator=D;D.createEvent("lastPageLinkLabelChange");D.createEvent("lastPageLinkClassChange");D.subscribe("recordOffsetChange",this.update,this,true);D.subscribe("totalRecordsChange",this.update,this,true);D.subscribe("rowsPerPageChange",thi!
 s.update,this,true);D.subscribe("beforeDestroy",this.destroy,t!
 his,true
);D.subscribe("lastPageLinkLabelChange",this.update,this,true);D.subscribe("lastPageLinkClassChange",this.update,this,true);};B.LastPageLink.init=function(D){D.setAttributeConfig("lastPageLinkLabel",{value:"last >>",validator:A.isString});D.setAttributeConfig("lastPageLinkClass",{value:"yui-pg-last",validator:A.isString});};B.LastPageLink.prototype={current:null,link:null,span:null,na:null,render:function(E){var G=this.paginator,H=G.get("lastPageLinkClass"),D=G.get("lastPageLinkLabel"),F=G.getTotalPages();this.link=document.createElement("a");this.span=document.createElement("span");this.na=this.span.cloneNode(false);this.link.id=E+"-last-link";this.link.href="#";this.link.className=H;this.link.innerHTML=D;YAHOO.util.Event.on(this.link,"click",this.onClick,this,true);this.span.id=E+"-last-span";this.span.className=H;this.span.innerHTML=D;this.na.id=E+"-last-na";switch(F){case C.VALUE_UNLIMITED:this.current=this.na;break;case G.getCurrentPage():this.current=this.sp!
 an;break;default:this.current=this.link;}return this.current;},update:function(E){if(E&&E.prevValue===E.newValue){return ;}var D=this.current?this.current.parentNode:null,F=this.link;if(D){switch(this.paginator.getTotalPages()){case C.VALUE_UNLIMITED:F=this.na;break;case this.paginator.getCurrentPage():F=this.span;break;}if(this.current!==F){D.replaceChild(F,this.current);this.current=F;}}},destroy:function(){YAHOO.util.Event.purgeElement(this.link);},onClick:function(D){YAHOO.util.Event.stopEvent(D);this.paginator.setPage(this.paginator.getTotalPages());}};B.PreviousPageLink=function(D){this.paginator=D;D.createEvent("previousPageLinkLabelChange");D.createEvent("previousPageLinkClassChange");D.subscribe("recordOffsetChange",this.update,this,true);D.subscribe("beforeDestroy",this.destroy,this,true);D.subscribe("previousPageLinkLabelChange",this.update,this,true);D.subscribe("previousPageLinkClassChange",this.update,this,true);};B.PreviousPageLink.init=function(D){D.setAttri!
 buteConfig("previousPageLinkLabel",{value:"< prev",val!
 idator:A
.isString});D.setAttributeConfig("previousPageLinkClass",{value:"yui-pg-previous",validator:A.isString});};B.PreviousPageLink.prototype={current:null,link:null,span:null,render:function(E){var F=this.paginator,G=F.get("previousPageLinkClass"),D=F.get("previousPageLinkLabel");this.link=document.createElement("a");this.span=document.createElement("span");this.link.id=E+"-prev-link";this.link.href="#";this.link.className=G;this.link.innerHTML=D;YAHOO.util.Event.on(this.link,"click",this.onClick,this,true);this.span.id=E+"-prev-span";this.span.className=G;this.span.innerHTML=D;this.current=F.get("recordOffset")<1?this.span:this.link;return this.current;},update:function(E){if(E&&E.prevValue===E.newValue){return ;}var D=this.current?this.current.parentNode:null;if(this.paginator.get("recordOffset")<1){if(D&&this.current===this.link){D.replaceChild(this.span,this.current);this.current=this.span;}}else{if(D&&this.current===this.span){D.replaceChild(this.link,this.current);this.curr!
 ent=this.link;}}},destroy:function(){YAHOO.util.Event.purgeElement(this.link);},onClick:function(D){YAHOO.util.Event.stopEvent(D);this.paginator.setPage(this.paginator.getPreviousPage());}};B.NextPageLink=function(D){this.paginator=D;D.createEvent("nextPageLinkLabelChange");D.createEvent("nextPageLinkClassChange");D.subscribe("recordOffsetChange",this.update,this,true);D.subscribe("totalRecordsChange",this.update,this,true);D.subscribe("rowsPerPageChange",this.update,this,true);D.subscribe("beforeDestroy",this.destroy,this,true);D.subscribe("nextPageLinkLabelChange",this.update,this,true);D.subscribe("nextPageLinkClassChange",this.update,this,true);};B.NextPageLink.init=function(D){D.setAttributeConfig("nextPageLinkLabel",{value:"next >",validator:A.isString});D.setAttributeConfig("nextPageLinkClass",{value:"yui-pg-next",validator:A.isString});};B.NextPageLink.prototype={current:null,link:null,span:null,render:function(E){var G=this.paginator,H=G.get("nextPageLinkCl!
 ass"),D=G.get("nextPageLinkLabel"),F=G.getTotalPages();
+this.link=document.createElement("a");this.span=document.createElement("span");this.link.id=E+"-next-link";this.link.href="#";this.link.className=H;this.link.innerHTML=D;YAHOO.util.Event.on(this.link,"click",this.onClick,this,true);this.span.id=E+"-next-span";this.span.className=H;this.span.innerHTML=D;this.current=G.getCurrentPage()===F?this.span:this.link;return this.current;},update:function(F){if(F&&F.prevValue===F.newValue){return ;}var E=this.paginator.getTotalPages(),D=this.current?this.current.parentNode:null;if(this.paginator.getCurrentPage()!==E){if(D&&this.current===this.span){D.replaceChild(this.link,this.current);this.current=this.link;}}else{if(this.current===this.link){if(D){D.replaceChild(this.span,this.current);this.current=this.span;}}}},destroy:function(){YAHOO.util.Event.purgeElement(this.link);},onClick:function(D){YAHOO.util.Event.stopEvent(D);this.paginator.setPage(this.paginator.getNextPage());}};B.PageLinks=function(D){this.paginator=D;D.createEvent!
 ("pageLinkClassChange");D.createEvent("currentPageClassChange");D.createEvent("pageLinksContainerClassChange");D.createEvent("pageLinksChange");D.subscribe("recordOffsetChange",this.update,this,true);D.subscribe("pageLinksChange",this.rebuild,this,true);D.subscribe("totalRecordsChange",this.rebuild,this,true);D.subscribe("rowsPerPageChange",this.rebuild,this,true);D.subscribe("pageLinkClassChange",this.rebuild,this,true);D.subscribe("currentPageClassChange",this.rebuild,this,true);D.subscribe("beforeDestroy",this.destroy,this,true);D.subscribe("pageLinksContainerClassChange",this.rebuild,this,true);};B.PageLinks.init=function(D){D.setAttributeConfig("pageLinkClass",{value:"yui-pg-page",validator:A.isString});D.setAttributeConfig("currentPageClass",{value:"yui-pg-current-page",validator:A.isString});D.setAttributeConfig("pageLinksContainerClass",{value:"yui-pg-pages",validator:A.isString});D.setAttributeConfig("pageLinks",{value:10,validator:A.isNumber});D.setAttributeConfig!
 ("pageLabelBuilder",{value:function(E,F){return E;},validator:!
 A.isFunc
tion});};B.PageLinks.calculateRange=function(F,G,E){var J=C.VALUE_UNLIMITED,I,D,H;if(!F||E===0||G===0||(G===J&&E===J)){return[0,-1];}if(G!==J){E=E===J?G:Math.min(E,G);}I=Math.max(1,Math.ceil(F-(E/2)));if(G===J){D=I+E-1;}else{D=Math.min(G,I+E-1);}H=E-(D-I+1);I=Math.max(1,I-H);return[I,D];};B.PageLinks.prototype={current:0,container:null,render:function(D){var E=this.paginator;this.container=document.createElement("span");this.container.id=D+"-pages";this.container.className=E.get("pageLinksContainerClass");YAHOO.util.Event.on(this.container,"click",this.onClick,this,true);this.update({newValue:null,rebuild:true});return this.container;},update:function(K){if(K&&K.prevValue===K.newValue){return ;}var F=this.paginator,J=F.getCurrentPage();if(this.current!==J||K.rebuild){var M=F.get("pageLabelBuilder"),I=B.PageLinks.calculateRange(J,F.getTotalPages(),F.get("pageLinks")),E=I[0],G=I[1],L="",D,H;D='<a href="#" class="'+F.get("pageLinkClass")+'" page="';for(H=E;H<=G;++H){if(H===J){L!
 +='<span class="'+F.get("currentPageClass")+" "+F.get("pageLinkClass")+'">'+M(H,F)+"</span>";}else{L+=D+H+'">'+M(H,F)+"</a>";}}this.container.innerHTML=L;}},rebuild:function(D){D.rebuild=true;this.update(D);},destroy:function(){YAHOO.util.Event.purgeElement(this.container,true);},onClick:function(E){var D=YAHOO.util.Event.getTarget(E);if(D&&YAHOO.util.Dom.hasClass(D,this.paginator.get("pageLinkClass"))){YAHOO.util.Event.stopEvent(E);this.paginator.setPage(parseInt(D.getAttribute("page"),10));}}};B.RowsPerPageDropdown=function(D){this.paginator=D;D.createEvent("rowsPerPageOptionsChange");D.createEvent("rowsPerPageDropdownClassChange");D.subscribe("rowsPerPageChange",this.update,this,true);D.subscribe("rowsPerPageOptionsChange",this.rebuild,this,true);D.subscribe("beforeDestroy",this.destroy,this,true);D.subscribe("rowsPerPageDropdownClassChange",this.rebuild,this,true);};B.RowsPerPageDropdown.init=function(D){D.setAttributeConfig("rowsPerPageOptions",{value:[],validator:A.is!
 Array});D.setAttributeConfig("rowsPerPageDropdownClass",{value!
 :"yui-pg
-rpp-options",validator:A.isString});};B.RowsPerPageDropdown.prototype={select:null,render:function(D){this.select=document.createElement("select");this.select.id=D+"-rpp";this.select.className=this.paginator.get("rowsPerPageDropdownClass");this.select.title="Rows per page";YAHOO.util.Event.on(this.select,"change",this.onChange,this,true);this.rebuild();return this.select;},update:function(H){if(H&&H.prevValue===H.newValue){return ;}var G=this.paginator.get("rowsPerPage"),E=this.select.options,F,D;for(F=0,D=E.length;F<D;++F){if(parseInt(E[F].value,10)===G){E[F].selected=true;}}},rebuild:function(K){var F=this.paginator,G=this.select,L=F.get("rowsPerPageOptions"),D=document.createElement("option"),I,J;while(G.firstChild){G.removeChild(G.firstChild);}for(I=0,J=L.length;I<J;++I){var H=D.cloneNode(false),E=L[I];H.value=A.isValue(E.value)?E.value:E;H.innerHTML=A.isValue(E.text)?E.text:E;G.appendChild(H);}this.update();},destroy:function(){YAHOO.util.Event.purgeElement(this.select!
 );},onChange:function(D){this.paginator.setRowsPerPage(parseInt(this.select.options[this.select.selectedIndex].value,10));}};B.CurrentPageReport=function(D){this.paginator=D;D.createEvent("pageReportClassChange");D.createEvent("pageReportTemplateChange");D.subscribe("recordOffsetChange",this.update,this,true);D.subscribe("totalRecordsChange",this.update,this,true);D.subscribe("rowsPerPageChange",this.update,this,true);D.subscribe("pageReportTemplateChange",this.update,this,true);D.subscribe("pageReportClassChange",this.update,this,true);};B.CurrentPageReport.init=function(D){D.setAttributeConfig("pageReportClass",{value:"yui-pg-current",validator:A.isString});D.setAttributeConfig("pageReportTemplate",{value:"({currentPage} of {totalPages})",validator:A.isString});D.setAttributeConfig("pageReportValueGenerator",{value:function(G){var F=G.getCurrentPage(),E=G.getPageRecords();return{"currentPage":E?F:0,"totalPages":G.getTotalPages(),"startIndex":E?E[0]:0,"endIndex":E?E[1]:0,"!
 startRecord":E?E[0]+1:0,"endRecord":E?E[1]+1:0,"totalRecords":!
 G.get("t
otalRecords")};
+},validator:A.isFunction});};B.CurrentPageReport.sprintf=function(E,D){return E.replace(/{([\w\s\-]+)}/g,function(F,G){return(G in D)?D[G]:"";});};B.CurrentPageReport.prototype={span:null,render:function(D){this.span=document.createElement("span");this.span.id=D+"-page-report";this.span.className=this.paginator.get("pageReportClass");this.update();return this.span;},update:function(D){if(D&&D.prevValue===D.newValue){return ;}this.span.innerHTML=B.CurrentPageReport.sprintf(this.paginator.get("pageReportTemplate"),this.paginator.get("pageReportValueGenerator")(this.paginator));}};})();YAHOO.widget.DataTable=function(A,G,I,C){var E=YAHOO.widget.DataTable,F=YAHOO.util.DataSource;this._nIndex=E._nCount;this._sId="yui-dt"+this._nIndex;this._oChainRender=new YAHOO.util.Chain();this._oChainSync=new YAHOO.util.Chain();this._oChainRender.subscribe("end",this._sync,this,true);this._initConfigs(C);this._initDataSource(I);if(!this._oDataSource){return ;}this._initColumnSet(G);if(!this._!
 oColumnSet){return ;}this._initRecordSet();if(!this._oRecordSet){return ;}this._initNodeTemplates();this._initContainerEl(A);if(!this._elContainer){return ;}this._initTableEl();if(!this._elContainer||!this._elThead||!this._elTbody){return ;}E.superclass.constructor.call(this,this._elContainer,this._oConfigs);var D=this.get("sortedBy");if(D){if(D.dir=="desc"){this._configs.sortedBy.value.dir=E.CLASS_DESC;}else{if(D.dir=="asc"){this._configs.sortedBy.value.dir=E.CLASS_ASC;}}}if(this._oConfigs.paginator&&!(this._oConfigs.paginator instanceof YAHOO.widget.Paginator)){this.updatePaginator(this._oConfigs.paginator);}this._initCellEditorEl();this._initColumnSort();YAHOO.util.Event.addListener(document,"click",this._onDocumentClick,this);E._nCount++;E._nCurrentCount++;var H={success:this.onDataReturnSetRows,failure:this.onDataReturnSetRows,scope:this,argument:{}};if(this.get("initialLoad")===true){this._oDataSource.sendRequest(this.get("initialRequest"),H);}else{if(this.get("initia!
 lLoad")===false){this.showTableMessage(E.MSG_EMPTY,E.CLASS_EMP!
 TY);this
._oChainRender.add({method:function(){if((this instanceof E)&&this._sId&&this._bInit){this._bInit=false;this.fireEvent("initEvent");}},scope:this});this._oChainRender.run();}else{var B=this.get("initialLoad");H.argument=B.argument;this._oDataSource.sendRequest(B.request,H);}}};(function(){var C=YAHOO.lang,F=YAHOO.util,E=YAHOO.widget,A=YAHOO.env.ua,D=F.Dom,I=F.Event,H=F.DataSource,G=E.DataTable,B=E.Paginator;C.augmentObject(G,{CLASS_LINER:"yui-dt-liner",CLASS_LABEL:"yui-dt-label",CLASS_COLTARGET:"yui-dt-coltarget",CLASS_RESIZER:"yui-dt-resizer",CLASS_RESIZERPROXY:"yui-dt-resizerproxy",CLASS_EDITOR:"yui-dt-editor",CLASS_PAGINATOR:"yui-dt-paginator",CLASS_PAGE:"yui-dt-page",CLASS_DEFAULT:"yui-dt-default",CLASS_PREVIOUS:"yui-dt-previous",CLASS_NEXT:"yui-dt-next",CLASS_FIRST:"yui-dt-first",CLASS_LAST:"yui-dt-last",CLASS_EVEN:"yui-dt-even",CLASS_ODD:"yui-dt-odd",CLASS_SELECTED:"yui-dt-selected",CLASS_HIGHLIGHTED:"yui-dt-highlighted",CLASS_HIDDEN:"yui-dt-hidden",CLASS_DISABLED:"yui!
 -dt-disabled",CLASS_EMPTY:"yui-dt-empty",CLASS_LOADING:"yui-dt-loading",CLASS_ERROR:"yui-dt-error",CLASS_EDITABLE:"yui-dt-editable",CLASS_DRAGGABLE:"yui-dt-draggable",CLASS_RESIZEABLE:"yui-dt-resizeable",CLASS_SCROLLABLE:"yui-dt-scrollable",CLASS_SORTABLE:"yui-dt-sortable",CLASS_ASC:"yui-dt-asc",CLASS_DESC:"yui-dt-desc",CLASS_BUTTON:"yui-dt-button",CLASS_CHECKBOX:"yui-dt-checkbox",CLASS_DROPDOWN:"yui-dt-dropdown",CLASS_RADIO:"yui-dt-radio",MSG_EMPTY:"No records found.",MSG_LOADING:"Loading data...",MSG_ERROR:"Data error.",_nCount:0,_nCurrentCount:0,_elStylesheet:null,_bStylesheetFallback:(A.ie&&(A.ie<7))?true:false,_oStylesheetRules:{},_elColumnDragTarget:null,_elColumnResizerProxy:null,_cloneObject:function(M){if(!C.isValue(M)){return M;}var O={};if(C.isArray(M)){var N=[];for(var L=0,K=M.length;L<K;L++){N[L]=G._cloneObject(M[L]);}O=N;}else{if(M.constructor&&(M.constructor==Object)){for(var J in M){if(C.hasOwnProperty(M,J)){if(C.isValue(M[J])&&(M[J].constructor==Object)||C.!
 isArray(M[J])){O[J]=G._cloneObject(M[J]);}else{O[J]=M[J];}}}}e!
 lse{O=M;
}}return O;},_initColumnDragTargetEl:function(){if(!G._elColumnDragTarget){var J=document.createElement("div");J.id="yui-dt-coltarget";J.className=G.CLASS_COLTARGET;J.style.display="none";document.body.insertBefore(J,document.body.firstChild);G._elColumnDragTarget=J;}return G._elColumnDragTarget;},_initColumnResizerProxyEl:function(){if(!G._elColumnResizerProxy){var J=document.createElement("div");J.id="yui-dt-colresizerproxy";D.addClass(J,G.CLASS_RESIZERPROXY);document.body.insertBefore(J,document.body.firstChild);G._elColumnResizerProxy=J;}return G._elColumnResizerProxy;},formatTheadCell:function(J,L,M){var R=L.getKey();var Q=C.isValue(L.label)?L.label:R;if(L.sortable){var O=M.getColumnSortDir(L);var N=(O===G.CLASS_DESC)?"descending":"ascending";var K=M.getId()+"-sort"+L.getId()+"-"+N;var P="Click to sort "+N;J.innerHTML='<a href="'+K+'" title="'+P+'" class="'+G.CLASS_SORTABLE+'">'+Q+"</a>";}else{J.innerHTML=Q;}},formatButton:function(J,K,L,N){var M=C.isValue(N)?N:"Click";!
 J.innerHTML='<button type="button" class="'+G.CLASS_BUTTON+'">'+M+"</button>";},formatCheckbox:function(J,K,L,N){var M=N;M=(M)?" checked":"";J.innerHTML='<input type="checkbox"'+M+' class="'+G.CLASS_CHECKBOX+'">';},formatCurrency:function(J,K,L,M){J.innerHTML=F.Number.format(M,{prefix:"$",decimalPlaces:2,decimalSeparator:".",thousandsSeparator:","});},formatDate:function(J,K,L,M){J.innerHTML=F.Date.format(M,{format:"MM/DD/YYYY"});},formatDropdown:function(L,S,Q,J){var R=(C.isValue(J))?J:S.getData(Q.key);var T=(C.isArray(Q.dropdownOptions))?Q.dropdownOptions:null;var K;var P=L.getElementsByTagName("select");if(P.length===0){K=document.createElement("select");D.addClass(K,G.CLASS_DROPDOWN);K=L.appendChild(K);I.addListener(K,"change",this._onDropdownChange,this);}K=P[0];if(K){K.innerHTML="";if(T){for(var N=0;N<T.length;N++){var O=T[N];var M=document.createElement("option");M.value=(C.isValue(O.value))?O.value:O;
+M.innerHTML=(C.isValue(O.text))?O.text:O;M=K.appendChild(M);if(M.value==R){M.selected=true;}}}else{K.innerHTML='<option selected value="'+R+'">'+R+"</option>";}}else{L.innerHTML=C.isValue(J)?J:"";}},formatEmail:function(J,K,L,M){if(C.isString(M)){J.innerHTML='<a href="mailto:'+M+'">'+M+"</a>";}else{J.innerHTML=C.isValue(M)?M:"";}},formatLink:function(J,K,L,M){if(C.isString(M)){J.innerHTML='<a href="'+M+'">'+M+"</a>";}else{J.innerHTML=C.isValue(M)?M:"";}},formatNumber:function(J,K,L,M){if(C.isNumber(M)){J.innerHTML=M;}else{J.innerHTML=C.isValue(M)?M:"";}},formatRadio:function(J,K,L,N){var M=N;M=(M)?" checked":"";J.innerHTML='<input type="radio"'+M+' name="col'+L.getId()+'-radio"'+' class="'+G.CLASS_RADIO+'">';},formatText:function(J,K,M,N){var L=(C.isValue(K.getData(M.key)))?K.getData(M.key):"";J.innerHTML=L.toString().replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");},formatTextarea:function(K,L,N,O){var M=(C.isValue(L.getData(N.key)))?L.getData(N.key):"";v!
 ar J="<textarea>"+M+"</textarea>";K.innerHTML=J;},formatTextbox:function(K,L,N,O){var M=(C.isValue(L.getData(N.key)))?L.getData(N.key):"";var J='<input type="text" value="'+M+'">';K.innerHTML=J;},handleSimplePagination:function(K,J){K.paginator.setTotalRecords(K.totalRecords,true);K.paginator.setStartIndex(K.recordOffset,true);K.paginator.setRowsPerPage(K.rowsPerPage,true);J.render();},handleDataSourcePagination:function(K,J){var N=K.records[1]-K.recordOffset;var L=J.get("generateRequest");var M=L({pagination:K},J);var O={success:J.onDataReturnSetRows,failure:J.onDataReturnSetRows,argument:{startIndex:K.recordOffset,pagination:K},scope:J};J._oDataSource.sendRequest(M,O);},editCheckbox:function(S,R){var T=S.cell;var X=S.record;var P=S.column;var J=S.container;var M=S.value;if(!C.isArray(M)){M=[M];}if(P.editorOptions&&C.isArray(P.editorOptions.checkboxOptions)){var W=P.editorOptions.checkboxOptions;var O,U,N,L,K;for(L=0;L<W.length;L++){O=C.isValue(W[L].label)?W[L].label:W[L];!
 U=R.getId()+"-editor-checkbox"+L;J.innerHTML+='<input type="ch!
 eckbox"'
+' name="'+R.getId()+'-editor-checkbox"'+' value="'+O+'"'+' id="'+U+'">';N=J.appendChild(document.createElement("label"));N.htmlFor=U;N.innerHTML=O;}var Q=[];var V;for(L=0;L<W.length;L++){V=D.get(R.getId()+"-editor-checkbox"+L);Q.push(V);for(K=0;K<M.length;K++){if(V.value===M[K]){V.checked=true;}}if(L===0){R._focusEl(V);}}for(L=0;L<W.length;L++){V=D.get(R.getId()+"-editor-checkbox"+L);I.addListener(V,"click",function(){var Z=[];for(var Y=0;Y<Q.length;Y++){if(Q[Y].checked){Z.push(Q[Y].value);}}R._oCellEditor.value=Z;R.fireEvent("editorUpdateEvent",{editor:R._oCellEditor});});}}},editDate:function(Q,N){var R=Q.cell;var U=Q.record;var L=Q.column;var J=Q.container;var S=Q.value;if(!(S instanceof Date)){S=Q.defaultValue||new Date();}if(YAHOO.widget.Calendar){var M=(S.getMonth()+1)+"/"+S.getDate()+"/"+S.getFullYear();var T=J.appendChild(document.createElement("div"));var P=L.getColEl();T.id=P+"-dateContainer";var K=new YAHOO.widget.Calendar(P+"-date",T.id,{selected:M,pagedate:S});!
 K.render();T.style.cssFloat="none";if(A.ie){var O=J.appendChild(document.createElement("br"));O.style.clear="both";}K.selectEvent.subscribe(function(W,V,X){N._oCellEditor.value=new Date(V[0][0][0],V[0][0][1]-1,V[0][0][2]);N.fireEvent("editorUpdateEvent",{editor:N._oCellEditor});});}else{}},editDropdown:function(P,O){var Q=P.cell;var U=P.record;var M=P.column;var K=P.container;var R=P.value;if(!C.isValue(R)){R=P.defaultValue;}var T=K.appendChild(document.createElement("select"));var S=(M.editorOptions&&C.isArray(M.editorOptions.dropdownOptions))?M.editorOptions.dropdownOptions:[];for(var L=0;L<S.length;L++){var N=S[L];var J=document.createElement("option");J.value=(C.isValue(N.value))?N.value:N;J.innerHTML=(C.isValue(N.text))?N.text:N;J=T.appendChild(J);if(R===T.options[L].value){T.options[L].selected=true;}}I.addListener(T,"change",function(){O._oCellEditor.value=T[T.selectedIndex].value;O.fireEvent("editorUpdateEvent",{editor:O._oCellEditor});});O._focusEl(T);},editRadio:f!
 unction(Q,O){var R=Q.cell;var V=Q.record;var N=Q.column;var J=!
 Q.contai
ner;var S=Q.value;if(!C.isValue(S)){S=Q.defaultValue;}if(N.editorOptions&&C.isArray(N.editorOptions.radioOptions)){var P=N.editorOptions.radioOptions;var K,T,M,L;for(L=0;L<P.length;L++){K=C.isValue(P[L].label)?P[L].label:P[L];T=O.getId()+"-col"+N.getId()+"-radioeditor"+L;J.innerHTML+='<input type="radio"'+' name="'+O.getId()+'-editor-radio"'+' value="'+K+'"'+' id="'+T+'">';M=J.appendChild(document.createElement("label"));M.htmlFor=T;M.innerHTML=K;}for(L=0;L<P.length;L++){var U=D.get(O.getId()+"-col"+N.getId()+"-radioeditor"+L);if(S===U.value){U.checked=true;O._focusEl(U);}I.addListener(U,"click",function(){O._oCellEditor.value=this.value;O.fireEvent("editorUpdateEvent",{editor:O._oCellEditor});});}}},editTextarea:function(Q,K){var N=Q.cell;var L=Q.record;var P=Q.column;var O=Q.container;var M=Q.value;if(!C.isValue(M)){M=Q.defaultValue||"";}var J=O.appendChild(document.createElement("textarea"));J.style.width=N.offsetWidth+"px";J.style.height="3em";J.value=M;I.addListener(J,"!
 keyup",function(){K._oCellEditor.value=J.value;K.fireEvent("editorUpdateEvent",{editor:K._oCellEditor});});J.focus();J.select();},editTextbox:function(P,J){var M=P.cell;var K=P.record;var O=P.column;var N=P.container;var L=P.value;if(!C.isValue(L)){L=P.defaultValue||"";}var Q;if(A.webkit>420){Q=N.appendChild(document.createElement("form")).appendChild(document.createElement("input"));}else{Q=N.appendChild(document.createElement("input"));}Q.type="text";Q.style.width=M.offsetWidth+"px";Q.value=L;I.addListener(Q,"keypress",function(R){if((R.keyCode===13)){YAHOO.util.Event.preventDefault(R);J.saveCellEditor();}});I.addListener(Q,"keyup",function(R){J._oCellEditor.value=Q.value;J.fireEvent("editorUpdateEvent",{editor:J._oCellEditor});});Q.focus();Q.select();},validateNumber:function(K){var J=K*1;if(C.isNumber(J)){return J;}else{return null;}},_generateRequest:function(L,K){var J=L;if(L.pagination){if(K._oDataSource.dataType===H.TYPE_XHR){J="?page="+L.pagination.page+"&recordOff!
 set="+L.pagination.recordOffset+"&rowsPerPage="+L.pagination.r!
 owsPerPa
ge;
+}}return J;}});G.Formatter={button:G.formatButton,checkbox:G.formatCheckbox,currency:G.formatCurrency,"date":G.formatDate,dropdown:G.formatDropdown,email:G.formatEmail,link:G.formatLink,"number":G.formatNumber,radio:G.formatRadio,text:G.formatText,textarea:G.formatTextarea,textbox:G.formatTextbox};C.extend(G,F.Element,{initAttributes:function(J){J=J||{};G.superclass.initAttributes.call(this,J);this.setAttributeConfig("summary",{value:null,validator:C.isString,method:function(K){this._elThead.parentNode.summary=K;}});this.setAttributeConfig("selectionMode",{value:"standard",validator:C.isString});this.setAttributeConfig("initialRequest",{value:null});this.setAttributeConfig("initialLoad",{value:true});this.setAttributeConfig("generateRequest",{value:G._generateRequest,validator:C.isFunction});this.setAttributeConfig("sortedBy",{value:null,validator:function(K){if(K){return((K.constructor==Object)&&K.key);}else{return(K===null);}},method:function(K){var M=this.get("sortedBy")!
 ;if(M&&(M.constructor==Object)&&M.key){var O=this._oColumnSet.getColumn(M.key);var N=this.getThEl(O);D.removeClass(N,G.CLASS_ASC);D.removeClass(N,G.CLASS_DESC);}if(K){var P=(K.column)?K.column:this._oColumnSet.getColumn(K.key);if(P){if(K.dir&&((K.dir=="asc")||(K.dir=="desc"))){var Q=(K.dir=="desc")?G.CLASS_DESC:G.CLASS_ASC;D.addClass(P.getThEl(),Q);}else{var L=K.dir||G.CLASS_ASC;D.addClass(P.getThEl(),L);}}}}});this.setAttributeConfig("paginator",{value:{rowsPerPage:500,currentPage:1,startRecordIndex:0,totalRecords:0,totalPages:0,rowsThisPage:0,pageLinks:0,pageLinksStart:1,dropdownOptions:null,containers:[],dropdowns:[],links:[]},validator:function(K){if(typeof K==="object"&&K){if(K instanceof B){return true;}else{if(K&&(K.constructor==Object)){if((K.rowsPerPage!==undefined)&&(K.currentPage!==undefined)&&(K.startRecordIndex!==undefined)&&(K.totalRecords!==undefined)&&(K.totalPages!==undefined)&&(K.rowsThisPage!==undefined)&&(K.pageLinks!==undefined)&&(K.pageLinksStart!==und!
 efined)&&(K.dropdownOptions!==undefined)&&(K.containers!==unde!
 fined)&&
(K.dropdowns!==undefined)&&(K.links!==undefined)){if(C.isNumber(K.rowsPerPage)&&C.isNumber(K.currentPage)&&C.isNumber(K.startRecordIndex)&&C.isNumber(K.totalRecords)&&C.isNumber(K.totalPages)&&C.isNumber(K.rowsThisPage)&&C.isNumber(K.pageLinks)&&C.isNumber(K.pageLinksStart)&&(C.isArray(K.dropdownOptions)||C.isNull(K.dropdownOptions))&&C.isArray(K.containers)&&C.isArray(K.dropdowns)&&C.isArray(K.links)){return true;}}}}}return false;},method:function(L){if(L instanceof B){L.subscribe("changeRequest",this.onPaginatorChange,this,true);var M=L.getContainerNodes();if(!M.length){var K=document.createElement("div");K.id=this._sId+"-paginator0";this._elContainer.insertBefore(K,this._elContainer.firstChild);var N=document.createElement("div");N.id=this._sId+"-paginator1";this._elContainer.appendChild(N);M=[K,N];D.addClass(M,G.CLASS_PAGINATOR);L.set("containers",M);}}}});this.setAttributeConfig("paginated",{value:false,validator:C.isBoolean,method:function(N){var P=this.get("paginated!
 ");var L,M;if(N==P){return ;}var Q=this.get("paginator");if(!(Q instanceof B)){Q=Q||{rowsPerPage:500,currentPage:1,startRecordIndex:0,totalRecords:0,totalPages:0,rowsThisPage:0,pageLinks:0,pageLinksStart:1,dropdownOptions:null,containers:[],dropdowns:[],links:[]};var O=Q.containers;if(N){if(O.length===0){var U=document.createElement("span");U.id=this._sId+"-paginator0";D.addClass(U,G.CLASS_PAGINATOR);U=this._elContainer.insertBefore(U,this._elContainer.firstChild);O.push(U);var S=document.createElement("span");S.id=this._sId+"-paginator1";D.addClass(S,G.CLASS_PAGINATOR);S=this._elContainer.appendChild(S);O.push(S);Q.containers=O;this._configs.paginator.value=Q;}else{for(L=0;L<O.length;L++){O[L].style.display="";}}if(Q.pageLinks>-1){var T=Q.links;if(T.length===0){for(L=0;L<O.length;L++){var R=document.createElement("span");R.id="yui-dt-pagselect"+L;R=O[L].appendChild(R);I.addListener(R,"click",this._onPaginatorLinkClick,this);this._configs.paginator.value.links.push(R);}}}fo!
 r(L=0;L<O.length;L++){var K=document.createElement("select");D!
 .addClas
s(K,G.CLASS_DROPDOWN);K=O[L].appendChild(K);K.id="yui-dt-pagselect"+L;I.addListener(K,"change",this._onPaginatorDropdownChange,this);this._configs.paginator.value.dropdowns.push(K);if(!Q.dropdownOptions){K.style.display="none";}}}else{if(O.length>0){for(L=0;L<O.length;L++){O[L].style.display="none";}}}}}});this.setAttributeConfig("paginationEventHandler",{value:G.handleSimplePagination,validator:C.isObject});this.setAttributeConfig("caption",{value:null,validator:C.isString,method:function(K){if(!this._elCaption){var L=this._elTbodyContainer.getElementsByTagName("table")[0];this._elCaption=L.createCaption();}this._elCaption.innerHTML=K;}});this.setAttributeConfig("scrollable",{value:false,validator:function(K){return(C.isBoolean(K));},method:function(O){var L=this._elTheadContainer.getElementsByTagName("table")[0],K=this._elTbodyContainer.getElementsByTagName("table")[0],N=L.getElementsByTagName("thead")[0],M=K.getElementsByTagName("thead")[0];if(O){if(N){L.removeChild(N);}i!
 f(M){K.removeChild(M);}L.appendChild(this._elThead);K.insertBefore(this._elA11yThead,K.firstChild||null);if(K.caption){L.insertBefore(K.caption,L.firstChild);}D.addClass(this._elContainer,G.CLASS_SCROLLABLE);K.style.marginTop="-"+this._elTbody.offsetTop+"px";this._syncColWidths();this._syncScrollPadding();}else{if(N){L.removeChild(N);}if(M){K.removeChild(M);}L.appendChild(this._elA11yThead);K.insertBefore(this._elThead,K.firstChild||null);K.style.marginTop="";if(L.caption){K.insertBefore(L.caption,K.firstChild);}D.removeClass(this._elContainer,G.CLASS_SCROLLABLE);}}});this.setAttributeConfig("width",{value:null,validator:C.isString,method:function(K){if(this.get("scrollable")){this._elTheadContainer.style.width=K;this._elTbodyContainer.style.width=K;}}});this.setAttributeConfig("height",{value:null,validator:C.isString,method:function(K){if(this.get("scrollable")){this._elTbodyContainer.style.height=K;}}});
+this.setAttributeConfig("draggableColumns",{value:false,validator:C.isBoolean,writeOnce:true});this.setAttributeConfig("renderLoopSize",{value:0,validator:C.isNumber});},_bInit:true,_nIndex:null,_nTrCount:0,_nTdCount:0,_sId:null,_oChainRender:null,_oChainSync:null,_aFallbackColResizer:[],_elContainer:null,_elTheadContainer:null,_elTbodyContainer:null,_elCaption:null,_elThead:null,_elTbody:null,_elMsgTbody:null,_elMsgTbodyRow:null,_elMsgTbodyCell:null,_oDataSource:null,_oColumnSet:null,_oRecordSet:null,_sFirstTrId:null,_sLastTrId:null,_tdElTemplate:null,_trElTemplate:null,_bScrollbarX:null,clearTextSelection:function(){var J;if(window.getSelection){J=window.getSelection();}else{if(document.getSelection){J=document.getSelection();}else{if(document.selection){J=document.selection;}}}if(J){if(J.empty){J.empty();}else{if(J.removeAllRanges){J.removeAllRanges();}else{if(J.collapse){J.collapse();}}}}},_focusEl:function(J){J=J||this._elTbody;setTimeout(function(){try{J.focus();}catc!
 h(K){}},0);},_sync:function(){this._syncColWidths();this._forceGeckoRedraw();},_syncColWidths:function(){if(!this.get("scrollable")){return ;}if(this._elTbody.rows.length>0){var R=this._oColumnSet.keys,J=this.getFirstTrEl();if(R&&J&&(J.cells.length===R.length)){var T=false;if((YAHOO.env.ua.gecko||YAHOO.env.ua.opera)&&this.get("scrollable")){T=true;if(this.get("width")){this._elTheadContainer.style.width="";this._elTbodyContainer.style.width="";}else{this._elContainer.style.width="";}}var O,Q,L=J.cells.length;for(O=0;O<L;O++){Q=R[O];if(!Q.width){this._setColumnWidth(Q,"auto");}}for(O=0;O<L;O++){Q=R[O];var N;if(!Q.width){var M=Q.getThEl();var P=J.cells[O];if(M.offsetWidth!==P.offsetWidth){var S=(M.offsetWidth>P.offsetWidth)?M.firstChild:P.firstChild;N=S.offsetWidth-(parseInt(D.getStyle(S,"paddingLeft"),10)|0)-(parseInt(D.getStyle(S,"paddingRight"),10)|0);N=(Q.minWidth&&(Q.minWidth>N))?Q.minWidth:N;}}else{N=Q.width;}if(Q.hidden){Q._nLastWidth=N;N=1;}if(N){this._setColumnWidth(!
 Q,N+"px");}}if(T){var K=this.get("width");this._elTheadContain!
 er.style
.width=K;this._elTbodyContainer.style.width=K;}}}this._syncScrollPadding();},_syncScrollPadding:function(){if(this.get("scrollable")){var L=this._elTbody,N=this._elTbodyContainer,P,J,O,M,K;if(!this.get("height")&&(A.ie)){if(L.rows.length>0){N.style.height=(N.scrollWidth>N.offsetWidth)?(L.offsetHeight+19)+"px":L.offsetHeight+"px";}else{N.style.height=(N.scrollWidth>N.offsetWidth)?(this._elMsgTbody.offsetHeight+19)+"px":this._elMsgTbody.offsetHeight+"px";}}if(!this.get("width")){this._elContainer.style.width=(N.scrollHeight>N.offsetHeight)?(L.parentNode.offsetWidth+19)+"px":(L.parentNode.offsetWidth+2)+"px";}else{if((N.scrollWidth>N.offsetWidth)||((N.scrollHeight>N.offsetHeight)&&(N.scrollWidth>N.offsetWidth-16))){if(!this._bScrollbarX){P=this._oColumnSet.headers[this._oColumnSet.headers.length-1];J=P.length;O=this._sId+"-th";for(M=0;M<J;M++){K=D.get(O+P[M]).firstChild;K.style.marginRight=(parseInt(D.getStyle(K,"marginRight"),10)+16)+"px";}this._bScrollbarX=true;}}else{if(this!
 ._bScrollbarX){P=this._oColumnSet.headers[this._oColumnSet.headers.length-1];J=P.length;O=this._sId+"-th";for(M=0;M<J;M++){K=D.get(O+P[M]).firstChild;D.setStyle(K,"marginRight","");}this._bScrollbarX=false;}}}if(this._elTbody.rows.length===0){this._elMsgTbody.parentNode.width=this.getTheadEl().parentNode.offsetWidth;}else{this._elMsgTbody.parentNode.width="";}}},_forceGeckoRedraw:function(){if(A.gecko){var J=this.getContainerEl();setTimeout(function(){D.removeClass(J,"yui-dt-noop");},0);setTimeout(function(){D.addClass(J,"yui-dt-noop");},0);}},_initNodeTemplates:function(){var K=document,J=K.createElement("tr"),M=K.createElement("td"),L=K.createElement("div");M.appendChild(L);this._tdElTemplate=M;this._trElTemplate=J;},_initContainerEl:function(J){if(this._elContainer){I.purgeElement(this._elContainer,true);this._elContainer.innerHTML="";}J=D.get(J);if(J&&J.nodeName&&(J.nodeName.toLowerCase()=="div")){I.purgeElement(J,true);J.innerHTML="";D.addClass(J,"yui-dt yui-dt-noop");!
 this._elTheadContainer=J.appendChild(document.createElement("d!
 iv"));D.
addClass(this._elTheadContainer,"yui-dt-hd");this._elTbodyContainer=J.appendChild(document.createElement("div"));D.addClass(this._elTbodyContainer,"yui-dt-bd");this._elContainer=J;}},_initConfigs:function(J){if(J){if(J.constructor!=Object){J=null;}else{if(C.isBoolean(J.paginator)){}}this._oConfigs=J;}else{this._oConfigs={};}},_initColumnSet:function(L){if(this._oColumnSet){for(var K=0,J=this._oColumnSet.keys.length;K<J;K++){G._oStylesheetRules[".yui-dt-col-"+this._oColumnSet.keys[K].getId()]=undefined;}this._oColumnSet=null;}if(C.isArray(L)){this._oColumnSet=new YAHOO.widget.ColumnSet(L);}else{if(L instanceof YAHOO.widget.ColumnSet){this._oColumnSet=L;}}},_initDataSource:function(J){this._oDataSource=null;if(J&&(J instanceof H)){this._oDataSource=J;}else{var K=null;var O=this._elContainer;var L;if(O.hasChildNodes()){var N=O.childNodes;for(L=0;L<N.length;L++){if(N[L].nodeName&&N[L].nodeName.toLowerCase()=="table"){K=N[L];break;}}if(K){var M=[];for(L=0;L<this._oColumnSet.keys.!
 length;L++){M.push({key:this._oColumnSet.keys[L].key});}this._oDataSource=new H(K);this._oDataSource.responseType=H.TYPE_HTMLTABLE;this._oDataSource.responseSchema={fields:M};}}}},_initRecordSet:function(){if(this._oRecordSet){this._oRecordSet.reset();}else{this._oRecordSet=new YAHOO.widget.RecordSet();}},_initTableEl:function(){var S;if(this._elThead){var N;var V=this._oColumnSet.tree[0];for(N=0;N<V.length;N++){if(V[N]._dd){V[N]._dd=V[N]._dd.unreg();}}var U=this._oColumnSet.keys;for(N=0;N<U.length;N++){if(U[N]._ddResizer){U[N]._ddResizer=U[N]._ddResizer.unreg();}}S=this._elThead.parentNode;I.purgeElement(S,true);S.parentNode.removeChild(S);this._elThead=null;}if(this._elTbody){S=this._elTbody.parentNode;I.purgeElement(S,true);S.parentNode.removeChild(S);this._elTbody=null;}var W=document.createElement("table");W.id=this._sId+"-headtable";W=this._elTheadContainer.appendChild(W);var T=document.createElement("table");
+T.id=this._sId+"-bodytable";this._elTbodyContainer.appendChild(T);this._initTheadEls();this._elTbody=T.appendChild(document.createElement("tbody"));this._elTbody.tabIndex=0;D.addClass(this._elTbody,G.CLASS_BODY);var Q=document.createElement("tbody");var J=Q.appendChild(document.createElement("tr"));D.addClass(J,G.CLASS_FIRST);D.addClass(J,G.CLASS_LAST);this._elMsgRow=J;var R=J.appendChild(document.createElement("td"));R.colSpan=this._oColumnSet.keys.length;D.addClass(R,G.CLASS_FIRST);D.addClass(R,G.CLASS_LAST);this._elMsgTd=R;this._elMsgTbody=T.appendChild(Q);var O=R.appendChild(document.createElement("div"));D.addClass(O,G.CLASS_LINER);this.showTableMessage(G.MSG_LOADING,G.CLASS_LOADING);var L=this._elContainer;var M=this._elThead;var K=this._elTbody;if(A.ie){K.hideFocus=true;}var P=this._elTbodyContainer;I.addListener(L,"focus",this._onTableFocus,this);I.addListener(K,"focus",this._onTbodyFocus,this);I.addListener(K,"mouseover",this._onTableMouseover,this);I.addListener(K!
 ,"mouseout",this._onTableMouseout,this);I.addListener(K,"mousedown",this._onTableMousedown,this);I.addListener(K,"keydown",this._onTbodyKeydown,this);I.addListener(K,"keypress",this._onTableKeypress,this);I.addListener(K.parentNode,"dblclick",this._onTableDblclick,this);I.addListener(K,"click",this._onTbodyClick,this);I.addListener(P,"scroll",this._onScroll,this);},_initTheadEls:function(){var b,Z,X,d,M,Q;if(!this._elThead){d=this._elThead=document.createElement("thead");M=this._elA11yThead=document.createElement("thead");Q=[d,M];I.addListener(d,"focus",this._onTheadFocus,this);I.addListener(d,"keydown",this._onTheadKeydown,this);I.addListener(d,"mouseover",this._onTableMouseover,this);I.addListener(d,"mouseout",this._onTableMouseout,this);I.addListener(d,"mousedown",this._onTableMousedown,this);I.addListener(d,"mouseup",this._onTableMouseup,this);I.addListener(d,"click",this._onTheadClick,this);I.addListener(d.parentNode,"dblclick",this._onTableDblclick,this);this._elThead!
 Container.firstChild.appendChild(M);this._elTbodyContainer.fir!
 stChild.
appendChild(d);}else{d=this._elThead;M=this._elA11yThead;Q=[d,M];for(b=0;b<Q.length;b++){for(Z=Q[b].rows.length-1;Z>-1;Z--){I.purgeElement(Q[b].rows[Z],true);Q[b].removeChild(Q[b].rows[Z]);}}}var R,m=this._oColumnSet;var L=m.tree;var P,T;for(X=0;X<Q.length;X++){for(b=0;b<L.length;b++){var Y=Q[X].appendChild(document.createElement("tr"));T=(X===1)?this._sId+"-hdrow"+b+"-a11y":this._sId+"-hdrow"+b;Y.id=T;for(Z=0;Z<L[b].length;Z++){R=L[b][Z];P=Y.appendChild(document.createElement("th"));if(X===0){R._elTh=P;}T=(X===1)?this._sId+"-th"+R.getId()+"-a11y":this._sId+"-th"+R.getId();P.id=T;P.yuiCellIndex=Z;this._initThEl(P,R,b,Z,(X===1));}if(X===0){if(b===0){D.addClass(Y,G.CLASS_FIRST);}if(b===(L.length-1)){D.addClass(Y,G.CLASS_LAST);}}}if(X===0){var V=m.headers[0];var N=m.headers[m.headers.length-1];for(b=0;b<V.length;b++){D.addClass(D.get(this._sId+"-th"+V[b]),G.CLASS_FIRST);}for(b=0;b<N.length;b++){D.addClass(D.get(this._sId+"-th"+N[b]),G.CLASS_LAST);}var U=(F.DD)?true:false;var k=!
 false;if(this._oConfigs.draggableColumns){for(b=0;b<this._oColumnSet.tree[0].length;b++){R=this._oColumnSet.tree[0][b];if(U){P=R.getThEl();D.addClass(P,G.CLASS_DRAGGABLE);var S=G._initColumnDragTargetEl();R._dd=new YAHOO.widget.ColumnDD(this,R,P,S);}else{k=true;}}}for(b=0;b<this._oColumnSet.keys.length;b++){R=this._oColumnSet.keys[b];if(R.resizeable){if(U){P=R.getThEl();D.addClass(P,G.CLASS_RESIZEABLE);var K=P.firstChild;var J=K.appendChild(document.createElement("div"));J.id=this._sId+"-colresizer"+R.getId();R._elResizer=J;D.addClass(J,G.CLASS_RESIZER);var n=G._initColumnResizerProxyEl();R._ddResizer=new YAHOO.util.ColumnResizer(this,R,P,J.id,n);var a=function(g){I.stopPropagation(g);};I.addListener(J,"click",a);}else{k=true;}}}if(k){}}else{}}for(var e=0,c=this._oColumnSet.keys.length;e<c;e++){if(this._oColumnSet.keys[e].hidden){var f=this._oColumnSet.keys[e];var W=f.getThEl();f._nLastWidth=W.offsetWidth-(parseInt(D.getStyle(W,"paddingLeft"),10)|0)-(parseInt(D.getStyle(W,"!
 paddingRight"),10)|0);this._setColumnWidth(f,"1px");}}if(A.web!
 kit&&A.w
ebkit<420){var O=this;setTimeout(function(){O._elThead.style.display="";},0);this._elThead.style.display="none";}},_initThEl:function(Q,O,S,K,R){var N=O.getKey();var J=O.getId();Q.yuiColumnKey=N;Q.yuiColumnId=J;Q.innerHTML="";Q.rowSpan=O.getRowspan();Q.colSpan=O.getColspan();var P=Q.appendChild(document.createElement("div"));var M=P.appendChild(document.createElement("span"));if(R){if(O.abbr){Q.abbr=O.abbr;}M.innerHTML=C.isValue(O.label)?O.label:N;}else{P.id=Q.id+"-liner";var L;if(C.isString(O.className)){L=[O.className];}else{if(C.isArray(O.className)){L=O.className;}else{L=[];}}L[L.length]="yui-dt-col-"+N.replace(/[^\w\-.:]/g,"");L[L.length]="yui-dt-col-"+O.getId();L[L.length]=G.CLASS_LINER;D.addClass(P,L.join(" "));D.addClass(M,G.CLASS_LABEL);L=[];if(O.resizeable){L[L.length]=G.CLASS_RESIZEABLE;}if(O.sortable){L[L.length]=G.CLASS_SORTABLE;}if(O.hidden){L[L.length]=G.CLASS_HIDDEN;}if(O.selected){L[L.length]=G.CLASS_SELECTED;}D.addClass(Q,L.join(" "));G.formatTheadCell(M,O,!
 this);}},_initCellEditorEl:function(){var J=document.createElement("div");J.id=this._sId+"-celleditor";J.style.display="none";J.tabIndex=0;D.addClass(J,G.CLASS_EDITOR);var L=D.getFirstChild(document.body);if(L){J=D.insertBefore(J,L);}else{J=document.body.appendChild(J);}var K={};K.container=J;K.value=null;K.isActive=false;this._oCellEditor=K;},_initColumnSort:function(){this.subscribe("theadCellClickEvent",this.onEventSortColumn);},_createTrEl:function(K){var J=this._trElTemplate.cloneNode(true);J.id=this._sId+"-bdrow"+this._nTrCount;this._nTrCount++;return this._updateTrEl(J,K);},_updateTrEl:function(J,X){var U=this._oColumnSet,N,K,M=this.get("sortedBy"),Q,P,S,W;if(M){N=M.key;K=M.dir;}J.style.display="none";while(J.childNodes.length>U.keys.length){J.removeChild(J.firstChild);}for(Q=J.childNodes.length||0,S=U.keys.length;Q<S;++Q){this._addTdEl(J,U.keys[Q],Q);}for(Q=0,S=U.keys.length;Q<S;++Q){var R=U.keys[Q],V=J.childNodes[Q],O=V.firstChild,T="",L=this.get("scrollable")?"-a1!
 1y ":" ";
+this.formatCell(O,X,R);for(P=0,W=U.headers[Q].length;P<W;++P){T+=this._sId+"-th"+U.headers[Q][P]+L;}V.headers=T;if(R.key===N){D.replaceClass(V,K===G.CLASS_ASC?G.CLASS_DESC:G.CLASS_ASC,K);}else{D.removeClass(V,G.CLASS_ASC);D.removeClass(V,G.CLASS_DESC);}if(R.hidden){D.addClass(V,G.CLASS_HIDDEN);}else{D.removeClass(V,G.CLASS_HIDDEN);}if(R.selected){D.addClass(V,G.CLASS_SELECTED);}else{D.removeClass(V,G.CLASS_SELECTED);}}J.yuiRecordId=X.getId();J.style.display="";return J;},_addTdEl:function(J,M,K){var L=this._tdElTemplate.cloneNode(true),N=L.firstChild;K=K||J.cells.length;L.id=J.id+"-cell"+this._nTdCount;this._nTdCount++;L.yuiColumnKey=M.getKey();L.yuiColumnId=M.getId();L.yuiCellIndex=K;if(!(K%this._oColumnSet.keys.length-1)){L.className=K?G.CLASS_LAST:G.CLASS_FIRST;}var O=J.cells[K]||null;return J.insertBefore(L,O);},_deleteTrEl:function(J){var K;if(!C.isNumber(J)){K=D.get(J).sectionRowIndex;}else{K=J;}if(C.isNumber(K)&&(K>-2)&&(K<this._elTbody.rows.length)){return this._elT!
 body.removeChild(this.getTrEl(J));}else{return null;}},_setFirstRow:function(){var J=this.getFirstTrEl();if(J){if(this._sFirstTrId){D.removeClass(this._sFirstTrId,G.CLASS_FIRST);}D.addClass(J,G.CLASS_FIRST);this._sFirstTrId=J.id;}else{this._sFirstTrId=null;}},_setLastRow:function(){var J=this.getLastTrEl();if(J){if(this._sLastTrId){D.removeClass(this._sLastTrId,G.CLASS_LAST);}D.addClass(J,G.CLASS_LAST);this._sLastTrId=J.id;}else{this._sLastTrId=null;}},_setRowStripes:function(T,L){var M=this._elTbody.rows,Q=0,S=M.length,P=[],R=0,N=[],J=0;if((T!==null)&&(T!==undefined)){var O=this.getTrEl(T);if(O){Q=O.sectionRowIndex;if(C.isNumber(L)&&(L>1)){S=Q+L;}}}for(var K=Q;K<S;K++){if(K%2){P[R++]=M[K];}else{N[J++]=M[K];}}if(P.length){D.replaceClass(P,G.CLASS_EVEN,G.CLASS_ODD);}if(N.length){D.replaceClass(N,G.CLASS_ODD,G.CLASS_EVEN);}},_onScroll:function(L,K){K._elTheadContainer.scrollLeft=K._elTbodyContainer.scrollLeft;if(K._oCellEditor&&K._oCellEditor.isActive){K.fireEvent("editorBlur!
 Event",{editor:K._oCellEditor});K.cancelCellEditor();}var M=I.!
 getTarge
t(L);var J=M.nodeName.toLowerCase();K.fireEvent("tableScrollEvent",{event:L,target:M});},_onDocumentClick:function(L,K){var M=I.getTarget(L);var J=M.nodeName.toLowerCase();if(!D.isAncestor(K._elContainer,M)){K.fireEvent("tableBlurEvent");if(K._oCellEditor&&K._oCellEditor.isActive){if(!D.isAncestor(K._oCellEditor.container,M)&&(K._oCellEditor.container.id!==M.id)){K.fireEvent("editorBlurEvent",{editor:K._oCellEditor});}}}},_onTableFocus:function(K,J){J.fireEvent("tableFocusEvent");},_onTheadFocus:function(K,J){J.fireEvent("theadFocusEvent");J.fireEvent("tableFocusEvent");},_onTbodyFocus:function(K,J){J.fireEvent("tbodyFocusEvent");J.fireEvent("tableFocusEvent");},_onTableMouseover:function(M,K){var N=I.getTarget(M);var J=N.nodeName.toLowerCase();var L=true;while(N&&(J!="table")){switch(J){case"body":return ;case"a":break;case"td":L=K.fireEvent("cellMouseoverEvent",{target:N,event:M});break;case"span":if(D.hasClass(N,G.CLASS_LABEL)){L=K.fireEvent("theadLabelMouseoverEvent",{ta!
 rget:N,event:M});L=K.fireEvent("headerLabelMouseoverEvent",{target:N,event:M});}break;case"th":L=K.fireEvent("theadCellMouseoverEvent",{target:N,event:M});L=K.fireEvent("headerCellMouseoverEvent",{target:N,event:M});break;case"tr":if(N.parentNode.nodeName.toLowerCase()=="thead"){L=K.fireEvent("theadRowMouseoverEvent",{target:N,event:M});L=K.fireEvent("headerRowMouseoverEvent",{target:N,event:M});}else{L=K.fireEvent("rowMouseoverEvent",{target:N,event:M});}break;default:break;}if(L===false){return ;}else{N=N.parentNode;if(N){J=N.nodeName.toLowerCase();}}}K.fireEvent("tableMouseoverEvent",{target:(N||K._elContainer),event:M});},_onTableMouseout:function(M,K){var N=I.getTarget(M);var J=N.nodeName.toLowerCase();var L=true;while(N&&(J!="table")){switch(J){case"body":return ;case"a":break;case"td":L=K.fireEvent("cellMouseoutEvent",{target:N,event:M});break;case"span":if(D.hasClass(N,G.CLASS_LABEL)){L=K.fireEvent("theadLabelMouseoutEvent",{target:N,event:M});L=K.fireEvent("headerL!
 abelMouseoutEvent",{target:N,event:M});}break;case"th":L=K.fir!
 eEvent("
theadCellMouseoutEvent",{target:N,event:M});L=K.fireEvent("headerCellMouseoutEvent",{target:N,event:M});break;case"tr":if(N.parentNode.nodeName.toLowerCase()=="thead"){L=K.fireEvent("theadRowMouseoutEvent",{target:N,event:M});L=K.fireEvent("headerRowMouseoutEvent",{target:N,event:M});}else{L=K.fireEvent("rowMouseoutEvent",{target:N,event:M});}break;default:break;}if(L===false){return ;}else{N=N.parentNode;if(N){J=N.nodeName.toLowerCase();}}}K.fireEvent("tableMouseoutEvent",{target:(N||K._elContainer),event:M});},_onTableMousedown:function(M,K){var N=I.getTarget(M);var J=N.nodeName.toLowerCase();var L=true;while(N&&(J!="table")){switch(J){case"body":return ;case"a":break;case"td":L=K.fireEvent("cellMousedownEvent",{target:N,event:M});break;case"span":if(D.hasClass(N,G.CLASS_LABEL)){L=K.fireEvent("theadLabelMousedownEvent",{target:N,event:M});L=K.fireEvent("headerLabelMousedownEvent",{target:N,event:M});}break;case"th":L=K.fireEvent("theadCellMousedownEvent",{target:N,event:M}!
 );L=K.fireEvent("headerCellMousedownEvent",{target:N,event:M});break;case"tr":if(N.parentNode.nodeName.toLowerCase()=="thead"){L=K.fireEvent("theadRowMousedownEvent",{target:N,event:M});L=K.fireEvent("headerRowMousedownEvent",{target:N,event:M});}else{L=K.fireEvent("rowMousedownEvent",{target:N,event:M});}break;default:break;}if(L===false){return ;}else{N=N.parentNode;if(N){J=N.nodeName.toLowerCase();}}}K.fireEvent("tableMousedownEvent",{target:(N||K._elContainer),event:M});},_onTableDblclick:function(M,K){var N=I.getTarget(M);var J=N.nodeName.toLowerCase();var L=true;while(N&&(J!="table")){switch(J){case"body":return ;case"td":L=K.fireEvent("cellDblclickEvent",{target:N,event:M});break;case"span":if(D.hasClass(N,G.CLASS_LABEL)){L=K.fireEvent("theadLabelDblclickEvent",{target:N,event:M});L=K.fireEvent("headerLabelDblclickEvent",{target:N,event:M});}break;case"th":L=K.fireEvent("theadCellDblclickEvent",{target:N,event:M});
+L=K.fireEvent("headerCellDblclickEvent",{target:N,event:M});break;case"tr":if(N.parentNode.nodeName.toLowerCase()=="thead"){L=K.fireEvent("theadRowDblclickEvent",{target:N,event:M});L=K.fireEvent("headerRowDblclickEvent",{target:N,event:M});}else{L=K.fireEvent("rowDblclickEvent",{target:N,event:M});}break;default:break;}if(L===false){return ;}else{N=N.parentNode;if(N){J=N.nodeName.toLowerCase();}}}K.fireEvent("tableDblclickEvent",{target:(N||K._elContainer),event:M});},_onTheadKeydown:function(M,K){if(I.getCharCode(M)===9){setTimeout(function(){if((K instanceof G)&&K._sId){K._elTbodyContainer.scrollLeft=K._elTheadContainer.scrollLeft;}},0);}var N=I.getTarget(M);var J=N.nodeName.toLowerCase();var L=true;while(N&&(J!="table")){switch(J){case"body":return ;case"input":case"textarea":break;case"thead":L=K.fireEvent("theadKeyEvent",{target:N,event:M});break;default:break;}if(L===false){return ;}else{N=N.parentNode;if(N){J=N.nodeName.toLowerCase();}}}K.fireEvent("tableKeyEvent",{!
 target:(N||K._elContainer),event:M});},_onTbodyKeydown:function(N,L){var K=L.get("selectionMode");if(K=="standard"){L._handleStandardSelectionByKey(N);}else{if(K=="single"){L._handleSingleSelectionByKey(N);}else{if(K=="cellblock"){L._handleCellBlockSelectionByKey(N);}else{if(K=="cellrange"){L._handleCellRangeSelectionByKey(N);}else{if(K=="singlecell"){L._handleSingleCellSelectionByKey(N);}}}}}if(L._oCellEditor&&L._oCellEditor.isActive){L.fireEvent("editorBlurEvent",{editor:L._oCellEditor});}var O=I.getTarget(N);var J=O.nodeName.toLowerCase();var M=true;while(O&&(J!="table")){switch(J){case"body":return ;case"tbody":M=L.fireEvent("tbodyKeyEvent",{target:O,event:N});break;default:break;}if(M===false){return ;}else{O=O.parentNode;if(O){J=O.nodeName.toLowerCase();}}}L.fireEvent("tableKeyEvent",{target:(O||L._elContainer),event:N});},_onTableKeypress:function(L,K){if(A.webkit){var J=I.getCharCode(L);if(J==40){I.stopEvent(L);}else{if(J==38){I.stopEvent(L);}}}},_onTheadClick:funct!
 ion(M,K){if(K._oCellEditor&&K._oCellEditor.isActive){K.fireEve!
 nt("edit
orBlurEvent",{editor:K._oCellEditor});}var N=I.getTarget(M);var J=N.nodeName.toLowerCase();var L=true;while(N&&(J!="table")){switch(J){case"body":return ;case"input":if(N.type.toLowerCase()=="checkbox"){L=K.fireEvent("theadCheckboxClickEvent",{target:N,event:M});}else{if(N.type.toLowerCase()=="radio"){L=K.fireEvent("theadRadioClickEvent",{target:N,event:M});}}break;case"a":L=K.fireEvent("theadLinkClickEvent",{target:N,event:M});break;case"button":L=K.fireEvent("theadButtonClickEvent",{target:N,event:M});break;case"span":if(D.hasClass(N,G.CLASS_LABEL)){L=K.fireEvent("theadLabelClickEvent",{target:N,event:M});L=K.fireEvent("headerLabelClickEvent",{target:N,event:M});}break;case"th":L=K.fireEvent("theadCellClickEvent",{target:N,event:M});L=K.fireEvent("headerCellClickEvent",{target:N,event:M});break;case"tr":L=K.fireEvent("theadRowClickEvent",{target:N,event:M});L=K.fireEvent("headerRowClickEvent",{target:N,event:M});break;default:break;}if(L===false){return ;}else{N=N.parentNo!
 de;if(N){J=N.nodeName.toLowerCase();}}}K.fireEvent("tableClickEvent",{target:(N||K._elContainer),event:M});},_onTbodyClick:function(M,K){if(K._oCellEditor&&K._oCellEditor.isActive){K.fireEvent("editorBlurEvent",{editor:K._oCellEditor});}var N=I.getTarget(M);var J=N.nodeName.toLowerCase();var L=true;while(N&&(J!="table")){switch(J){case"body":return ;case"input":if(N.type.toLowerCase()=="checkbox"){L=K.fireEvent("checkboxClickEvent",{target:N,event:M});}else{if(N.type.toLowerCase()=="radio"){L=K.fireEvent("radioClickEvent",{target:N,event:M});}}break;case"a":L=K.fireEvent("linkClickEvent",{target:N,event:M});break;case"button":L=K.fireEvent("buttonClickEvent",{target:N,event:M});break;case"td":L=K.fireEvent("cellClickEvent",{target:N,event:M});break;case"tr":L=K.fireEvent("rowClickEvent",{target:N,event:M});break;default:break;}if(L===false){return ;}else{N=N.parentNode;if(N){J=N.nodeName.toLowerCase();}}}K.fireEvent("tableClickEvent",{target:(N||K._elContainer),event:M});},!
 _onDropdownChange:function(K,J){var L=I.getTarget(K);J.fireEve!
 nt("drop
downChangeEvent",{event:K,target:L});},getId:function(){return this._sId;},toString:function(){return"DataTable instance "+this._sId;},getDataSource:function(){return this._oDataSource;},getColumnSet:function(){return this._oColumnSet;},getRecordSet:function(){return this._oRecordSet;},getCellEditor:function(){return this._oCellEditor;},getContainerEl:function(){return this._elContainer;},getTheadEl:function(){return this._elThead;},getTbodyEl:function(){return this._elTbody;},getMsgTbodyEl:function(){return this._elMsgTbody;},getMsgTdEl:function(){return this._elMsgTd;},getTrEl:function(N){var M=this._elTbody.rows;if(N instanceof YAHOO.widget.Record){var L=this.getTrIndex(N);if(L!==null){return M[L];}else{return null;}}else{if(C.isNumber(N)&&(N>-1)&&(N<M.length)){return M[N];}else{var J;var K=D.get(N);if(K&&(K.ownerDocument==document)){if(K.nodeName.toLowerCase()!="tr"){J=D.getAncestorByTagName(K,"tr");}else{J=K;}if(J&&(J.parentNode==this._elTbody)){return J;}}}}return null!
 ;},getFirstTrEl:function(){return this._elTbody.rows[0]||null;},getLastTrEl:function(){var J=this._elTbody.rows;if(J.length>0){return J[J.length-1]||null;}},getNextTrEl:function(L){var J=this.getTrIndex(L);if(J!==null){var K=this._elTbody.rows;if(J<K.length-1){return K[J+1];}}return null;},getPreviousTrEl:function(L){var J=this.getTrIndex(L);if(J!==null){var K=this._elTbody.rows;if(J>0){return K[J-1];}}return null;},getTdLinerEl:function(J){var K=this.getTdEl(J);return K.firstChild||null;},getTdEl:function(J){var O;var M=D.get(J);if(M&&(M.ownerDocument==document)){if(M.nodeName.toLowerCase()!="td"){O=D.getAncestorByTagName(M,"td");}else{O=M;}if(O&&(O.parentNode.parentNode==this._elTbody)){return O;}}else{if(J){var N,L;if(C.isString(J.columnId)&&C.isString(J.recordId)){N=this.getRecord(J.recordId);var P=this.getColumnById(J.columnId);if(P){L=P.getKeyIndex();}}if(J.record&&J.column&&J.column.getKeyIndex){N=J.record;
+L=J.column.getKeyIndex();}var K=this.getTrEl(N);if((L!==null)&&K&&K.cells&&K.cells.length>0){return K.cells[L]||null;}}}return null;},getFirstTdEl:function(K){var J=this.getTrEl(K)||this.getFirstTrEl();if(J&&(J.cells.length>0)){return J.cells[0];}return null;},getLastTdEl:function(K){var J=this.getTrEl(K)||this.getLastTrEl();if(J&&(J.cells.length>0)){return J.cells[J.cells.length-1];}return null;},getNextTdEl:function(J){var N=this.getTdEl(J);if(N){var L=N.yuiCellIndex;var K=this.getTrEl(N);if(L<K.cells.length-1){return K.cells[L+1];}else{var M=this.getNextTrEl(K);if(M){return M.cells[0];}}}return null;},getPreviousTdEl:function(J){var N=this.getTdEl(J);if(N){var L=N.yuiCellIndex;var K=this.getTrEl(N);if(L>0){return K.cells[L-1];}else{var M=this.getPreviousTrEl(K);if(M){return this.getLastTdEl(M);}}}return null;},getAboveTdEl:function(J){var L=this.getTdEl(J);if(L){var K=this.getPreviousTrEl(L);if(K){return K.cells[L.yuiCellIndex];}}return null;},getBelowTdEl:function(J){va!
 r L=this.getTdEl(J);if(L){var K=this.getNextTrEl(L);if(K){return K.cells[L.yuiCellIndex];}}return null;},getThLinerEl:function(K){var J=this.getThEl(K);return J.firstChild||null;},getThEl:function(M){var J;if(M instanceof YAHOO.widget.Column){var L=M;J=L.getThEl();if(J){return J;}}else{var K=D.get(M);if(K&&(K.ownerDocument==document)){if(K.nodeName.toLowerCase()!="th"){J=D.getAncestorByTagName(K,"th");}else{J=K;}if(J&&(J.parentNode.parentNode==this._elThead)){return J;}}}return null;},getTrIndex:function(O){var N;if(O instanceof YAHOO.widget.Record){N=this._oRecordSet.getRecordIndex(O);if(N===null){return null;}}else{if(C.isNumber(O)){N=O;}}if(C.isNumber(N)){if((N>-1)&&(N<this._oRecordSet.getLength())){var L=this.get("paginator");if(L instanceof B||this.get("paginated")){var M=0,P=0;if(L instanceof B){var K=L.getPageRecords();M=K[0];P=K[1];}else{M=L.startRecordIndex;P=M+L.rowsPerPage-1;}if((N>=M)&&(N<=P)){return N-M;}else{return null;}}else{return N;}}else{return null;}}els!
 e{var J=this.getTrEl(O);if(J&&(J.ownerDocument==document)&&(J.!
 parentNo
de==this._elTbody)){return J.sectionRowIndex;}}return null;},initializeTable:function(){this._bInit=true;this._oRecordSet.reset();this._unselectAllTrEls();this._unselectAllTdEls();this._aSelections=null;this._oAnchorRecord=null;this._oAnchorCell=null;this.set("sortedBy",null);},render:function(){this._oChainRender.stop();this.showTableMessage(G.MSG_LOADING,G.CLASS_LOADING);var S,R,Q,P,U,X;var W=this.get("paginator");var Z=W instanceof B||this.get("paginated");if(Z){if(W instanceof B){X=this._oRecordSet.getRecords(W.getStartIndex(),W.getRowsPerPage());W.render();}else{this.updatePaginator();var N=W.rowsPerPage;var K=(W.currentPage-1)*N;X=this._oRecordSet.getRecords(K,N);this.formatPaginators();}}else{X=this._oRecordSet.getRecords();}var b=this._elTbody;var M=b.rows;if(C.isArray(X)&&(X.length>0)){var V=this.getSelectedRows();var a=this.getSelectedCells();var L=(V.length>0)||(a.length>0);while(b.hasChildNodes()&&(M.length>X.length)){b.deleteRow(-1);}if(L){this._unselectAllTrEls!
 ();this._unselectAllTdEls();}this.hideTableMessage();var J=this.get("renderLoopSize");var O,T;if(M.length>0){T=M.length;this._oChainRender.add({method:function(e){if((this instanceof G)&&this._sId){var d=e.nCurrentRow,c=J>0?Math.min(d+J,M.length):M.length;for(;d<c;++d){this._updateTrEl(M[d],X[d]);}if(J>0){this._syncColWidths();}e.nCurrentRow=d;}},iterations:(J>0)?Math.ceil(T/J):1,argument:{nCurrentRow:0},scope:this,timeout:(J>0)?0:-1});}O=M.length;T=X.length;var Y=(T-O);if(Y>0){this._oChainRender.add({method:function(e){if((this instanceof G)&&this._sId){var d=e.nCurrentRow,c=J>0?Math.min(d+J,T):T,g=document.createDocumentFragment(),f;for(;d<c;++d){f=this._createTrEl(X[d]);f.className=(d%2)?G.CLASS_ODD:G.CLASS_EVEN;g.appendChild(f);}this._elTbody.appendChild(g);if(J>0){this._syncColWidths();}e.nCurrentRow=d;}},iterations:(J>0)?Math.ceil(Y/J):1,argument:{nCurrentRow:O},scope:this,timeout:(J>0)?0:-1});}this._oChainRender.add({method:function(d){if((this instanceof G)&&this._s!
 Id){this._setFirstRow();this._setLastRow();if(L){for(R=0;R<M.l!
 ength;R+
+){var f=M[R];var c=this.get("selectionMode");if((c=="standard")||(c=="single")){for(Q=0;Q<V.length;Q++){if(V[Q]===f.yuiRecordId){D.addClass(f,G.CLASS_SELECTED);if(R===M.length-1){this._oAnchorRecord=this.getRecord(f.yuiRecordId);}}}}else{for(Q=0;Q<f.cells.length;Q++){var e=f.cells[Q];for(P=0;P<a.length;P++){if((a[P].recordId===f.yuiRecordId)&&(a[P].columnId===e.yuiColumnId)){D.addClass(e,G.CLASS_SELECTED);if(Q===f.cells.length-1){this._oAnchorCell={record:this.getRecord(f.yuiRecordId),column:this.getColumnById(e.yuiColumnId)};}}}}}}}}if(this._bInit){this._forceGeckoRedraw();this._oChainRender.add({method:function(){if((this instanceof G)&&this._sId&&this._bInit){this._bInit=false;this.fireEvent("initEvent");}},scope:this});this._oChainRender.run();}else{this.fireEvent("renderEvent");this.fireEvent("refreshEvent");}},scope:this,timeout:(J>0)?0:-1});this._oChainRender.add({method:function(){if((this instanceof G)&&this._sId){this._syncColWidths();}},scope:this});this._oChainR!
 ender.run();}else{while(b.hasChildNodes()){b.deleteRow(-1);}this.showTableMessage(G.MSG_EMPTY,G.CLASS_EMPTY);}},destroy:function(){this._oChainRender.stop();var L;var M=this._oColumnSet.tree[0];for(L=0;L<M.length;L++){if(M[L]._dd){M[L]._dd=M[L]._dd.unreg();}}var K=this._oColumnSet.keys;for(L=0;L<K.length;L++){if(K[L]._ddResizer){K[L]._ddResizer=K[L]._ddResizer.unreg();}}I.purgeElement(this._oCellEditor.container,true);document.body.removeChild(this._oCellEditor.container);var J=this.toString();var N=this._elContainer;this._oRecordSet.unsubscribeAll();this.unsubscribeAll();I.purgeElement(N,true);I.removeListener(document,"click",this._onDocumentClick);N.innerHTML="";for(var O in this){if(C.hasOwnProperty(this,O)){this[O]=null;}}G._nCurrentCount--;if(G._nCurrentCount<1){if(G._elStylesheet){document.getElementsByTagName("head")[0].removeChild(G._elStylesheet);G._elStylesheet=null;}}},showTableMessage:function(K,J){var L=this._elMsgTd;
+if(C.isString(K)){L.firstChild.innerHTML=K;}if(C.isString(J)){D.addClass(L.firstChild,J);}this._elMsgTbody.parentNode.style.width=this.getTheadEl().parentNode.offsetWidth+"px";this._elMsgTbody.style.display="";this.fireEvent("tableMsgShowEvent",{html:K,className:J});},hideTableMessage:function(){if(this._elMsgTbody.style.display!="none"){this._elMsgTbody.style.display="none";this._elMsgTbody.parentNode.style.width="";this.fireEvent("tableMsgHideEvent");}},focus:function(){this.focusTbodyEl();},focusTheadEl:function(){this._focusEl(this._elThead);},focusTbodyEl:function(){this._focusEl(this._elTbody);},getRecordIndex:function(M){var L;if(!C.isNumber(M)){if(M instanceof YAHOO.widget.Record){return this._oRecordSet.getRecordIndex(M);}else{var K=this.getTrEl(M);if(K){L=K.sectionRowIndex;}}}else{L=M;}if(C.isNumber(L)){var J=this.get("paginator");if(J instanceof B){return J.get("recordOffset")+L;}else{if(this.get("paginated")){return J.startRecordIndex+L;}else{return L;}}}return !
 null;},getRecord:function(L){var K=this._oRecordSet.getRecord(L);if(!K){var J=this.getTrEl(L);if(J){K=this._oRecordSet.getRecord(J.yuiRecordId);}}if(K instanceof YAHOO.widget.Record){return this._oRecordSet.getRecord(K);}else{return null;}},getColumn:function(J){var L=this._oColumnSet.getColumn(J);if(!L){var K=this.getTdEl(J);if(K){L=this._oColumnSet.getColumnById(K.yuiColumnId);}else{K=this.getThEl(J);if(K){L=this._oColumnSet.getColumnById(K.yuiColumnId);}}}if(!L){}return L;},getColumnById:function(J){return this._oColumnSet.getColumnById(J);},getColumnSortDir:function(L){if(L.sortOptions&&L.sortOptions.defaultOrder){if(L.sortOptions.defaultOrder=="asc"){L.sortOptions.defaultDir=G.CLASS_ASC;}else{if(L.sortOptions.defaultOrder=="desc"){L.sortOptions.defaultDir=G.CLASS_DESC;}}}var K=(L.sortOptions&&L.sortOptions.defaultDir)?L.sortOptions.defaultDir:G.CLASS_ASC;var J=false;var M=this.get("sortedBy");if(M&&(M.key===L.key)){J=true;if(M.dir){K=(M.dir==G.CLASS_ASC)?G.CLASS_DESC:G!
 .CLASS_ASC;}else{K=(K==G.CLASS_ASC)?G.CLASS_DESC:G.CLASS_ASC;}!
 }return 
K;},sortColumn:function(O,M){if(O&&(O instanceof YAHOO.widget.Column)){if(!O.sortable){D.addClass(this.getThEl(O),G.CLASS_SORTABLE);}if(M&&(M!==G.CLASS_ASC)&&(M!==G.CLASS_DESC)){M=null;}var L=M||this.getColumnSortDir(O);var P=this.get("sortedBy")||{};var K=(P.key===O.key)?true:false;if(!K||M){var N=(O.sortOptions&&C.isFunction(O.sortOptions.sortFunction))?O.sortOptions.sortFunction:function(R,Q,T){var S=YAHOO.util.Sort.compare(R.getData(O.key),Q.getData(O.key),T);if(S===0){return YAHOO.util.Sort.compare(R.getId(),Q.getId(),T);}else{return S;}};this._oRecordSet.sortRecords(N,((L==G.CLASS_DESC)?true:false));}else{this._oRecordSet.reverseRecords();}this.set("sortedBy",{key:O.key,dir:L,column:O});var J=this.get("paginator");if(J instanceof B){J.setPage(1,true);}else{if(this.get("paginated")){this.updatePaginator({currentPage:1});}}G.formatTheadCell(O.getThEl().firstChild.firstChild,O,this);this.render();this.fireEvent("columnSortEvent",{column:O,dir:L});}else{}},_setColumnWidth:!
 function(O,J){O=this.getColumn(O);if(O){if(!G._bStylesheetFallback){var S;if(!G._elStylesheet){S=document.createElement("style");S.type="text/css";G._elStylesheet=document.getElementsByTagName("head").item(0).appendChild(S);}if(G._elStylesheet){S=G._elStylesheet;var R=".yui-dt-col-"+O.getId();var P=G._oStylesheetRules[R];if(!P){if(S.styleSheet&&S.styleSheet.addRule){S.styleSheet.addRule(R,"overflow:hidden");S.styleSheet.addRule(R,"width:"+J);P=S.styleSheet.rules[S.styleSheet.rules.length-1];}else{if(S.sheet&&S.sheet.insertRule){S.sheet.insertRule(R+" {overflow:hidden;width:"+J+";}",S.sheet.cssRules.length);P=S.sheet.cssRules[S.sheet.cssRules.length-1];}else{G._bStylesheetFallback=true;}}G._oStylesheetRules[R]=P;}else{P.style.width=J;}return ;}G._bStylesheetFallback=true;}if(G._bStylesheetFallback){if(J=="auto"){J="";}if(!this._aFallbackColResizer[this._elTbody.rows.length]){var N,M,L;var Q=["var colIdx=oColumn.getKeyIndex();","oColumn.getThEl().firstChild.style.width="];for!
 (N=this._elTbody.rows.length-1,M=2;N>=0;--N){Q[M++]="this._elT!
 body.row
s[";Q[M++]=N;Q[M++]="].cells[colIdx].firstChild.style.width=";Q[M++]="this._elTbody.rows[";Q[M++]=N;Q[M++]="].cells[colIdx].style.width=";}Q[M]="sWidth;";Q[M+1]="oColumn.getThEl().firstChild.style.overflow=";for(N=this._elTbody.rows.length-1,L=M+2;N>=0;--N){Q[L++]="this._elTbody.rows[";Q[L++]=N;Q[L++]="].cells[colIdx].firstChild.style.overflow=";Q[L++]="this._elTbody.rows[";Q[L++]=N;Q[L++]="].cells[colIdx].style.overflow=";}Q[L]='"hidden";';this._aFallbackColResizer[this._elTbody.rows.length]=new Function("oColumn","sWidth",Q.join(""));}var K=this._aFallbackColResizer[this._elTbody.rows.length];if(K){K.call(this,O,J);return ;}}}else{}},setColumnWidth:function(K,J){K=this.getColumn(K);if(K){if(C.isNumber(J)){J=(J>K.minWidth)?J:K.minWidth;K.width=J;this._setColumnWidth(K,J+"px");this._syncScrollPadding();this.fireEvent("columnSetWidthEvent",{column:K,width:J});return ;}}},hideColumn:function(P){P=this.getColumn(P);if(P&&!P.hidden){if(P.getTreeIndex()!==null){var M=this.getTbod!
 yEl().rows;var L=M.length;var K=this._oColumnSet.getDescendants(P);for(var O=0;O<K.length;O++){var Q=K[O];Q.hidden=true;var S=Q.getThEl();var R=S.firstChild;Q._nLastWidth=R.offsetWidth-(parseInt(D.getStyle(R,"paddingLeft"),10)|0)-(parseInt(D.getStyle(R,"paddingRight"),10)|0);D.addClass(S,G.CLASS_HIDDEN);var J=Q.getKeyIndex();if(J!==null){for(var N=0;N<L;N++){D.addClass(M[N].cells[J],G.CLASS_HIDDEN);}this._setColumnWidth(Q,"1px");if(Q.resizeable){D.removeClass(Q.getResizerEl(),G.CLASS_RESIZER);}if(Q.sortable){D.removeClass(Q.getThEl(),G.CLASS_SORTABLE);Q.getThEl().firstChild.firstChild.firstChild.style.display="none";}}else{S.firstChild.style.width="1px";}this.fireEvent("columnHideEvent",{column:Q});}}else{}}},showColumn:function(P){P=this.getColumn(P);if(P&&P.hidden){if(P.getTreeIndex()!==null){var M=this.getTbodyEl().rows;var L=M.length;var K=this._oColumnSet.getDescendants(P);for(var O=0;O<K.length;O++){var Q=K[O];
+Q.hidden=false;var R=Q.getThEl();D.removeClass(R,G.CLASS_HIDDEN);var J=Q.getKeyIndex();if(J!==null){for(var N=0;N<L;N++){D.removeClass(M[N].cells[J],G.CLASS_HIDDEN);}this.setColumnWidth(Q,(Q._nLastWidth||Q.minWidth),true);if(Q.sortable){Q.getThEl().firstChild.firstChild.firstChild.style.display="";D.removeClass(Q.getThEl(),G.CLASS_SORTABLE);}if(Q.resizeable){Q._ddResizer.resetResizerEl();D.addClass(Q.getResizerEl(),G.CLASS_RESIZER);}}else{R.firstChild.style.width="";}Q._nLastWidth=null;this.fireEvent("columnShowEvent",{column:Q});}}else{}}},removeColumn:function(L){var K=L.getTreeIndex();if(K!==null){this._oChainRender.stop();var J=this._oColumnSet.getDefinitions();L=J.splice(K,1)[0];this._initColumnSet(J);this._initTheadEls();this.render();this.fireEvent("columnRemoveEvent",{column:L});return L;}},insertColumn:function(M,J){if(M instanceof YAHOO.widget.Column){M=M.getDefinition();}else{if(M.constructor!==Object){return ;}}var K=this._oColumnSet;if(!C.isValue(J)||!C.isNumbe!
 r(J)){J=K.tree[0].length;}this._oChainRender.stop();var L=this._oColumnSet.getDefinitions();L.splice(J,0,M);this._initColumnSet(L);this._initTheadEls();this.render();this.fireEvent("columnInsertEvent",{column:M,index:J});},selectColumn:function(L){L=this.getColumn(L);if(L&&!L.selected){if(L.getKeyIndex()!==null){L.selected=true;var M=L.getThEl();D.addClass(M,G.CLASS_SELECTED);var K=this.getTbodyEl().rows;var J=this._oChainRender;J.add({method:function(N){if((this instanceof G)&&this._sId&&K[N.rowIndex]&&K[N.rowIndex].cells[N.cellIndex]){D.addClass(K[N.rowIndex].cells[N.cellIndex],G.CLASS_SELECTED);}N.rowIndex++;},scope:this,iterations:K.length,argument:{rowIndex:0,cellIndex:L.getKeyIndex()}});J.run();this.fireEvent("columnSelectEvent",{column:L});}else{}}},unselectColumn:function(L){L=this.getColumn(L);if(L&&L.selected){if(L.getKeyIndex()!==null){L.selected=false;var M=L.getThEl();D.removeClass(M,G.CLASS_SELECTED);var K=this.getTbodyEl().rows;var J=this._oChainRender;J.add(!
 {method:function(N){if((this instanceof G)&&this._sId&&K[N.row!
 Index]&&
K[N.rowIndex].cells[N.cellIndex]){D.removeClass(K[N.rowIndex].cells[N.cellIndex],G.CLASS_SELECTED);}N.rowIndex++;},scope:this,iterations:K.length,argument:{rowIndex:0,cellIndex:L.getKeyIndex()}});J.run();this.fireEvent("columnUnselectEvent",{column:L});}else{}}},getSelectedColumns:function(N){var K=[];var L=this._oColumnSet.keys;for(var M=0,J=L.length;M<J;M++){if(L[M].selected){K[K.length]=L[M];}}return K;},highlightColumn:function(J){var M=this.getColumn(J);if(M&&(M.getKeyIndex()!==null)){var N=M.getThEl();D.addClass(N,G.CLASS_HIGHLIGHTED);var L=this.getTbodyEl().rows;var K=this._oChainRender;K.add({method:function(O){if((this instanceof G)&&this._sId&&L[O.rowIndex]&&L[O.rowIndex].cells[O.cellIndex]){D.addClass(L[O.rowIndex].cells[O.cellIndex],G.CLASS_HIGHLIGHTED);}O.rowIndex++;},scope:this,iterations:L.length,argument:{rowIndex:0,cellIndex:M.getKeyIndex()}});K.run();this.fireEvent("columnHighlightEvent",{column:M});}else{}},unhighlightColumn:function(J){var M=this.getColum!
 n(J);if(M&&(M.getKeyIndex()!==null)){var N=M.getThEl();D.removeClass(N,G.CLASS_HIGHLIGHTED);var L=this.getTbodyEl().rows;var K=this._oChainRender;K.add({method:function(O){if((this instanceof G)&&this._sId&&L[O.rowIndex]&&L[O.rowIndex].cells[O.cellIndex]){D.removeClass(L[O.rowIndex].cells[O.cellIndex],G.CLASS_HIGHLIGHTED);}O.rowIndex++;},scope:this,iterations:L.length,argument:{rowIndex:0,cellIndex:M.getKeyIndex()}});K.run();this.fireEvent("columnUnhighlightEvent",{column:M});}else{}},_addTrEl:function(K,J){var L=this._createTrEl(K);if(L){if(J>=0&&J<this._elTbody.rows.length){this._elTbody.insertBefore(L,this._elTbody.rows[J]);if(!J){this._setFirstRow();}}else{this._elTbody.appendChild(L);this._setLastRow();J=this._elTbody.rows.length-1;}this._setRowStripes(J);}return L;},addRow:function(P,L){if(P&&(P.constructor==Object)){var N=this._oRecordSet.addRecord(P,L);if(N){var J;var K=this.get("paginator");if(K instanceof B||this.get("paginated")){J=this.getRecordIndex(N);var M;if!
 (K instanceof B){var O=K.get("totalRecords");if(O!==B.VALUE_UN!
 LIMITED)
{K.set("totalRecords",O+1);}M=(K.getPageRecords())[1];}else{M=K.startRecordIndex+K.rowsPerPage-1;this.updatePaginator();}if(J<=M){this.render();}this.fireEvent("rowAddEvent",{record:N});return ;}else{J=this.getTrIndex(N);if(C.isNumber(J)){this._oChainRender.add({method:function(Q){if((this instanceof G)&&this._sId){var R=this._addTrEl(N,J);if(R){this.hideTableMessage();this.fireEvent("rowAddEvent",{record:N});}}},scope:this,timeout:(this.get("renderLoopSize")>0)?0:-1});this._oChainRender.run();return ;}}}}},addRows:function(L,N){if(C.isArray(L)){var O=this._oRecordSet.addRecords(L,N);if(O){var S=this.getRecordIndex(O[0]);var R=this.get("paginator");if(R instanceof B||this.get("paginated")){var Q;if(R instanceof B){var P=R.get("totalRecords");if(P!==B.VALUE_UNLIMITED){R.set("totalRecords",P+O.length);}Q=(R.getPageRecords())[1];}else{Q=R.startRecordIndex+R.rowsPerPage-1;this.updatePaginator();}if(S<=Q){this.render();}this.fireEvent("rowsAddEvent",{records:O});return ;}else{var!
  M=this.get("renderLoopSize");var K=S+L.length;var J=(K-S);this._oChainRender.add({method:function(W){if((this instanceof G)&&this._sId){var V=W.nCurrentRow,U=W.nCurrentRecord,T=M>0?Math.min(V+M,K):K;for(;V<T;++V,++U){this._addTrEl(O[U],V);}W.nCurrentRow=V;W.nCurrentRecord=U;}},iterations:(M>0)?Math.ceil(K/M):1,argument:{nCurrentRow:S,nCurrentRecord:0},scope:this,timeout:(M>0)?0:-1});this._oChainRender.add({method:function(){this.fireEvent("rowsAddEvent",{records:O});},scope:this,timeout:-1});this._oChainRender.run();this.hideTableMessage();return ;}}}},updateRow:function(O,P){var J,N,M,K;if((O instanceof YAHOO.widget.Record)||(C.isNumber(O))){J=this._oRecordSet.getRecord(O);K=this.getTrEl(J);}else{K=this.getTrEl(O);if(K){J=this.getRecord(K);}}if(J){var L=J.getData();N=YAHOO.widget.DataTable._cloneObject(L);M=this._oRecordSet.updateRecord(J,P);}else{return ;}if(K){this._oChainRender.add({method:function(){if((this instanceof G)&&this._sId){this._updateTrEl(K,M);
+this.fireEvent("rowUpdateEvent",{record:M,oldData:N});}},scope:this,timeout:(this.get("renderLoopSize")>0)?0:-1});this._oChainRender.run();}else{this.fireEvent("rowUpdateEvent",{record:M,oldData:N});}},deleteRow:function(S){var J=this.getRecordIndex(S);if(C.isNumber(J)){var T=this.getRecord(J);if(T){var L=this.getTrIndex(J);var P=T.getId();var R=this._aSelections||[];for(var M=R.length-1;M>-1;M--){if((C.isNumber(R[M])&&(R[M]===P))||((R[M].constructor==Object)&&(R[M].recordId===P))){R.splice(M,1);}}var K=this._oRecordSet.deleteRecord(J);if(K){var Q=this.get("paginator");if(Q instanceof B||this.get("paginated")){var O;if(Q instanceof B){var N=Q.get("totalRecords");if(N!==B.VALUE_UNLIMITED){Q.set("totalRecords",N-1);}O=(Q.getPageRecords())[1];}else{O=Q.startRecordIndex+Q.rowsPerPage-1;this.updatePaginator();}if(J<=O){this.render();}return ;}else{if(C.isNumber(L)){this._oChainRender.add({method:function(){if((this instanceof G)&&this._sId){var U=(L==this.getLastTrEl().sectionRo!
 wIndex);this._deleteTrEl(L);if(this._elTbody.rows.length===0){this.showTableMessage(G.MSG_EMPTY,G.CLASS_EMPTY);}else{if(L===0){this._setFirstRow();}if(U){this._setLastRow();}if(L!=this._elTbody.rows.length){this._setRowStripes(L);}}this.fireEvent("rowDeleteEvent",{recordIndex:J,oldData:K,trElIndex:L});}},scope:this,timeout:(this.get("renderLoopSize")>0)?0:-1});this._oChainRender.run();return ;}}}}}return null;},deleteRows:function(Y,R){var K=this.getRecordIndex(Y);if(C.isNumber(K)){var Z=this.getRecord(K);if(Z){var L=this.getTrIndex(K);var U=Z.getId();var X=this._aSelections||[];for(var P=X.length-1;P>-1;P--){if((C.isNumber(X[P])&&(X[P]===U))||((X[P].constructor==Object)&&(X[P].recordId===U))){X.splice(P,1);}}var M=K+1;var W=K;if(R&&C.isNumber(R)){M=(R>0)?K+R-1:K;W=(R>0)?K:K+R+1;R=(R>0)?R:R*-1;}else{R=1;}var O=this._oRecordSet.deleteRecords(W,R);if(O){var V=this.get("paginator");if(V instanceof B||this.get("paginated")){var T;if(V instanceof B){var S=V.get("totalRecords");i!
 f(S!==B.VALUE_UNLIMITED){V.set("totalRecords",S-1);}T=(V.getPa!
 geRecord
s())[1];}else{T=V.startRecordIndex+V.rowsPerPage-1;this.updatePaginator();}if(W<=T){this.render();}return ;}else{if(C.isNumber(L)){var Q=this.get("renderLoopSize");var N=W;var J=R;this._oChainRender.add({method:function(c){if((this instanceof G)&&this._sId){var b=c.nCurrentRow,a=(Q>0)?(Math.max(b-Q,N)-1):N-1;for(;b>a;--b){this._deleteTrEl(b);}c.nCurrentRow=b;}},iterations:(Q>0)?Math.ceil(R/Q):1,argument:{nCurrentRow:M},scope:this,timeout:(Q>0)?0:-1});this._oChainRender.add({method:function(){if(this._elTbody.rows.length===0){this.showTableMessage(G.MSG_EMPTY,G.CLASS_EMPTY);}else{this._setFirstRow();this._setLastRow();this._setRowStripes();}this.fireEvent("rowsDeleteEvent",{recordIndex:R,oldData:O,count:L});},scope:this,timeout:-1});this._oChainRender.run();return ;}}}}}return null;},formatCell:function(M,K,O){if(!(K instanceof YAHOO.widget.Record)){K=this.getRecord(M);}if(!(O instanceof YAHOO.widget.Column)){O=this._oColumnSet.getColumn(M.parentNode.yuiColumnKey);}if(K&&O){v!
 ar L=O.key;var P=K.getData(L);var N;if(C.isString(O.className)){N=[O.className];}else{if(C.isArray(O.className)){N=O.className;}else{N=[];}}N[N.length]="yui-dt-col-"+L.replace(/[^\w\-.:]/g,"");N[N.length]="yui-dt-col-"+O.getId();N[N.length]=G.CLASS_LINER;if(O.sortable){N[N.length]=G.CLASS_SORTABLE;}if(O.resizeable){N[N.length]=G.CLASS_RESIZEABLE;}if(O.editor){N[N.length]=G.CLASS_EDITABLE;}M.className="";D.addClass(M,N.join(" "));var J=typeof O.formatter==="function"?O.formatter:G.Formatter[O.formatter+""];if(J){J.call(this,M,K,O,P);}else{M.innerHTML=P===undefined||P===null||(typeof P==="number"&&isNaN(P))?"":P.toString();}this.fireEvent("cellFormatEvent",{record:K,column:O,key:L,el:M});}else{}},onPaginatorChange:function(J){var K=this.get("paginationEventHandler");K(J,this);},_aSelections:null,_oAnchorRecord:null,_oAnchorCell:null,_unselectAllTrEls:function(){var J=D.getElementsByClassName(G.CLASS_SELECTED,"tr",this._elTbody);D.removeClass(J,G.CLASS_SELECTED);},_getSelectio!
 nTrigger:function(){var M=this.get("selectionMode");var L={};v!
 ar P,J,K
,O,N;if((M=="cellblock")||(M=="cellrange")||(M=="singlecell")){P=this.getLastSelectedCell();if(!P){return null;}else{J=this.getRecord(P.recordId);K=this.getRecordIndex(J);O=this.getTrEl(J);N=this.getTrIndex(O);if(N===null){return null;}else{L.record=J;L.recordIndex=K;L.el=this.getTdEl(P);L.trIndex=N;L.column=this.getColumnById(P.columnId);L.colKeyIndex=L.column.getKeyIndex();L.cell=P;return L;}}}else{J=this.getLastSelectedRecord();if(!J){return null;}else{J=this.getRecord(J);K=this.getRecordIndex(J);O=this.getTrEl(J);N=this.getTrIndex(O);if(N===null){return null;}else{L.record=J;L.recordIndex=K;L.el=O;L.trIndex=N;return L;}}}},_getSelectionAnchor:function(L){var K=this.get("selectionMode");var M={};var N,P,J;if((K=="cellblock")||(K=="cellrange")||(K=="singlecell")){var O=this._oAnchorCell;if(!O){if(L){O=this._oAnchorCell=L.cell;}else{return null;}}N=this._oAnchorCell.record;P=this._oRecordSet.getRecordIndex(N);J=this.getTrIndex(N);if(J===null){if(P<this.getRecordIndex(this.g!
 etFirstTrEl())){J=0;}else{J=this.getRecordIndex(this.getLastTrEl());}}M.record=N;M.recordIndex=P;M.trIndex=J;M.column=this._oAnchorCell.column;M.colKeyIndex=M.column.getKeyIndex();M.cell=O;return M;}else{N=this._oAnchorRecord;if(!N){if(L){N=this._oAnchorRecord=L.record;}else{return null;}}P=this.getRecordIndex(N);J=this.getTrIndex(N);if(J===null){if(P<this.getRecordIndex(this.getFirstTrEl())){J=0;}else{J=this.getRecordIndex(this.getLastTrEl());}}M.record=N;M.recordIndex=P;M.trIndex=J;return M;}},_handleStandardSelectionByMouse:function(K){var J=K.target;var M=this.getTrEl(J);if(M){var P=K.event;var S=P.shiftKey;var O=P.ctrlKey||((navigator.userAgent.toLowerCase().indexOf("mac")!=-1)&&P.metaKey);var R=this.getRecord(M);var L=this._oRecordSet.getRecordIndex(R);var Q=this._getSelectionAnchor();var N;if(S&&O){if(Q){if(this.isSelected(Q.record)){if(Q.recordIndex<L){for(N=Q.recordIndex+1;N<=L;N++){if(!this.isSelected(N)){this.selectRow(N);
+}}}else{for(N=Q.recordIndex-1;N>=L;N--){if(!this.isSelected(N)){this.selectRow(N);}}}}else{if(Q.recordIndex<L){for(N=Q.recordIndex+1;N<=L-1;N++){if(this.isSelected(N)){this.unselectRow(N);}}}else{for(N=L+1;N<=Q.recordIndex-1;N++){if(this.isSelected(N)){this.unselectRow(N);}}}this.selectRow(R);}}else{this._oAnchorRecord=R;if(this.isSelected(R)){this.unselectRow(R);}else{this.selectRow(R);}}}else{if(S){this.unselectAllRows();if(Q){if(Q.recordIndex<L){for(N=Q.recordIndex;N<=L;N++){this.selectRow(N);}}else{for(N=Q.recordIndex;N>=L;N--){this.selectRow(N);}}}else{this._oAnchorRecord=R;this.selectRow(R);}}else{if(O){this._oAnchorRecord=R;if(this.isSelected(R)){this.unselectRow(R);}else{this.selectRow(R);}}else{this._handleSingleSelectionByMouse(K);return ;}}}}},_handleStandardSelectionByKey:function(N){var J=I.getCharCode(N);if((J==38)||(J==40)){var L=N.shiftKey;var K=this._getSelectionTrigger();if(!K){return null;}I.stopEvent(N);var M=this._getSelectionAnchor(K);if(L){if((J==40)&!
 &(M.recordIndex<=K.trIndex)){this.selectRow(this.getNextTrEl(K.el));}else{if((J==38)&&(M.recordIndex>=K.trIndex)){this.selectRow(this.getPreviousTrEl(K.el));}else{this.unselectRow(K.el);}}}else{this._handleSingleSelectionByKey(N);}}},_handleSingleSelectionByMouse:function(L){var M=L.target;var K=this.getTrEl(M);if(K){var J=this.getRecord(K);this._oAnchorRecord=J;this.unselectAllRows();this.selectRow(J);}},_handleSingleSelectionByKey:function(M){var J=I.getCharCode(M);if((J==38)||(J==40)){var K=this._getSelectionTrigger();if(!K){return null;}I.stopEvent(M);var L;if(J==38){L=this.getPreviousTrEl(K.el);if(L===null){L=this.getFirstTrEl();}}else{if(J==40){L=this.getNextTrEl(K.el);if(L===null){L=this.getLastTrEl();}}}this.unselectAllRows();this.selectRow(L);this._oAnchorRecord=this.getRecord(L);}},_handleCellBlockSelectionByMouse:function(Z){var a=Z.target;var K=this.getTdEl(a);if(K){var Y=Z.event;var P=Y.shiftKey;var L=Y.ctrlKey||((navigator.userAgent.toLowerCase().indexOf("mac"!
 )!=-1)&&Y.metaKey);var R=this.getTrEl(K);var Q=this.getTrIndex!
 (R);var 
U=this.getColumn(K);var V=U.getKeyIndex();var T=this.getRecord(R);var c=this._oRecordSet.getRecordIndex(T);var O={record:T,column:U};var S=this._getSelectionAnchor();var N=this.getTbodyEl().rows;var M,J,b,X,W;if(P&&L){if(S){if(this.isSelected(S.cell)){if(S.recordIndex===c){if(S.colKeyIndex<V){for(X=S.colKeyIndex+1;X<=V;X++){this.selectCell(R.cells[X]);}}else{if(V<S.colKeyIndex){for(X=V;X<S.colKeyIndex;X++){this.selectCell(R.cells[X]);}}}}else{if(S.recordIndex<c){M=Math.min(S.colKeyIndex,V);J=Math.max(S.colKeyIndex,V);for(X=S.trIndex;X<=Q;X++){for(W=M;W<=J;W++){this.selectCell(N[X].cells[W]);}}}else{M=Math.min(S.trIndex,V);J=Math.max(S.trIndex,V);for(X=S.trIndex;X>=Q;X--){for(W=J;W>=M;W--){this.selectCell(N[X].cells[W]);}}}}}else{if(S.recordIndex===c){if(S.colKeyIndex<V){for(X=S.colKeyIndex+1;X<V;X++){this.unselectCell(R.cells[X]);}}else{if(V<S.colKeyIndex){for(X=V+1;X<S.colKeyIndex;X++){this.unselectCell(R.cells[X]);}}}}if(S.recordIndex<c){for(X=S.trIndex;X<=Q;X++){b=N[X];fo!
 r(W=0;W<b.cells.length;W++){if(b.sectionRowIndex===S.trIndex){if(W>S.colKeyIndex){this.unselectCell(b.cells[W]);}}else{if(b.sectionRowIndex===Q){if(W<V){this.unselectCell(b.cells[W]);}}else{this.unselectCell(b.cells[W]);}}}}}else{for(X=Q;X<=S.trIndex;X++){b=N[X];for(W=0;W<b.cells.length;W++){if(b.sectionRowIndex==Q){if(W>V){this.unselectCell(b.cells[W]);}}else{if(b.sectionRowIndex==S.trIndex){if(W<S.colKeyIndex){this.unselectCell(b.cells[W]);}}else{this.unselectCell(b.cells[W]);}}}}}this.selectCell(K);}}else{this._oAnchorCell=O;if(this.isSelected(O)){this.unselectCell(O);}else{this.selectCell(O);}}}else{if(P){this.unselectAllCells();if(S){if(S.recordIndex===c){if(S.colKeyIndex<V){for(X=S.colKeyIndex;X<=V;X++){this.selectCell(R.cells[X]);}}else{if(V<S.colKeyIndex){for(X=V;X<=S.colKeyIndex;X++){this.selectCell(R.cells[X]);}}}}else{if(S.recordIndex<c){M=Math.min(S.colKeyIndex,V);J=Math.max(S.colKeyIndex,V);for(X=S.trIndex;X<=Q;X++){for(W=M;W<=J;W++){this.selectCell(N[X].cells[!
 W]);}}}else{M=Math.min(S.colKeyIndex,V);J=Math.max(S.colKeyInd!
 ex,V);fo
r(X=Q;X<=S.trIndex;X++){for(W=M;W<=J;W++){this.selectCell(N[X].cells[W]);}}}}}else{this._oAnchorCell=O;this.selectCell(O);}}else{if(L){this._oAnchorCell=O;if(this.isSelected(O)){this.unselectCell(O);}else{this.selectCell(O);}}else{this._handleSingleCellSelectionByMouse(Z);}}}}},_handleCellBlockSelectionByKey:function(O){var J=I.getCharCode(O);var T=O.shiftKey;if((J==9)||!T){this._handleSingleCellSelectionByKey(O);return ;}if((J>36)&&(J<41)){var U=this._getSelectionTrigger();if(!U){return null;}I.stopEvent(O);var R=this._getSelectionAnchor(U);var K,S,L,Q,M;var P=this.getTbodyEl().rows;var N=U.el.parentNode;if(J==40){if(R.recordIndex<=U.recordIndex){M=this.getNextTrEl(U.el);if(M){S=R.colKeyIndex;L=U.colKeyIndex;if(S>L){for(K=S;K>=L;K--){Q=M.cells[K];this.selectCell(Q);}}else{for(K=S;K<=L;K++){Q=M.cells[K];this.selectCell(Q);}}}}else{S=Math.min(R.colKeyIndex,U.colKeyIndex);L=Math.max(R.colKeyIndex,U.colKeyIndex);for(K=S;K<=L;K++){this.unselectCell(N.cells[K]);}}}else{if(J==38){!
 if(R.recordIndex>=U.recordIndex){M=this.getPreviousTrEl(U.el);if(M){S=R.colKeyIndex;L=U.colKeyIndex;if(S>L){for(K=S;K>=L;K--){Q=M.cells[K];this.selectCell(Q);}}else{for(K=S;K<=L;K++){Q=M.cells[K];this.selectCell(Q);}}}}else{S=Math.min(R.colKeyIndex,U.colKeyIndex);L=Math.max(R.colKeyIndex,U.colKeyIndex);for(K=S;K<=L;K++){this.unselectCell(N.cells[K]);}}}else{if(J==39){if(R.colKeyIndex<=U.colKeyIndex){if(U.colKeyIndex<N.cells.length-1){S=R.trIndex;L=U.trIndex;if(S>L){for(K=S;K>=L;K--){Q=P[K].cells[U.colKeyIndex+1];this.selectCell(Q);}}else{for(K=S;K<=L;K++){Q=P[K].cells[U.colKeyIndex+1];this.selectCell(Q);}}}}else{S=Math.min(R.trIndex,U.trIndex);L=Math.max(R.trIndex,U.trIndex);for(K=S;K<=L;K++){this.unselectCell(P[K].cells[U.colKeyIndex]);}}}else{if(J==37){if(R.colKeyIndex>=U.colKeyIndex){if(U.colKeyIndex>0){S=R.trIndex;L=U.trIndex;if(S>L){for(K=S;K>=L;K--){Q=P[K].cells[U.colKeyIndex-1];this.selectCell(Q);}}else{for(K=S;
+K<=L;K++){Q=P[K].cells[U.colKeyIndex-1];this.selectCell(Q);}}}}else{S=Math.min(R.trIndex,U.trIndex);L=Math.max(R.trIndex,U.trIndex);for(K=S;K<=L;K++){this.unselectCell(P[K].cells[U.colKeyIndex]);}}}}}}}},_handleCellRangeSelectionByMouse:function(X){var Y=X.target;var J=this.getTdEl(Y);if(J){var W=X.event;var N=W.shiftKey;var K=W.ctrlKey||((navigator.userAgent.toLowerCase().indexOf("mac")!=-1)&&W.metaKey);var P=this.getTrEl(J);var O=this.getTrIndex(P);var S=this.getColumn(J);var T=S.getKeyIndex();var R=this.getRecord(P);var a=this._oRecordSet.getRecordIndex(R);var M={record:R,column:S};var Q=this._getSelectionAnchor();var L=this.getTbodyEl().rows;var Z,V,U;if(N&&K){if(Q){if(this.isSelected(Q.cell)){if(Q.recordIndex===a){if(Q.colKeyIndex<T){for(V=Q.colKeyIndex+1;V<=T;V++){this.selectCell(P.cells[V]);}}else{if(T<Q.colKeyIndex){for(V=T;V<Q.colKeyIndex;V++){this.selectCell(P.cells[V]);}}}}else{if(Q.recordIndex<a){for(V=Q.colKeyIndex+1;V<P.cells.length;V++){this.selectCell(P.cell!
 s[V]);}for(V=Q.trIndex+1;V<O;V++){for(U=0;U<L[V].cells.length;U++){this.selectCell(L[V].cells[U]);}}for(V=0;V<=T;V++){this.selectCell(P.cells[V]);}}else{for(V=T;V<P.cells.length;V++){this.selectCell(P.cells[V]);}for(V=O+1;V<Q.trIndex;V++){for(U=0;U<L[V].cells.length;U++){this.selectCell(L[V].cells[U]);}}for(V=0;V<Q.colKeyIndex;V++){this.selectCell(P.cells[V]);}}}}else{if(Q.recordIndex===a){if(Q.colKeyIndex<T){for(V=Q.colKeyIndex+1;V<T;V++){this.unselectCell(P.cells[V]);}}else{if(T<Q.colKeyIndex){for(V=T+1;V<Q.colKeyIndex;V++){this.unselectCell(P.cells[V]);}}}}if(Q.recordIndex<a){for(V=Q.trIndex;V<=O;V++){Z=L[V];for(U=0;U<Z.cells.length;U++){if(Z.sectionRowIndex===Q.trIndex){if(U>Q.colKeyIndex){this.unselectCell(Z.cells[U]);}}else{if(Z.sectionRowIndex===O){if(U<T){this.unselectCell(Z.cells[U]);}}else{this.unselectCell(Z.cells[U]);}}}}}else{for(V=O;V<=Q.trIndex;V++){Z=L[V];for(U=0;U<Z.cells.length;U++){if(Z.sectionRowIndex==O){if(U>T){this.unselectCell(Z.cells[U]);}}else{if(Z!
 .sectionRowIndex==Q.trIndex){if(U<Q.colKeyIndex){this.unselect!
 Cell(Z.c
ells[U]);}}else{this.unselectCell(Z.cells[U]);}}}}}this.selectCell(J);}}else{this._oAnchorCell=M;if(this.isSelected(M)){this.unselectCell(M);}else{this.selectCell(M);}}}else{if(N){this.unselectAllCells();if(Q){if(Q.recordIndex===a){if(Q.colKeyIndex<T){for(V=Q.colKeyIndex;V<=T;V++){this.selectCell(P.cells[V]);}}else{if(T<Q.colKeyIndex){for(V=T;V<=Q.colKeyIndex;V++){this.selectCell(P.cells[V]);}}}}else{if(Q.recordIndex<a){for(V=Q.trIndex;V<=O;V++){Z=L[V];for(U=0;U<Z.cells.length;U++){if(Z.sectionRowIndex==Q.trIndex){if(U>=Q.colKeyIndex){this.selectCell(Z.cells[U]);}}else{if(Z.sectionRowIndex==O){if(U<=T){this.selectCell(Z.cells[U]);}}else{this.selectCell(Z.cells[U]);}}}}}else{for(V=O;V<=Q.trIndex;V++){Z=L[V];for(U=0;U<Z.cells.length;U++){if(Z.sectionRowIndex==O){if(U>=T){this.selectCell(Z.cells[U]);}}else{if(Z.sectionRowIndex==Q.trIndex){if(U<=Q.colKeyIndex){this.selectCell(Z.cells[U]);}}else{this.selectCell(Z.cells[U]);}}}}}}}else{this._oAnchorCell=M;this.selectCell(M);}}else!
 {if(K){this._oAnchorCell=M;if(this.isSelected(M)){this.unselectCell(M);}else{this.selectCell(M);}}else{this._handleSingleCellSelectionByMouse(X);}}}}},_handleCellRangeSelectionByKey:function(N){var J=I.getCharCode(N);var R=N.shiftKey;if((J==9)||!R){this._handleSingleCellSelectionByKey(N);return ;}if((J>36)&&(J<41)){var S=this._getSelectionTrigger();if(!S){return null;}I.stopEvent(N);var Q=this._getSelectionAnchor(S);var K,L,P;var O=this.getTbodyEl().rows;var M=S.el.parentNode;if(J==40){L=this.getNextTrEl(S.el);if(Q.recordIndex<=S.recordIndex){for(K=S.colKeyIndex+1;K<M.cells.length;K++){P=M.cells[K];this.selectCell(P);}if(L){for(K=0;K<=S.colKeyIndex;K++){P=L.cells[K];this.selectCell(P);}}}else{for(K=S.colKeyIndex;K<M.cells.length;K++){this.unselectCell(M.cells[K]);}if(L){for(K=0;K<S.colKeyIndex;K++){this.unselectCell(L.cells[K]);}}}}else{if(J==38){L=this.getPreviousTrEl(S.el);if(Q.recordIndex>=S.recordIndex){for(K=S.colKeyIndex-1;K>-1;K--){P=M.cells[K];this.selectCell(P);}if!
 (L){for(K=M.cells.length-1;K>=S.colKeyIndex;K--){P=L.cells[K];!
 this.sel
ectCell(P);}}}else{for(K=S.colKeyIndex;K>-1;K--){this.unselectCell(M.cells[K]);}if(L){for(K=M.cells.length-1;K>S.colKeyIndex;K--){this.unselectCell(L.cells[K]);}}}}else{if(J==39){L=this.getNextTrEl(S.el);if(Q.recordIndex<S.recordIndex){if(S.colKeyIndex<M.cells.length-1){P=M.cells[S.colKeyIndex+1];this.selectCell(P);}else{if(L){P=L.cells[0];this.selectCell(P);}}}else{if(Q.recordIndex>S.recordIndex){this.unselectCell(M.cells[S.colKeyIndex]);if(S.colKeyIndex<M.cells.length-1){}else{}}else{if(Q.colKeyIndex<=S.colKeyIndex){if(S.colKeyIndex<M.cells.length-1){P=M.cells[S.colKeyIndex+1];this.selectCell(P);}else{if(S.trIndex<O.length-1){P=L.cells[0];this.selectCell(P);}}}else{this.unselectCell(M.cells[S.colKeyIndex]);}}}}else{if(J==37){L=this.getPreviousTrEl(S.el);if(Q.recordIndex<S.recordIndex){this.unselectCell(M.cells[S.colKeyIndex]);if(S.colKeyIndex>0){}else{}}else{if(Q.recordIndex>S.recordIndex){if(S.colKeyIndex>0){P=M.cells[S.colKeyIndex-1];this.selectCell(P);}else{if(S.trIndex!
 >0){P=L.cells[L.cells.length-1];this.selectCell(P);}}}else{if(Q.colKeyIndex>=S.colKeyIndex){if(S.colKeyIndex>0){P=M.cells[S.colKeyIndex-1];this.selectCell(P);}else{if(S.trIndex>0){P=L.cells[L.cells.length-1];this.selectCell(P);}}}else{this.unselectCell(M.cells[S.colKeyIndex]);if(S.colKeyIndex>0){}else{}}}}}}}}}},_handleSingleCellSelectionByMouse:function(O){var P=O.target;var L=this.getTdEl(P);if(L){var K=this.getTrEl(L);var J=this.getRecord(K);var N=this.getColumn(L);var M={record:J,column:N};this._oAnchorCell=M;this.unselectAllCells();this.selectCell(M);}},_handleSingleCellSelectionByKey:function(N){var J=I.getCharCode(N);if((J==9)||((J>36)&&(J<41))){var L=N.shiftKey;var K=this._getSelectionTrigger();if(!K){return null;}var M;if(J==40){M=this.getBelowTdEl(K.el);if(M===null){M=K.el;}}else{if(J==38){M=this.getAboveTdEl(K.el);if(M===null){M=K.el;}}else{if((J==39)||(!L&&(J==9))){M=this.getNextTdEl(K.el);if(M===null){return ;
+}}else{if((J==37)||(L&&(J==9))){M=this.getPreviousTdEl(K.el);if(M===null){return ;}}}}}I.stopEvent(N);this.unselectAllCells();this.selectCell(M);this._oAnchorCell={record:this.getRecord(M),column:this.getColumn(M)};}},getSelectedTrEls:function(){return D.getElementsByClassName(G.CLASS_SELECTED,"tr",this._elTbody);},selectRow:function(P){var O,J;if(P instanceof YAHOO.widget.Record){O=this._oRecordSet.getRecord(P);J=this.getTrEl(O);}else{if(C.isNumber(P)){O=this.getRecord(P);J=this.getTrEl(O);}else{J=this.getTrEl(P);O=this.getRecord(J);}}if(O){var N=this._aSelections||[];var M=O.getId();var L=-1;if(N.indexOf){L=N.indexOf(M);}else{for(var K=N.length-1;K>-1;K--){if(N[K]===M){L=K;break;}}}if(L>-1){N.splice(L,1);}N.push(M);this._aSelections=N;if(!this._oAnchorRecord){this._oAnchorRecord=O;}if(J){D.addClass(J,G.CLASS_SELECTED);}this.fireEvent("rowSelectEvent",{record:O,el:J});}else{}},unselectRow:function(Q){var J=this.getTrEl(Q);var P;if(Q instanceof YAHOO.widget.Record){P=this._!
 oRecordSet.getRecord(Q);}else{if(C.isNumber(Q)){P=this.getRecord(Q);}else{P=this.getRecord(J);}}if(P){var O=this._aSelections||[];var M=P.getId();var L=-1;var N=false;if(O.indexOf){L=O.indexOf(M);}else{for(var K=O.length-1;K>-1;K--){if(O[K]===M){L=K;break;}}}if(L>-1){O.splice(L,1);}if(N){this._aSelections=O;D.removeClass(J,G.CLASS_SELECTED);this.fireEvent("rowUnselectEvent",{record:P,el:J});return ;}D.removeClass(J,G.CLASS_SELECTED);this.fireEvent("rowUnselectEvent",{record:P,el:J});}},unselectAllRows:function(){var K=this._aSelections||[];for(var J=K.length-1;J>-1;J--){if(C.isString(K[J])){K.splice(J,1);}}this._aSelections=K;this._unselectAllTrEls();this.fireEvent("unselectAllRowsEvent");},_unselectAllTdEls:function(){var J=D.getElementsByClassName(G.CLASS_SELECTED,"td",this._elTbody);D.removeClass(J,G.CLASS_SELECTED);},getSelectedTdEls:function(){return D.getElementsByClassName(G.CLASS_SELECTED,"td",this._elTbody);},selectCell:function(J){var P=this.getTdEl(J);if(P){var O!
 =this.getRecord(P);var N=P.yuiColumnId;if(O&&N){var M=this._aS!
 election
s||[];var L=O.getId();for(var K=M.length-1;K>-1;K--){if((M[K].recordId===L)&&(M[K].columnId===N)){M.splice(K,1);break;}}M.push({recordId:L,columnId:N});this._aSelections=M;if(!this._oAnchorCell){this._oAnchorCell={record:O,column:this.getColumnById(N)};}D.addClass(P,G.CLASS_SELECTED);this.fireEvent("cellSelectEvent",{record:O,column:this.getColumnById(N),key:P.yuiColumnKey,el:P});return ;}}},unselectCell:function(J){var O=this.getTdEl(J);if(O){var N=this.getRecord(O);var M=O.yuiColumnId;if(N&&M){var L=this._aSelections||[];var P=N.getId();for(var K=L.length-1;K>-1;K--){if((L[K].recordId===P)&&(L[K].columnId===M)){L.splice(K,1);this._aSelections=L;D.removeClass(O,G.CLASS_SELECTED);this.fireEvent("cellUnselectEvent",{record:N,column:this.getColumnById(M),key:O.yuiColumnKey,el:O});return ;}}}}},unselectAllCells:function(){var K=this._aSelections||[];for(var J=K.length-1;J>-1;J--){if(K[J].constructor==Object){K.splice(J,1);}}this._aSelections=K;this._unselectAllTdEls();this.fire!
 Event("unselectAllCellsEvent");},isSelected:function(O){if(O&&(O.ownerDocument==document)){return(D.hasClass(this.getTdEl(O),G.CLASS_SELECTED)||D.hasClass(this.getTrEl(O),G.CLASS_SELECTED));}else{var N,K,J;var M=this._aSelections;if(M&&M.length>0){if(O instanceof YAHOO.widget.Record){N=O;}else{if(C.isNumber(O)){N=this.getRecord(O);}}if(N){K=N.getId();if(M.indexOf){if(M.indexOf(K)>-1){return true;}}else{for(J=M.length-1;J>-1;J--){if(M[J]===K){return true;}}}}else{if(O.record&&O.column){K=O.record.getId();var L=O.column.getId();for(J=M.length-1;J>-1;J--){if((M[J].recordId===K)&&(M[J].columnId===L)){return true;}}}}}}return false;},getSelectedRows:function(){var J=[];var L=this._aSelections||[];for(var K=0;K<L.length;K++){if(C.isString(L[K])){J.push(L[K]);}}return J;},getSelectedCells:function(){var K=[];var L=this._aSelections||[];for(var J=0;J<L.length;J++){if(L[J]&&(L[J].constructor==Object)){K.push(L[J]);}}return K;},getLastSelectedRecord:function(){var K=this._aSelections!
 ;if(K&&K.length>0){for(var J=K.length-1;J>-1;J--){if(C.isStrin!
 g(K[J]))
{return K[J];}}}},getLastSelectedCell:function(){var K=this._aSelections;if(K&&K.length>0){for(var J=K.length-1;J>-1;J--){if(K[J].recordId&&K[J].columnId){return K[J];}}}},highlightRow:function(L){var J=this.getTrEl(L);if(J){var K=this.getRecord(J);D.addClass(J,G.CLASS_HIGHLIGHTED);this.fireEvent("rowHighlightEvent",{record:K,el:J});return ;}},unhighlightRow:function(L){var J=this.getTrEl(L);if(J){var K=this.getRecord(J);D.removeClass(J,G.CLASS_HIGHLIGHTED);this.fireEvent("rowUnhighlightEvent",{record:K,el:J});return ;}},highlightCell:function(J){var M=this.getTdEl(J);if(M){var L=this.getRecord(M);var K=M.yuiColumnId;D.addClass(M,G.CLASS_HIGHLIGHTED);this.fireEvent("cellHighlightEvent",{record:L,column:this.getColumnById(K),key:M.yuiColumnKey,el:M});return ;}},unhighlightCell:function(J){var L=this.getTdEl(J);if(L){var K=this.getRecord(L);D.removeClass(L,G.CLASS_HIGHLIGHTED);this.fireEvent("cellUnhighlightEvent",{record:K,column:this.getColumnById(L.yuiColumnId),key:L.yuiCol!
 umnKey,el:L});return ;}},showCellEditor:function(N,L,P){N=D.get(N);if(N&&(N.ownerDocument===document)){if(!L||!(L instanceof YAHOO.widget.Record)){L=this.getRecord(N);}if(!P||!(P instanceof YAHOO.widget.Column)){P=this.getColumn(N);}if(L&&P){var M=this._oCellEditor;if(M.isActive){this.cancelCellEditor();}if(!P.editor){return ;}M.cell=N;M.record=L;M.column=P;M.validator=(P.editorOptions&&C.isFunction(P.editorOptions.validator))?P.editorOptions.validator:null;M.value=L.getData(P.key);M.defaultValue=null;var O=M.container;var J=D.getX(N);var Q=D.getY(N);if(isNaN(J)||isNaN(Q)){J=N.offsetLeft+D.getX(this._elTbody.parentNode)-this._elTbody.scrollLeft;Q=N.offsetTop+D.getY(this._elTbody.parentNode)-this._elTbody.scrollTop+this._elThead.offsetHeight;}O.style.left=J+"px";O.style.top=Q+"px";this.doBeforeShowCellEditor(this._oCellEditor);O.style.display="";I.addListener(O,"keydown",function(S,R){if((S.keyCode==27)){R.cancelCellEditor();
+R.focusTbodyEl();}else{R.fireEvent("editorKeydownEvent",{editor:R._oCellEditor,event:S});}},this);var K;if(C.isString(P.editor)){switch(P.editor){case"checkbox":K=G.editCheckbox;break;case"date":K=G.editDate;break;case"dropdown":K=G.editDropdown;break;case"radio":K=G.editRadio;break;case"textarea":K=G.editTextarea;break;case"textbox":K=G.editTextbox;break;default:K=null;}}else{if(C.isFunction(P.editor)){K=P.editor;}}if(K){K(this._oCellEditor,this);if(!P.editorOptions||!P.editorOptions.disableBtns){this.showCellEditorBtns(O);}M.isActive=true;this.fireEvent("editorShowEvent",{editor:M});return ;}}}},doBeforeShowCellEditor:function(J){},showCellEditorBtns:function(L){var M=L.appendChild(document.createElement("div"));D.addClass(M,G.CLASS_BUTTON);var K=M.appendChild(document.createElement("button"));D.addClass(K,G.CLASS_DEFAULT);K.innerHTML="OK";I.addListener(K,"click",function(O,N){N.onEventSaveCellEditor(O,N);N.focusTbodyEl();},this,true);var J=M.appendChild(document.createEl!
 ement("button"));J.innerHTML="Cancel";I.addListener(J,"click",function(O,N){N.onEventCancelCellEditor(O,N);N.focusTbodyEl();},this,true);},resetCellEditor:function(){var J=this._oCellEditor.container;J.style.display="none";I.purgeElement(J,true);J.innerHTML="";this._oCellEditor.value=null;this._oCellEditor.isActive=false;},saveCellEditor:function(){if(this._oCellEditor.isActive){var J=this._oCellEditor.value;var K=YAHOO.widget.DataTable._cloneObject(this._oCellEditor.record.getData(this._oCellEditor.column.key));if(this._oCellEditor.validator){J=this._oCellEditor.value=this._oCellEditor.validator.call(this,J,K,this._oCellEditor);if(J===null){this.resetCellEditor();this.fireEvent("editorRevertEvent",{editor:this._oCellEditor,oldData:K,newData:J});return ;}}this._oRecordSet.updateRecordValue(this._oCellEditor.record,this._oCellEditor.column.key,this._oCellEditor.value);this.formatCell(this._oCellEditor.cell.firstChild);this._oChainRender.add({method:function(){this._syncColWi!
 dths();},scope:this});this._oChainRender.run();this.resetCellE!
 ditor();
this.fireEvent("editorSaveEvent",{editor:this._oCellEditor,oldData:K,newData:J});}else{}},cancelCellEditor:function(){if(this._oCellEditor.isActive){this.resetCellEditor();this.fireEvent("editorCancelEvent",{editor:this._oCellEditor});}else{}},doBeforeLoadData:function(J,K,L){return true;},onEventSortColumn:function(L){var J=L.event;var N=L.target;var K=this.getThEl(N)||this.getTdEl(N);if(K&&K.yuiColumnKey){var M=this.getColumn(K.yuiColumnKey);if(M.sortable){I.stopEvent(J);this.sortColumn(M);}}else{}},onEventSelectColumn:function(J){this.selectColumn(J.target);},onEventHighlightColumn:function(J){if(!D.isAncestor(J.target,I.getRelatedTarget(J.event))){this.highlightColumn(J.target);}},onEventUnhighlightColumn:function(J){if(!D.isAncestor(J.target,I.getRelatedTarget(J.event))){this.unhighlightColumn(J.target);}},onEventSelectRow:function(K){var J=this.get("selectionMode");if(J=="single"){this._handleSingleSelectionByMouse(K);}else{this._handleStandardSelectionByMouse(K);}},on!
 EventSelectCell:function(K){var J=this.get("selectionMode");if(J=="cellblock"){this._handleCellBlockSelectionByMouse(K);}else{if(J=="cellrange"){this._handleCellRangeSelectionByMouse(K);}else{this._handleSingleCellSelectionByMouse(K);}}},onEventHighlightRow:function(J){if(!D.isAncestor(J.target,I.getRelatedTarget(J.event))){this.highlightRow(J.target);}},onEventUnhighlightRow:function(J){if(!D.isAncestor(J.target,I.getRelatedTarget(J.event))){this.unhighlightRow(J.target);}},onEventHighlightCell:function(J){if(!D.isAncestor(J.target,I.getRelatedTarget(J.event))){this.highlightCell(J.target);}},onEventUnhighlightCell:function(J){if(!D.isAncestor(J.target,I.getRelatedTarget(J.event))){this.unhighlightCell(J.target);}},onEventFormatCell:function(J){var M=J.target;var K=this.getTdEl(M);if(K&&K.yuiColumnKey){var L=this.getColumn(K.yuiColumnKey);this.formatCell(K.firstChild,this.getRecord(K),L);}else{}},onEventShowCellEditor:function(J){var L=J.target;var K=this.getTdEl(L);if(K){!
 this.showCellEditor(K);}else{}},onEventSaveCellEditor:function!
 (J){this
.saveCellEditor();},onEventCancelCellEditor:function(J){this.cancelCellEditor();},onDataReturnInitializeTable:function(J,K,L){this.initializeTable();this.onDataReturnSetRows(J,K,L);},onDataReturnAppendRows:function(L,M,N){this.fireEvent("dataReturnEvent",{request:L,response:M,payload:N});var K=this.doBeforeLoadData(L,M,N);if(K&&M&&!M.error&&C.isArray(M.results)){this.addRows(M.results);this._handleDataReturnPayload(L,M,this._mergeResponseMeta(N,M.meta));var J=this.get("paginator");if(J&&J instanceof B&&J.get("totalRecords")<this._oRecordSet.getLength()){J.set("totalRecords",this._oRecordSet.getLength());}}else{if(K&&M.error){this.showTableMessage(G.MSG_ERROR,G.CLASS_ERROR);}}},onDataReturnInsertRows:function(L,M,O){this.fireEvent("dataReturnEvent",{request:L,response:M,payload:O});var K=this.doBeforeLoadData(L,M,O);if(K&&M&&!M.error&&C.isArray(M.results)){var N=this._mergeResponseMeta({recordInsertIndex:(O?O.insertIndex||0:0)},O,M.meta);this.addRows(M.results,N.insertIndex);!
 this._handleDataReturnPayload(L,M,N);var J=this.get("paginator");if(J&&J instanceof B&&J.get("totalRecords")<this._oRecordSet.getLength()){J.set("totalRecords",this._oRecordSet.getLength());}}else{if(K&&M.error){this.showTableMessage(G.MSG_ERROR,G.CLASS_ERROR);}}},onDataReturnSetRows:function(M,L,O){this.fireEvent("dataReturnEvent",{request:M,response:L,payload:O});var K=this.doBeforeLoadData(M,L,O);if(K&&L&&!L.error&&C.isArray(L.results)){var J=this.get("paginator");if(!(J instanceof B)){J=null;}var N=this._mergeResponseMeta({recordStartIndex:O?O.startIndex:null},O,L.meta);if(!C.isNumber(N.recordStartIndex)){N.recordStartIndex=J&&N.pagination?N.pagination.recordOffset||0:0;}this._oRecordSet.setRecords(L.results,N.recordStartIndex);this._handleDataReturnPayload(M,L,N);if(J&&J.get("totalRecords")<this._oRecordSet.getLength()){J.set("totalRecords",this._oRecordSet.getLength());}this.render();}else{if(K&&L.error){this.showTableMessage(G.MSG_ERROR,G.CLASS_ERROR);
+}}},_mergeResponseMeta:function(){var O={},K=arguments,N=0,J=K.length,L,P;for(;N<J;++N){P=K[N];if(C.isObject(P)){for(L in P){if(C.hasOwnProperty(P,L)){if(L.indexOf("pagination")===0&&L.charAt(10)){if(!O.pagination){O.pagination={};}O.pagination[L.substr(10,1).toLowerCase()+L.substr(11)]=P[L];}else{if(/^sort(Key|Dir)/.test(L)){if(!O.sorting){var M=this.get("sortedBy");O.sorting=M?{key:M.key}:{};}O.sorting[RegExp.$1.toLowerCase()]=P[L];}else{O[L]=P[L];}}}}}}return O;},_handleDataReturnPayload:function(L,K,M){if(M){var J=this.get("paginator");if(J instanceof B){if(!C.isUndefined(M.totalRecords)){J.set("totalRecords",parseInt(M.totalRecords,10)|0);}if(C.isObject(M.pagination)){J.set("rowsPerPage",M.pagination.rowsPerPage);J.set("recordOffset",M.pagination.recordOffset);}}if(M.sorting){this.set("sortedBy",M.sorting);}}},getBody:function(){return this.getTbodyEl();},getCell:function(J){return this.getTdEl(J);},getRow:function(J){return this.getTrEl(J);},refreshView:function(){thi!
 s.render();},select:function(K){if(!C.isArray(K)){K=[K];}for(var J=0;J<K.length;J++){this.selectRow(K[J]);}},updatePaginator:function(K){var M=this.get("paginator");var J=M.currentPage;for(var L in K){if(C.hasOwnProperty(M,L)){M[L]=K[L];}}M.totalRecords=this._oRecordSet.getLength();M.rowsThisPage=Math.min(M.rowsPerPage,M.totalRecords);M.totalPages=Math.ceil(M.totalRecords/M.rowsThisPage);if(isNaN(M.totalPages)){M.totalPages=0;}if(M.currentPage>M.totalPages){if(M.totalPages<1){M.currentPage=1;}else{M.currentPage=M.totalPages;}}if(M.currentPage!==J){M.startRecordIndex=(M.currentPage-1)*M.rowsPerPage;}this.set("paginator",M);return this.get("paginator");},showPage:function(K){var J=this.get("paginator");if(!C.isNumber(K)||(K<1)){if(J instanceof B){if(!J.hasPage(K)){K=1;}}else{if(K>J.totalPages){K=1;}}}if(J instanceof B){J.setPage(K);}else{this.updatePaginator({currentPage:K});this.render();}},formatPaginators:function(){var K=this.get("paginator");if(K instanceof B){K.update()!
 ;return ;}var J;var L=false;if(K.pageLinks>-1){for(J=0;J<K.lin!
 ks.lengt
h;J++){this.formatPaginatorLinks(K.links[J],K.currentPage,K.pageLinksStart,K.pageLinks,K.totalPages);}}for(J=0;J<K.dropdowns.length;J++){if(K.dropdownOptions){L=true;this.formatPaginatorDropdown(K.dropdowns[J],K.dropdownOptions);}else{K.dropdowns[J].style.display="none";}}if(L&&A.opera){document.body.style+="";}},formatPaginatorDropdown:function(O,N){if(O&&(O.ownerDocument==document)){while(O.firstChild){O.removeChild(O.firstChild);}for(var L=0;L<N.length;L++){var P=N[L];var J=document.createElement("option");J.value=(C.isValue(P.value))?P.value:P;J.innerHTML=(C.isValue(P.text))?P.text:P;J=O.appendChild(J);}var K=O.options;if(K.length){for(var M=K.length-1;M>-1;M--){if((this.get("paginator").rowsPerPage+"")===K[M].value){K[M].selected=true;}}}O.style.display="";return ;}},formatPaginatorLinks:function(N,J,W,M,T){if(N&&(N.ownerDocument==document)&&C.isNumber(J)&&C.isNumber(W)&&C.isNumber(T)){var P=(J==1)?true:false;var K=(J==T)?true:false;var R=(P)?' <span class="'+G.CLASS_DI!
 SABLED+" "+G.CLASS_FIRST+'"><<</span> ':' <a href="#" class="'+G.CLASS_FIRST+'"><<</a> ';var U=(P)?' <span class="'+G.CLASS_DISABLED+" "+G.CLASS_PREVIOUS+'"><</span> ':' <a href="#" class="'+G.CLASS_PREVIOUS+'"><</a> ';var X=(K)?' <span class="'+G.CLASS_DISABLED+" "+G.CLASS_NEXT+'">></span> ':' <a href="#" class="'+G.CLASS_NEXT+'">></a> ';var L=(K)?' <span class="'+G.CLASS_DISABLED+" "+G.CLASS_LAST+'">>></span> ':' <a href="#" class="'+G.CLASS_LAST+'">>></a> ';var Q=R+U;var Y=T;var S=1;var V=T;if(M>0){Y=(W+M<T)?W+M-1:T;S=(J-Math.floor(Y/2)>0)?J-Math.floor(Y/2):1;V=(J+Math.floor(Y/2)<=T)?J+Math.floor(Y/2):T;if(S===1){V=Y;}else{if(V===T){S=T-Y+1;}}if(V-S===Y){V--;}}for(var O=S;O<=V;O++){if(O!=J){Q+=' <a href="#" class="'+G.CLASS_PAGE+'">'+O+"</a> ";}else{Q+=' <span class="'+G.CLASS_SELECTED+'">'+O+"</span>";}}Q+=X+L;N.innerHTML=Q;return ;}},_onPaginatorLinkClick:function(L,K){var M=I.getTarget(L);var J=M.nodeName.toLowerCase();if(K._oCellEd!
 itor&&K._oCellEditor.isActive){K.fireEvent("editorBlurEvent",{!
 editor:K
._oCellEditor});}while(M&&(J!="table")){switch(J){case"body":return ;case"a":I.stopEvent(L);switch(M.className){case G.CLASS_PAGE:K.showPage(parseInt(M.innerHTML,10));return ;case G.CLASS_FIRST:K.showPage(1);return ;case G.CLASS_LAST:K.showPage(K.get("paginator").totalPages);return ;case G.CLASS_PREVIOUS:K.showPage(K.get("paginator").currentPage-1);return ;case G.CLASS_NEXT:K.showPage(K.get("paginator").currentPage+1);return ;}break;default:return ;}M=M.parentNode;if(M){J=M.nodeName.toLowerCase();}else{return ;}}},_onPaginatorDropdownChange:function(N,K){var O=I.getTarget(N);var M=O[O.selectedIndex].value;var J=C.isValue(parseInt(M,10))?parseInt(M,10):null;if(J!==null){var L=(K.get("paginator").currentPage-1)*J;K.updatePaginator({rowsPerPage:J,startRecordIndex:L});K.render();}else{}},onEventEditCell:function(J){this.onEventShowCellEditor(J);},onDataReturnReplaceRows:function(J,K){this.onDataReturnInitializeTable(J,K);}});G.prototype.onDataReturnSetRecords=G.prototype.onDataR!
 eturnSetRows;})();YAHOO.register("datatable",YAHOO.widget.DataTable,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/datatable/datatable-beta.js
===================================================================
--- trunk/root/static/yui/datatable/datatable-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/datatable/datatable-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,16 +1,4274 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
+ * Mechanism to execute a series of callbacks in a non-blocking queue.  Each callback is executed via setTimout unless configured with a negative timeout, in which case it is run in blocking mode in the same execution thread as the previous callback.  Callbacks can be function references or object literals with the following keys:
+ * <ul>
+ *    <li><code>method</code> - {Function} REQUIRED the callback function.</li>
+ *    <li><code>scope</code> - {Object} the scope from which to execute the callback.  Default is the global window scope.</li>
+ *    <li><code>argument</code> - {Array} parameters to be passed to method as individual arguments.</li>
+ *    <li><code>timeout</code> - {number} millisecond delay to wait after previous callback completion before executing this callback.  Negative values cause immediate blocking execution.  Default 0.</li>
+ *    <li><code>until</code> - {Function} boolean function executed before each iteration.  Return true to indicate completion and proceed to the next callback.</li>
+ *    <li><code>iterations</code> - {Number} number of times to execute the callback before proceeding to the next callback in the chain. Incompatible with <code>until</code>.</li>
+ * </ul>
+ *
+ * @namespace YAHOO.util
+ * @class Chain
+ * @constructor
+ * @param callback* {Function|Object} Any number of callbacks to initialize the queue
+*/
+YAHOO.util.Chain = function () {
+    /**
+     * The callback queue
+     * @property q
+     * @type {Array}
+     * @private
+     */
+    this.q = [].slice.call(arguments);
+
+    /**
+     * Event fired when the callback queue is emptied via execution (not via
+     * a call to chain.stop().
+     * @event end
+     */
+    this.createEvent('end');
+};
+
+YAHOO.util.Chain.prototype = {
+    /**
+     * Timeout id used to pause or stop execution and indicate the execution state of the Chain.  0 indicates paused or stopped, -1 indicates blocking execution, and any positive number indicates non-blocking execution.
+     * @property id
+     * @type {number}
+     * @private
+     */
+    id   : 0,
+
+    /**
+     * Begin executing the chain, or resume execution from the last paused position.
+     * @method run
+     * @return {Chain} the Chain instance
+     */
+    run : function () {
+        // Grab the first callback in the queue
+        var c  = this.q[0],
+            fn;
+
+        // If there is no callback in the queue or the Chain is currently
+        // in an execution mode, return
+        if (!c) {
+            this.fireEvent('end');
+            return this;
+        } else if (this.id) {
+            return this;
+        }
+
+        fn = c.method || c;
+
+        if (typeof fn === 'function') {
+            var o    = c.scope || {},
+                args = c.argument || [],
+                ms   = c.timeout || 0,
+                me   = this;
+                
+            if (!(args instanceof Array)) {
+                args = [args];
+            }
+
+            // Execute immediately if the callback timeout is negative.
+            if (ms < 0) {
+                this.id = ms;
+                if (c.until) {
+                    for (;!c.until();) {
+                        // Execute the callback from scope, with argument
+                        fn.apply(o,args);
+                    }
+                } else if (c.iterations) {
+                    for (;c.iterations-- > 0;) {
+                        fn.apply(o,args);
+                    }
+                } else {
+                    fn.apply(o,args);
+                }
+                this.q.shift();
+                this.id = 0;
+                return this.run();
+            } else {
+                // If the until condition is set, check if we're done
+                if (c.until) {
+                    if (c.until()) {
+                        // Shift this callback from the queue and execute the next
+                        // callback
+                        this.q.shift();
+                        return this.run();
+                    }
+                // Otherwise if either iterations is not set or we're
+                // executing the last iteration, shift callback from the queue
+                } else if (!c.iterations || !--c.iterations) {
+                    this.q.shift();
+                }
+
+                // Otherwise set to execute after the configured timeout
+                this.id = setTimeout(function () {
+                    // Execute the callback from scope, with argument
+                    fn.apply(o,args);
+                    // Check if the Chain was not paused from inside the callback
+                    if (me.id) {
+                        // Indicate ready to run state
+                        me.id = 0;
+                        // Start the fun all over again
+                        me.run();
+                    }
+                },ms);
+            }
+        }
+
+        return this;
+    },
+    
+    /**
+     * Add a callback to the end of the queue
+     * @method add
+     * @param c {Function|Object} the callback function ref or object literal
+     * @return {Chain} the Chain instance
+     */
+    add  : function (c) {
+        this.q.push(c);
+        return this;
+    },
+
+    /**
+     * Pause the execution of the Chain after the current execution of the
+     * current callback completes.  If called interstitially, clears the
+     * timeout for the pending callback. Paused Chains can be restarted with
+     * chain.run()
+     * @method pause
+     * @return {Chain} the Chain instance
+     */
+    pause: function () {
+        clearTimeout(this.id);
+        this.id = 0;
+        return this;
+    },
+
+    /**
+     * Stop and clear the Chain's queue after the current execution of the
+     * current callback completes.
+     * @method stop
+     * @return {Chain} the Chain instance
+     */
+    stop : function () { 
+        this.pause();
+        this.q = [];
+        return this;
+    }
+};
+YAHOO.lang.augmentProto(YAHOO.util.Chain,YAHOO.util.EventProvider);
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * The ColumnSet class defines and manages a DataTable's Columns,
+ * including nested hierarchies and access to individual Column instances.
+ *
+ * @namespace YAHOO.widget
+ * @class ColumnSet
+ * @uses YAHOO.util.EventProvider
+ * @constructor
+ * @param aDefinitions {Object[]} Array of object literals that define cells in
+ * the THEAD.
+ */
+YAHOO.widget.ColumnSet = function(aDefinitions) {
+    this._sId = "yui-cs" + YAHOO.widget.ColumnSet._nCount;
+
+    // First clone the defs
+    aDefinitions = YAHOO.widget.DataTable._cloneObject(aDefinitions);
+    this._init(aDefinitions);
+
+    YAHOO.widget.ColumnSet._nCount++;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Private member variables
+//
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Internal class variable to index multiple ColumnSet instances.
+ *
+ * @property ColumnSet._nCount
+ * @type Number
+ * @private
+ * @static
+ */
+YAHOO.widget.ColumnSet._nCount = 0;
+
+YAHOO.widget.ColumnSet.prototype = {
+    /**
+     * Unique instance name.
+     *
+     * @property _sId
+     * @type String
+     * @private
+     */
+    _sId : null,
+
+    /**
+     * Array of object literal Column definitions passed to the constructor.
+     *
+     * @property _aDefinitions
+     * @type Object[]
+     * @private
+     */
+    _aDefinitions : null,
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public member variables
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Top-down tree representation of Column hierarchy.
+     *
+     * @property tree
+     * @type YAHOO.widget.Column[]
+     */
+    tree : null,
+
+    /**
+     * Flattened representation of all Columns.
+     *
+     * @property flat
+     * @type YAHOO.widget.Column[]
+     * @default []
+     */
+    flat : null,
+
+    /**
+     * Array of Columns that map one-to-one to a table column.
+     *
+     * @property keys
+     * @type YAHOO.widget.Column[]
+     * @default []
+     */
+    keys : null,
+
+    /**
+     * ID index of nested parent hierarchies for HEADERS accessibility attribute.
+     *
+     * @property headers
+     * @type String[]
+     * @default []
+     */
+    headers : null,
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Private methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Initializes ColumnSet instance with data from Column definitions.
+     *
+     * @method _init
+     * @param aDefinitions {Object[]} Array of object literals that define cells in
+     * the THEAD .
+     * @private
+     */
+
+    _init : function(aDefinitions) {        
+        // DOM tree representation of all Columns
+        var tree = [];
+        // Flat representation of all Columns
+        var flat = [];
+        // Flat representation of only Columns that are meant to display data
+        var keys = [];
+        // Array of HEADERS attribute values for all keys in the "keys" array
+        var headers = [];
+
+        // Tracks current node list depth being tracked
+        var nodeDepth = -1;
+
+        // Internal recursive function to define Column instances
+        var parseColumns = function(nodeList, parent) {
+            // One level down
+            nodeDepth++;
+
+            // Create corresponding tree node if not already there for this depth
+            if(!tree[nodeDepth]) {
+                tree[nodeDepth] = [];
+            }
+
+
+            // Parse each node at this depth for attributes and any children
+            for(var j=0; j<nodeList.length; j++) {
+                var currentNode = nodeList[j];
+
+                // Instantiate a new Column for each node
+                var oColumn = new YAHOO.widget.Column(currentNode);
+                
+                // Assign unique ID to Column and cross-reference it back to the
+                // original object literal definition
+                currentNode.yuiColumnId = oColumn._sId = YAHOO.widget.Column._nCount + "";
+                
+                // Assign a key if not found
+                if(!YAHOO.lang.isValue(oColumn.key)) {
+                    oColumn.key = "yui-dt-col" + YAHOO.widget.Column._nCount;
+                }
+                // Increment counter
+                YAHOO.widget.Column._nCount++;
+
+                // Add the new Column to the flat list
+                flat.push(oColumn);
+
+                // Assign its parent as an attribute, if applicable
+                if(parent) {
+                    oColumn.parent = parent;
+                }
+
+                // The Column has descendants
+                if(YAHOO.lang.isArray(currentNode.children)) {
+                    oColumn.children = currentNode.children;
+
+                    // Determine COLSPAN value for this Column
+                    var terminalChildNodes = 0;
+                    var countTerminalChildNodes = function(ancestor) {
+                        var descendants = ancestor.children;
+                        // Drill down each branch and count terminal nodes
+                        for(var k=0; k<descendants.length; k++) {
+                            // Keep drilling down
+                            if(YAHOO.lang.isArray(descendants[k].children)) {
+                                countTerminalChildNodes(descendants[k]);
+                            }
+                            // Reached branch terminus
+                            else {
+                                terminalChildNodes++;
+                            }
+                        }
+                    };
+                    countTerminalChildNodes(currentNode);
+                    oColumn._nColspan = terminalChildNodes;
+
+                    // Cascade certain properties to children if not defined on their own
+                    var currentChildren = currentNode.children;
+                    for(var k=0; k<currentChildren.length; k++) {
+                        var child = currentChildren[k];
+                        if(oColumn.className && (child.className === undefined)) {
+                            child.className = oColumn.className;
+                        }
+                        if(oColumn.editor && (child.editor === undefined)) {
+                            child.editor = oColumn.editor;
+                        }
+                        if(oColumn.editorOptions && (child.editorOptions === undefined)) {
+                            child.editorOptions = oColumn.editorOptions;
+                        }
+                        if(oColumn.formatter && (child.formatter === undefined)) {
+                            child.formatter = oColumn.formatter;
+                        }
+                        if(oColumn.resizeable && (child.resizeable === undefined)) {
+                            child.resizeable = oColumn.resizeable;
+                        }
+                        if(oColumn.sortable && (child.sortable === undefined)) {
+                            child.sortable = oColumn.sortable;
+                        }
+                        if(oColumn.width && (child.width === undefined)) {
+                            child.width = oColumn.width;
+                        }
+                        // Backward compatibility
+                        if(oColumn.type && (child.type === undefined)) {
+                            child.type = oColumn.type;
+                        }
+                        if(oColumn.type && !oColumn.formatter) {
+                            oColumn.formatter = oColumn.type;
+                        }
+                        if(oColumn.text && !YAHOO.lang.isValue(oColumn.label)) {
+                            oColumn.label = oColumn.text;
+                        }
+                        if(oColumn.parser) {
+                        }
+                        if(oColumn.sortOptions && ((oColumn.sortOptions.ascFunction) ||
+                                (oColumn.sortOptions.descFunction))) {
+                        }
+                    }
+
+                    // The children themselves must also be parsed for Column instances
+                    if(!tree[nodeDepth+1]) {
+                        tree[nodeDepth+1] = [];
+                    }
+                    parseColumns(currentChildren, oColumn);
+                }
+                // This Column does not have any children
+                else {
+                    oColumn._nKeyIndex = keys.length;
+                    oColumn._nColspan = 1;
+                    keys.push(oColumn);
+                }
+
+                // Add the Column to the top-down tree
+                tree[nodeDepth].push(oColumn);
+            }
+            nodeDepth--;
+        };
+
+        // Parse out Column instances from the array of object literals
+        if(YAHOO.lang.isArray(aDefinitions)) {
+            parseColumns(aDefinitions);
+
+            // Store the array
+            this._aDefinitions = aDefinitions;
+        }
+        else {
+            return null;
+        }
+
+        var i;
+
+        // Determine ROWSPAN value for each Column in the tree
+        var parseTreeForRowspan = function(tree) {
+            var maxRowDepth = 1;
+            var currentRow;
+            var currentColumn;
+
+            // Calculate the max depth of descendants for this row
+            var countMaxRowDepth = function(row, tmpRowDepth) {
+                tmpRowDepth = tmpRowDepth || 1;
+
+                for(var n=0; n<row.length; n++) {
+                    var col = row[n];
+                    // Column has children, so keep counting
+                    if(YAHOO.lang.isArray(col.children)) {
+                        tmpRowDepth++;
+                        countMaxRowDepth(col.children, tmpRowDepth);
+                        tmpRowDepth--;
+                    }
+                    // No children, is it the max depth?
+                    else {
+                        if(tmpRowDepth > maxRowDepth) {
+                            maxRowDepth = tmpRowDepth;
+                        }
+                    }
+
+                }
+            };
+
+            // Count max row depth for each row
+            for(var m=0; m<tree.length; m++) {
+                currentRow = tree[m];
+                countMaxRowDepth(currentRow);
+
+                // Assign the right ROWSPAN values to each Column in the row
+                for(var p=0; p<currentRow.length; p++) {
+                    currentColumn = currentRow[p];
+                    if(!YAHOO.lang.isArray(currentColumn.children)) {
+                        currentColumn._nRowspan = maxRowDepth;
+                    }
+                    else {
+                        currentColumn._nRowspan = 1;
+                    }
+                }
+
+                // Reset counter for next row
+                maxRowDepth = 1;
+            }
+        };
+        parseTreeForRowspan(tree);
+
+        // Store tree index values
+        for(i=0; i<tree[0].length; i++) {
+            tree[0][i]._nTreeIndex = i;
+        }
+
+        // Store header relationships in an array for HEADERS attribute
+        var recurseAncestorsForHeaders = function(i, oColumn) {
+            headers[i].push(oColumn._sId);
+            if(oColumn.parent) {
+                recurseAncestorsForHeaders(i, oColumn.parent);
+            }
+        };
+        for(i=0; i<keys.length; i++) {
+            headers[i] = [];
+            recurseAncestorsForHeaders(i, keys[i]);
+            headers[i] = headers[i].reverse();
+        }
+
+        // Save to the ColumnSet instance
+        this.tree = tree;
+        this.flat = flat;
+        this.keys = keys;
+        this.headers = headers;
+    },
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns unique name of the ColumnSet instance.
+     *
+     * @method getId
+     * @return {String} Unique name of the ColumnSet instance.
+     */
+
+    getId : function() {
+        return this._sId;
+    },
+
+    /**
+     * ColumnSet instance name, for logging.
+     *
+     * @method toString
+     * @return {String} Unique name of the ColumnSet instance.
+     */
+
+    toString : function() {
+        return "ColumnSet instance " + this._sId;
+    },
+
+    /**
+     * Public accessor to the definitions array.
+     *
+     * @method getDefinitions
+     * @return {Object[]} Array of object literal Column definitions.
+     */
+
+    getDefinitions : function() {
+        var aDefinitions = this._aDefinitions;
+        
+        // Internal recursive function to define Column instances
+        var parseColumns = function(nodeList, oSelf) {
+            // Parse each node at this depth for attributes and any children
+            for(var j=0; j<nodeList.length; j++) {
+                var currentNode = nodeList[j];
+                
+                // Get the Column for each node
+                var oColumn = oSelf.getColumnById(currentNode.yuiColumnId);
+                
+                if(oColumn) {    
+                    // Update the definition
+                    currentNode.abbr = oColumn.abbr;
+                    currentNode.className = oColumn.className;
+                    currentNode.editor = oColumn.editor;
+                    currentNode.editorOptions = oColumn.editorOptions;
+                    currentNode.formatter = oColumn.formatter;
+                    currentNode.hidden = oColumn.hidden;
+                    currentNode.key = oColumn.key;
+                    currentNode.label = oColumn.label;
+                    currentNode.minWidth = oColumn.minWidth;
+                    currentNode.resizeable = oColumn.resizeable;
+                    currentNode.selected = oColumn.selected;
+                    currentNode.sortable = oColumn.sortable;
+                    currentNode.sortOptions = oColumn.sortOptions;
+                    currentNode.width = oColumn.width;
+                }
+                            
+                // The Column has descendants
+                if(YAHOO.lang.isArray(currentNode.children)) {
+                    // The children themselves must also be parsed for Column instances
+                    parseColumns(currentNode.children, oSelf);
+                }
+            }
+        };
+
+        parseColumns(aDefinitions, this);
+        this._aDefinitions = aDefinitions;
+        return aDefinitions;
+    },
+
+    /**
+     * Returns Column instance with given ID.
+     *
+     * @method getColumnById
+     * @param column {String} Column ID.
+     * @return {YAHOO.widget.Column} Column instance.
+     */
+
+    getColumnById : function(column) {
+        if(YAHOO.lang.isString(column)) {
+            var allColumns = this.flat;
+            for(var i=allColumns.length-1; i>-1; i--) {
+                if(allColumns[i]._sId === column) {
+                    return allColumns[i];
+                }
+            }
+        }
+        return null;
+    },
+
+    /**
+     * Returns Column instance with given key or ColumnSet key index.
+     *
+     * @method getColumn
+     * @param column {String | Number} Column key or ColumnSet key index.
+     * @return {YAHOO.widget.Column} Column instance.
+     */
+
+    getColumn : function(column) {
+        if(YAHOO.lang.isNumber(column) && this.keys[column]) {
+            return this.keys[column];
+        }
+        else if(YAHOO.lang.isString(column)) {
+            var allColumns = this.flat;
+            var aColumns = [];
+            for(var i=0; i<allColumns.length; i++) {
+                if(allColumns[i].key === column) {
+                    aColumns.push(allColumns[i]);
+                }
+            }
+            if(aColumns.length === 1) {
+                return aColumns[0];
+            }
+            else if(aColumns.length > 1) {
+                return aColumns;
+            }
+        }
+        return null;
+    },
+
+    /**
+     * Public accessor returns array of given Column's desendants (if any), including itself.
+     *
+     * @method getDescendants
+     * @parem {YAHOO.widget.Column} Column instance.
+     * @return {Array} Array including the Column itself and all descendants (if any).
+     */
+    getDescendants : function(oColumn) {
+        var oSelf = this;
+        var allDescendants = [];
+        var i;
+
+        // Recursive function to loop thru all children
+        var parse = function(oParent) {
+            allDescendants.push(oParent);
+            // This Column has children
+            if(oParent.children) {
+                for(i=0; i<oParent.children.length; i++) {
+                    parse(oSelf.getColumn(oParent.children[i].key));
+                }
+            }
+        };
+        parse(oColumn);
+
+        return allDescendants;
+    }
+};
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * The Column class defines and manages attributes of DataTable Columns
+ *
+ * @namespace YAHOO.widget
+ * @class Column
+ * @constructor
+ * @param oConfigs {Object} Object literal of definitions.
+ */
+YAHOO.widget.Column = function(oConfigs) {
+    // Object literal defines Column attributes
+    if(oConfigs && (oConfigs.constructor == Object)) {
+        for(var sConfig in oConfigs) {
+            if(sConfig) {
+                this[sConfig] = oConfigs[sConfig];
+            }
+        }
+   }
+    // Backward compatibility
+    if(this.width && !YAHOO.lang.isNumber(this.width)) {
+        this.width = null;
+    }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Private member variables
+//
+/////////////////////////////////////////////////////////////////////////////
+
+YAHOO.lang.augmentObject(YAHOO.widget.Column, {
+    /**
+     * Internal class variable to index multiple Column instances.
+     *
+     * @property Column._nCount
+     * @type Number
+     * @private
+     * @static
+     */
+    _nCount : 0,
+
+    formatCheckbox : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.widget.DataTable.formatCheckbox(elCell, oRecord, oColumn, oData);
+    },
+
+    formatCurrency : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.widget.DataTable.formatCurrency(elCell, oRecord, oColumn, oData);
+    },
+
+    formatDate : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.widget.DataTable.formatDate(elCell, oRecord, oColumn, oData);
+    },
+
+    formatEmail : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.widget.DataTable.formatEmail(elCell, oRecord, oColumn, oData);
+    },
+
+    formatLink : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.widget.DataTable.formatLink(elCell, oRecord, oColumn, oData);
+    },
+
+    formatNumber : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.widget.DataTable.formatNumber(elCell, oRecord, oColumn, oData);
+    },
+
+    formatSelect : function(elCell, oRecord, oColumn, oData) {
+        YAHOO.widget.DataTable.formatDropdown(elCell, oRecord, oColumn, oData);
+    }
+});
+
+YAHOO.widget.Column.prototype = {
+    /**
+     * Unique String identifier assigned at instantiation.
+     *
+     * @property _sId
+     * @type String
+     * @private
+     */
+    _sId : null,
+
+    /**
+     * Object literal definition
+     *
+     * @property _oDefinition
+     * @type Object
+     * @private
+     */
+    _oDefinition : null,
+
+    /**
+     * Reference to Column's current position index within its ColumnSet's keys
+     * array, if applicable. This property only applies to non-nested and bottom-
+     * level child Columns.
+     *
+     * @property _nKeyIndex
+     * @type Number
+     * @private
+     */
+    _nKeyIndex : null,
+
+    /**
+     * Reference to Column's current position index within its ColumnSet's tree
+     * array, if applicable. This property only applies to non-nested and top-
+     * level parent Columns.
+     *
+     * @property _nTreeIndex
+     * @type Number
+     * @private
+     */
+    _nTreeIndex : null,
+
+    /**
+     * Number of table cells the Column spans.
+     *
+     * @property _nColspan
+     * @type Number
+     * @private
+     */
+    _nColspan : 1,
+
+    /**
+     * Number of table rows the Column spans.
+     *
+     * @property _nRowspan
+     * @type Number
+     * @private
+     */
+    _nRowspan : 1,
+
+    /**
+     * Column's parent Column instance, or null.
+     *
+     * @property _oParent
+     * @type YAHOO.widget.Column
+     * @private
+     */
+    _oParent : null,
+
+    /*TODO: remove
+     * The DOM reference the associated COL element.
+     *
+     * @property _elCol
+     * @type HTMLElement
+     * @private
+     */
+    //YAHOO.widget.Column.prototype._elCol = null;
+
+    /**
+     * The DOM reference to the associated TH element.
+     *
+     * @property _elTh
+     * @type HTMLElement
+     * @private
+     */
+    _elTh : null,
+
+    /**
+     * The DOM reference to the associated resizerelement (if any).
+     *
+     * @property _elResizer
+     * @type HTMLElement
+     * @private
+     */
+    _elResizer : null,
+
+    /**
+     * For unreg() purposes, a reference to the Column's DragDrop instance.
+     *
+     * @property _dd
+     * @type YAHOO.util.DragDrop
+     * @private
+     */
+    _dd : null,
+
+    /**
+     * For unreg() purposes, a reference to the Column resizer's DragDrop instance.
+     *
+     * @property _ddResizer
+     * @type YAHOO.util.DragDrop
+     * @private
+     */
+    _ddResizer : null,
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public member variables
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Associated database field, or null.
+     *
+     * @property key
+     * @type String
+     */
+    key : null,
+
+    /**
+     * Text or HTML for display as Column's label in the TH element.
+     *
+     * @property label
+     * @type String
+     */
+    label : null,
+
+    /**
+     * Column head cell ABBR for accessibility.
+     *
+     * @property abbr
+     * @type String
+     */
+    abbr : null,
+
+    /**
+     * Array of object literals that define children (nested headers) of a Column.
+     *
+     * @property children
+     * @type Object[]
+     */
+    children : null,
+
+    /**
+     * Column width (in pixels).
+     *
+     * @property width
+     * @type Number
+     */
+    width : null,
+
+    /**
+     * Minimum Column width (in pixels).
+     *
+     * @property minWidth
+     * @type Number
+     * @default 10
+     */
+    minWidth : 10,
+
+    /**
+     * True if Column is in hidden state.
+     *
+     * @property hidden
+     * @type Boolean
+     * @default false     
+     */
+    hidden : false,
+
+    /**
+     * True if Column is in selected state.
+     *
+     * @property selected
+     * @type Boolean
+     * @default false     
+     */
+    selected : false,
+
+    /**
+     * Custom CSS class or array of classes to be applied to every cell in the Column.
+     *
+     * @property className
+     * @type String || String[]
+     */
+    className : null,
+
+    /**
+     * Defines a format function.
+     *
+     * @property formatter
+     * @type String || HTMLFunction
+     */
+    formatter : null,
+
+    /**
+     * Defines an editor function, otherwise Column is not editable.
+     *
+     * @property editor
+     * @type String || HTMLFunction
+     */
+    editor : null,
+
+    /**
+     * Defines editor options for Column in an object literal of param:value pairs.
+     *
+     * @property editorOptions
+     * @type Object
+     */
+    editorOptions : null,
+
+    /**
+     * True if Column is resizeable, false otherwise. The Drag & Drop Utility is
+     * required to enable this feature. Only bottom-level and non-nested Columns are
+     * resizeble. 
+     *
+     * @property resizeable
+     * @type Boolean
+     * @default false
+     */
+    resizeable : false,
+
+    /**
+     * True if Column is sortable, false otherwise.
+     *
+     * @property sortable
+     * @type Boolean
+     * @default false
+     */
+    sortable : false,
+
+    /**
+     * @property sortOptions.defaultOrder
+     * @deprecated Use sortOptions.defaultDir.
+     */
+    /**
+     * Default sort direction for Column: YAHOO.widget.DataTable.CLASS_ASC or YAHOO.widget.DataTable.CLASS_DESC.
+     *
+     * @property sortOptions.defaultDir
+     * @type String
+     * @default null
+     */
+    /**
+     * Custom sort handler.
+     *
+     * @property sortOptions.sortFunction
+     * @type Function
+     * @default null
+     */
+    sortOptions : null,
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns unique ID string.
+     *
+     * @method getId
+     * @return {String} Unique ID string.
+     */
+    getId : function() {
+        return this._sId;
+    },
+
+    /**
+     * Column instance name, for logging.
+     *
+     * @method toString
+     * @return {String} Column's unique name.
+     */
+    toString : function() {
+        return "Column instance " + this._sId;
+    },
+
+    /**
+     * Returns object literal definition.
+     *
+     * @method getDefinition
+     * @return {Object} Object literal definition.
+     */
+    getDefinition : function() {
+        var oDefinition = this._oDefinition;
+        
+        // Update the definition
+        oDefinition.abbr = this.abbr;
+        oDefinition.className = this.className;
+        oDefinition.editor = this.editor;
+        oDefinition.editorOptions = this.editorOptions;
+        oDefinition.formatter = this.formatter;
+        oDefinition.key = this.key;
+        oDefinition.label = this.label;
+        oDefinition.minWidth = this.minWidth;
+        oDefinition.resizeable = this.resizeable;
+        oDefinition.sortable = this.sortable;
+        oDefinition.sortOptions = this.sortOptions;
+        oDefinition.width = this.width;
+
+        return oDefinition;
+    },
+
+    /**
+     * Returns unique Column key.
+     *
+     * @method getKey
+     * @return {String} Column key.
+     */
+    getKey : function() {
+        return this.key;
+    },
+
+    /**
+     * Public accessor returns Column's current position index within its
+     * ColumnSet's keys array, if applicable. Only non-nested and bottom-level
+     * child Columns will return a value.
+     *
+     * @method getKeyIndex
+     * @return {Number} Position index, or null.
+     */
+    getKeyIndex : function() {
+        return this._nKeyIndex;
+    },
+
+    /**
+     * Public accessor returns Column's current position index within its
+     * ColumnSet's tree array, if applicable. Only non-nested and top-level parent
+     * Columns will return a value;
+     *
+     * @method getTreeIndex
+     * @return {Number} Position index, or null.
+     */
+    getTreeIndex : function() {
+        return this._nTreeIndex;
+    },
+
+    /**
+     * Public accessor returns Column's parent instance if any, or null otherwise.
+     *
+     * @method getParent
+     * @return {YAHOO.widget.Column} Column's parent instance.
+     */
+    getParent : function() {
+        return this._oParent;
+    },
+
+    /**
+     * Public accessor returns Column's calculated COLSPAN value.
+     *
+     * @method getColspan
+     * @return {Number} Column's COLSPAN value.
+     */
+    getColspan : function() {
+        return this._nColspan;
+    },
+    // Backward compatibility
+    getColSpan : function() {
+        return this.getColspan();
+    },
+
+    /**
+     * Public accessor returns Column's calculated ROWSPAN value.
+     *
+     * @method getRowspan
+     * @return {Number} Column's ROWSPAN value.
+     */
+    getRowspan : function() {
+        return this._nRowspan;
+    },
+
+    /**
+     * Returns DOM reference to the key TH element.
+     *
+     * @method getThEl
+     * @return {HTMLElement} TH element.
+     */
+    getThEl : function() {
+        return this._elTh;
+    },
+
+    /**
+     * Returns DOM reference to the resizer element, or null.
+     *
+     * @method getResizerEl
+     * @return {HTMLElement} DIV element.
+     */
+    getResizerEl : function() {
+        return this._elResizer;
+    },
+
+    // Backward compatibility
+    /**
+     * @method getColEl
+     * @deprecated Use getThEl
+     */
+    getColEl : function() {
+        return this.getThEl();
+    },
+    getIndex : function() {
+        return this.getKeyIndex();
+    },
+    format : function() {
+    }
+};
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * Sort static utility to support Column sorting.
+ *
+ * @namespace YAHOO.util
+ * @class Sort
+ * @static
+ */
+YAHOO.util.Sort = {
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Comparator function for simple case-insensitive string sorting.
+     *
+     * @method compare
+     * @param a {Object} First sort argument.
+     * @param b {Object} Second sort argument.
+     * @param desc {Boolean} True if sort direction is descending, false if
+     * sort direction is ascending.
+     */
+    compare: function(a, b, desc) {
+        if((a === null) || (typeof a == "undefined")) {
+            if((b === null) || (typeof b == "undefined")) {
+                return 0;
+            }
+            else {
+                return 1;
+            }
+        }
+        else if((b === null) || (typeof b == "undefined")) {
+            return -1;
+        }
+
+        if(a.constructor == String) {
+            a = a.toLowerCase();
+        }
+        if(b.constructor == String) {
+            b = b.toLowerCase();
+        }
+        if(a < b) {
+            return (desc) ? 1 : -1;
+        }
+        else if (a > b) {
+            return (desc) ? -1 : 1;
+        }
+        else {
+            return 0;
+        }
+    }
+};
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * ColumnDD subclasses DragDrop to support rearrangeable Columns.
+ *
+ * @namespace YAHOO.util
+ * @class ColumnDD
+ * @extends YAHOO.util.DDProxy
+ * @constructor
+ * @param oDataTable {YAHOO.widget.DataTable} DataTable instance.
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @param elTh {HTMLElement} TH element reference.
+ * @param elTarget {HTMLElement} Drag target element.
+ */
+YAHOO.widget.ColumnDD = function(oDataTable, oColumn, elTh, elTarget) {
+    if(oDataTable && oColumn && elTh && elTarget) {
+        this.datatable = oDataTable;
+        this.table = oDataTable.getTheadEl().parentNode;
+        this.column = oColumn;
+        this.headCell = elTh;
+        this.pointer = elTarget;
+        this.newIndex = null;
+        this.init(elTh);
+        this.initFrame(); // Needed for DDProxy
+        this.invalidHandleTypes = {};
+
+        //Set padding to account for children of nested columns
+        this.setPadding(10, 0, (this.datatable.getTheadEl().offsetHeight + 10) , 0);
+    }
+    else {
+    }
+};
+
+if(YAHOO.util.DDProxy) {
+    YAHOO.extend(YAHOO.widget.ColumnDD, YAHOO.util.DDProxy, {
+        initConstraints: function() {
+            //Get the top, right, bottom and left positions
+            var region = YAHOO.util.Dom.getRegion(this.table),
+                //Get the element we are working on
+                el = this.getEl(),
+                //Get the xy position of it
+                xy = YAHOO.util.Dom.getXY(el),
+                //Get the width and height
+                width = parseInt(YAHOO.util.Dom.getStyle(el, 'width'), 10),
+                height = parseInt(YAHOO.util.Dom.getStyle(el, 'height'), 10),
+                //Set left to x minus left
+                left = ((xy[0] - region.left) + 15), //Buffer of 15px
+                //Set right to right minus x minus width
+                right = ((region.right - xy[0] - width) + 15);
+    
+            //Set the constraints based on the above calculations
+            this.setXConstraint(left, right);
+            this.setYConstraint(10, 10);
+            
+            YAHOO.util.Event.on(window, 'resize', function() {
+                this.initConstraints();
+            }, this, true);
+        },
+        _resizeProxy: function() {
+            this.constructor.superclass._resizeProxy.apply(this, arguments);
+            var dragEl = this.getDragEl(),
+                el = this.getEl();
+
+            YAHOO.util.Dom.setStyle(this.pointer, 'height', (this.table.parentNode.offsetHeight + 10) + 'px');
+            YAHOO.util.Dom.setStyle(this.pointer, 'display', 'block');
+            var xy = YAHOO.util.Dom.getXY(el);
+            YAHOO.util.Dom.setXY(this.pointer, [xy[0], (xy[1] - 5)]);
+            
+            YAHOO.util.Dom.setStyle(dragEl, 'height', this.datatable.getContainerEl().offsetHeight + "px");
+            YAHOO.util.Dom.setStyle(dragEl, 'width', (parseInt(YAHOO.util.Dom.getStyle(dragEl, 'width'),10) + 4) + 'px');
+            YAHOO.util.Dom.setXY(this.dragEl, xy);
+        },
+        onMouseDown: function() {
+                this.initConstraints();
+                this.resetConstraints();
+        },
+        clickValidator: function(e) {
+            if(!this.column.hidden) {
+                var target = YAHOO.util.Event.getTarget(e);
+                return ( this.isValidHandleChild(target) &&
+                            (this.id == this.handleElId ||
+                                this.DDM.handleWasClicked(target, this.id)) );
+            }
+        },
+        onDragOver: function(ev, id) {
+            // Validate target
+            var target = this.datatable.getColumn(id);
+            if(target) {
+                var mouseX = YAHOO.util.Event.getPageX(ev),
+                targetX = YAHOO.util.Dom.getX(id),
+                midX = targetX + ((YAHOO.util.Dom.get(id).offsetWidth)/2),
+                currentIndex =  this.column.getTreeIndex(),
+                targetIndex = target.getTreeIndex(),
+                newIndex = targetIndex;
+                
+                
+                if (mouseX < midX) {
+                   YAHOO.util.Dom.setX(this.pointer, targetX);
+                } else {
+                    var thisWidth = parseInt(target.getThEl().offsetWidth, 10);
+                    YAHOO.util.Dom.setX(this.pointer, (targetX + thisWidth));
+                    newIndex++;
+                }
+                if (targetIndex > currentIndex) {
+                    newIndex--;
+                }
+                if(newIndex < 0) {
+                    newIndex = 0;
+                }
+                else if(newIndex > this.datatable.getColumnSet().tree[0].length) {
+                    newIndex = this.datatable.getColumnSet().tree[0].length;
+                }
+                this.newIndex = newIndex;
+            }
+        },
+        onDragDrop: function() {
+            if(YAHOO.lang.isNumber(this.newIndex) && (this.newIndex !== this.column.getTreeIndex())) {
+                var oDataTable = this.datatable;
+                oDataTable._oChainRender.stop();
+                var aColumnDefs = oDataTable._oColumnSet.getDefinitions();
+                var oColumn = aColumnDefs.splice(this.column.getTreeIndex(),1)[0];
+                aColumnDefs.splice(this.newIndex, 0, oColumn);
+                oDataTable._initColumnSet(aColumnDefs);
+                oDataTable._initTheadEls();
+                oDataTable.render();
+                oDataTable.fireEvent("columnReorderEvent");
+            }
+        },
+        endDrag: function() {
+            this.newIndex = null;
+            YAHOO.util.Dom.setStyle(this.pointer, 'display', 'none');
+        }
+    });
+}
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * ColumnResizer subclasses DragDrop to support resizeable Columns.
+ *
+ * @namespace YAHOO.util
+ * @class ColumnResizer
+ * @extends YAHOO.util.DDProxy
+ * @constructor
+ * @param oDataTable {YAHOO.widget.DataTable} DataTable instance.
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @param elTh {HTMLElement} TH element reference.
+ * @param sHandleElId {String} DOM ID of the handle element that causes the resize.
+ * @param elProxy {HTMLElement} Resizer proxy element.
+ */
+YAHOO.util.ColumnResizer = function(oDataTable, oColumn, elTh, sHandleId, elProxy) {
+    if(oDataTable && oColumn && elTh && sHandleId) {
+        this.datatable = oDataTable;
+        this.column = oColumn;
+        this.headCell = elTh;
+        this.headCellLiner = elTh.firstChild;
+        this.init(sHandleId, sHandleId, {dragOnly:true, dragElId: elProxy.id});
+        this.initFrame(); // Needed for proxy
+    }
+    else {
+    }
+};
+
+if(YAHOO.util.DD) {
+    YAHOO.extend(YAHOO.util.ColumnResizer, YAHOO.util.DDProxy, {
+        /////////////////////////////////////////////////////////////////////////////
+        //
+        // Public methods
+        //
+        /////////////////////////////////////////////////////////////////////////////
+        /**
+         * Resets resizer element.
+         *
+         * @method resetResizerEl
+         */
+        resetResizerEl : function() {
+            var resizerStyle = YAHOO.util.Dom.get(this.handleElId).style;
+            resizerStyle.left = "auto";
+            resizerStyle.right = 0;
+            resizerStyle.top = "auto";
+            resizerStyle.bottom = 0;
+        },
+    
+        /////////////////////////////////////////////////////////////////////////////
+        //
+        // Public DOM event handlers
+        //
+        /////////////////////////////////////////////////////////////////////////////
+    
+        /**
+         * Handles mouseup events on the Column resizer.
+         *
+         * @method onMouseUp
+         * @param e {string} The mouseup event
+         */
+        onMouseUp : function(e) {
+            this.resetResizerEl();
+            
+            var el = this.headCell.firstChild;
+            var newWidth = el.offsetWidth -
+                (parseInt(YAHOO.util.Dom.getStyle(el,"paddingLeft"),10)|0) -
+                (parseInt(YAHOO.util.Dom.getStyle(el,"paddingRight"),10)|0);
+
+            this.datatable.fireEvent("columnResizeEvent", {column:this.column,target:this.headCell,width:newWidth});
+        },
+    
+        /**
+         * Handles mousedown events on the Column resizer.
+         *
+         * @method onMouseDown
+         * @param e {string} The mousedown event
+         */
+        onMouseDown : function(e) {
+            this.startWidth = this.headCell.firstChild.offsetWidth;
+            this.startX = YAHOO.util.Event.getXY(e)[0];
+            this.nLinerPadding = (parseInt(YAHOO.util.Dom.getStyle(this.headCellLiner,"paddingLeft"),10)|0) +
+                    (parseInt(YAHOO.util.Dom.getStyle(this.headCellLiner,"paddingRight"),10)|0);
+        },
+    
+        /**
+         * Custom clickValidator to ensure Column is not in hidden state.
+         *
+         * @method clickValidator
+         * @param {Event} e
+         * @private
+         */
+        clickValidator : function(e) {
+            if(!this.column.hidden) {
+                var target = YAHOO.util.Event.getTarget(e);
+                return ( this.isValidHandleChild(target) &&
+                            (this.id == this.handleElId ||
+                                this.DDM.handleWasClicked(target, this.id)) );
+            }
+        },
+    
+        /**
+         * Handles drag events on the Column resizer.
+         *
+         * @method onDrag
+         * @param e {string} The drag event
+         */
+        onDrag : function(e) {
+            var newX = YAHOO.util.Event.getXY(e)[0];
+            if(newX > YAHOO.util.Dom.getX(this.headCellLiner)) {
+                var offsetX = newX - this.startX;
+                var newWidth = this.startWidth + offsetX - this.nLinerPadding;
+                this.datatable.setColumnWidth(this.column, newWidth);
+            }
+        }
+    });
+}
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * A RecordSet defines and manages a set of Records.
+ *
+ * @namespace YAHOO.widget
+ * @class RecordSet
+ * @param data {Object || Object[]} An object literal or an array of data.
+ * @constructor
+ */
+YAHOO.widget.RecordSet = function(data) {
+    // Internal variables
+    this._sId = "yui-rs" + YAHOO.widget.RecordSet._nCount;
+    YAHOO.widget.RecordSet._nCount++;
+    this._records = [];
+    //this._length = 0;
+
+    if(data) {
+        if(YAHOO.lang.isArray(data)) {
+            this.addRecords(data);
+        }
+        else if(data.constructor == Object) {
+            this.addRecord(data);
+        }
+    }
+
+    /**
+     * Fired when a new Record is added to the RecordSet.
+     *
+     * @event recordAddEvent
+     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
+     * @param oArgs.data {Object} Data added.
+     */
+    this.createEvent("recordAddEvent");
+
+    /**
+     * Fired when multiple Records are added to the RecordSet at once.
+     *
+     * @event recordsAddEvent
+     * @param oArgs.records {YAHOO.widget.Record[]} An array of Record instances.
+     * @param oArgs.data {Object[]} Data added.
+     */
+    this.createEvent("recordsAddEvent");
+
+    /**
+     * Fired when a Record is set in the RecordSet.
+     *
+     * @event recordSetEvent
+     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
+     * @param oArgs.data {Object} Data added.
+     */
+    this.createEvent("recordSetEvent");
+
+    /**
+     * Fired when multiple Records are set in the RecordSet at once.
+     *
+     * @event recordsSetEvent
+     * @param oArgs.records {YAHOO.widget.Record[]} An array of Record instances.
+     * @param oArgs.data {Object[]} Data added.
+     */
+    this.createEvent("recordsSetEvent");
+
+    /**
+     * Fired when a Record is updated with new data.
+     *
+     * @event recordUpdateEvent
+     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
+     * @param oArgs.newData {Object} New data.
+     * @param oArgs.oldData {Object} Old data.
+     */
+    this.createEvent("recordUpdateEvent");
+    
+    /**
+     * Fired when a Record is deleted from the RecordSet.
+     *
+     * @event recordDeleteEvent
+     * @param oArgs.data {Object} A copy of the data held by the Record,
+     * or an array of data object literals if multiple Records were deleted at once.
+     * @param oArgs.index {Object} Index of the deleted Record.
+     */
+    this.createEvent("recordDeleteEvent");
+
+    /**
+     * Fired when multiple Records are deleted from the RecordSet at once.
+     *
+     * @event recordsDeleteEvent
+     * @param oArgs.data {Object[]} An array of data object literals copied
+     * from the Records.
+     * @param oArgs.index {Object} Index of the first deleted Record.
+     */
+    this.createEvent("recordsDeleteEvent");
+    
+    /**
+     * Fired when all Records are deleted from the RecordSet at once.
+     *
+     * @event resetEvent
+     */
+    this.createEvent("resetEvent");
+
+    /**
+     * @event keyUpdateEvent    
+     * @deprecated Use recordValueUpdateEvent     
+     */
+    this.createEvent("keyUpdateEvent");
+    /**
+     * Fired when a Record value is updated with new data.
+     *
+     * @event recordValueUpdateEvent
+     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
+     * @param oArgs.key {String} The updated key.
+     * @param oArgs.newData {Object} New data.
+     * @param oArgs.oldData {Object} Old data.
+     *
+     */
+    this.createEvent("recordValueUpdateEvent");
+
+};
+
+/**
+ * Internal class variable to name multiple Recordset instances.
+ *
+ * @property RecordSet._nCount
+ * @type Number
+ * @private
+ * @static
+ */
+YAHOO.widget.RecordSet._nCount = 0;
+
+YAHOO.widget.RecordSet.prototype = {
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Private member variables
+    //
+    /////////////////////////////////////////////////////////////////////////////
+    /**
+     * Unique String identifier assigned at instantiation.
+     *
+     * @property _sId
+     * @type String
+     * @private
+     */
+    _sId : null,
+
+    /**
+     * Internal counter of how many Records are in the RecordSet.
+     *
+     * @property _length
+     * @type Number
+     * @private
+     * @deprecated No longer used
+     */
+    //_length : null,
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Private methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Adds one Record to the RecordSet at the given index. If index is null,
+     * then adds the Record to the end of the RecordSet.
+     *
+     * @method _addRecord
+     * @param oData {Object} An object literal of data.
+     * @param index {Number} (optional) Position index.
+     * @return {YAHOO.widget.Record} A Record instance.
+     * @private
+     */
+    _addRecord : function(oData, index) {
+        var oRecord = new YAHOO.widget.Record(oData);
+        
+        if(YAHOO.lang.isNumber(index) && (index > -1)) {
+            this._records.splice(index,0,oRecord);
+        }
+        else {
+            //index = this.getLength();
+            //this._records[index] = oRecord;
+            this._records[this._records.length] = oRecord;
+        }
+        //this._length++;
+        return oRecord;
+    },
+
+    /**
+     * Sets/replaces one Record to the RecordSet at the given index.  Existing
+     * Records with higher indexes are not shifted.  If no index specified, the
+     * Record is added to the end of the RecordSet.
+     *
+     * @method _setRecord
+     * @param oData {Object} An object literal of data.
+     * @param index {Number} (optional) Position index.
+     * @return {YAHOO.widget.Record} A Record instance.
+     * @private
+     */
+    _setRecord : function(oData, index) {
+        if (!YAHOO.lang.isNumber(index) || index < 0) {
+            index = this._records.length;
+        }
+        return (this._records[index] = new YAHOO.widget.Record(oData));
+        /*
+        if(YAHOO.lang.isNumber(index) && (index > -1)) {
+            this._records[index] = oRecord;
+            if((index+1) > this.getLength()) {
+                this._length = index+1;
+            }
+        }
+        else {
+            this._records[this.getLength()] = oRecord;
+            this._length++;
+        }
+        return oRecord;
+        */
+    },
+
+    /**
+     * Deletes Records from the RecordSet at the given index. If range is null,
+     * then only one Record is deleted.
+     *
+     * @method _deleteRecord
+     * @param index {Number} Position index.
+     * @param range {Number} (optional) How many Records to delete
+     * @private
+     */
+    _deleteRecord : function(index, range) {
+        if(!YAHOO.lang.isNumber(range) || (range < 0)) {
+            range = 1;
+        }
+        this._records.splice(index, range);
+        //this._length = this._length - range;
+    },
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns unique name of the RecordSet instance.
+     *
+     * @method getId
+     * @return {String} Unique name of the RecordSet instance.
+     */
+    getId : function() {
+        return this._sId;
+    },
+
+    /**
+     * Public accessor to the unique name of the RecordSet instance.
+     *
+     * @method toString
+     * @return {String} Unique name of the RecordSet instance.
+     */
+    toString : function() {
+        return "RecordSet instance " + this._sId;
+    },
+
+    /**
+     * Returns the number of Records held in the RecordSet.
+     *
+     * @method getLength
+     * @return {Number} Number of records in the RecordSet.
+     */
+    getLength : function() {
+            //return this._length;
+            return this._records.length;
+    },
+
+    /**
+     * Returns Record by ID or RecordSet position index.
+     *
+     * @method getRecord
+     * @param record {YAHOO.widget.Record | Number | String} Record instance,
+     * RecordSet position index, or Record ID.
+     * @return {YAHOO.widget.Record} Record object.
+     */
+    getRecord : function(record) {
+        var i;
+        if(record instanceof YAHOO.widget.Record) {
+            for(i=0; i<this._records.length; i++) {
+                if(this._records[i] && (this._records[i]._sId === record._sId)) {
+                    return record;
+                }
+            }
+        }
+        else if(YAHOO.lang.isNumber(record)) {
+            if((record > -1) && (record < this.getLength())) {
+                return this._records[record];
+            }
+        }
+        else if(YAHOO.lang.isString(record)) {
+            for(i=0; i<this._records.length; i++) {
+                if(this._records[i] && (this._records[i]._sId === record)) {
+                    return this._records[i];
+                }
+            }
+        }
+        // Not a valid Record for this RecordSet
+        return null;
+
+    },
+
+    /**
+     * Returns an array of Records from the RecordSet.
+     *
+     * @method getRecords
+     * @param index {Number} (optional) Recordset position index of which Record to
+     * start at.
+     * @param range {Number} (optional) Number of Records to get.
+     * @return {YAHOO.widget.Record[]} Array of Records starting at given index and
+     * length equal to given range. If index is not given, all Records are returned.
+     */
+    getRecords : function(index, range) {
+        if(!YAHOO.lang.isNumber(index)) {
+            return this._records;
+        }
+        if(!YAHOO.lang.isNumber(range)) {
+            return this._records.slice(index);
+        }
+        return this._records.slice(index, index+range);
+    },
+
+    /**
+     * Returns a boolean indicating whether Records exist in the RecordSet at the
+     * specified index range.  Returns true if and only if a Record exists at each
+     * index in the range.
+     * @method hasRecords
+     * @param index
+     * @param range
+     * @return {Boolean} true if all indices are populated in the RecordSet
+     */
+    hasRecords : function (index, range) {
+        var recs = this.getRecords(index,range);
+        for (var i = 0; i < range; ++i) {
+            if (typeof recs[i] === 'undefined') {
+                return false;
+            }
+        }
+        return true;
+    },
+
+    /**
+     * Returns current position index for the given Record.
+     *
+     * @method getRecordIndex
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @return {Number} Record's RecordSet position index.
+     */
+
+    getRecordIndex : function(oRecord) {
+        if(oRecord) {
+            for(var i=this._records.length-1; i>-1; i--) {
+                if(this._records[i] && oRecord.getId() === this._records[i].getId()) {
+                    return i;
+                }
+            }
+        }
+        return null;
+
+    },
+
+    /**
+     * Adds one Record to the RecordSet at the given index. If index is null,
+     * then adds the Record to the end of the RecordSet.
+     *
+     * @method addRecord
+     * @param oData {Object} An object literal of data.
+     * @param index {Number} (optional) Position index.
+     * @return {YAHOO.widget.Record} A Record instance.
+     */
+    addRecord : function(oData, index) {
+        if(oData && (oData.constructor == Object)) {
+            var oRecord = this._addRecord(oData, index);
+            this.fireEvent("recordAddEvent",{record:oRecord,data:oData});
+            return oRecord;
+        }
+        else {
+            return null;
+        }
+    },
+
+    /**
+     * Adds multiple Records at once to the RecordSet at the given index with the
+     * given object literal data. If index is null, then the new Records are
+     * added to the end of the RecordSet.
+     *
+     * @method addRecords
+     * @param aData {Object[]} An object literal data or an array of data object literals.
+     * @param index {Number} (optional) Position index.
+     * @return {YAHOO.widget.Record[]} An array of Record instances.
+     */
+    addRecords : function(aData, index) {
+        if(YAHOO.lang.isArray(aData)) {
+            var newRecords = [];
+            // Can't go backwards bc we need to preserve order
+            for(var i=0; i<aData.length; i++) {
+                if(aData[i] && (aData[i].constructor == Object)) {
+                    var record = this._addRecord(aData[i], index);
+                    newRecords.push(record);
+                }
+           }
+            this.fireEvent("recordsAddEvent",{records:newRecords,data:aData});
+           return newRecords;
+        }
+        else if(aData && (aData.constructor == Object)) {
+            var oRecord = this._addRecord(aData);
+            this.fireEvent("recordsAddEvent",{records:[oRecord],data:aData});
+            return oRecord;
+        }
+        else {
+            return null;
+        }
+    },
+
+    /**
+     * Sets or replaces one Record to the RecordSet at the given index. Unlike
+     * addRecord, an existing Record at that index is not shifted to preserve it.
+     * If no index is specified, it adds the Record to the end of the RecordSet.
+     *
+     * @method setRecord
+     * @param oData {Object} An object literal of data.
+     * @param index {Number} (optional) Position index.
+     * @return {YAHOO.widget.Record} A Record instance.
+     */
+    setRecord : function(oData, index) {
+        if(oData && (oData.constructor == Object)) {
+            var oRecord = this._setRecord(oData, index);
+            this.fireEvent("recordSetEvent",{record:oRecord,data:oData});
+            return oRecord;
+        }
+        else {
+            return null;
+        }
+    },
+
+    /**
+     * Sets or replaces multiple Records at once to the RecordSet with the given
+     * data, starting at the given index. If index is not specified, then the new
+     * Records are added to the end of the RecordSet.
+     *
+     * @method setRecords
+     * @param aData {Object[]} An array of object literal data.
+     * @param index {Number} (optional) Position index.
+     * @return {YAHOO.widget.Record[]} An array of Record instances.
+     */
+    setRecords : function(aData, index) {
+        var Rec   = YAHOO.widget.Record,
+            a     = YAHOO.lang.isArray(aData) ? aData : [aData],
+            added = [],
+            i = 0, l = a.length, j = 0;
+
+        index = parseInt(index,10)|0;
+
+        for(; i < l; ++i) {
+            if (typeof a[i] === 'object' && a[i]) {
+                added[j++] = this._records[index + i] = new Rec(a[i]);
+            }
+        }
+
+        this.fireEvent("recordsSet",{records:added,data:aData});
+
+        if (a.length && !added.length) {
+        }
+
+        return added.length > 1 ? added : added[0];
+    },
+
+    /**
+     * Updates given Record with given data.
+     *
+     * @method updateRecord
+     * @param record {YAHOO.widget.Record | Number | String} A Record instance,
+     * a RecordSet position index, or a Record ID.
+     * @param oData {Object} Object literal of new data.
+     * @return {YAHOO.widget.Record} Updated Record, or null.
+     */
+    updateRecord : function(record, oData) {
+        var oRecord = this.getRecord(record);
+        if(oRecord && oData && (oData.constructor == Object)) {
+            // Copy data from the Record for the event that gets fired later
+            var oldData = {};
+            for(var key in oRecord._oData) {
+                oldData[key] = oRecord._oData[key];
+            }
+            oRecord._oData = oData;
+            this.fireEvent("recordUpdateEvent",{record:oRecord,newData:oData,oldData:oldData});
+            return oRecord;
+        }
+        else {
+            return null;
+        }
+    },
+
+    /**
+     * @method updateKey
+     * @deprecated Use updateRecordValue
+     */
+    updateKey : function(record, sKey, oData) {
+        this.updateRecordValue(record, sKey, oData);
+    },
+    /**
+     * Sets given Record at given key to given data.
+     *
+     * @method updateRecordValue
+     * @param record {YAHOO.widget.Record | Number | String} A Record instance,
+     * a RecordSet position index, or a Record ID.
+     * @param sKey {String} Key name.
+     * @param oData {Object} New data.
+     */
+    updateRecordValue : function(record, sKey, oData) {
+        var oRecord = this.getRecord(record);
+        if(oRecord) {
+            var oldData = null;
+            var keyValue = oRecord._oData[sKey];
+            // Copy data from the Record for the event that gets fired later
+            if(keyValue && keyValue.constructor == Object) {
+                oldData = {};
+                for(var key in keyValue) {
+                    oldData[key] = keyValue[key];
+                }
+            }
+            // Copy by value
+            else {
+                oldData = keyValue;
+            }
+
+            oRecord._oData[sKey] = oData;
+            this.fireEvent("keyUpdateEvent",{record:oRecord,key:sKey,newData:oData,oldData:oldData});
+            this.fireEvent("recordValueUpdateEvent",{record:oRecord,key:sKey,newData:oData,oldData:oldData});
+        }
+        else {
+        }
+    },
+
+    /**
+     * Replaces all Records in RecordSet with new object literal data.
+     *
+     * @method replaceRecords
+     * @param data {Object || Object[]} An object literal of data or an array of
+     * data object literals.
+     * @return {YAHOO.widget.Record || YAHOO.widget.Record[]} A Record instance or
+     * an array of Records.
+     */
+    replaceRecords : function(data) {
+        this.reset();
+        return this.addRecords(data);
+    },
+
+    /**
+     * Sorts all Records by given function. Records keep their unique IDs but will
+     * have new RecordSet position indexes.
+     *
+     * @method sortRecords
+     * @param fnSort {Function} Reference to a sort function.
+     * @param desc {Boolean} True if sort direction is descending, false if sort
+     * direction is ascending.
+     * @return {YAHOO.widget.Record[]} Sorted array of Records.
+     */
+    sortRecords : function(fnSort, desc) {
+        return this._records.sort(function(a, b) {return fnSort(a, b, desc);});
+    },
+
+    /**
+     * Reverses all Records, so ["one", "two", "three"] becomes ["three", "two", "one"].
+     *
+     * @method reverseRecords
+     * @return {YAHOO.widget.Record[]} Reverse-sorted array of Records.
+     */
+    reverseRecords : function() {
+        return this._records.reverse();
+    },
+
+    /**
+     * Removes the Record at the given position index from the RecordSet. If a range
+     * is also provided, removes that many Records, starting from the index. Length
+     * of RecordSet is correspondingly shortened.
+     *
+     * @method deleteRecord
+     * @param index {Number} Record's RecordSet position index.
+     * @param range {Number} (optional) How many Records to delete.
+     * @return {Object} A copy of the data held by the deleted Record.
+     */
+    deleteRecord : function(index) {
+        if(YAHOO.lang.isNumber(index) && (index > -1) && (index < this.getLength())) {
+            // Copy data from the Record for the event that gets fired later
+            var oData = YAHOO.widget.DataTable._cloneObject(this.getRecord(index).getData());
+            
+            this._deleteRecord(index);
+            this.fireEvent("recordDeleteEvent",{data:oData,index:index});
+            return oData;
+        }
+        else {
+            return null;
+        }
+    },
+
+    /**
+     * Removes the Record at the given position index from the RecordSet. If a range
+     * is also provided, removes that many Records, starting from the index. Length
+     * of RecordSet is correspondingly shortened.
+     *
+     * @method deleteRecords
+     * @param index {Number} Record's RecordSet position index.
+     * @param range {Number} (optional) How many Records to delete.
+     * @return {Object[]} An array of copies of the data held by the deleted Records.     
+     */
+    deleteRecords : function(index, range) {
+        if(!YAHOO.lang.isNumber(range)) {
+            range = 1;
+        }
+        if(YAHOO.lang.isNumber(index) && (index > -1) && (index < this.getLength())) {
+            var recordsToDelete = this.getRecords(index, range);
+            // Copy data from each Record for the event that gets fired later
+            var deletedData = [];
+            
+            for(var i=0; i<recordsToDelete.length; i++) {
+                deletedData[deletedData.length] = YAHOO.widget.DataTable._cloneObject(recordsToDelete[i]);
+            }
+            this._deleteRecord(index, range);
+
+            this.fireEvent("recordsDeleteEvent",{data:deletedData,index:index});
+
+            return deletedData;
+        }
+        else {
+            return null;
+        }
+    },
+
+    /**
+     * Deletes all Records from the RecordSet.
+     *
+     * @method reset
+     */
+    reset : function() {
+        this._records = [];
+        //this._length = 0;
+        this.fireEvent("resetEvent");
+    }
+};
+
+YAHOO.augment(YAHOO.widget.RecordSet, YAHOO.util.EventProvider);
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+/**
+ * The Record class defines a DataTable record.
+ *
+ * @namespace YAHOO.widget
+ * @class Record
+ * @constructor
+ * @param oConfigs {Object} (optional) Object literal of key/value pairs.
+ */
+YAHOO.widget.Record = function(oLiteral) {
+    this._sId = "yui-rec" + YAHOO.widget.Record._nCount;
+    YAHOO.widget.Record._nCount++;
+    this._oData = {};
+    if(oLiteral && (oLiteral.constructor == Object)) {
+        for(var sKey in oLiteral) {
+            this._oData[sKey] = oLiteral[sKey];
+        }
+    }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Private member variables
+//
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Internal class variable to give unique IDs to Record instances.
+ *
+ * @property Record._nCount
+ * @type Number
+ * @private
+ */
+YAHOO.widget.Record._nCount = 0;
+
+YAHOO.widget.Record.prototype = {
+    /**
+     * Immutable unique ID assigned at instantiation. Remains constant while a
+     * Record's position index can change from sorting.
+     *
+     * @property _sId
+     * @type String
+     * @private
+     */
+    _sId : null,
+
+    /**
+     * Holds data for the Record in an object literal.
+     *
+     * @property _oData
+     * @type Object
+     * @private
+     */
+    _oData : null,
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public member variables
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns unique ID assigned at instantiation.
+     *
+     * @method getId
+     * @return String
+     */
+    getId : function() {
+        return this._sId;
+    },
+
+    /**
+     * Returns data for the Record for a key if given, or the entire object
+     * literal otherwise.
+     *
+     * @method getData
+     * @param sKey {String} (Optional) The key to retrieve a single data value.
+     * @return Object
+     */
+    getData : function(sKey) {
+        if(YAHOO.lang.isString(sKey)) {
+            return this._oData[sKey];
+        }
+        else {
+            return this._oData;
+        }
+    },
+
+    /**
+     * Sets given data at the given key. Use the RecordSet method setValue to trigger
+     * events. 
+     *
+     * @method setData
+     * @param sKey {String} The key of the new value.
+     * @param oData {MIXED} The new value.
+     */
+    setData : function(sKey, oData) {
+        this._oData[sKey] = oData;
+    }
+};
+/**
+ * The Paginator widget provides a set of controls to navigate through paged
+ * data.
+ *
+ * @namespace YAHOO.widget
+ * @class Paginator
+ * @uses YAHOO.util.EventProvider
+ * @uses YAHOO.util.AttributeProvider
+ *
+ * @constructor
+ * @param config {Object} Object literal to set instance and ui component
+ * configuration.
+ */
+YAHOO.widget.Paginator = function (config) {
+    var UNLIMITED = YAHOO.widget.Paginator.VALUE_UNLIMITED,
+        lang      = YAHOO.lang,
+        attrib, initialPage, records, perPage;
+
+    config = lang.isObject(config) ? config : {};
+
+    this.initConfig();
+
+    this.initEvents();
+
+    // Set the basic config keys first
+    this.set('rowsPerPage',config.rowsPerPage,true);
+    if (lang.isNumber(config.totalRecords)) {
+        this.set('totalRecords',config.totalRecords,true);
+    }
+    
+    this.initUIComponents();
+
+    // Update the other config values
+    for (attrib in config) {
+        if (lang.hasOwnProperty(config,attrib)) {
+            this.set(attrib,config[attrib],true);
+        }
+    }
+
+    // Calculate the initial record offset
+    initialPage = this.get('initialPage');
+    records     = this.get('totalRecords');
+    perPage     = this.get('rowsPerPage');
+    if (initialPage > 1 && perPage !== UNLIMITED) {
+        var startIndex = (initialPage - 1) * perPage;
+        if (records === UNLIMITED || startIndex < records) {
+            this.set('recordOffset',startIndex,true);
+        }
+    }
+};
+
+
+// Static members
+YAHOO.lang.augmentObject(YAHOO.widget.Paginator, {
+    /**
+     * Incrementing index used to give instances unique ids.
+     * @static
+     * @property id
+     * @type number
+     * @private
+     */
+    id : 0,
+
+    /**
+     * Base of id strings used for ui components.
+     * @static
+     * @property ID_BASE
+     * @type string
+     * @private
+     */
+    ID_BASE : 'yui-pg',
+
+    /**
+     * Used to identify unset, optional configurations, or used explicitly in
+     * the case of totalRecords to indicate unlimited pagination.
+     * @static
+     * @property VALUE_UNLIMITED
+     * @type number
+     * @final
+     */
+    VALUE_UNLIMITED : -1,
+
+    /**
+     * Default template used by Paginator instances.  Update this if you want
+     * all new Paginators to use a different default template.
+     * @static
+     * @property TEMPLATE_DEFAULT
+     * @type string
+     */
+    TEMPLATE_DEFAULT : "{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}",
+
+    /**
+     * Common alternate pagination format, including page links, links for
+     * previous, next, first and last pages as well as a rows-per-page
+     * dropdown.  Offered as a convenience.
+     * @static
+     * @property TEMPLATE_ROWS_PER_PAGE
+     * @type string
+     */
+    TEMPLATE_ROWS_PER_PAGE : "{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
+
+},true);
+
+
+// Instance members and methods
+YAHOO.widget.Paginator.prototype = {
+
+    // Instance members
+
+    /**
+     * Array of nodes in which to render pagination controls.  This is set via
+     * the "containers" attribute.
+     * @property _containers
+     * @type Array(HTMLElement)
+     * @private
+     */
+    _containers : [],
+
+
+
+
+    // Instance methods
+
+    /**
+     * Initialize the Paginator's attributes (see YAHOO.util.Element class
+     * AttributeProvider).
+     * @method initConfig
+     * @private
+     */
+    initConfig : function () {
+
+        var UNLIMITED = YAHOO.widget.Paginator.VALUE_UNLIMITED,
+            l         = YAHOO.lang;
+
+        /**
+         * REQUIRED. Number of records constituting a "page"
+         * @attribute rowsPerPage
+         * @type integer
+         */
+        this.setAttributeConfig('rowsPerPage', {
+            value     : 0,
+            validator : l.isNumber
+        });
+
+        /**
+         * REQUIRED. Node references or ids of nodes in which to render the
+         * pagination controls.
+         * @attribute containers
+         * @type {string|HTMLElement|Array(string|HTMLElement)}
+         */
+        this.setAttributeConfig('containers', {
+            value     : null,
+            writeOnce : true,
+            validator : function (val) {
+                if (!l.isArray(val)) {
+                    val = [val];
+                }
+                for (var i = 0, len = val.length; i < len; ++i) {
+                    if (l.isString(val[i]) || 
+                        (l.isObject(val[i]) && val[i].nodeType === 1)) {
+                        continue;
+                    }
+                    return false;
+                }
+                return true;
+            },
+            method : function (val) {
+                val = YAHOO.util.Dom.get(val);
+                if (!l.isArray(val)) {
+                    val = [val];
+                }
+                this._containers = val;
+            }
+        });
+
+        /**
+         * Total number of records to paginate through
+         * @attribute totalRecords
+         * @type integer
+         * @default 0
+         */
+        this.setAttributeConfig('totalRecords', {
+            value     : 0,
+            validator : l.isNumber
+        });
+
+        /**
+         * Zero based index of the record considered first on the current page.
+         * For page based interactions, don't modify this attribute directly;
+         * use setPage(n).
+         * @attribute recordOffset
+         * @type integer
+         * @default 0
+         */
+        this.setAttributeConfig('recordOffset', {
+            value     : 0,
+            validator : function (val) {
+                var total = this.get('totalRecords');
+                if (l.isNumber(val)) {
+                    return total === UNLIMITED || total > val;
+                }
+
+                return false;
+            }
+        });
+
+        /**
+         * Page to display on initial paint
+         * @attribute initialPage
+         * @type integer
+         * @default 1
+         */
+        this.setAttributeConfig('initialPage', {
+            value     : 1,
+            validator : l.isNumber
+        });
+
+        /**
+         * Template used to render controls.  The string will be used as
+         * innerHTML on all specified container nodes.  Bracketed keys
+         * (e.g. {pageLinks}) in the string will be replaced with an instance
+         * of the so named ui component.
+         * @see Paginator.TEMPLATE_DEFAULT
+         * @see Paginator.TEMPLATE_ROWS_PER_PAGE
+         * @attribute template
+         * @type string
+         */
+        this.setAttributeConfig('template', {
+            value : YAHOO.widget.Paginator.TEMPLATE_DEFAULT,
+            validator : l.isString
+        });
+
+        /**
+         * Class assigned to the element(s) containing pagination controls.
+         * @attribute containerClass
+         * @type string
+         * @default 'yui-pg-container'
+         */
+        this.setAttributeConfig('containerClass', {
+            value : 'yui-pg-container',
+            validator : l.isString
+        });
+
+        /**
+         * Display pagination controls even when there is only one page.  Set
+         * to false to forgo rendering and/or hide the containers when there
+         * is only one page of data.  Note if you are using the rowsPerPage
+         * dropdown ui component, visibility will be maintained as long as the
+         * number of records exceeds the smallest page size.
+         * @attribute alwaysVisible
+         * @type boolean
+         * @default true
+         */
+        this.setAttributeConfig('alwaysVisible', {
+            value : true,
+            validator : l.isBoolean
+        });
+
+        /**
+         * Update the UI immediately upon interaction.  If false, changeRequest
+         * subscribers or other external code will need to explicitly set the
+         * new values in the paginator to trigger repaint.
+         * @attribute updateOnChange
+         * @type boolean
+         * @default false
+         */
+        this.setAttributeConfig('updateOnChange', {
+            value     : false,
+            validator : l.isBoolean
+        });
+
+
+
+        // Read only attributes
+
+        /**
+         * Unique id assigned to this instance
+         * @attribute id
+         * @type integer
+         * @final
+         */
+        this.setAttributeConfig('id', {
+            value    : YAHOO.widget.Paginator.id++,
+            readOnly : true
+        });
+
+        /**
+         * Indicator of whether the DOM nodes have been initially created
+         * @attribute rendered
+         * @type boolean
+         * @final
+         */
+        this.setAttributeConfig('rendered', {
+            value    : false,
+            readOnly : true
+        });
+
+    },
+
+    /**
+     * Initialize registered ui components onto this instance.
+     * @method initUIComponents
+     * @private
+     */
+    initUIComponents : function () {
+        var ui = YAHOO.widget.Paginator.ui;
+        for (var name in ui) {
+            var UIComp = ui[name];
+            if (YAHOO.lang.isObject(UIComp) &&
+                YAHOO.lang.isFunction(UIComp.init)) {
+                UIComp.init(this);
+            }
+        }
+    },
+
+    /**
+     * Initialize this instance's CustomEvents.
+     * @method initEvents
+     * @private
+     */
+    initEvents : function () {
+        this.createEvent('recordOffsetChange');
+        this.createEvent('totalRecordsChange');
+        this.createEvent('rowsPerPageChange');
+        this.createEvent('alwaysVisibleChange');
+
+        this.createEvent('rendered');
+        this.createEvent('changeRequest');
+        this.createEvent('beforeDestroy');
+
+        // Listen for changes to totalRecords and alwaysVisible 
+        this.subscribe('totalRecordsChange',this.updateVisibility,this,true);
+        this.subscribe('alwaysVisibleChange',this.updateVisibility,this,true);
+    },
+
+    /**
+     * Render the pagination controls per the format attribute into the
+     * specified container nodes.
+     * @method render
+     */
+    render : function () {
+        if (this.get('rendered')) {
+            return;
+        }
+
+        // Forgo rendering if only one page and alwaysVisible is off
+        var totalRecords = this.get('totalRecords');
+        if (totalRecords !== YAHOO.widget.Paginator.VALUE_UNLIMITED &&
+            totalRecords < this.get('rowsPerPage') &&
+            !this.get('alwaysVisible')) {
+            return;
+        }
+
+        var Dom            = YAHOO.util.Dom,
+            template       = this.get('template'),
+            containerClass = this.get('containerClass');
+
+        // add marker spans to the template html to indicate drop zones
+        // for ui components
+        template = template.replace(/\{([a-z0-9_ \-]+)\}/gi,
+            '<span class="yui-pg-ui $1"></span>');
+        for (var i = 0, len = this._containers.length; i < len; ++i) {
+            var c       = this._containers[i],
+                // ex. yui-pg0-1 (first paginator, second container)
+                id_base = YAHOO.widget.Paginator.ID_BASE + this.get('id') +
+                          '-' + i;
+
+            if (!c) {
+                continue;
+            }
+            // Hide the container while its contents are rendered
+            c.style.display = 'none';
+
+            Dom.addClass(c,containerClass);
+
+            // Place the template innerHTML
+            c.innerHTML = template;
+
+            // Replace each marker with the ui component's render() output
+            var markers = Dom.getElementsByClassName('yui-pg-ui','span',c);
+
+            for (var j = 0, jlen = markers.length; j < jlen; ++j) {
+                var m      = markers[j],
+                    mp     = m.parentNode,
+                    name   = m.className.replace(/\s*yui-pg-ui\s+/g,''),
+                    UIComp = YAHOO.widget.Paginator.ui[name];
+
+                if (YAHOO.lang.isFunction(UIComp)) {
+                    var comp = new UIComp(this);
+                    if (YAHOO.lang.isFunction(comp.render)) {
+                        mp.replaceChild(comp.render(id_base),m);
+                    }
+                }
+            }
+
+            // Show the container allowing page reflow
+            c.style.display = '';
+        }
+
+        // Set render attribute manually to support its readOnly contract
+        if (this._containers.length) {
+            this.setAttributeConfig('rendered',{value:true});
+
+            this.fireEvent('rendered',this.getState());
+        }
+    },
+
+    /**
+     * Removes controls from the page and unhooks events.
+     * @method destroy
+     */
+    destroy : function () {
+        this.fireEvent('beforeDestroy');
+        for (var i = 0, len = this._containers.length; i < len; ++i) {
+            this._containers[i].innerHTML = '';
+        }
+        this.setAttributeConfig('rendered',{value:false});
+    },
+
+    /**
+     * Hides the containers if there is only one page of data and attribute
+     * alwaysVisible is false.  Conversely, it displays the containers if either
+     * there is more than one page worth of data or alwaysVisible is turned on.
+     * @method updateVisibility
+     */
+    updateVisibility : function (e) {
+        var alwaysVisible = this.get('alwaysVisible');
+        if (e.type === 'alwaysVisibleChange' || !alwaysVisible) {
+            var totalRecords = this.get('totalRecords'),
+                visible = true,
+                rpp = this.get('rowsPerPage'),
+                rppOptions = this.get('rowsPerPageOptions'),
+                i,len;
+
+            if (YAHOO.lang.isArray(rppOptions)) {
+                for (i = 0, len = rppOptions.length; i < len; ++i) {
+                    rpp = Math.min(rpp,rppOptions[i]);
+                }
+            }
+
+            if (totalRecords !== YAHOO.widget.Paginator.VALUE_UNLIMITED &&
+                totalRecords <= rpp) {
+                visible = false;
+            }
+
+            visible = visible || alwaysVisible;
+
+            for (i = 0, len = this._containers.length; i < len; ++i) {
+                YAHOO.util.Dom.setStyle(this._containers[i],'display',
+                    visible ? '' : 'none');
+            }
+        }
+    },
+
+
+
+
+    /**
+     * Get the configured container nodes
+     * @method getContainerNodes
+     * @return {Array} array of HTMLElement nodes
+     */
+    getContainerNodes : function () {
+        return this._containers;
+    },
+
+    /**
+     * Get the total number of pages in the data set according to the current
+     * rowsPerPage and totalRecords values.  If totalRecords is not set, or
+     * set to YAHOO.widget.Paginator.VALUE_UNLIMITED, returns
+     * YAHOO.widget.Paginator.VALUE_UNLIMITED.
+     * @method getTotalPages
+     * @return {number}
+     */
+    getTotalPages : function () {
+        var records = this.get('totalRecords');
+        var perPage = this.get('rowsPerPage');
+
+        // rowsPerPage not set.  Can't calculate
+        if (!perPage) {
+            return null;
+        }
+
+        if (records === YAHOO.widget.Paginator.VALUE_UNLIMITED) {
+            return YAHOO.widget.Paginator.VALUE_UNLIMITED;
+        }
+
+        return Math.ceil(records/perPage);
+    },
+
+    /**
+     * Does the requested page have any records?
+     * @method hasPage
+     * @param page {number} the page in question
+     * @return {boolean}
+     */
+    hasPage : function (page) {
+        if (!YAHOO.lang.isNumber(page) || page < 1) {
+            return false;
+        }
+
+        var totalPages = this.getTotalPages();
+
+        return (totalPages === YAHOO.widget.Paginator.VALUE_UNLIMITED || totalPages >= page);
+    },
+
+    /**
+     * Get the page number corresponding to the current record offset.
+     * @method getCurrentPage
+     * @return {number}
+     */
+    getCurrentPage : function () {
+        var perPage = this.get('rowsPerPage');
+        if (!perPage || !this.get('totalRecords')) {
+            return 0;
+        }
+        return Math.floor(this.get('recordOffset') / perPage) + 1;
+    },
+
+    /**
+     * Are there records on the next page?
+     * @method hasNextPage
+     * @return {boolean}
+     */
+    hasNextPage : function () {
+        var currentPage = this.getCurrentPage(),
+            totalPages  = this.getTotalPages();
+
+        return currentPage && (totalPages === YAHOO.widget.Paginator.VALUE_UNLIMITED || currentPage < totalPages);
+    },
+
+    /**
+     * Get the page number of the next page, or null if the current page is the
+     * last page.
+     * @method getNextPage
+     * @return {number}
+     */
+    getNextPage : function () {
+        return this.hasNextPage() ? this.getCurrentPage() + 1 : null;
+    },
+
+    /**
+     * Is there a page before the current page?
+     * @method hasPreviousPage
+     * @return {boolean}
+     */
+    hasPreviousPage : function () {
+        return (this.getCurrentPage() > 1);
+    },
+
+    /**
+     * Get the page number of the previous page, or null if the current page
+     * is the first page.
+     * @method getPreviousPage
+     * @return {number}
+     */
+    getPreviousPage : function () {
+        return (this.hasPreviousPage() ? this.getCurrentPage() - 1 : 1);
+    },
+
+    /**
+     * Get the start and end record indexes of the specified page.
+     * @method getPageRecords
+     * @param page {number} (optional) The page (current page if not specified)
+     * @return {Array} [start_index, end_index]
+     */
+    getPageRecords : function (page) {
+        if (!YAHOO.lang.isNumber(page)) {
+            page = this.getCurrentPage();
+        }
+
+        var perPage = this.get('rowsPerPage'),
+            records = this.get('totalRecords'),
+            start, end;
+
+        if (!page || !perPage) {
+            return null;
+        }
+
+        start = (page - 1) * perPage;
+        if (records !== YAHOO.widget.Paginator.VALUE_UNLIMITED) {
+            if (start >= records) {
+                return null;
+            }
+            end = Math.min(start + perPage, records) - 1;
+        } else {
+            end = start + perPage - 1;
+        }
+
+        return [start,end];
+    },
+
+    /**
+     * Set the current page to the provided page number if possible.
+     * @method setPage
+     * @param newPage {number} the new page number
+     * @param silent {boolean} whether to forcibly avoid firing the
+     * changeRequest event
+     */
+    setPage : function (page,silent) {
+        if (this.hasPage(page) && page !== this.getCurrentPage()) {
+            if (this.get('updateOnChange') || silent) {
+                this.set('recordOffset', (page - 1) * this.get('rowsPerPage'));
+            } else {
+                this.fireEvent('changeRequest',this.getState({'page':page}));
+            }
+        }
+    },
+
+    /**
+     * Get the number of rows per page.
+     * @method getRowsPerPage
+     * @return {number} the current setting of the rowsPerPage attribute
+     */
+    getRowsPerPage : function () {
+        return this.get('rowsPerPage');
+    },
+
+    /**
+     * Set the number of rows per page.
+     * @method setRowsPerPage
+     * @param rpp {number} the new number of rows per page
+     * @param silent {boolean} whether to forcibly avoid firing the
+     * changeRequest event
+     */
+    setRowsPerPage : function (rpp,silent) {
+        if (YAHOO.lang.isNumber(rpp) && rpp > 0 &&
+            rpp !== this.get('rowsPerPage')) {
+            if (this.get('updateOnChange') || silent) {
+                this.set('rowsPerPage',rpp);
+            } else {
+                this.fireEvent('changeRequest',
+                    this.getState({'rowsPerPage':rpp}));
+            }
+        }
+    },
+
+    /**
+     * Get the total number of records.
+     * @method getTotalRecords
+     * @return {number} the current setting of totalRecords attribute
+     */
+    getTotalRecords : function () {
+        return this.get('totalRecords');
+    },
+
+    /**
+     * Set the total number of records.
+     * @method setTotalRecords
+     * @param total {number} the new total number of records
+     * @param silent {boolean} whether to forcibly avoid firing the changeRequest event
+     */
+    setTotalRecords : function (total,silent) {
+        if (YAHOO.lang.isNumber(total) && total >= 0 &&
+            total !== this.get('totalRecords')) {
+            if (this.get('updateOnChange') || silent) {
+                this.set('totalRecords',total);
+            } else {
+                this.fireEvent('changeRequest',
+                    this.getState({'totalRecords':total}));
+            }
+        }
+    },
+
+    /**
+     * Get the index of the first record on the current page
+     * @method getStartIndex
+     * @return {number} the index of the first record on the current page
+     */
+    getStartIndex : function () {
+        return this.get('recordOffset');
+    },
+
+    /**
+     * Move the record offset to a new starting index.  This will likely cause
+     * the calculated current page to change.  You should probably use setPage.
+     * @method setStartIndex
+     * @param offset {number} the new record offset
+     * @param silent {boolean} whether to forcibly avoid firing the changeRequest event
+     */
+    setStartIndex : function (offset,silent) {
+        if (YAHOO.lang.isNumber(offset) && offset >= 0 &&
+            offset !== this.get('recordOffset')) {
+            if (this.get('updateOnChange') || silent) {
+                this.set('recordOffset',offset);
+            } else {
+                this.fireEvent('changeRequest',
+                    this.getState({'recordOffset':offset}));
+            }
+        }
+    },
+
+    /**
+     * Get an object literal describing the current state of the paginator.  If
+     * an object literal of proposed values is passed, the proposed state will
+     * be returned as an object literal with the following keys:
+     * <ul>
+     * <li>paginator - instance of the Paginator</li>
+     * <li>page - number</li>
+     * <li>totalRecords - number</li>
+     * <li>recordOffset - number</li>
+     * <li>rowsPerPage - number</li>
+     * <li>records - [ start_index, end_index ]</li>
+     * <li>before - (OPTIONAL) { state object literal for current state }</li>
+     * </ul>
+     * @method getState
+     * @return {object}
+     * @param changes {object} OPTIONAL object literal with proposed values
+     * Supported change keys include:
+     * <ul>
+     * <li>rowsPerPage</li>
+     * <li>totalRecords</li>
+     * <li>recordOffset OR</li>
+     * <li>page</li>
+     * </ul>
+     */
+    getState : function (changes) {
+        var UNLIMITED = YAHOO.widget.Paginator.VALUE_UNLIMITED,
+            L         = YAHOO.lang;
+
+        var currentState = {
+            paginator    : this,
+            page         : this.getCurrentPage(),
+            totalRecords : this.get('totalRecords'),
+            recordOffset : this.get('recordOffset'),
+            rowsPerPage  : this.get('rowsPerPage'),
+            records      : this.getPageRecords()
+        };
+
+        if (!changes) {
+            return currentState;
+        }
+
+        var newOffset = currentState.recordOffset;
+        var state = {
+            paginator    : this,
+            before       : currentState,
+
+            rowsPerPage  : changes.rowsPerPage || currentState.rowsPerPage,
+            totalRecords : (L.isNumber(changes.totalRecords) ?
+                                Math.max(changes.totalRecords,UNLIMITED) :
+                                currentState.totalRecords)
+        };
+
+        if (state.totalRecords === 0) {
+            newOffset  = 0;
+            state.page = 0;
+        } else {
+            if (!L.isNumber(changes.recordOffset) &&
+                 L.isNumber(changes.page)) {
+                newOffset = (changes.page - 1) * state.rowsPerPage;
+                if (state.totalRecords === UNLIMITED) {
+                    state.page = changes.page;
+                } else {
+                    // Limit values by totalRecords and rowsPerPage
+                    state.page = Math.min(
+                                    changes.page,
+                                    Math.ceil(state.totalRecords / state.rowsPerPage));
+                    newOffset  = Math.min(newOffset, state.totalRecords - 1);
+                }
+            } else {
+                newOffset  = Math.min(newOffset,state.totalRecords - 1);
+                state.page = Math.floor(newOffset/state.rowsPerPage) + 1;
+            }
+        }
+
+        // Jump offset to top of page
+        state.recordOffset = state.recordOffset ||
+                             newOffset - (newOffset % state.rowsPerPage);
+
+        state.records = [ state.recordOffset,
+                          state.recordOffset + state.rowsPerPage - 1 ];
+
+        if (state.totalRecords !== UNLIMITED &&
+            state.recordOffset < state.totalRecords &&
+            state.records[1] > state.totalRecords - 1) {
+            // limit upper index to totalRecords - 1
+            state.records[1] = state.totalRecords - 1;
+        }
+
+        return state;
+    }
+};
+
+YAHOO.lang.augmentProto(YAHOO.widget.Paginator, YAHOO.util.AttributeProvider);
+
+
+
+
+
+
+// UI Components
+
+(function () {
+
+// UI Component namespace
+YAHOO.widget.Paginator.ui = {};
+
+var Paginator = YAHOO.widget.Paginator,
+    ui        = Paginator.ui,
+    l         = YAHOO.lang;
+
+/**
+ * ui Component to generate the link to jump to the first page.
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class FirstPageLink
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.FirstPageLink = function (p) {
+    this.paginator = p;
+
+    p.createEvent('firstPageLinkLabelChange');
+    p.createEvent('firstPageLinkClassChange');
+
+    p.subscribe('recordOffsetChange',this.update,this,true);
+    p.subscribe('beforeDestroy',this.destroy,this,true);
+
+    // TODO: make this work
+    p.subscribe('firstPageLinkLabelChange',this.update,this,true);
+    p.subscribe('firstPageLinkClassChange',this.update,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param p {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.FirstPageLink.init = function (p) {
+
+    /**
+     * Used as innerHTML for the first page link/span.
+     * @attribute firstPageLinkLabel
+     * @default '<< first'
+     */
+    p.setAttributeConfig('firstPageLinkLabel', {
+        value : '<< first',
+        validator : l.isString
+    });
+
+    /**
+     * CSS class assigned to the link/span
+     * @attribute firstPageLinkClass
+     * @default 'yui-pg-first'
+     */
+    p.setAttributeConfig('firstPageLinkClass', {
+        value : 'yui-pg-first',
+        validator : l.isString
+    });
+};
+
+// Instance members and methods
+ui.FirstPageLink.prototype = {
+
+    /**
+     * The currently placed HTMLElement node
+     * @property current
+     * @type HTMLElement
+     * @private
+     */
+    current   : null,
+
+    /**
+     * Link node
+     * @property link
+     * @type HTMLElement
+     * @private
+     */
+    link      : null,
+
+    /**
+     * Span node (inactive link)
+     * @property span
+     * @type HTMLElement
+     * @private
+     */
+    span      : null,
+
+    /**
+     * Generate the nodes and return the appropriate node given the current
+     * pagination state.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        var p     = this.paginator,
+            c     = p.get('firstPageLinkClass'),
+            label = p.get('firstPageLinkLabel');
+
+        this.link     = document.createElement('a');
+        this.span     = document.createElement('span');
+
+        this.link.id        = id_base + '-first-link';
+        this.link.href      = '#';
+        this.link.className = c;
+        this.link.innerHTML = label;
+        YAHOO.util.Event.on(this.link,'click',this.onClick,this,true);
+
+        this.span.id        = id_base + '-first-span';
+        this.span.className = c;
+        this.span.innerHTML = label;
+
+        this.current = p.get('recordOffset') < 1 ? this.span : this.link;
+        return this.current;
+    },
+
+    /**
+     * Swap the link and span nodes if appropriate.
+     * @method update
+     * @param e {CustomEvent} The calling change event
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+        var par = this.current ? this.current.parentNode : null;
+        if (this.paginator.get('recordOffset') < 1) {
+            if (par && this.current === this.link) {
+                par.replaceChild(this.span,this.current);
+                this.current = this.span;
+            }
+        } else {
+            if (par && this.current === this.span) {
+                par.replaceChild(this.link,this.current);
+                this.current = this.link;
+            }
+        }
+    },
+
+    /**
+     * Removes the onClick listener from the link in preparation for content
+     * removal.
+     * @method destroy
+     * @private
+     */
+    destroy : function () {
+        YAHOO.util.Event.purgeElement(this.link);
+    },
+
+    /**
+     * Listener for the link's onclick event.  Pass new value to setPage method.
+     * @method onClick
+     * @param e {DOMEvent} The click event
+     */
+    onClick : function (e) {
+        YAHOO.util.Event.stopEvent(e);
+        this.paginator.setPage(1);
+    }
+};
+
+
+
+/**
+ * ui Component to generate the link to jump to the last page.
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class LastPageLink
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.LastPageLink = function (p) {
+    this.paginator = p;
+
+    p.createEvent('lastPageLinkLabelChange');
+    p.createEvent('lastPageLinkClassChange');
+
+    p.subscribe('recordOffsetChange',this.update,this,true);
+    p.subscribe('totalRecordsChange',this.update,this,true);
+    p.subscribe('rowsPerPageChange', this.update,this,true);
+    p.subscribe('beforeDestroy',this.destroy,this,true);
+
+    // TODO: make this work
+    p.subscribe('lastPageLinkLabelChange',this.update,this,true);
+    p.subscribe('lastPageLinkClassChange', this.update,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param paginator {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.LastPageLink.init = function (p) {
+
+    /**
+     * Used as innerHTML for the last page link/span.
+     * @attribute lastPageLinkLabel
+     * @default 'last >>'
+     */
+    p.setAttributeConfig('lastPageLinkLabel', {
+        value : 'last >>',
+        validator : l.isString
+    });
+
+    /**
+     * CSS class assigned to the link/span
+     * @attribute lastPageLinkClass
+     * @default 'yui-pg-last'
+     */
+    p.setAttributeConfig('lastPageLinkClass', {
+        value : 'yui-pg-last',
+        validator : l.isString
+    });
+};
+
+ui.LastPageLink.prototype = {
+
+    /**
+     * Currently placed HTMLElement node
+     * @property current
+     * @type HTMLElement
+     * @private
+     */
+    current   : null,
+
+    /**
+     * Link HTMLElement node
+     * @property link
+     * @type HTMLElement
+     * @private
+     */
+    link      : null,
+
+    /**
+     * Span node (inactive link)
+     * @property span
+     * @type HTMLElement
+     * @private
+     */
+    span      : null,
+
+    /**
+     * Empty place holder node for when the last page link is inappropriate to
+     * display in any form (unlimited paging).
+     * @property na
+     * @type HTMLElement
+     * @private
+     */
+    na        : null,
+
+
+    /**
+     * Generate the nodes and return the appropriate node given the current
+     * pagination state.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        var p     = this.paginator,
+            c     = p.get('lastPageLinkClass'),
+            label = p.get('lastPageLinkLabel'),
+            last  = p.getTotalPages();
+
+        this.link = document.createElement('a');
+        this.span = document.createElement('span');
+        this.na   = this.span.cloneNode(false);
+
+        this.link.id        = id_base + '-last-link';
+        this.link.href      = '#';
+        this.link.className = c;
+        this.link.innerHTML = label;
+        YAHOO.util.Event.on(this.link,'click',this.onClick,this,true);
+
+        this.span.id        = id_base + '-last-span';
+        this.span.className = c;
+        this.span.innerHTML = label;
+
+        this.na.id = id_base + '-last-na';
+
+        switch (last) {
+            case Paginator.VALUE_UNLIMITED :
+                    this.current = this.na; break;
+            case p.getCurrentPage() :
+                    this.current = this.span; break;
+            default :
+                    this.current = this.link;
+        }
+
+        return this.current;
+    },
+
+    /**
+     * Swap the link, span, and na nodes if appropriate.
+     * @method update
+     * @param e {CustomEvent} The calling change event (ignored)
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+        var par   = this.current ? this.current.parentNode : null,
+            after = this.link;
+
+        if (par) {
+            switch (this.paginator.getTotalPages()) {
+                case Paginator.VALUE_UNLIMITED :
+                        after = this.na; break;
+                case this.paginator.getCurrentPage() :
+                        after = this.span; break;
+            }
+
+            if (this.current !== after) {
+                par.replaceChild(after,this.current);
+                this.current = after;
+            }
+        }
+    },
+
+    /**
+     * Removes the onClick listener from the link in preparation for content
+     * removal.
+     * @method destroy
+     * @private
+     */
+    destroy : function () {
+        YAHOO.util.Event.purgeElement(this.link);
+    },
+
+    /**
+     * Listener for the link's onclick event.  Passes to setPage method.
+     * @method onClick
+     * @param e {DOMEvent} The click event
+     */
+    onClick : function (e) {
+        YAHOO.util.Event.stopEvent(e);
+        this.paginator.setPage(this.paginator.getTotalPages());
+    }
+};
+
+
+/**
+ * ui Component to generate the link to jump to the previous page.
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class PreviousPageLink
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.PreviousPageLink = function (p) {
+    this.paginator = p;
+
+    p.createEvent('previousPageLinkLabelChange');
+    p.createEvent('previousPageLinkClassChange');
+
+    p.subscribe('recordOffsetChange',this.update,this,true);
+    p.subscribe('beforeDestroy',this.destroy,this,true);
+
+    // TODO: make this work
+    p.subscribe('previousPageLinkLabelChange',this.update,this,true);
+    p.subscribe('previousPageLinkClassChange',this.update,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param p {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.PreviousPageLink.init = function (p) {
+
+    /**
+     * Used as innerHTML for the previous page link/span.
+     * @attribute previousPageLinkLabel
+     * @default '< prev'
+     */
+    p.setAttributeConfig('previousPageLinkLabel', {
+        value : '< prev',
+        validator : l.isString
+    });
+
+    /**
+     * CSS class assigned to the link/span
+     * @attribute previousPageLinkClass
+     * @default 'yui-pg-previous'
+     */
+    p.setAttributeConfig('previousPageLinkClass', {
+        value : 'yui-pg-previous',
+        validator : l.isString
+    });
+};
+
+ui.PreviousPageLink.prototype = {
+
+    /**
+     * Currently placed HTMLElement node
+     * @property current
+     * @type HTMLElement
+     * @private
+     */
+    current   : null,
+
+    /**
+     * Link node
+     * @property link
+     * @type HTMLElement
+     * @private
+     */
+    link      : null,
+
+    /**
+     * Span node (inactive link)
+     * @property span
+     * @type HTMLElement
+     * @private
+     */
+    span      : null,
+
+
+    /**
+     * Generate the nodes and return the appropriate node given the current
+     * pagination state.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        var p     = this.paginator,
+            c     = p.get('previousPageLinkClass'),
+            label = p.get('previousPageLinkLabel');
+
+        this.link     = document.createElement('a');
+        this.span     = document.createElement('span');
+
+        this.link.id        = id_base + '-prev-link';
+        this.link.href      = '#';
+        this.link.className = c;
+        this.link.innerHTML = label;
+        YAHOO.util.Event.on(this.link,'click',this.onClick,this,true);
+
+        this.span.id        = id_base + '-prev-span';
+        this.span.className = c;
+        this.span.innerHTML = label;
+
+        this.current = p.get('recordOffset') < 1 ? this.span : this.link;
+        return this.current;
+    },
+
+    /**
+     * Swap the link and span nodes if appropriate.
+     * @method update
+     * @param e {CustomEvent} The calling change event
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+        var par = this.current ? this.current.parentNode : null;
+        if (this.paginator.get('recordOffset') < 1) {
+            if (par && this.current === this.link) {
+                par.replaceChild(this.span,this.current);
+                this.current = this.span;
+            }
+        } else {
+            if (par && this.current === this.span) {
+                par.replaceChild(this.link,this.current);
+                this.current = this.link;
+            }
+        }
+    },
+
+    /**
+     * Removes the onClick listener from the link in preparation for content
+     * removal.
+     * @method destroy
+     * @private
+     */
+    destroy : function () {
+        YAHOO.util.Event.purgeElement(this.link);
+    },
+
+    /**
+     * Listener for the link's onclick event.  Passes to setPage method.
+     * @method onClick
+     * @param e {DOMEvent} The click event
+     */
+    onClick : function (e) {
+        YAHOO.util.Event.stopEvent(e);
+        this.paginator.setPage(this.paginator.getPreviousPage());
+    }
+};
+
+
+
+/**
+ * ui Component to generate the link to jump to the next page.
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class NextPageLink
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.NextPageLink = function (p) {
+    this.paginator = p;
+
+    p.createEvent('nextPageLinkLabelChange');
+    p.createEvent('nextPageLinkClassChange');
+
+    p.subscribe('recordOffsetChange',this.update,this,true);
+    p.subscribe('totalRecordsChange',this.update,this,true);
+    p.subscribe('rowsPerPageChange', this.update,this,true);
+    p.subscribe('beforeDestroy',this.destroy,this,true);
+
+    // TODO: make this work
+    p.subscribe('nextPageLinkLabelChange', this.update,this,true);
+    p.subscribe('nextPageLinkClassChange', this.update,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param p {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.NextPageLink.init = function (p) {
+
+    /**
+     * Used as innerHTML for the next page link/span.
+     * @attribute nextPageLinkLabel
+     * @default 'next >'
+     */
+    p.setAttributeConfig('nextPageLinkLabel', {
+        value : 'next >',
+        validator : l.isString
+    });
+
+    /**
+     * CSS class assigned to the link/span
+     * @attribute nextPageLinkClass
+     * @default 'yui-pg-next'
+     */
+    p.setAttributeConfig('nextPageLinkClass', {
+        value : 'yui-pg-next',
+        validator : l.isString
+    });
+};
+
+ui.NextPageLink.prototype = {
+
+    /**
+     * Currently placed HTMLElement node
+     * @property current
+     * @type HTMLElement
+     * @private
+     */
+    current   : null,
+
+    /**
+     * Link node
+     * @property link
+     * @type HTMLElement
+     * @private
+     */
+    link      : null,
+
+    /**
+     * Span node (inactive link)
+     * @property span
+     * @type HTMLElement
+     * @private
+     */
+    span      : null,
+
+
+    /**
+     * Generate the nodes and return the appropriate node given the current
+     * pagination state.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        var p     = this.paginator,
+            c     = p.get('nextPageLinkClass'),
+            label = p.get('nextPageLinkLabel'),
+            last  = p.getTotalPages();
+
+        this.link     = document.createElement('a');
+        this.span     = document.createElement('span');
+
+        this.link.id        = id_base + '-next-link';
+        this.link.href      = '#';
+        this.link.className = c;
+        this.link.innerHTML = label;
+        YAHOO.util.Event.on(this.link,'click',this.onClick,this,true);
+
+        this.span.id        = id_base + '-next-span';
+        this.span.className = c;
+        this.span.innerHTML = label;
+
+        this.current = p.getCurrentPage() === last ? this.span : this.link;
+
+        return this.current;
+    },
+
+    /**
+     * Swap the link and span nodes if appropriate.
+     * @method update
+     * @param e {CustomEvent} The calling change event
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+        var last = this.paginator.getTotalPages(),
+            par  = this.current ? this.current.parentNode : null;
+
+        if (this.paginator.getCurrentPage() !== last) {
+            if (par && this.current === this.span) {
+                par.replaceChild(this.link,this.current);
+                this.current = this.link;
+            }
+        } else if (this.current === this.link) {
+            if (par) {
+                par.replaceChild(this.span,this.current);
+                this.current = this.span;
+            }
+        }
+    },
+
+    /**
+     * Removes the onClick listener from the link in preparation for content
+     * removal.
+     * @method destroy
+     * @private
+     */
+    destroy : function () {
+        YAHOO.util.Event.purgeElement(this.link);
+    },
+
+    /**
+     * Listener for the link's onclick event.  Passes to setPage method.
+     * @method onClick
+     * @param e {DOMEvent} The click event
+     */
+    onClick : function (e) {
+        YAHOO.util.Event.stopEvent(e);
+        this.paginator.setPage(this.paginator.getNextPage());
+    }
+};
+
+
+/**
+ * ui Component to generate the page links
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class PageLinks
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.PageLinks = function (p) {
+    this.paginator = p;
+
+    p.createEvent('pageLinkClassChange');
+    p.createEvent('currentPageClassChange');
+    p.createEvent('pageLinksContainerClassChange');
+    p.createEvent('pageLinksChange');
+
+    p.subscribe('recordOffsetChange',this.update,this,true);
+    p.subscribe('pageLinksChange',   this.rebuild,this,true);
+    p.subscribe('totalRecordsChange',this.rebuild,this,true);
+    p.subscribe('rowsPerPageChange', this.rebuild,this,true);
+    p.subscribe('pageLinkClassChange', this.rebuild,this,true);
+    p.subscribe('currentPageClassChange', this.rebuild,this,true);
+    p.subscribe('beforeDestroy',this.destroy,this,true);
+
+    //TODO: Make this work
+    p.subscribe('pageLinksContainerClassChange', this.rebuild,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param p {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.PageLinks.init = function (p) {
+
+    /**
+     * CSS class assigned to each page link/span.
+     * @attribute pageLinkClass
+     * @default 'yui-pg-page'
+     */
+    p.setAttributeConfig('pageLinkClass', {
+        value : 'yui-pg-page',
+        validator : l.isString
+    });
+
+    /**
+     * CSS class assigned to the current page span.
+     * @attribute currentPageClass
+     * @default 'yui-pg-current-page'
+     */
+    p.setAttributeConfig('currentPageClass', {
+        value : 'yui-pg-current-page',
+        validator : l.isString
+    });
+
+    /**
+     * CSS class assigned to the span containing the page links.
+     * @attribute pageLinksContainerClass
+     * @default 'yui-pg-pages'
+     */
+    p.setAttributeConfig('pageLinksContainerClass', {
+        value : 'yui-pg-pages',
+        validator : l.isString
+    });
+
+    /**
+     * Maximum number of page links to display at one time.
+     * @attribute pageLinks
+     * @default 10
+     */
+    p.setAttributeConfig('pageLinks', {
+        value : 10,
+        validator : l.isNumber
+    });
+
+    /**
+     * Function used generate the innerHTML for each page link/span.  The
+     * function receives as parameters the page number and a reference to the
+     * paginator object.
+     * @attribute pageLabelBuilder
+     * @default function (page, paginator) { return page; }
+     */
+    p.setAttributeConfig('pageLabelBuilder', {
+        value : function (page, paginator) { return page; },
+        validator : l.isFunction
+    });
+};
+
+/**
+ * Calculates start and end page numbers given a current page, attempting
+ * to keep the current page in the middle
+ * @static
+ * @method calculateRange
+ * @param {int} currentPage  The current page
+ * @param {int} totalPages   (optional) Maximum number of pages
+ * @param {int} numPages     (optional) Preferred number of pages in range
+ * @return {Array} [start_page_number, end_page_number]
+ */
+ui.PageLinks.calculateRange = function (currentPage,totalPages,numPages) {
+    var UNLIMITED = Paginator.VALUE_UNLIMITED,
+        start, end, delta;
+
+    // Either has no pages, or unlimited pages.  Show none.
+    if (!currentPage || numPages === 0 || totalPages === 0 ||
+        (totalPages === UNLIMITED && numPages === UNLIMITED)) {
+        return [0,-1];
+    }
+
+    // Limit requested pageLinks if there are fewer totalPages
+    if (totalPages !== UNLIMITED) {
+        numPages = numPages === UNLIMITED ?
+                    totalPages :
+                    Math.min(numPages,totalPages);
+    }
+
+    // Determine start and end, trying to keep current in the middle
+    start = Math.max(1,Math.ceil(currentPage - (numPages/2)));
+    if (totalPages === UNLIMITED) {
+        end = start + numPages - 1;
+    } else {
+        end = Math.min(totalPages, start + numPages - 1);
+    }
+
+    // Adjust the start index when approaching the last page
+    delta = numPages - (end - start + 1);
+    start = Math.max(1, start - delta);
+
+    return [start,end];
+};
+
+
+ui.PageLinks.prototype = {
+
+    /**
+     * Current page
+     * @property current
+     * @type number
+     * @private
+     */
+    current     : 0,
+
+    /**
+     * Span node containing the page links
+     * @property container
+     * @type HTMLElement
+     * @private
+     */
+    container   : null,
+
+
+    /**
+     * Generate the nodes and return the container node containing page links
+     * appropriate to the current pagination state.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        var p = this.paginator;
+
+        // Set up container
+        this.container = document.createElement('span');
+        this.container.id        = id_base + '-pages';
+        this.container.className = p.get('pageLinksContainerClass');
+        YAHOO.util.Event.on(this.container,'click',this.onClick,this,true);
+
+        // Call update, flagging a need to rebuild
+        this.update({newValue : null, rebuild : true});
+
+        return this.container;
+    },
+
+    /**
+     * Update the links if appropriate
+     * @method update
+     * @param e {CustomEvent} The calling change event
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+        var p           = this.paginator,
+            currentPage = p.getCurrentPage();
+
+        // Replace content if there's been a change
+        if (this.current !== currentPage || e.rebuild) {
+            var labelBuilder = p.get('pageLabelBuilder'),
+                range        = ui.PageLinks.calculateRange(
+                                currentPage,
+                                p.getTotalPages(),
+                                p.get('pageLinks')),
+                start        = range[0],
+                end          = range[1],
+                content      = '',
+                linkTemplate,i;
+
+            linkTemplate = '<a href="#" class="' + p.get('pageLinkClass') +
+                           '" page="';
+            for (i = start; i <= end; ++i) {
+                if (i === currentPage) {
+                    content +=
+                        '<span class="' + p.get('currentPageClass') + ' ' +
+                                          p.get('pageLinkClass') + '">' +
+                        labelBuilder(i,p) + '</span>';
+                } else {
+                    content +=
+                        linkTemplate + i + '">' + labelBuilder(i,p) + '</a>';
+                }
+            }
+
+            this.container.innerHTML = content;
+        }
+    },
+
+    /**
+     * Force a rebuild of the page links.
+     * @method rebuild
+     * @param e {CustomEvent} The calling change event
+     */
+    rebuild     : function (e) {
+        e.rebuild = true;
+        this.update(e);
+    },
+
+    /**
+     * Removes the onClick listener from the container in preparation for
+     * content removal.
+     * @method destroy
+     * @private
+     */
+    destroy : function () {
+        YAHOO.util.Event.purgeElement(this.container,true);
+    },
+
+    /**
+     * Listener for the container's onclick event.  Looks for qualifying link
+     * clicks, and pulls the page number from the link's page attribute.
+     * Sends link's page attribute to the Paginator's setPage method.
+     * @method onClick
+     * @param e {DOMEvent} The click event
+     */
+    onClick : function (e) {
+        var t = YAHOO.util.Event.getTarget(e);
+        if (t && YAHOO.util.Dom.hasClass(t,
+                        this.paginator.get('pageLinkClass'))) {
+
+            YAHOO.util.Event.stopEvent(e);
+
+            this.paginator.setPage(parseInt(t.getAttribute('page'),10));
+        }
+    }
+
+};
+
+
+/**
+ * ui Component to generate the rows-per-page dropdown
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class RowsPerPageDropdown
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.RowsPerPageDropdown = function (p) {
+    this.paginator = p;
+
+    p.createEvent('rowsPerPageOptionsChange');
+    p.createEvent('rowsPerPageDropdownClassChange');
+
+    p.subscribe('rowsPerPageChange',this.update,this,true);
+    p.subscribe('rowsPerPageOptionsChange',this.rebuild,this,true);
+    p.subscribe('beforeDestroy',this.destroy,this,true);
+
+    // TODO: make this work
+    p.subscribe('rowsPerPageDropdownClassChange',this.rebuild,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param p {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.RowsPerPageDropdown.init = function (p) {
+
+    /**
+     * Array of available rows-per-page sizes.  Converted into select options.
+     * Array values may be positive integers or object literals in the form<br>
+     * { value : NUMBER, text : STRING }
+     * @attribute rowsPerPageOptions
+     * @default []
+     */
+    p.setAttributeConfig('rowsPerPageOptions', {
+        value : [],
+        validator : l.isArray
+    });
+
+    /**
+     * CSS class assigned to the select node
+     * @attribute rowsPerPageDropdownClass
+     * @default 'yui-pg-rpp-options'
+     */
+    p.setAttributeConfig('rowsPerPageDropdownClass', {
+        value : 'yui-pg-rpp-options',
+        validator : l.isString
+    });
+};
+
+ui.RowsPerPageDropdown.prototype = {
+
+    /**
+     * select node
+     * @property select
+     * @type HTMLElement
+     * @private
+     */
+    select  : null,
+
+
+    /**
+     * Generate the select and option nodes and returns the select node.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        this.select = document.createElement('select');
+        this.select.id        = id_base + '-rpp';
+        this.select.className = this.paginator.get('rowsPerPageDropdownClass');
+        this.select.title = 'Rows per page';
+
+        YAHOO.util.Event.on(this.select,'change',this.onChange,this,true);
+
+        this.rebuild();
+
+        return this.select;
+    },
+
+    /**
+     * Select the appropriate option if changed.
+     * @method update
+     * @param e {CustomEvent} The calling change event
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+        var rpp     = this.paginator.get('rowsPerPage'),
+            options = this.select.options,
+            i,len;
+
+        for (i = 0, len = options.length; i < len; ++i) {
+            if (parseInt(options[i].value,10) === rpp) {
+                options[i].selected = true;
+            }
+        }
+    },
+
+
+    /**
+     * (Re)generate the select options.
+     * @method rebuild
+     */
+    rebuild : function (e) {
+        var p       = this.paginator,
+            sel     = this.select,
+            options = p.get('rowsPerPageOptions'),
+            opt_tem = document.createElement('option'),
+            i,len;
+
+        while (sel.firstChild) {
+            sel.removeChild(sel.firstChild);
+        }
+
+        for (i = 0, len = options.length; i < len; ++i) {
+            var node = opt_tem.cloneNode(false),
+                opt  = options[i];
+            node.value = l.isValue(opt.value) ? opt.value : opt;
+            node.innerHTML = l.isValue(opt.text) ? opt.text : opt;
+            sel.appendChild(node);
+        }
+
+        this.update();
+    },
+
+    /**
+     * Removes the onChange listener from the select in preparation for content
+     * removal.
+     * @method destroy
+     * @private
+     */
+    destroy : function () {
+        YAHOO.util.Event.purgeElement(this.select);
+    },
+
+    /**
+     * Listener for the select's onchange event.  Sent to setRowsPerPage method.
+     * @method onChange
+     * @param e {DOMEvent} The change event
+     */
+    onChange : function (e) {
+        this.paginator.setRowsPerPage(
+                parseInt(this.select.options[this.select.selectedIndex].value,10));
+    }
+};
+
+
+
+/**
+ * ui Component to generate the textual report of current pagination status.
+ * E.g. "Now viewing page 1 of 13".
+ *
+ * @namespace YAHOO.widget.Paginator.ui
+ * @class CurrentPageReport
+ * @for YAHOO.widget.Paginator
+ *
+ * @constructor
+ * @param p {Pagintor} Paginator instance to attach to
+ */
+ui.CurrentPageReport = function (p) {
+    this.paginator = p;
+
+    p.createEvent('pageReportClassChange');
+    p.createEvent('pageReportTemplateChange');
+
+    p.subscribe('recordOffsetChange',this.update,this,true);
+    p.subscribe('totalRecordsChange',this.update,this,true);
+    p.subscribe('rowsPerPageChange', this.update,this,true);
+    p.subscribe('pageReportTemplateChange', this.update,this,true);
+
+    //TODO: make this work
+    p.subscribe('pageReportClassChange', this.update,this,true);
+};
+
+/**
+ * Decorates Paginator instances with new attributes. Called during
+ * Paginator instantiation.
+ * @method init
+ * @param p {Paginator} Paginator instance to decorate
+ * @static
+ */
+ui.CurrentPageReport.init = function (p) {
+
+    /**
+     * CSS class assigned to the span containing the info.
+     * @attribute pageReportClass
+     * @default 'yui-pg-current'
+     */
+    p.setAttributeConfig('pageReportClass', {
+        value : 'yui-pg-current',
+        validator : l.isString
+    });
+
+    /**
+     * Used as innerHTML for the span.  Place holders in the form of {name}
+     * will be replaced with the so named value from the key:value map
+     * generated by the function held in the pageReportValueGenerator attribute.
+     * @attribute pageReportTemplate
+     * @default '({currentPage} of {totalPages})'
+     * @see pageReportValueGenerator attribute
+     */
+    p.setAttributeConfig('pageReportTemplate', {
+        value : '({currentPage} of {totalPages})',
+        validator : l.isString
+    });
+
+    /**
+     * Function to generate the value map used to populate the
+     * pageReportTemplate.  The function is passed the Paginator instance as a
+     * parameter.  The default function returns a map with the following keys:
+     * <ul>
+     * <li>currentPage</li>
+     * <li>totalPages</li>
+     * <li>startIndex</li>
+     * <li>endIndex</li>
+     * <li>startRecord</li>
+     * <li>endRecord</li>
+     * <li>totalRecords</li>
+     * </ul>
+     * @attribute pageReportValueGenarator
+     */
+    p.setAttributeConfig('pageReportValueGenerator', {
+        value : function (paginator) {
+            var curPage = paginator.getCurrentPage(),
+                records = paginator.getPageRecords();
+
+            return {
+                'currentPage' : records ? curPage : 0,
+                'totalPages'  : paginator.getTotalPages(),
+                'startIndex'  : records ? records[0] : 0,
+                'endIndex'    : records ? records[1] : 0,
+                'startRecord' : records ? records[0] + 1 : 0,
+                'endRecord'   : records ? records[1] + 1 : 0,
+                'totalRecords': paginator.get('totalRecords')
+            };
+        },
+        validator : l.isFunction
+    });
+};
+
+/**
+ * Replace place holders in a string with the named values found in an
+ * object literal.
+ * @static
+ * @method sprintf
+ * @param template {string} The content string containing place holders
+ * @param values {object} The key:value pairs used to replace the place holders
+ * @return {string}
+ */
+ui.CurrentPageReport.sprintf = function (template, values) {
+    return template.replace(/{([\w\s\-]+)}/g, function (x,key) {
+            return (key in values) ? values[key] : '';
+        });
+};
+
+ui.CurrentPageReport.prototype = {
+
+    /**
+     * Span node containing the formatted info
+     * @property span
+     * @type HTMLElement
+     * @private
+     */
+    span : null,
+
+
+    /**
+     * Generate the span containing info formatted per the pageReportTemplate
+     * attribute.
+     * @method render
+     * @param id_base {string} used to create unique ids for generated nodes
+     * @return {HTMLElement}
+     */
+    render : function (id_base) {
+        this.span = document.createElement('span');
+        this.span.id        = id_base + '-page-report';
+        this.span.className = this.paginator.get('pageReportClass');
+        this.update();
+        
+        return this.span;
+    },
+    
+    /**
+     * Regenerate the content of the span if appropriate. Calls
+     * CurrentPageReport.sprintf with the value of the pageReportTemplate
+     * attribute and the value map returned from pageReportValueGenerator
+     * function.
+     * @method update
+     * @param e {CustomEvent} The calling change event
+     */
+    update : function (e) {
+        if (e && e.prevValue === e.newValue) {
+            return;
+        }
+
+
+        this.span.innerHTML = ui.CurrentPageReport.sprintf(
+            this.paginator.get('pageReportTemplate'),
+            this.paginator.get('pageReportValueGenerator')(this.paginator));
+    }
+};
+
+})();
+/**
  * The DataTable widget provides a progressively enhanced DHTML control for
  * displaying tabular data across A-grade browsers.
  *
  * @module datatable
- * @requires yahoo, dom, event, datasource
- * @optional dragdrop
+ * @requires yahoo, dom, event, element, datasource
+ * @optional connection, dragdrop
  * @title DataTable Widget
  * @beta
  */
@@ -32,80 +4290,1438 @@
  * @param oConfigs {object} (optional) Object literal of configuration values.
  */
 YAHOO.widget.DataTable = function(elContainer,aColumnDefs,oDataSource,oConfigs) {
+    var DT = YAHOO.widget.DataTable,
+        DS = YAHOO.util.DataSource;
+
     // Internal vars
-    this._nIndex = YAHOO.widget.DataTable._nCount;
-    this._sName = "instance" + this._nIndex;
-    this.id = "yui-dt"+this._nIndex;
+    this._nIndex = DT._nCount;
+    this._sId = "yui-dt"+this._nIndex;
+    this._oChainRender = new YAHOO.util.Chain();
+    this._oChainSync = new YAHOO.util.Chain();
+    this._oChainRender.subscribe("end",this._sync, this, true);
 
-    // Initialize container element
-    this._initContainerEl(elContainer);
-    if(!this._elContainer) {
+    // Initialize configs
+    this._initConfigs(oConfigs);
+
+    // Initialize DataSource
+    this._initDataSource(oDataSource);
+    if(!this._oDataSource) {
         return;
     }
 
-    // Initialize configs
-    this._initConfigs(oConfigs);
-
     // Initialize ColumnSet
     this._initColumnSet(aColumnDefs);
     if(!this._oColumnSet) {
         return;
     }
-    
+
     // Initialize RecordSet
     this._initRecordSet();
     if(!this._oRecordSet) {
         return;
     }
 
-    // Initialize DataSource
-    this._initDataSource(oDataSource);
-    if(!this._oDataSource) {
+    // Initialize node templates
+    this._initNodeTemplates();
+
+    // Initialize container element
+    this._initContainerEl(elContainer);
+    if(!this._elContainer) {
         return;
     }
 
-    // Progressive enhancement special case
-    if(this._oDataSource.dataType == YAHOO.util.DataSource.TYPE_HTMLTABLE) {
-        this._oDataSource.sendRequest(this.get("initialRequest"), this._onDataReturnEnhanceTable, this);
+    // Initialize the rest of the DOM elements
+    this._initTableEl();
+    if(!this._elContainer || !this._elThead || !this._elTbody) {
+        return;
     }
-    else {
-        // Initialize DOM elements
-        this._initTableEl();
-        if(!this._elTable || !this._elThead || !this._elTbody) {
-            return;
-        }
 
-        // Call Element's constructor after DOM elements are created
-        // but *before* table is populated with data
-        YAHOO.widget.DataTable.superclass.constructor.call(this, this._elContainer, this._oConfigs);
-        
-        //HACK: Set the Paginator values here via updatePaginator
-        if(this._oConfigs && this._oConfigs.paginator) {
-            this.updatePaginator(this._oConfigs.paginator);
+    // Call Element's constructor after DOM elements are created
+    // but *before* table is populated with data
+    DT.superclass.constructor.call(this, this._elContainer, this._oConfigs);
+
+    // HACK: Set sortedBy values for backward compatibility
+    var oSortedBy = this.get("sortedBy");
+    if(oSortedBy) {
+        if(oSortedBy.dir == "desc") {
+            this._configs.sortedBy.value.dir = DT.CLASS_DESC;
         }
+        else if(oSortedBy.dir == "asc") {
+            this._configs.sortedBy.value.dir = DT.CLASS_ASC;
+        }
+    }
 
-        // Send out for data in an asynchronous request
-        this._oDataSource.sendRequest(this.get("initialRequest"), this.onDataReturnInitializeTable, this);
+    //HACK: Set the paginator values.  Attribute doesn't afford for merging
+    // obj value's keys.  It's all or nothing.  Merge in provided keys.
+    if(this._oConfigs.paginator && !(this._oConfigs.paginator instanceof YAHOO.widget.Paginator)) {
+        // Backward compatibility
+        this.updatePaginator(this._oConfigs.paginator);
     }
 
     // Initialize inline Cell editing
     this._initCellEditorEl();
-
+    
     // Initialize Column sort
     this._initColumnSort();
 
-    // Initialize DOM event listeners
-    this._initDomEvents();
+    // Once per instance
+    YAHOO.util.Event.addListener(document, "click", this._onDocumentClick, this);
 
-    YAHOO.widget.DataTable._nCount++;
+    DT._nCount++;
+    DT._nCurrentCount++;
+    
+    // Send a simple initial request
+    var oCallback = {
+        success : this.onDataReturnSetRows,
+        failure : this.onDataReturnSetRows,
+        scope   : this,
+        argument: {}
+    };
+    if(this.get("initialLoad") === true) {
+        this._oDataSource.sendRequest(this.get("initialRequest"), oCallback);
+    }
+    // Do not send an initial request at all
+    else if(this.get("initialLoad") === false) {
+        this.showTableMessage(DT.MSG_EMPTY, DT.CLASS_EMPTY);
+        this._oChainRender.add({
+            method: function() {
+                if((this instanceof DT) && this._sId && this._bInit) {
+                    this._bInit = false;
+                    this.fireEvent("initEvent");
+                }
+            },
+            scope: this
+        });
+        this._oChainRender.run();
+    }
+    // Send an initial request with a custom payload
+    else {
+        var oCustom = this.get("initialLoad");
+        oCallback.argument = oCustom.argument;
+        this._oDataSource.sendRequest(oCustom.request, oCallback);
+    }
 };
 
-if(YAHOO.util.Element) {
-    YAHOO.lang.extend(YAHOO.widget.DataTable, YAHOO.util.Element);
-}
-else {
-}
+/////////////////////////////////////////////////////////////////////////////
+//
+// Public constants
+//
+/////////////////////////////////////////////////////////////////////////////
+(function () {
 
+var lang   = YAHOO.lang,
+    util   = YAHOO.util,
+    widget = YAHOO.widget,
+    ua     = YAHOO.env.ua,
+    
+    Dom    = util.Dom,
+    Ev     = util.Event,
+    DS     = util.DataSource,
+    DT     = widget.DataTable,
+    Pag    = widget.Paginator;
+    
+
+    
+
+lang.augmentObject(DT, {
+
+    /**
+     * Class name assigned to liner DIV elements.
+     *
+     * @property DataTable.CLASS_LINER
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-liner"
+     */
+    CLASS_LINER : "yui-dt-liner",
+
+    /**
+     * Class name assigned to display label elements.
+     *
+     * @property DataTable.CLASS_LABEL
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-label"
+     */
+    CLASS_LABEL : "yui-dt-label",
+
+    /**
+     * Class name assigned to Column drag target.
+     *
+     * @property DataTable.CLASS_COLTARGET
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-coltarget"
+     */
+    CLASS_COLTARGET : "yui-dt-coltarget",
+
+    /**
+     * Class name assigned to resizer handle elements.
+     *
+     * @property DataTable.CLASS_RESIZER
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-resizer"
+     */
+    CLASS_RESIZER : "yui-dt-resizer",
+
+    /**
+     * Class name assigned to resizer proxy elements.
+     *
+     * @property DataTable.CLASS_RESIZERPROXY
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-resizerproxy"
+     */
+    CLASS_RESIZERPROXY : "yui-dt-resizerproxy",
+
+    /**
+     * Class name assigned to Editor container elements.
+     *
+     * @property DataTable.CLASS_EDITOR
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-editor"
+     */
+    CLASS_EDITOR : "yui-dt-editor",
+
+    /**
+     * Class name assigned to paginator container elements.
+     *
+     * @property DataTable.CLASS_PAGINATOR
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-paginator"
+     */
+    CLASS_PAGINATOR : "yui-dt-paginator",
+
+    /**
+     * Class name assigned to page number indicators.
+     *
+     * @property DataTable.CLASS_PAGE
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-page"
+     */
+    CLASS_PAGE : "yui-dt-page",
+
+    /**
+     * Class name assigned to default indicators.
+     *
+     * @property DataTable.CLASS_DEFAULT
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-default"
+     */
+    CLASS_DEFAULT : "yui-dt-default",
+
+    /**
+     * Class name assigned to previous indicators.
+     *
+     * @property DataTable.CLASS_PREVIOUS
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-previous"
+     */
+    CLASS_PREVIOUS : "yui-dt-previous",
+
+    /**
+     * Class name assigned next indicators.
+     *
+     * @property DataTable.CLASS_NEXT
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-next"
+     */
+    CLASS_NEXT : "yui-dt-next",
+
+    /**
+     * Class name assigned to first elements.
+     *
+     * @property DataTable.CLASS_FIRST
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-first"
+     */
+    CLASS_FIRST : "yui-dt-first",
+
+    /**
+     * Class name assigned to last elements.
+     *
+     * @property DataTable.CLASS_LAST
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-last"
+     */
+    CLASS_LAST : "yui-dt-last",
+
+    /**
+     * Class name assigned to even elements.
+     *
+     * @property DataTable.CLASS_EVEN
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-even"
+     */
+    CLASS_EVEN : "yui-dt-even",
+
+    /**
+     * Class name assigned to odd elements.
+     *
+     * @property DataTable.CLASS_ODD
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-odd"
+     */
+    CLASS_ODD : "yui-dt-odd",
+
+    /**
+     * Class name assigned to selected elements.
+     *
+     * @property DataTable.CLASS_SELECTED
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-selected"
+     */
+    CLASS_SELECTED : "yui-dt-selected",
+
+    /**
+     * Class name assigned to highlighted elements.
+     *
+     * @property DataTable.CLASS_HIGHLIGHTED
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-highlighted"
+     */
+    CLASS_HIGHLIGHTED : "yui-dt-highlighted",
+
+    /**
+     * Class name assigned to hidden elements.
+     *
+     * @property DataTable.CLASS_HIDDEN
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-hidden"
+     */
+    CLASS_HIDDEN : "yui-dt-hidden",
+
+    /**
+     * Class name assigned to disabled elements.
+     *
+     * @property DataTable.CLASS_DISABLED
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-disabled"
+     */
+    CLASS_DISABLED : "yui-dt-disabled",
+
+    /**
+     * Class name assigned to empty indicators.
+     *
+     * @property DataTable.CLASS_EMPTY
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-empty"
+     */
+    CLASS_EMPTY : "yui-dt-empty",
+
+    /**
+     * Class name assigned to loading indicatorx.
+     *
+     * @property DataTable.CLASS_LOADING
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-loading"
+     */
+    CLASS_LOADING : "yui-dt-loading",
+
+    /**
+     * Class name assigned to error indicators.
+     *
+     * @property DataTable.CLASS_ERROR
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-error"
+     */
+    CLASS_ERROR : "yui-dt-error",
+
+    /**
+     * Class name assigned to editable elements.
+     *
+     * @property DataTable.CLASS_EDITABLE
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-editable"
+     */
+    CLASS_EDITABLE : "yui-dt-editable",
+
+    /**
+     * Class name assigned to draggable elements.
+     *
+     * @property DataTable.CLASS_DRAGGABLE
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-draggable"
+     */
+    CLASS_DRAGGABLE : "yui-dt-draggable",
+
+    /**
+     * Class name assigned to resizeable elements.
+     *
+     * @property DataTable.CLASS_RESIZEABLE
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-resizeable"
+     */
+    CLASS_RESIZEABLE : "yui-dt-resizeable",
+
+    /**
+     * Class name assigned to scrollable elements.
+     *
+     * @property DataTable.CLASS_SCROLLABLE
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-scrollable"
+     */
+    CLASS_SCROLLABLE : "yui-dt-scrollable",
+
+    /**
+     * Class name assigned to sortable elements.
+     *
+     * @property DataTable.CLASS_SORTABLE
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-sortable"
+     */
+    CLASS_SORTABLE : "yui-dt-sortable",
+
+    /**
+     * Class name assigned to ascending elements.
+     *
+     * @property DataTable.CLASS_ASC
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-asc"
+     */
+    CLASS_ASC : "yui-dt-asc",
+
+    /**
+     * Class name assigned to descending elements.
+     *
+     * @property DataTable.CLASS_DESC
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-desc"
+     */
+    CLASS_DESC : "yui-dt-desc",
+
+    /**
+     * Class name assigned to BUTTON elements and/or container elements.
+     *
+     * @property DataTable.CLASS_BUTTON
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-button"
+     */
+    CLASS_BUTTON : "yui-dt-button",
+
+    /**
+     * Class name assigned to INPUT TYPE=CHECKBOX elements and/or container elements.
+     *
+     * @property DataTable.CLASS_CHECKBOX
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-checkbox"
+     */
+    CLASS_CHECKBOX : "yui-dt-checkbox",
+
+    /**
+     * Class name assigned to SELECT elements and/or container elements.
+     *
+     * @property DataTable.CLASS_DROPDOWN
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-dropdown"
+     */
+    CLASS_DROPDOWN : "yui-dt-dropdown",
+
+    /**
+     * Class name assigned to INPUT TYPE=RADIO elements and/or container elements.
+     *
+     * @property DataTable.CLASS_RADIO
+     * @type String
+     * @static
+     * @final
+     * @default "yui-dt-radio"
+     */
+    CLASS_RADIO : "yui-dt-radio",
+
+    /**
+     * Message to display if DataTable has no data.
+     *
+     * @property DataTable.MSG_EMPTY
+     * @type String
+     * @static
+     * @final
+     * @default "No records found."
+     */
+    MSG_EMPTY : "No records found.",
+
+    /**
+     * Message to display while DataTable is loading data.
+     *
+     * @property DataTable.MSG_LOADING
+     * @type String
+     * @static
+     * @final
+     * @default "Loading data..."
+     */
+    MSG_LOADING : "Loading data...",
+
+    /**
+     * Message to display while DataTable has data error.
+     *
+     * @property DataTable.MSG_ERROR
+     * @type String
+     * @static
+     * @final
+     * @default "Data error."
+     */
+    MSG_ERROR : "Data error.",
+
+    /////////////////////////////////////////////////////////////////////////
+    //
+    // Private static variables
+    //
+    /////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Internal class variable for indexing multiple DataTable instances.
+     *
+     * @property DataTable._nCount
+     * @type Number
+     * @private
+     * @static
+     */
+    _nCount : 0,
+
+    /**
+     * Internal class variable tracking current number of DataTable instances,
+     * so that certain class values can be reset when all instances are destroyed.          
+     *
+     * @property DataTable._nCurrentCount
+     * @type Number
+     * @private
+     * @static
+     */
+    _nCurrentCount : 0,
+
+    /**
+     * Reference to STYLE node that is dynamically created and written to
+     * in order to manage Column widths.
+     *
+     * @property DataTable._elStylesheet
+     * @type HTMLElement
+     * @private
+     * @static     
+     */
+    _elStylesheet : null,
+
+    /**
+     * Set to true if _elStylesheet cannot be populated due to browser incompatibility.
+     *
+     * @property DataTable._bStylesheetFallback
+     * @type boolean
+     * @private
+     * @static     
+     */
+    _bStylesheetFallback : (ua.ie && (ua.ie<7)) ? true : false,
+
+    /**
+     * Object literal hash of Columns and their dynamically create style rules.
+     *
+     * @property DataTable._oStylesheetRules
+     * @type Object
+     * @private
+     * @static     
+     */
+    _oStylesheetRules : {},
+
+    /**
+     * Element reference to shared Column drag target.
+     *
+     * @property DataTable._elColumnDragTarget
+     * @type HTMLElement
+     * @private
+     * @static 
+     */
+    _elColumnDragTarget : null,
+
+    /**
+     * Element reference to shared Column resizer proxy.
+     *
+     * @property DataTable._elColumnResizerProxy
+     * @type HTMLElement
+     * @private
+     * @static 
+     */
+    _elColumnResizerProxy : null,
+
+    /**
+     * Clones object literal or array of object literals.
+     *
+     * @method DataTable._cloneObject
+     * @param o {Object} Object.
+     * @private
+     * @static     
+     */
+    _cloneObject : function(o) {
+        if(!lang.isValue(o)) {
+            return o;
+        }
+        
+        var copy = {};
+        
+        if(lang.isArray(o)) {
+            var array = [];
+            for(var i=0,len=o.length;i<len;i++) {
+                array[i] = DT._cloneObject(o[i]);
+            }
+            copy = array;
+        }
+        else if(o.constructor && (o.constructor == Object)) { 
+            for (var x in o){
+                if(lang.hasOwnProperty(o, x)) {
+                    if(lang.isValue(o[x]) && (o[x].constructor == Object) || lang.isArray(o[x])) {
+                        copy[x] = DT._cloneObject(o[x]);
+                    }
+                    else {
+                        copy[x] = o[x];
+                    }
+                }
+            }
+        }
+        else {
+            copy = o;
+        }
+    
+        return copy;
+    },
+
+    /**
+     * Creates HTML markup for shared Column drag target.
+     *
+     * @method DataTable._initColumnDragTargetEl
+     * @return {HTMLElement} Reference to Column drag target. 
+     * @private
+     * @static 
+     */
+    _initColumnDragTargetEl : function() {
+        if(!DT._elColumnDragTarget) {
+            // Attach Column drag target element as first child of body
+            var elColumnDragTarget = document.createElement('div');
+            elColumnDragTarget.id = "yui-dt-coltarget";
+            elColumnDragTarget.className = DT.CLASS_COLTARGET;
+            elColumnDragTarget.style.display = "none";
+            document.body.insertBefore(elColumnDragTarget, document.body.firstChild);
+
+            // Internal tracker of Column drag target
+            DT._elColumnDragTarget = elColumnDragTarget;
+            
+        }
+        return DT._elColumnDragTarget;
+    },
+
+    /**
+     * Creates HTML markup for shared Column resizer proxy.
+     *
+     * @method DataTable._initColumnResizerProxyEl
+     * @return {HTMLElement} Reference to Column resizer proxy.
+     * @private 
+     * @static 
+     */
+    _initColumnResizerProxyEl : function() {
+        if(!DT._elColumnResizerProxy) {
+
+            // Attach Column resizer element as first child of body
+            var elColumnResizerProxy = document.createElement("div");
+            elColumnResizerProxy.id = "yui-dt-colresizerproxy";
+            Dom.addClass(elColumnResizerProxy, DT.CLASS_RESIZERPROXY);
+            document.body.insertBefore(elColumnResizerProxy, document.body.firstChild);
+
+            // Internal tracker of Column resizer proxy
+            DT._elColumnResizerProxy = elColumnResizerProxy;
+        }
+        return DT._elColumnResizerProxy;
+    },
+
+    /**
+     * Outputs markup into the given TH based on given Column.
+     *
+     * @method DataTable.formatTheadCell
+     * @param elCellLabel {HTMLElement} The label DIV element within the TH liner.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oSelf {DT} DataTable instance.
+     * @static
+     */
+    formatTheadCell : function(elCellLabel, oColumn, oSelf) {
+        var sKey = oColumn.getKey();
+        var sLabel = lang.isValue(oColumn.label) ? oColumn.label : sKey;
+
+        // Add accessibility link for sortable Columns
+        if(oColumn.sortable) {
+            // Calculate the direction
+            var sSortClass = oSelf.getColumnSortDir(oColumn);
+            var sSortDir = (sSortClass === DT.CLASS_DESC) ? "descending" : "ascending";
+
+            // Generate a unique HREF for visited status
+            var sHref = oSelf.getId() + "-sort" + oColumn.getId() + "-" + sSortDir;
+            
+            // Generate a dynamic TITLE for sort status
+            var sTitle = "Click to sort " + sSortDir;
+            
+            // Format the element
+            elCellLabel.innerHTML = "<a href=\"" + sHref + "\" title=\"" + sTitle + "\" class=\"" + DT.CLASS_SORTABLE + "\">" + sLabel + "</a>";
+        }
+        // Just display the label for non-sortable Columns
+        else {
+            elCellLabel.innerHTML = sLabel;
+        }
+    },
+
+    /**
+     * Formats a BUTTON element.
+     *
+     * @method DataTable.formatButton
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object | Boolean} Data value for the cell. By default, the value
+     * is what gets written to the BUTTON.
+     * @static
+     */
+    formatButton : function(el, oRecord, oColumn, oData) {
+        var sValue = lang.isValue(oData) ? oData : "Click";
+        //TODO: support YAHOO.widget.Button
+        //if(YAHOO.widget.Button) {
+
+        //}
+        //else {
+            el.innerHTML = "<button type=\"button\" class=\""+
+                    DT.CLASS_BUTTON + "\">" + sValue + "</button>";
+        //}
+    },
+
+    /**
+     * Formats a CHECKBOX element.
+     *
+     * @method DataTable.formatCheckbox
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object | Boolean} Data value for the cell. Can be a simple
+     * Boolean to indicate whether checkbox is checked or not. Can be object literal
+     * {checked:bBoolean, label:sLabel}. Other forms of oData require a custom
+     * formatter.
+     * @static
+     */
+    formatCheckbox : function(el, oRecord, oColumn, oData) {
+        var bChecked = oData;
+        bChecked = (bChecked) ? " checked" : "";
+        el.innerHTML = "<input type=\"checkbox\"" + bChecked +
+                " class=\"" + DT.CLASS_CHECKBOX + "\">";
+    },
+
+    /**
+     * Formats currency. Default unit is USD.
+     *
+     * @method DataTable.formatCurrency
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Number} Data value for the cell.
+     * @static
+     */
+    formatCurrency : function(el, oRecord, oColumn, oData) {
+        el.innerHTML = util.Number.format(oData, {
+                prefix:"$",
+                decimalPlaces:2,
+                decimalSeparator:".",
+                thousandsSeparator:","
+            });
+    },
+
+    /**
+     * Formats JavaScript Dates.
+     *
+     * @method DataTable.formatDate
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} Data value for the cell, or null.
+     * @static
+     */
+    formatDate : function(el, oRecord, oColumn, oData) {
+        el.innerHTML = util.Date.format(oData, {format:"MM/DD/YYYY"});
+    },
+
+    /**
+     * Formats SELECT elements.
+     *
+     * @method DataTable.formatDropdown
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} Data value for the cell, or null.
+     * @static
+     */
+    formatDropdown : function(el, oRecord, oColumn, oData) {
+        var selectedValue = (lang.isValue(oData)) ? oData : oRecord.getData(oColumn.key);
+        var options = (lang.isArray(oColumn.dropdownOptions)) ?
+                oColumn.dropdownOptions : null;
+
+        var selectEl;
+        var collection = el.getElementsByTagName("select");
+
+        // Create the form element only once, so we can attach the onChange listener
+        if(collection.length === 0) {
+            // Create SELECT element
+            selectEl = document.createElement("select");
+            Dom.addClass(selectEl, DT.CLASS_DROPDOWN);
+            selectEl = el.appendChild(selectEl);
+
+            // Add event listener
+            Ev.addListener(selectEl,"change",this._onDropdownChange,this);
+        }
+
+        selectEl = collection[0];
+
+        // Update the form element
+        if(selectEl) {
+            // Clear out previous options
+            selectEl.innerHTML = "";
+
+            // We have options to populate
+            if(options) {
+                // Create OPTION elements
+                for(var i=0; i<options.length; i++) {
+                    var option = options[i];
+                    var optionEl = document.createElement("option");
+                    optionEl.value = (lang.isValue(option.value)) ?
+                            option.value : option;
+                    optionEl.innerHTML = (lang.isValue(option.text)) ?
+                            option.text : option;
+                    optionEl = selectEl.appendChild(optionEl);
+                    if (optionEl.value == selectedValue) {
+                        optionEl.selected = true;
+                    }
+                }
+            }
+            // Selected value is our only option
+            else {
+                selectEl.innerHTML = "<option selected value=\"" + selectedValue + "\">" + selectedValue + "</option>";
+            }
+        }
+        else {
+            el.innerHTML = lang.isValue(oData) ? oData : "";
+        }
+    },
+
+    /**
+     * Formats emails.
+     *
+     * @method DataTable.formatEmail
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} Data value for the cell, or null.
+     * @static
+     */
+    formatEmail : function(el, oRecord, oColumn, oData) {
+        if(lang.isString(oData)) {
+            el.innerHTML = "<a href=\"mailto:" + oData + "\">" + oData + "</a>";
+        }
+        else {
+            el.innerHTML = lang.isValue(oData) ? oData : "";
+        }
+    },
+
+    /**
+     * Formats links.
+     *
+     * @method DataTable.formatLink
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} Data value for the cell, or null.
+     * @static
+     */
+    formatLink : function(el, oRecord, oColumn, oData) {
+        if(lang.isString(oData)) {
+            el.innerHTML = "<a href=\"" + oData + "\">" + oData + "</a>";
+        }
+        else {
+            el.innerHTML = lang.isValue(oData) ? oData : "";
+        }
+    },
+
+    /**
+     * Formats numbers.
+     *
+     * @method DataTable.formatNumber
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} Data value for the cell, or null.
+     * @static
+     */
+    formatNumber : function(el, oRecord, oColumn, oData) {
+        if(lang.isNumber(oData)) {
+            el.innerHTML = oData;
+        }
+        else {
+            el.innerHTML = lang.isValue(oData) ? oData : "";
+        }
+    },
+
+    /**
+     * Formats INPUT TYPE=RADIO elements.
+     *
+     * @method DataTable.formatRadio
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} (Optional) Data value for the cell.
+     * @static
+     */
+    formatRadio : function(el, oRecord, oColumn, oData) {
+        var bChecked = oData;
+        bChecked = (bChecked) ? " checked" : "";
+        el.innerHTML = "<input type=\"radio\"" + bChecked +
+                " name=\"col" + oColumn.getId() + "-radio\"" +
+                " class=\"" + DT.CLASS_RADIO+ "\">";
+    },
+
+    /**
+     * Formats text strings.
+     *
+     * @method DataTable.formatText
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} (Optional) Data value for the cell.
+     * @static
+     */
+    formatText : function(el, oRecord, oColumn, oData) {
+        var value = (lang.isValue(oRecord.getData(oColumn.key))) ?
+                oRecord.getData(oColumn.key) : "";
+        //TODO: move to util function
+        el.innerHTML = value.toString().replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
+    },
+
+    /**
+     * Formats TEXTAREA elements.
+     *
+     * @method DataTable.formatTextarea
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} (Optional) Data value for the cell.
+     * @static
+     */
+    formatTextarea : function(el, oRecord, oColumn, oData) {
+        var value = (lang.isValue(oRecord.getData(oColumn.key))) ?
+                oRecord.getData(oColumn.key) : "";
+        var markup = "<textarea>" + value + "</textarea>";
+        el.innerHTML = markup;
+    },
+
+    /**
+     * Formats INPUT TYPE=TEXT elements.
+     *
+     * @method DataTable.formatTextbox
+     * @param el {HTMLElement} The element to format with markup.
+     * @param oRecord {YAHOO.widget.Record} Record instance.
+     * @param oColumn {YAHOO.widget.Column} Column instance.
+     * @param oData {Object} (Optional) Data value for the cell.
+     * @static
+     */
+    formatTextbox : function(el, oRecord, oColumn, oData) {
+        var value = (lang.isValue(oRecord.getData(oColumn.key))) ?
+                oRecord.getData(oColumn.key) : "";
+        var markup = "<input type=\"text\" value=\"" + value + "\">";
+        el.innerHTML = markup;
+    },
+
+    /**
+     * Handles Pag changeRequest events for static DataSources
+     * (i.e. DataSources that return all data immediately)
+     * @method DataTable.handleSimplePagination
+     * @param {object} the requested state of the pagination
+     * @param {DataTable} the DataTable instance
+     * @static     
+     */
+    handleSimplePagination : function (oState,self) {
+        // Set the core pagination values silently (the second param)
+        // to avoid looping back through the changeRequest mechanism
+        oState.paginator.setTotalRecords(oState.totalRecords,true);
+        oState.paginator.setStartIndex(oState.recordOffset,true);
+        oState.paginator.setRowsPerPage(oState.rowsPerPage,true);
+
+        self.render();
+    },
+
+    /**
+     * Handles Pag changeRequest events for dynamic DataSources
+     * such as DataSource.TYPE_XHR or DataSource.TYPE_JSFUNCTION.
+     * @method DataTable.handleDataSourcePagination
+     * @param {object} the requested state of the pagination
+     * @param {DataTable} the DataTable instance
+     * @static     
+     */
+    handleDataSourcePagination : function (oState,self) {
+        var requestedRecords = oState.records[1] - oState.recordOffset;
+
+        // Translate the proposed page state into a DataSource request param
+        var generateRequest = self.get('generateRequest');
+        var request = generateRequest({ pagination : oState }, self);
+
+        var callback = {
+            success : self.onDataReturnSetRows,
+            failure : self.onDataReturnSetRows,
+            argument : {
+                startIndex : oState.recordOffset,
+                pagination : oState
+            },
+            scope : self
+        };
+
+        self._oDataSource.sendRequest(request, callback);
+    },
+
+    /**
+     * Enables CHECKBOX Editor.
+     *
+     * @method DataTable.editCheckbox
+     * @param oEditor {Object} Object literal representation of Editor values.
+     * @param oSelf {DT} Reference back to DataTable instance.
+     * @static
+     */
+    //DT.editCheckbox = function(elContainer, oRecord, oColumn, oEditor, oSelf) 
+    editCheckbox : function(oEditor, oSelf) {
+        var elCell = oEditor.cell;
+        var oRecord = oEditor.record;
+        var oColumn = oEditor.column;
+        var elContainer = oEditor.container;
+        var aCheckedValues = oEditor.value;
+        if(!lang.isArray(aCheckedValues)) {
+            aCheckedValues = [aCheckedValues];
+        }
+
+        // Checkboxes
+        if(oColumn.editorOptions && lang.isArray(oColumn.editorOptions.checkboxOptions)) {
+            var checkboxOptions = oColumn.editorOptions.checkboxOptions;
+            var checkboxValue, checkboxId, elLabel, j, k;
+            // First create the checkbox buttons in an IE-friendly way
+            for(j=0; j<checkboxOptions.length; j++) {
+                checkboxValue = lang.isValue(checkboxOptions[j].label) ?
+                        checkboxOptions[j].label : checkboxOptions[j];
+                checkboxId =  oSelf.getId() + "-editor-checkbox" + j;
+                elContainer.innerHTML += "<input type=\"checkbox\"" +
+                        " name=\"" + oSelf.getId() + "-editor-checkbox\"" +
+                        " value=\"" + checkboxValue + "\"" +
+                        " id=\"" +  checkboxId + "\">";
+                // Then create the labels in an IE-friendly way
+                elLabel = elContainer.appendChild(document.createElement("label"));
+                elLabel.htmlFor = checkboxId;
+                elLabel.innerHTML = checkboxValue;
+            }
+            var aCheckboxEls = [];
+            var checkboxEl;
+            // Loop through checkboxes to check them
+            for(j=0; j<checkboxOptions.length; j++) {
+                checkboxEl = Dom.get(oSelf.getId() + "-editor-checkbox" + j);
+                aCheckboxEls.push(checkboxEl);
+                for(k=0; k<aCheckedValues.length; k++) {
+                    if(checkboxEl.value === aCheckedValues[k]) {
+                        checkboxEl.checked = true;
+                    }
+                }
+                // Focus the first checkbox
+                if(j===0) {
+                    oSelf._focusEl(checkboxEl);
+                }
+            }
+            // Loop through checkboxes to assign click handlers
+            for(j=0; j<checkboxOptions.length; j++) {
+                checkboxEl = Dom.get(oSelf.getId() + "-editor-checkbox" + j);
+                Ev.addListener(checkboxEl, "click", function(){
+                    var aNewValues = [];
+                    for(var m=0; m<aCheckboxEls.length; m++) {
+                        if(aCheckboxEls[m].checked) {
+                            aNewValues.push(aCheckboxEls[m].value);
+                        }
+                    }
+                    oSelf._oCellEditor.value = aNewValues;
+                    oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
+                });
+            }
+        }
+    },
+
+    /**
+     * Enables Date Editor.
+     *
+     * @method DataTable.editDate
+     * @param oEditor {Object} Object literal representation of Editor values.
+     * @param oSelf {DT} Reference back to DataTable instance.
+     * @static
+     */
+    editDate : function(oEditor, oSelf) {
+        var elCell = oEditor.cell;
+        var oRecord = oEditor.record;
+        var oColumn = oEditor.column;
+        var elContainer = oEditor.container;
+        var value = oEditor.value;
+        
+        // Set a default
+        if(!(value instanceof Date)) {
+            value = oEditor.defaultValue || new Date();
+        }
+
+        // Calendar widget
+        if(YAHOO.widget.Calendar) {
+            var selectedValue = (value.getMonth()+1)+"/"+value.getDate()+"/"+value.getFullYear();
+            var calContainer = elContainer.appendChild(document.createElement("div"));
+            var calPrefix = oColumn.getColEl();
+            calContainer.id = calPrefix + "-dateContainer";
+            var calendar =
+                    new YAHOO.widget.Calendar(calPrefix + "-date",
+                    calContainer.id,
+                    {selected:selectedValue, pagedate:value});
+            calendar.render();
+            calContainer.style.cssFloat = "none";
+
+            if(ua.ie) {
+                var calFloatClearer = elContainer.appendChild(document.createElement("br"));
+                calFloatClearer.style.clear = "both";
+            }
+
+            calendar.selectEvent.subscribe(function(type, args, obj) {
+                oSelf._oCellEditor.value = new Date(args[0][0][0], args[0][0][1]-1, args[0][0][2]);
+                oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
+            });
+        }
+        else {
+            //TODO;
+        }
+    },
+
+    /**
+     * Enables SELECT Editor.
+     *
+     * @method DataTable.editDropdown
+     * @param oEditor {Object} Object literal representation of Editor values.
+     * @param oSelf {DT} Reference back to DataTable instance.
+     * @static
+     */
+    editDropdown : function(oEditor, oSelf) {
+        var elCell = oEditor.cell;
+        var oRecord = oEditor.record;
+        var oColumn = oEditor.column;
+        var elContainer = oEditor.container;
+        var value = oEditor.value;
+        
+        // Set a default
+        if(!lang.isValue(value)) {
+            value = oEditor.defaultValue;
+        }
+
+
+        // Textbox
+        var elDropdown = elContainer.appendChild(document.createElement("select"));
+        var dropdownOptions = (oColumn.editorOptions && lang.isArray(oColumn.editorOptions.dropdownOptions)) ?
+                oColumn.editorOptions.dropdownOptions : [];
+        for(var j=0; j<dropdownOptions.length; j++) {
+            var dropdownOption = dropdownOptions[j];
+            var elOption = document.createElement("option");
+            elOption.value = (lang.isValue(dropdownOption.value)) ?
+                    dropdownOption.value : dropdownOption;
+            elOption.innerHTML = (lang.isValue(dropdownOption.text)) ?
+                    dropdownOption.text : dropdownOption;
+            elOption = elDropdown.appendChild(elOption);
+            if(value === elDropdown.options[j].value) {
+                elDropdown.options[j].selected = true;
+            }
+        }
+
+        // Set up a listener on each check box to track the input value
+        Ev.addListener(elDropdown, "change",
+            function(){
+                oSelf._oCellEditor.value = elDropdown[elDropdown.selectedIndex].value;
+                oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
+        });
+
+        // Focus the dropdown
+        oSelf._focusEl(elDropdown);
+    },
+
+    /**
+     * Enables INPUT TYPE=RADIO Editor.
+     *
+     * @method DataTable.editRadio
+     * @param oEditor {Object} Object literal representation of Editor values.
+     * @param oSelf {DT} Reference back to DataTable instance.
+     * @static
+     */
+    editRadio : function(oEditor, oSelf) {
+        var elCell = oEditor.cell;
+        var oRecord = oEditor.record;
+        var oColumn = oEditor.column;
+        var elContainer = oEditor.container;
+        var value = oEditor.value;
+
+        // Set a default
+        if(!lang.isValue(value)) {
+            value = oEditor.defaultValue;
+        }
+
+        // Radios
+        if(oColumn.editorOptions && lang.isArray(oColumn.editorOptions.radioOptions)) {
+            var radioOptions = oColumn.editorOptions.radioOptions;
+            var radioValue, radioId, elLabel, j;
+            // First create the radio buttons in an IE-friendly way
+            for(j=0; j<radioOptions.length; j++) {
+                radioValue = lang.isValue(radioOptions[j].label) ?
+                        radioOptions[j].label : radioOptions[j];
+                radioId =  oSelf.getId() + "-col" + oColumn.getId() + "-radioeditor" + j;
+                elContainer.innerHTML += "<input type=\"radio\"" +
+                        " name=\"" + oSelf.getId() + "-editor-radio\"" +
+                        " value=\"" + radioValue + "\"" +
+                        " id=\"" +  radioId + "\">";
+                // Then create the labels in an IE-friendly way
+                elLabel = elContainer.appendChild(document.createElement("label"));
+                elLabel.htmlFor = radioId;
+                elLabel.innerHTML = radioValue;
+            }
+            // Then check one, and assign click handlers
+            for(j=0; j<radioOptions.length; j++) {
+                var radioEl = Dom.get(oSelf.getId() + "-col" + oColumn.getId() + "-radioeditor" + j);
+                if(value === radioEl.value) {
+                    radioEl.checked = true;
+                    oSelf._focusEl(radioEl);
+                }
+                Ev.addListener(radioEl, "click",
+                    function(){
+                        oSelf._oCellEditor.value = this.value;
+                        oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
+                });
+            }
+        }
+    },
+
+    /**
+     * Enables TEXTAREA Editor.
+     *
+     * @method DataTable.editTextarea
+     * @param oEditor {Object} Object literal representation of Editor values.
+     * @param oSelf {DT} Reference back to DataTable instance.
+     * @static
+     */
+    editTextarea : function(oEditor, oSelf) {
+       var elCell = oEditor.cell;
+       var oRecord = oEditor.record;
+       var oColumn = oEditor.column;
+       var elContainer = oEditor.container;
+       var value = oEditor.value;
+
+        // Set a default
+        if(!lang.isValue(value)) {
+            value = oEditor.defaultValue || "";
+        }
+
+        // Textarea
+        var elTextarea = elContainer.appendChild(document.createElement("textarea"));
+        elTextarea.style.width = elCell.offsetWidth + "px"; //(parseInt(elCell.offsetWidth,10)) + "px";
+        elTextarea.style.height = "3em"; //(parseInt(elCell.offsetHeight,10)) + "px";
+        elTextarea.value = value;
+
+        // Set up a listener on each check box to track the input value
+        Ev.addListener(elTextarea, "keyup", function(){
+            //TODO: set on a timeout
+            oSelf._oCellEditor.value = elTextarea.value;
+            oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
+        });
+
+        // Select the text
+        elTextarea.focus();
+        elTextarea.select();
+    },
+
+    /**
+     * Enables INPUT TYPE=TEXT Editor.
+     *
+     * @method DataTable.editTextbox
+     * @param oEditor {Object} Object literal representation of Editor values.
+     * @param oSelf {DT} Reference back to DataTable instance.
+     * @static
+     */
+    editTextbox : function(oEditor, oSelf) {
+       var elCell = oEditor.cell;
+       var oRecord = oEditor.record;
+       var oColumn = oEditor.column;
+       var elContainer = oEditor.container;
+       var value = oEditor.value;
+
+        // Set a default
+        if(!lang.isValue(value)) {
+            value = oEditor.defaultValue || "";
+        }
+
+        // Textbox
+        var elTextbox;
+        // Bug 1802582: SF3/Mac needs a form element wrapping the input
+        if(ua.webkit>420) {
+            elTextbox = elContainer.appendChild(document.createElement("form")).appendChild(document.createElement("input"));
+        }
+        else {
+            elTextbox = elContainer.appendChild(document.createElement("input"));
+        }
+        elTextbox.type = "text";
+        elTextbox.style.width = elCell.offsetWidth + "px"; //(parseInt(elCell.offsetWidth,10)) + "px";
+        //elTextbox.style.height = "1em"; //(parseInt(elCell.offsetHeight,10)) + "px";
+        elTextbox.value = value;
+
+        // Bug: 1802582 Set up a listener on each textbox to track on keypress
+        // since SF/OP can't preventDefault on keydown
+        Ev.addListener(elTextbox, "keypress", function(v){
+            // Prevent form submit
+            // Save on "enter"
+            if((v.keyCode === 13)) {
+                YAHOO.util.Event.preventDefault(v);
+                oSelf.saveCellEditor();
+            }
+        });
+
+        // Set up a listener on each textbox to track the input value
+        Ev.addListener(elTextbox, "keyup", function(v){
+            // Update the tracker value
+            oSelf._oCellEditor.value = elTextbox.value;
+            oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
+        });
+
+        // Select the text
+        elTextbox.focus();
+        elTextbox.select();
+    },
+
+    /**
+     * Validates Editor input value to type Number, doing type conversion as
+     * necessary. A valid Number value is return, else the previous value is returned
+     * if input value does not validate.
+     *
+     *
+     * @method DataTable.validateNumber
+     * @param oData {Object} Data to validate.
+     * @static
+    */
+    validateNumber : function(oData) {
+        //Convert to number
+        var number = oData * 1;
+
+        // Validate
+        if(lang.isNumber(number)) {
+            return number;
+        }
+        else {
+            return null;
+        }
+    },
+
+    /**
+     * Translates (proposed) DataTable state data into a form consumable by
+     * DataSource sendRequest as the request parameter.  Use
+     * set('generateRequest', yourFunc) to use a custom function rather than this
+     * one.
+     * @method DataTable._generateRequest
+     * @param oData {Object} Object literal defining the current or proposed state
+     * @param oDataTable {DataTable} Reference to the DataTable instance
+     * @returns {MIXED} Returns appropriate value based on DataSource type
+     * @private
+     * @static     
+     */
+    _generateRequest : function (oData, oDataTable) {
+        var request = oData;
+
+        if (oData.pagination) {
+            if (oDataTable._oDataSource.dataType === DS.TYPE_XHR) {
+                request = '?page=' +         oData.pagination.page +
+                          '&recordOffset=' + oData.pagination.recordOffset +
+                          '&rowsPerPage=' +  oData.pagination.rowsPerPage;
+            }
+        }
+        
+        return request;
+    }
+});
+
+// Do in separate step so referenced properties are available
+// TODO: editor shortcuts
+/**
+ * Cell formatting functions.
+ * @property DataTable.Formatter
+ * @type Object
+ * @static
+ */
+DT.Formatter = {
+    button   : DT.formatButton,
+    checkbox : DT.formatCheckbox,
+    currency : DT.formatCurrency,
+    "date"   : DT.formatDate,
+    dropdown : DT.formatDropdown,
+    email    : DT.formatEmail,
+    link     : DT.formatLink,
+    "number" : DT.formatNumber,
+    radio    : DT.formatRadio,
+    text     : DT.formatText,
+    textarea : DT.formatTextarea,
+    textbox  : DT.formatTextbox
+};
+
+lang.extend(DT, util.Element, {
+
 /////////////////////////////////////////////////////////////////////////////
 //
 // Superclass methods
@@ -120,9 +5736,9 @@
  * @private
  */
 
-YAHOO.widget.DataTable.prototype.initAttributes = function(oConfigs) {
+initAttributes : function(oConfigs) {
     oConfigs = oConfigs || {};
-    YAHOO.widget.DataTable.superclass.initAttributes.call(this, oConfigs);
+    DT.superclass.initAttributes.call(this, oConfigs);
 
     /**
     * @attribute summary
@@ -131,9 +5747,9 @@
     */
     this.setAttributeConfig("summary", {
         value: null,
-        validator: YAHOO.lang.isString,
+        validator: lang.isString,
         method: function(sSummary) {
-            this._elTable.summary = sSummary;
+            this._elThead.parentNode.summary = sSummary;
         }
     });
 
@@ -167,20 +5783,62 @@
     */
     this.setAttributeConfig("selectionMode", {
         value: "standard",
-        validator: YAHOO.lang.isString
+        validator: lang.isString
     });
 
     /**
     * @attribute initialRequest
-    * @description Defines the initial request that gets sent to the DataSource.
-    * @type String
+    * @description Defines the initial request that gets sent to the DataSource
+    * during initialization. Value is ignored if initialLoad is set to any value
+    * other than true.    
+    * @type MIXED
+    * @default null
     */
     this.setAttributeConfig("initialRequest", {
-        value: "",
-        validator: YAHOO.lang.isString
+        value: null
     });
 
     /**
+    * @attribute initialLoad
+    * @description Determines whether or not to load data at instantiation. By
+    * default, will trigger a sendRequest() to the DataSource and pass in the
+    * request defined by initialRequest. If set to false, data will not load
+    * at instantiation. Alternatively, implementers who wish to work with a 
+    * custom payload may pass in an object literal with the following values:
+    *     
+    *    <dl>
+    *      <dt>request (MIXED)</dt>
+    *      <dd>Request value.</dd>
+    *
+    *      <dt>argument (MIXED)</dt>
+    *      <dd>Custom data that will be passed through to the callback function.</dd>
+    *    </dl>
+    *
+    *                    
+    * @type Boolean | Object
+    * @default true
+    */
+    this.setAttributeConfig("initialLoad", {
+        value: true
+    });
+
+    /**
+     * @attribute generateRequest
+     * @description A function used to translate proposed DataTable state info
+     * into a value which is then passed to the DataSource's sendRequest method.
+     * This function is called to get the DataTable's initial data as well as
+     * any data changes or requests such as pagination or sorting.  The method
+     * is passed two params, an object literal with the state data and a
+     * reference to the DataTable.
+     * @type function
+     * @default DT._generateRequest
+     */
+    this.setAttributeConfig("generateRequest", {
+        value: DT._generateRequest,
+        validator: lang.isFunction
+    });
+
+    /**
     * @attribute sortedBy
     * @description Object literal provides metadata for initial sort values if
     * data will arrive pre-sorted:
@@ -188,15 +5846,20 @@
     *     <dt>sortedBy.key</dt>
     *     <dd>{String} Key of sorted Column</dd>
     *     <dt>sortedBy.dir</dt>
-    *     <dd>{String} Initial sort direction, either "asc" or "desc"</dd>
+    *     <dd>{String} Initial sort direction, either DT.CLASS_ASC or DT.CLASS_DESC</dd>
     * </dl>
-    * @type Object
+    * @type Object | null
     */
     this.setAttributeConfig("sortedBy", {
         value: null,
         // TODO: accepted array for nested sorts
         validator: function(oNewSortedBy) {
-            return (oNewSortedBy && (oNewSortedBy.constructor == Object) && oNewSortedBy.key);
+            if(oNewSortedBy) {
+                return ((oNewSortedBy.constructor == Object) && oNewSortedBy.key);
+            }
+            else {
+                return (oNewSortedBy === null);
+            }
         },
         method: function(oNewSortedBy) {
             // Remove ASC/DESC from TH
@@ -204,25 +5867,35 @@
             if(oOldSortedBy && (oOldSortedBy.constructor == Object) && oOldSortedBy.key) {
                 var oldColumn = this._oColumnSet.getColumn(oOldSortedBy.key);
                 var oldThEl = this.getThEl(oldColumn);
-                YAHOO.util.Dom.removeClass(oldThEl, YAHOO.widget.DataTable.CLASS_ASC);
-                YAHOO.util.Dom.removeClass(oldThEl, YAHOO.widget.DataTable.CLASS_DESC);
+                Dom.removeClass(oldThEl, DT.CLASS_ASC);
+                Dom.removeClass(oldThEl, DT.CLASS_DESC);
             }
-            
+
             // Set ASC/DESC on TH
-            var column = (oNewSortedBy.column) ? oNewSortedBy.column : this._oColumnSet.getColumn(oNewSortedBy.key);
-            if(column) {
-                var newClass = (oNewSortedBy.dir && (oNewSortedBy.dir != "asc")) ?
-                        YAHOO.widget.DataTable.CLASS_DESC :
-                        YAHOO.widget.DataTable.CLASS_ASC;
-                YAHOO.util.Dom.addClass(this.id + "-col" + column.getId(), newClass);
+            if(oNewSortedBy) {
+                var column = (oNewSortedBy.column) ? oNewSortedBy.column : this._oColumnSet.getColumn(oNewSortedBy.key);
+                if(column) {
+                    // Backward compatibility
+                    if(oNewSortedBy.dir && ((oNewSortedBy.dir == "asc") ||  (oNewSortedBy.dir == "desc"))) {
+                        var newClass = (oNewSortedBy.dir == "desc") ?
+                                DT.CLASS_DESC :
+                                DT.CLASS_ASC;
+                        Dom.addClass(column.getThEl(), newClass);
+                    }
+                    else {
+                         var sortClass = oNewSortedBy.dir || DT.CLASS_ASC;
+                         Dom.addClass(column.getThEl(), sortClass);
+                    }
+                }
             }
         }
     });
-
+    
     /**
     * @attribute paginator
-    * @description Object literal of pagination values.
-    * @default <br>
+    * @description Stores an instance of Pag, or (for
+    * backward compatibility), an object literal of pagination values in the
+    * following form:<br>
     *   { containers:[], // UI container elements <br>
     *   rowsPerPage:500, // 500 rows <br>
     *   currentPage:1,  // page one <br>
@@ -231,11 +5904,12 @@
     *   dropdownOptions:null, // no dropdown <br>
     *   links: [], // links elements <br>
     *   dropdowns: [] } //dropdown elements
-    * 
-    * @type Object
+    *
+    * @default null
+    * @type {Object|YAHOO.widget.Paginator}
     */
     this.setAttributeConfig("paginator", {
-        value: {
+        value : { // Backward compatibility
             rowsPerPage:500, // 500 rows per page
             currentPage:1,  // show page one
             startRecordIndex:0, // start with first Record
@@ -249,175 +5923,247 @@
             dropdowns: [], //dropdown element references,
             links: [] // links elements
         },
-        validator: function(oNewPaginator) {
-            if(oNewPaginator && (oNewPaginator.constructor == Object)) {
-                // Check for incomplete set of values
-                if((oNewPaginator.rowsPerPage !== undefined) &&
-                        (oNewPaginator.currentPage !== undefined) &&
-                        (oNewPaginator.startRecordIndex !== undefined) &&
-                        (oNewPaginator.totalRecords !== undefined) &&
-                        (oNewPaginator.totalPages !== undefined) &&
-                        (oNewPaginator.rowsThisPage !== undefined) &&
-                        (oNewPaginator.pageLinks !== undefined) &&
-                        (oNewPaginator.pageLinksStart !== undefined) &&
-                        (oNewPaginator.dropdownOptions !== undefined) &&
-                        (oNewPaginator.containers !== undefined) &&
-                        (oNewPaginator.dropdowns !== undefined) &&
-                        (oNewPaginator.links !== undefined)) {
+        validator : function (oNewPaginator) {
+            if (typeof oNewPaginator === 'object' && oNewPaginator) {
+                if (oNewPaginator instanceof Pag) {
+                    return true;
+                }
+                else {
+                    // Backward compatibility
+                    if(oNewPaginator && (oNewPaginator.constructor == Object)) {
+                        // Check for incomplete set of values
+                        if((oNewPaginator.rowsPerPage !== undefined) &&
+                                (oNewPaginator.currentPage !== undefined) &&
+                                (oNewPaginator.startRecordIndex !== undefined) &&
+                                (oNewPaginator.totalRecords !== undefined) &&
+                                (oNewPaginator.totalPages !== undefined) &&
+                                (oNewPaginator.rowsThisPage !== undefined) &&
+                                (oNewPaginator.pageLinks !== undefined) &&
+                                (oNewPaginator.pageLinksStart !== undefined) &&
+                                (oNewPaginator.dropdownOptions !== undefined) &&
+                                (oNewPaginator.containers !== undefined) &&
+                                (oNewPaginator.dropdowns !== undefined) &&
+                                (oNewPaginator.links !== undefined)) {
 
-                    // Validate each value
-                    if(YAHOO.lang.isNumber(oNewPaginator.rowsPerPage) &&
-                            YAHOO.lang.isNumber(oNewPaginator.currentPage) &&
-                            YAHOO.lang.isNumber(oNewPaginator.startRecordIndex) &&
-                            YAHOO.lang.isNumber(oNewPaginator.totalRecords) &&
-                            YAHOO.lang.isNumber(oNewPaginator.totalPages) &&
-                            YAHOO.lang.isNumber(oNewPaginator.rowsThisPage) &&
-                            YAHOO.lang.isNumber(oNewPaginator.pageLinks) &&
-                            YAHOO.lang.isNumber(oNewPaginator.pageLinksStart) &&
-                            YAHOO.lang.isArray(oNewPaginator.dropdownOptions) &&
-                            YAHOO.lang.isArray(oNewPaginator.containers) &&
-                            YAHOO.lang.isArray(oNewPaginator.dropdowns) &&
-                            YAHOO.lang.isArray(oNewPaginator.links)) {
-                        return true;
+                            // Validate each value
+                            if(lang.isNumber(oNewPaginator.rowsPerPage) &&
+                                    lang.isNumber(oNewPaginator.currentPage) &&
+                                    lang.isNumber(oNewPaginator.startRecordIndex) &&
+                                    lang.isNumber(oNewPaginator.totalRecords) &&
+                                    lang.isNumber(oNewPaginator.totalPages) &&
+                                    lang.isNumber(oNewPaginator.rowsThisPage) &&
+                                    lang.isNumber(oNewPaginator.pageLinks) &&
+                                    lang.isNumber(oNewPaginator.pageLinksStart) &&
+                                    (lang.isArray(oNewPaginator.dropdownOptions) || lang.isNull(oNewPaginator.dropdownOptions)) &&
+                                    lang.isArray(oNewPaginator.containers) &&
+                                    lang.isArray(oNewPaginator.dropdowns) &&
+                                    lang.isArray(oNewPaginator.links)) {
+                                return true;
+                            }
+                        }
                     }
                 }
             }
             return false;
+        },
+        method : function (oNewPaginator) {
+            // Hook into the pagintor's change event
+            if (oNewPaginator instanceof Pag) {
+                oNewPaginator.subscribe('changeRequest', this.onPaginatorChange, this, true);
+
+                // If the paginator has no configured containers, add some
+                var containers = oNewPaginator.getContainerNodes();
+                if (!containers.length) {
+                    // Build the container nodes
+                    var c_above = document.createElement('div');
+                    c_above.id = this._sId + "-paginator0";
+                    this._elContainer.insertBefore(c_above,this._elContainer.firstChild);
+
+                    // ...and one below the table
+                    var c_below = document.createElement('div');
+                    c_below.id = this._sId + "-paginator1";
+                    this._elContainer.appendChild(c_below);
+
+                    containers = [c_above, c_below];
+                    Dom.addClass(containers,
+                                DT.CLASS_PAGINATOR);
+
+                    oNewPaginator.set('containers',containers);
+                }
+            }
         }
     });
 
     /**
     * @attribute paginated
-    * @description True if built-in client-side pagination is enabled
-    * @default false
-    * @type Boolean
+    * @deprecated No longer used, as long as "paginator" value is an instance of
+    * Paginator class.  
     */
     this.setAttributeConfig("paginated", {
         value: false,
-        validator: YAHOO.lang.isBoolean,
-        method: function(oParam) {
-            var oPaginator = this.get("paginator");
-            var aContainerEls = oPaginator.containers;
-            var i;
-            
-            // Paginator is enabled
-            if(oParam) {
-                // No containers found, create two from scratch
-                if(aContainerEls.length === 0) {
-                    // One before TABLE
-                    var pag0 = document.createElement("span");
-                    pag0.id = this.id + "-paginator0";
-                    YAHOO.util.Dom.addClass(pag0, YAHOO.widget.DataTable.CLASS_PAGINATOR);
-                    pag0 = this._elContainer.insertBefore(pag0, this._elTable);
-                    aContainerEls.push(pag0);
+        validator: lang.isBoolean,
+        method : function (on) {
+            var curVal = this.get('paginated');
+            var i,len;
+            if (on == curVal) {
+                return;
+            }
 
-                    // One after TABLE
-                    var pag1 = document.createElement("span");
-                    pag1.id = this.id + "-paginator1";
-                    YAHOO.util.Dom.addClass(pag1, YAHOO.widget.DataTable.CLASS_PAGINATOR);
-                    pag1 = this._elContainer.insertBefore(pag1, this._elTable.nextSibling);
-                    aContainerEls.push(pag1);
+            var oPaginator  = this.get('paginator');
+            if (!(oPaginator instanceof Pag)) {
+                // Backward compatibility--pagination generated here
+                oPaginator = oPaginator || {
+                    rowsPerPage     : 500,  // 500 rows per page
+                    currentPage     : 1,    // show page one
+                    startRecordIndex: 0,    // start with first Record
+                    totalRecords    : 0,    // how many Records total
+                    totalPages      : 0,    // how many pages total
+                    rowsThisPage    : 0,    // how many rows this page
+                    pageLinks       : 0,    // show all links
+                    pageLinksStart  : 1,    // first link is page 1
+                    dropdownOptions : null, // no dropdown
+                    containers      : [],   // Paginator container element references
+                    dropdowns       : [],   // dropdown element references,
+                    links           : []    // links elements
+                };
+                var aContainerEls = oPaginator.containers;
 
-                    // Add containers directly to tracker
-                    this._configs.paginator.value.containers = [pag0, pag1];
+                // Paginator is enabled
+                if(on) {
+                    // No containers found, create two from scratch
+                    if(aContainerEls.length === 0) {
+                        // One before TABLE
+                        var pag0 = document.createElement("span");
+                        pag0.id = this._sId + "-paginator0";
+                        Dom.addClass(pag0, DT.CLASS_PAGINATOR);
+                        pag0 = this._elContainer.insertBefore(pag0, this._elContainer.firstChild);
+                        aContainerEls.push(pag0);
 
-                }
-                else {
-                    // Show each container
-                    for(i=0; i<aContainerEls.length; i++) {
-                        aContainerEls[i].style.display = "";
+                        // One after TABLE
+                        var pag1 = document.createElement("span");
+                        pag1.id = this._sId + "-paginator1";
+                        Dom.addClass(pag1, DT.CLASS_PAGINATOR);
+                        pag1 = this._elContainer.appendChild(pag1);
+                        aContainerEls.push(pag1);
+
+                        // (re)set the paginator value directly
+                        oPaginator.containers = aContainerEls;
+                        this._configs.paginator.value= oPaginator;
                     }
-                }
-
-                // Links are enabled
-                if(oPaginator.pageLinks > -1) {
-                    var aLinkEls = oPaginator.links;
-                    // No links containers found, create from scratch
-                    if(aLinkEls.length === 0) {
+                    else {
+                        // Show each container
                         for(i=0; i<aContainerEls.length; i++) {
-                            // Create one links container per Paginator container
-                            var linkEl = document.createElement("span");
-                            linkEl.id = "yui-dt-pagselect"+i;
-                            linkEl = aContainerEls[i].appendChild(linkEl);
+                            aContainerEls[i].style.display = "";
+                        }
+                    }
 
-                            // Add event listener
-                            //TODO: anon fnc
-                            YAHOO.util.Event.addListener(linkEl,"click",this._onPaginatorLinkClick,this);
+                    // Links are enabled
+                    if(oPaginator.pageLinks > -1) {
+                        var aLinkEls = oPaginator.links;
+                        // No links containers found, create from scratch
+                        if(aLinkEls.length === 0) {
+                            for(i=0; i<aContainerEls.length; i++) {
+                                // Create one links container per Paginator container
+                                var linkEl = document.createElement("span");
+                                linkEl.id = "yui-dt-pagselect"+i;
+                                linkEl = aContainerEls[i].appendChild(linkEl);
 
-                             // Add directly to tracker
-                            this._configs.paginator.value.links.push(linkEl);
+                                // Add event listener
+                                //TODO: anon fnc
+                                Ev.addListener(linkEl,"click",this._onPaginatorLinkClick,this);
+
+                                 // Add directly to tracker
+                                this._configs.paginator.value.links.push(linkEl);
+                           }
                        }
-                   }
-                }
+                    }
 
-                // Show these options in the dropdown
-                var dropdownOptions = oPaginator.dropdownOptions || [];
+                    for(i=0; i<aContainerEls.length; i++) {
+                        // Create one SELECT element per Paginator container
+                        var selectEl = document.createElement("select");
+                        Dom.addClass(selectEl, DT.CLASS_DROPDOWN);
+                        selectEl = aContainerEls[i].appendChild(selectEl);
+                        selectEl.id = "yui-dt-pagselect"+i;
 
-                for(i=0; i<aContainerEls.length; i++) {
-                    // Create one SELECT element per Paginator container
-                    var selectEl = document.createElement("select");
-                    YAHOO.util.Dom.addClass(selectEl, YAHOO.widget.DataTable.CLASS_DROPDOWN);
-                    selectEl = aContainerEls[i].appendChild(selectEl);
-                    selectEl.id = "yui-dt-pagselect"+i;
+                        // Add event listener
+                        //TODO: anon fnc
+                        Ev.addListener(selectEl,"change",this._onPaginatorDropdownChange,this);
 
-                    // Add event listener
-                    //TODO: anon fnc
-                    YAHOO.util.Event.addListener(selectEl,"change",this._onPaginatorDropdownChange,this);
+                        // Add DOM reference directly to tracker
+                       this._configs.paginator.value.dropdowns.push(selectEl);
 
-                    // Add DOM reference directly to tracker
-                   this._configs.paginator.value.dropdowns.push(selectEl);
+                        // Hide dropdown
+                        if(!oPaginator.dropdownOptions) {
+                            selectEl.style.display = "none";
+                        }
+                    }
 
-                    // Hide dropdown
-                    if(!oPaginator.dropdownOptions) {
-                        selectEl.style.display = "none";
-                    }
+                    //TODO: fire paginatorDisabledEvent & add to api doc
                 }
+                // Pagination is disabled
+                else {
+                    // Containers found
+                    if(aContainerEls.length > 0) {
+                        // Destroy or just hide?
 
-                //TODO: fire paginatorDisabledEvent & add to api doc
-            }
-            // Pagination is disabled
-            else {
-                // Containers found
-                if(aContainerEls.length > 0) {
-                    // Destroy or just hide?
-                    
-                    // Hide each container
-                    for(i=0; i<aContainerEls.length; i++) {
-                        aContainerEls[i].style.display = "none";
-                    }
+                        // Hide each container
+                        for(i=0; i<aContainerEls.length; i++) {
+                            aContainerEls[i].style.display = "none";
+                        }
 
-                    /*TODO?
-                    // Destroy each container
-                    for(i=0; i<aContainerEls.length; i++) {
-                        YAHOO.util.Event.purgeElement(aContainerEls[i], true);
-                        aContainerEls.innerHTML = null;
-                        //TODO: remove container?
-                        // aContainerEls[i].parentNode.removeChild(aContainerEls[i]);
+                        /*TODO?
+                        // Destroy each container
+                        for(i=0; i<aContainerEls.length; i++) {
+                            Ev.purgeElement(aContainerEls[i], true);
+                            aContainerEls.innerHTML = null;
+                            //TODO: remove container?
+                            // aContainerEls[i].parentNode.removeChild(aContainerEls[i]);
+                        }
+                        */
                     }
-                    */
+                    //TODO: fire paginatorDisabledEvent & add to api doc
                 }
-                //TODO: fire paginatorDisabledEvent & add to api doc
             }
         }
     });
 
     /**
+     * @attribute paginationEventHandler
+     * @description For use with Pag pagination.  A
+     * handler function that receives the requestChange event from the
+     * configured paginator.  The handler method will be passed these
+     * parameters:
+     * <ol>
+     * <li>oState {Object} - an object literal describing the requested
+     * pagination state</li>
+     * <li>oSelf {DataTable} - The DataTable instance.</li>
+     * </ol>
+     * 
+     * For pagination through dynamic or server side data, assign
+     * DT.handleDataSourcePagination or your own custom
+     * handler.
+     * @type {function|Object}
+     * @default DT.handleSimplePagination
+     */
+    this.setAttributeConfig("paginationEventHandler", {
+        value     : DT.handleSimplePagination,
+        validator : lang.isObject
+    });
+
+    /**
     * @attribute caption
     * @description Value for the CAPTION element.
     * @type String
     */
     this.setAttributeConfig("caption", {
         value: null,
-        validator: YAHOO.lang.isString,
+        validator: lang.isString,
         method: function(sCaption) {
             // Create CAPTION element
             if(!this._elCaption) {
-                if(!this._elTable.firstChild) {
-                    this._elCaption = this._elTable.appendChild(document.createElement("caption"));
-                }
-                else {
-                    this._elCaption = this._elTable.insertBefore(document.createElement("caption"), this._elTable.firstChild);
-                }
+                var bodyTable = this._elTbodyContainer.getElementsByTagName('table')[0];
+                
+                this._elCaption = bodyTable.createCaption();
             }
             // Set CAPTION value
             this._elCaption.innerHTML = sCaption;
@@ -426,467 +6172,237 @@
 
     /**
     * @attribute scrollable
-    * @description True if primary TBODY should scroll while THEAD remains fixed.
-    * When enabling this feature, captions cannot be used, and the following
-    * features are not recommended: inline editing, resizeable columns.
+    * @description True if primary TBODY should scroll.
     * @default false
     * @type Boolean
     */
     this.setAttributeConfig("scrollable", {
         value: false,
         validator: function(oParam) {
-            //TODO: validate agnst resizeable
-            return (YAHOO.lang.isBoolean(oParam) &&
-                    // Not compatible with caption
-                    !YAHOO.lang.isString(this.get("caption")));
+            return (lang.isBoolean(oParam));
         },
         method: function(oParam) {
+            var headTable = this._elTheadContainer.getElementsByTagName('table')[0],
+                bodyTable = this._elTbodyContainer.getElementsByTagName('table')[0],
+                headThead = headTable.getElementsByTagName('thead')[0],
+                bodyThead = bodyTable.getElementsByTagName('thead')[0];
+
             if(oParam) {
-                //TODO: conf height
-                YAHOO.util.Dom.addClass(this._elContainer,YAHOO.widget.DataTable.CLASS_SCROLLABLE);
-                YAHOO.util.Dom.addClass(this._elTbody,YAHOO.widget.DataTable.CLASS_SCROLLBODY);
+                if (headThead) {
+                    headTable.removeChild(headThead);
+                }
+                if (bodyThead) {
+                    bodyTable.removeChild(bodyThead);
+                }
+                headTable.appendChild(this._elThead);
+                bodyTable.insertBefore(this._elA11yThead,bodyTable.firstChild || null);
+
+                // Move the caption from the body table to the head table
+                // if there is a caption
+                if (bodyTable.caption) {
+                    headTable.insertBefore(bodyTable.caption,headTable.firstChild);
+                }
+
+                Dom.addClass(this._elContainer,DT.CLASS_SCROLLABLE);
+
+                // Bug 1716354 - fix gap in Safari 2 and 3 (also seen in
+                // other browsers)
+                bodyTable.style.marginTop = "-"+this._elTbody.offsetTop+"px";
+
+                this._syncColWidths();
+                this._syncScrollPadding();
             }
             else {
-                YAHOO.util.Dom.removeClass(this._elContainer,YAHOO.widget.DataTable.CLASS_SCROLLABLE);
-                YAHOO.util.Dom.removeClass(this._elTbody,YAHOO.widget.DataTable.CLASS_SCROLLBODY);
+                if (headThead) {
+                    headTable.removeChild(headThead);
+                }
+                if (bodyThead) {
+                    bodyTable.removeChild(bodyThead);
+                }
+                headTable.appendChild(this._elA11yThead);
+                bodyTable.insertBefore(this._elThead,bodyTable.firstChild || null);
+                bodyTable.style.marginTop = '';
 
+                // Move the caption from the head table to the body table
+                // if there is a caption
+                if (headTable.caption) {
+                    bodyTable.insertBefore(headTable.caption,bodyTable.firstChild);
+                }
+
+                Dom.removeClass(this._elContainer,DT.CLASS_SCROLLABLE);
             }
         }
     });
-};
 
+    /**
+    * @attribute width
+    * @description Table width for scrollable tables
+    * @type String
+    */
+    this.setAttributeConfig("width", {
+        value: null,
+        validator: lang.isString,
+        method: function(oParam) {
+            if(this.get("scrollable")) {
+                this._elTheadContainer.style.width = oParam;
+                this._elTbodyContainer.style.width = oParam;            
+            }
+        }
+    });
+
+    /**
+    * @attribute height
+    * @description Table height for scrollable tables
+    * @type String
+    */
+    this.setAttributeConfig("height", {
+        value: null,
+        validator: lang.isString,
+        method: function(oParam) {
+            if(this.get("scrollable")) {
+                this._elTbodyContainer.style.height = oParam;  
+            }          
+        }
+    });
+
+    /**
+    * @attribute draggableColumns
+    * @description True if Columns are draggable to reorder, false otherwise.
+    * The Drag & Drop Utility is required to enable this feature. Only top-level
+    * and non-nested Columns are draggable. Write once.
+    * @default false
+    * @type Boolean
+    */
+    this.setAttributeConfig("draggableColumns", {
+        value: false,
+        validator: lang.isBoolean,
+        writeOnce: true
+    });
+
+    /**
+     * @attribute renderLoopSize 	 
+     * @description A value greater than 0 enables DOM rendering of rows to be
+     * executed from a non-blocking timeout queue and sets how many rows to be
+     * rendered per timeout. Recommended for very large data sets.     
+     * @type Number 	 
+     * @default 0 	 
+     */ 	 
+     this.setAttributeConfig("renderLoopSize", { 	 
+         value: 0, 	 
+         validator: lang.isNumber 	 
+     }); 	 
+},
+
 /////////////////////////////////////////////////////////////////////////////
 //
-// Public constants
+// Private member variables
 //
 /////////////////////////////////////////////////////////////////////////////
 
 /**
- * Class name assigned to TABLE element.
+ * True if instance is initialized, so as to fire the initEvent rather than
+ * renderEvent.
  *
- * @property DataTable.CLASS_TABLE
- * @type String
- * @static
- * @final
- * @default "yui-dt-table"
+ * @property _bInit
+ * @type Boolean
+ * @default true
+ * @private
  */
-YAHOO.widget.DataTable.CLASS_TABLE = "yui-dt-table";
+_bInit : true,
 
 /**
- * Class name assigned to header container elements within each TH element.
+ * Index assigned to instance.
  *
- * @property DataTable.CLASS_HEADER
- * @type String
- * @static
- * @final
- * @default "yui-dt-header"
+ * @property _nIndex
+ * @type Number
+ * @private
  */
-YAHOO.widget.DataTable.CLASS_HEADER = "yui-dt-header";
+_nIndex : null,
 
 /**
- * Class name assigned to the primary TBODY element.
+ * Counter for IDs assigned to TR elements.
  *
- * @property DataTable.CLASS_BODY
- * @type String
- * @static
- * @final
- * @default "yui-dt-body"
+ * @property _nTrCount
+ * @type Number
+ * @private
  */
-YAHOO.widget.DataTable.CLASS_BODY = "yui-dt-body";
+_nTrCount : 0,
 
 /**
- * Class name assigned to the scrolling TBODY element of a fixed scrolling DataTable.
+ * Counter for IDs assigned to TD elements.
  *
- * @property DataTable.CLASS_SCROLLBODY
- * @type String
- * @static
- * @final
- * @default "yui-dt-scrollbody"
+ * @property _nTdCount
+ * @type Number
+ * @private
  */
-YAHOO.widget.DataTable.CLASS_SCROLLBODY = "yui-dt-scrollbody";
+_nTdCount : 0,
 
 /**
- * Class name assigned to display label elements.
+ * Unique id assigned to instance "yui-dtN", useful prefix for generating unique
+ * DOM ID strings and log messages.
  *
- * @property DataTable.CLASS_LABEL
+ * @property _sId
  * @type String
- * @static
- * @final
- * @default "yui-dt-label"
+ * @private
  */
-YAHOO.widget.DataTable.CLASS_LABEL = "yui-dt-label";
+_sId : null,
 
 /**
- * Class name assigned to resizer handle elements.
+ * Render chain.
  *
- * @property DataTable.CLASS_RESIZER
- * @type String
- * @static
- * @final
- * @default "yui-dt-resizer"
+ * @property _oChainRender
+ * @type YAHOO.util.Chain
+ * @private
  */
-YAHOO.widget.DataTable.CLASS_RESIZER = "yui-dt-resizer";
+_oChainRender : null,
 
 /**
- * Class name assigned to Editor container elements.
+ * Sync chain.
  *
- * @property DataTable.CLASS_EDITOR
- * @type String
- * @static
- * @final
- * @default "yui-dt-editor"
- */
-YAHOO.widget.DataTable.CLASS_EDITOR = "yui-dt-editor";
-
-/**
- * Class name assigned to paginator container elements.
- *
- * @property DataTable.CLASS_PAGINATOR
- * @type String
- * @static
- * @final
- * @default "yui-dt-paginator"
- */
-YAHOO.widget.DataTable.CLASS_PAGINATOR = "yui-dt-paginator";
-
-/**
- * Class name assigned to page number indicators.
- *
- * @property DataTable.CLASS_PAGE
- * @type String
- * @static
- * @final
- * @default "yui-dt-page"
- */
-YAHOO.widget.DataTable.CLASS_PAGE = "yui-dt-page";
-
-/**
- * Class name assigned to default indicators.
- *
- * @property DataTable.CLASS_DEFAULT
- * @type String
- * @static
- * @final
- * @default "yui-dt-default"
- */
-YAHOO.widget.DataTable.CLASS_DEFAULT = "yui-dt-default";
-
-/**
- * Class name assigned to previous indicators.
- *
- * @property DataTable.CLASS_PREVIOUS
- * @type String
- * @static
- * @final
- * @default "yui-dt-previous"
- */
-YAHOO.widget.DataTable.CLASS_PREVIOUS = "yui-dt-previous";
-
-/**
- * Class name assigned next indicators.
- *
- * @property DataTable.CLASS_NEXT
- * @type String
- * @static
- * @final
- * @default "yui-dt-next"
- */
-YAHOO.widget.DataTable.CLASS_NEXT = "yui-dt-next";
-
-/**
- * Class name assigned to first elements.
- *
- * @property DataTable.CLASS_FIRST
- * @type String
- * @static
- * @final
- * @default "yui-dt-first"
- */
-YAHOO.widget.DataTable.CLASS_FIRST = "yui-dt-first";
-
-/**
- * Class name assigned to last elements.
- *
- * @property DataTable.CLASS_LAST
- * @type String
- * @static
- * @final
- * @default "yui-dt-last"
- */
-YAHOO.widget.DataTable.CLASS_LAST = "yui-dt-last";
-
-/**
- * Class name assigned to even elements.
- *
- * @property DataTable.CLASS_EVEN
- * @type String
- * @static
- * @final
- * @default "yui-dt-even"
- */
-YAHOO.widget.DataTable.CLASS_EVEN = "yui-dt-even";
-
-/**
- * Class name assigned to odd elements.
- *
- * @property DataTable.CLASS_ODD
- * @type String
- * @static
- * @final
- * @default "yui-dt-odd"
- */
-YAHOO.widget.DataTable.CLASS_ODD = "yui-dt-odd";
-
-/**
- * Class name assigned to selected elements.
- *
- * @property DataTable.CLASS_SELECTED
- * @type String
- * @static
- * @final
- * @default "yui-dt-selected"
- */
-YAHOO.widget.DataTable.CLASS_SELECTED = "yui-dt-selected";
-
-/**
- * Class name assigned to highlighted elements.
- *
- * @property DataTable.CLASS_HIGHLIGHTED
- * @type String
- * @static
- * @final
- * @default "yui-dt-highlighted"
- */
-YAHOO.widget.DataTable.CLASS_HIGHLIGHTED = "yui-dt-highlighted";
-
-/**
- * Class name assigned to disabled elements.
- *
- * @property DataTable.CLASS_DISABLED
- * @type String
- * @static
- * @final
- * @default "yui-dt-disabled"
- */
-YAHOO.widget.DataTable.CLASS_DISABLED = "yui-dt-disabled";
-
-/**
- * Class name assigned to empty indicators.
- *
- * @property DataTable.CLASS_EMPTY
- * @type String
- * @static
- * @final
- * @default "yui-dt-empty"
- */
-YAHOO.widget.DataTable.CLASS_EMPTY = "yui-dt-empty";
-
-/**
- * Class name assigned to loading indicatorx.
- *
- * @property DataTable.CLASS_LOADING
- * @type String
- * @static
- * @final
- * @default "yui-dt-loading"
- */
-YAHOO.widget.DataTable.CLASS_LOADING = "yui-dt-loading";
-
-/**
- * Class name assigned to error indicators.
- *
- * @property DataTable.CLASS_ERROR
- * @type String
- * @static
- * @final
- * @default "yui-dt-error"
- */
-YAHOO.widget.DataTable.CLASS_ERROR = "yui-dt-error";
-
-/**
- * Class name assigned to editable elements.
- *
- * @property DataTable.CLASS_EDITABLE
- * @type String
- * @static
- * @final
- * @default "yui-dt-editable"
- */
-YAHOO.widget.DataTable.CLASS_EDITABLE = "yui-dt-editable";
-
-/**
- * Class name assigned to scrollable elements.
- *
- * @property DataTable.CLASS_SCROLLABLE
- * @type String
- * @static
- * @final
- * @default "yui-dt-scrollable"
- */
-YAHOO.widget.DataTable.CLASS_SCROLLABLE = "yui-dt-scrollable";
-
-/**
- * Class name assigned to sortable elements.
- *
- * @property DataTable.CLASS_SORTABLE
- * @type String
- * @static
- * @final
- * @default "yui-dt-sortable"
- */
-YAHOO.widget.DataTable.CLASS_SORTABLE = "yui-dt-sortable";
-
-/**
- * Class name assigned to ascending elements.
- *
- * @property DataTable.CLASS_ASC
- * @type String
- * @static
- * @final
- * @default "yui-dt-asc"
- */
-YAHOO.widget.DataTable.CLASS_ASC = "yui-dt-asc";
-
-/**
- * Class name assigned to descending elements.
- *
- * @property DataTable.CLASS_DESC
- * @type String
- * @static
- * @final
- * @default "yui-dt-desc"
- */
-YAHOO.widget.DataTable.CLASS_DESC = "yui-dt-desc";
-
-/**
- * Class name assigned to BUTTON elements and/or container elements.
- *
- * @property DataTable.CLASS_BUTTON
- * @type String
- * @static
- * @final
- * @default "yui-dt-button"
- */
-YAHOO.widget.DataTable.CLASS_BUTTON = "yui-dt-button";
-
-/**
- * Class name assigned to INPUT TYPE=CHECKBOX elements and/or container elements.
- *
- * @property DataTable.CLASS_CHECKBOX
- * @type String
- * @static
- * @final
- * @default "yui-dt-checkbox"
- */
-YAHOO.widget.DataTable.CLASS_CHECKBOX = "yui-dt-checkbox";
-
-/**
- * Class name assigned to SELECT elements and/or container elements.
- *
- * @property DataTable.CLASS_DROPDOWN
- * @type String
- * @static
- * @final
- * @default "yui-dt-dropdown"
- */
-YAHOO.widget.DataTable.CLASS_DROPDOWN = "yui-dt-dropdown";
-
-/**
- * Class name assigned to INPUT TYPE=RADIO elements and/or container elements.
- *
- * @property DataTable.CLASS_RADIO
- * @type String
- * @static
- * @final
- * @default "yui-dt-radio"
- */
-YAHOO.widget.DataTable.CLASS_RADIO = "yui-dt-radio";
-
-/**
- * Message to display if DataTable has no data.
- *
- * @property DataTable.MSG_EMPTY
- * @type String
- * @static
- * @final
- * @default "No records found."
- */
-YAHOO.widget.DataTable.MSG_EMPTY = "No records found.";
-
-/**
- * Message to display while DataTable is loading data.
- *
- * @property DataTable.MSG_LOADING
- * @type String
- * @static
- * @final
- * @default "Loading data..."
- */
-YAHOO.widget.DataTable.MSG_LOADING = "Loading data...";
-
-/**
- * Message to display while DataTable has data error.
- *
- * @property DataTable.MSG_ERROR
- * @type String
- * @static
- * @final
- * @default "Data error."
- */
-YAHOO.widget.DataTable.MSG_ERROR = "Data error.";
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Private member variables
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Internal class variable for indexing multiple DataTable instances.
- *
- * @property DataTable._nCount
- * @type Number
+ * @property _oChainSync
+ * @type YAHOO.util.Chain
  * @private
- * @static
  */
-YAHOO.widget.DataTable._nCount = 0;
+_oChainSync : null,
 
 /**
- * Index assigned to instance.
+ * Sparse array of custom functions to set column widths for browsers that don't
+ * support dynamic CSS rules.  Functions are added at the index representing
+ * the number of rows they update.
  *
- * @property _nIndex
- * @type Number
+ * @property _aFallbackColResizer
+ * @type Array
  * @private
  */
-YAHOO.widget.DataTable.prototype._nIndex = null;
+_aFallbackColResizer : [],
 
 /**
- * Counter for IDs assigned to TR elements.
+ * DOM reference to the container element for the DataTable instance into which
+ * all other elements get created.
  *
- * @property _nTrCount
- * @type Number
+ * @property _elContainer
+ * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._nTrCount = 0;
+_elContainer : null,
 
 /**
- * Unique name assigned to instance.
+ * DOM reference to the container element for the DataTable's primary THEAD.
  *
- * @property _sName
- * @type String
+ * @property _elTheadContainer
+ * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._sName = null;
+_elTheadContainer : null,
 
 /**
- * DOM reference to the container element for the DataTable instance into which
- * the TABLE element gets created.
+ * DOM reference to the container element for the DataTable's primary TBODY.
  *
- * @property _elContainer
+ * @property _elTbodyContainer
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elContainer = null;
+_elTbodyContainer : null,
 
 /**
  * DOM reference to the CAPTION element for the DataTable instance.
@@ -895,25 +6411,16 @@
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elCaption = null;
+_elCaption : null,
 
 /**
- * DOM reference to the TABLE element for the DataTable instance.
+ * DOM reference to the primary THEAD element for the DataTable instance.
  *
- * @property _elTable
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.DataTable.prototype._elTable = null;
-
-/**
- * DOM reference to the THEAD element for the DataTable instance.
- *
  * @property _elThead
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elThead = null;
+_elThead : null,
 
 /**
  * DOM reference to the primary TBODY element for the DataTable instance.
@@ -922,7 +6429,7 @@
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elTbody = null;
+_elTbody : null,
 
 /**
  * DOM reference to the secondary TBODY element used to display DataTable messages.
@@ -931,7 +6438,7 @@
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elMsgTbody = null;
+_elMsgTbody : null,
 
 /**
  * DOM reference to the secondary TBODY element's single TR element used to display DataTable messages.
@@ -940,7 +6447,7 @@
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elMsgTbodyRow = null;
+_elMsgTbodyRow : null,
 
 /**
  * DOM reference to the secondary TBODY element's single TD element used to display DataTable messages.
@@ -949,7 +6456,7 @@
  * @type HTMLElement
  * @private
  */
-YAHOO.widget.DataTable.prototype._elMsgTbodyCell = null;
+_elMsgTbodyCell : null,
 
 /**
  * DataSource instance for the DataTable instance.
@@ -958,7 +6465,7 @@
  * @type YAHOO.util.DataSource
  * @private
  */
-YAHOO.widget.DataTable.prototype._oDataSource = null;
+_oDataSource : null,
 
 /**
  * ColumnSet instance for the DataTable instance.
@@ -967,7 +6474,7 @@
  * @type YAHOO.widget.ColumnSet
  * @private
  */
-YAHOO.widget.DataTable.prototype._oColumnSet = null;
+_oColumnSet : null,
 
 /**
  * RecordSet instance for the DataTable instance.
@@ -976,26 +6483,16 @@
  * @type YAHOO.widget.RecordSet
  * @private
  */
-YAHOO.widget.DataTable.prototype._oRecordSet = null;
+_oRecordSet : null,
 
 /**
- * ID string of first label link element of the current DataTable page, if any.
- * Used for focusing sortable Columns with TAB.
- *
- * @property _sFirstLabelLinkId
- * @type String
- * @private
- */
-YAHOO.widget.DataTable.prototype._sFirstLabelLinkId = null;
-
-/**
  * ID string of first TR element of the current DataTable page.
  *
  * @property _sFirstTrId
  * @type String
  * @private
  */
-YAHOO.widget.DataTable.prototype._sFirstTrId = null;
+_sFirstTrId : null,
 
 /**
  * ID string of the last TR element of the current DataTable page.
@@ -1004,10 +6501,31 @@
  * @type String
  * @private
  */
-YAHOO.widget.DataTable.prototype._sLastTrId = null;
+_sLastTrId : null,
 
+/**
+ * Template cell to create all new cells from.
+ * @property _tdElTemplate
+ * @type {HTMLElement}
+ * @private 
+ */
+_tdElTemplate : null,
 
+/**
+ * Template row to create all new rows from.
+ * @property _trElTemplate
+ * @type {HTMLElement}
+ * @private 
+ */
+_trElTemplate : null,
 
+/**
+ * True if x-scrollbar is currently visible.
+ * @property _bScrollbarX
+ * @type {Boolean}
+ * @private 
+ */
+_bScrollbarX : null,
 
 
 
@@ -1035,8 +6553,6 @@
 
 
 
-
-
 /////////////////////////////////////////////////////////////////////////////
 //
 // Private methods
@@ -1044,40 +6560,348 @@
 /////////////////////////////////////////////////////////////////////////////
 
 /**
+ * Clears browser text selection. Useful to call on rowSelectEvent or
+ * cellSelectEvent to prevent clicks or dblclicks from selecting text in the
+ * browser.
+ *
+ * @method clearTextSelection
+ */
+clearTextSelection : function() {
+    var sel;
+    if(window.getSelection) {
+    	sel = window.getSelection();
+    }
+    else if(document.getSelection) {
+    	sel = document.getSelection();
+    }
+    else if(document.selection) {
+    	sel = document.selection;
+    }
+    if(sel) {
+        if(sel.empty) {
+            sel.empty();
+        }
+        else if (sel.removeAllRanges) {
+            sel.removeAllRanges();
+        }
+        else if(sel.collapse) {
+            sel.collapse();
+        }
+    }
+},
+
+/**
  * Sets focus on the given element.
  *
  * @method _focusEl
  * @param el {HTMLElement} Element.
  * @private
  */
-YAHOO.widget.DataTable.prototype._focusEl = function(el) {
-    el = el || this._elTable;
+_focusEl : function(el) {
+    el = el || this._elTbody;
     // http://developer.mozilla.org/en/docs/index.php?title=Key-navigable_custom_DHTML_widgets
     // The timeout is necessary in both IE and Firefox 1.5, to prevent scripts from doing
     // strange unexpected things as the user clicks on buttons and other controls.
-    setTimeout(function() { el.focus(); },0);
-};
+    setTimeout(function() {
+        try {
+            el.focus();
+        }
+        catch(e) {
+        }
+    },0);
+},
 
+/**
+ * Post render syncing of Column widths and scroll padding
+ *
+ * @method _sync
+ * @private
+ */
+_sync : function() {
+    this._syncColWidths();
+    this._forceGeckoRedraw();
+},
 
+/**
+ * Syncs up widths of THs and TDs across all those Columns without width values.
+ * Actual adjustment is to the liner DIVs so window resizing will not affect cells. 
+ *
+ * @method _syncColWidths
+ * @private
+ */
+_syncColWidths : function() {
+    if(!this.get('scrollable')) {
+        return;
+    }
 
+    if(this._elTbody.rows.length > 0) {
+        // Validate there is at least one row with cells and at least one Column
+        var allKeys = this._oColumnSet.keys,
+            elRow = this.getFirstTrEl();
+    
+        if(allKeys && elRow && (elRow.cells.length === allKeys.length)) {
+            // Temporarily unsnap container since it causes inaccurate calculations
+            var bUnsnap = false;
+            if((YAHOO.env.ua.gecko || YAHOO.env.ua.opera) && this.get("scrollable")) {
+                bUnsnap = true;
+                if(this.get("width")) {
+                    this._elTheadContainer.style.width = "";
+                    this._elTbodyContainer.style.width = "";
+                }
+                else {
+                    this._elContainer.style.width = "";
+                }
+            }
+    
+            var i,
+                oColumn,
+                cellsLen = elRow.cells.length;
+            // First time through, reset the widths to get an accurate measure of the TD
+            for(i=0; i<cellsLen; i++) {
+                oColumn = allKeys[i];
+                // Only for Columns without widths
+                if(!oColumn.width) {
+                    this._setColumnWidth(oColumn, "auto");
+                }
+            }
+    
+            // Calculate width for every Column
+            for(i=0; i<cellsLen; i++) {
+                oColumn = allKeys[i];
+                var newWidth;
+                
+                // Columns without widths
+                if(!oColumn.width) {
+                    var elTh = oColumn.getThEl();
+                    var elTd = elRow.cells[i];
+                    
+                    if(elTh.offsetWidth !== elTd.offsetWidth) {
+                        var elWider = (elTh.offsetWidth > elTd.offsetWidth) ? elTh.firstChild : elTd.firstChild;               
+                        // Calculate the final width by comparing liner widths
+                        newWidth = elWider.offsetWidth -
+                                (parseInt(Dom.getStyle(elWider,"paddingLeft"),10)|0) -
+                                (parseInt(Dom.getStyle(elWider,"paddingRight"),10)|0);
+                        
+                        // Validate against minWidth        
+                        newWidth = (oColumn.minWidth && (oColumn.minWidth > newWidth)) ?
+                                oColumn.minWidth : newWidth;
+                
+                    }
+                }
+                // Columns with widths
+                else {
+                    newWidth = oColumn.width;
+                }
+                
+                // Hidden Columns
+                if(oColumn.hidden) {
+                    oColumn._nLastWidth = newWidth;
+                    newWidth = 1;
+                }
+                
+                // Update to the new width
+                if(newWidth) {
+                    this._setColumnWidth(oColumn, newWidth+"px"); 
+                }
+            }
+            
+            // Resnap unsnapped containers
+            if(bUnsnap) {
+                var sWidth = this.get("width");
+                this._elTheadContainer.style.width = sWidth;
+                this._elTbodyContainer.style.width = sWidth;     
+            } 
+        }
+    }
 
+    this._syncScrollPadding();
+},
 
+/**
+ * Syncs padding around scrollable tables, including Column header right-padding
+ * and container width and height.
+ *
+ * @method _syncScrollPadding
+ * @private
+ */
+_syncScrollPadding : function() {
+    // Proceed only if scrollable is enabled
+    if(this.get("scrollable")) {
+        var elTbody = this._elTbody,
+            elTbodyContainer = this._elTbodyContainer,
+            aLastHeaders, len, prefix, i, elLiner;
+        
+        // IE 6 and 7 only when y-scrolling not enabled
+        if(!this.get("height") && (ua.ie)) {
+            // Snap outer container height to content
+            // but account for x-scrollbar if it is visible
+            if(elTbody.rows.length > 0) {
+                elTbodyContainer.style.height = 
+                        (elTbodyContainer.scrollWidth > elTbodyContainer.offsetWidth) ?
+                        (elTbody.offsetHeight + 19) + "px" : 
+                        elTbody.offsetHeight + "px";
+            }
+            else {
+                elTbodyContainer.style.height = 
+                        (elTbodyContainer.scrollWidth > elTbodyContainer.offsetWidth) ?
+                        (this._elMsgTbody.offsetHeight + 19) + "px" : 
+                        this._elMsgTbody.offsetHeight + "px";
+            }
+        }
+
+        // X-scrolling not enabled
+        if(!this.get("width")) {
+            // Snap outer container width to content
+            // but account for y-scrollbar if it is visible
+            this._elContainer.style.width = 
+                    (elTbodyContainer.scrollHeight > elTbodyContainer.offsetHeight) ?
+                    (elTbody.parentNode.offsetWidth + 19) + "px" :
+                    //TODO: Can we detect left and right border widths instead of hard coding?
+                    (elTbody.parentNode.offsetWidth + 2) + "px";
+        }
+        // X-scrolling is enabled and x-scrollbar is visible
+        else if((elTbodyContainer.scrollWidth > elTbodyContainer.offsetWidth) ||
+            ((elTbodyContainer.scrollHeight > elTbodyContainer.offsetHeight) && (elTbodyContainer.scrollWidth > elTbodyContainer.offsetWidth-16))) {
+            // Perform sync routine
+            if(!this._bScrollbarX) {
+                // Add Column header right-padding
+                aLastHeaders = this._oColumnSet.headers[this._oColumnSet.headers.length-1];
+                len = aLastHeaders.length;
+                prefix = this._sId+"-th";
+                for(i=0; i<len; i++) {
+                    //TODO: A better way to get th cell
+                    elLiner = Dom.get(prefix+aLastHeaders[i]).firstChild;
+                    elLiner.style.marginRight = 
+                            (parseInt(Dom.getStyle(elLiner,"marginRight"),10) + 
+                            16) + "px";
+                }
+                
+                // Save state   
+                this._bScrollbarX = true;
+            }
+        }
+        // X-scrollbar enabled but x-scrollbar is not visible
+        else {
+            // Perform sync routine
+            if(this._bScrollbarX) {                 
+                // Remove Column header right-padding                   
+                aLastHeaders = this._oColumnSet.headers[this._oColumnSet.headers.length-1];
+                len = aLastHeaders.length;
+                prefix = this._sId+"-th";
+                for(i=0; i<len; i++) {
+                    //TODO: A better way to get th cell
+                    elLiner = Dom.get(prefix+aLastHeaders[i]).firstChild;
+                    Dom.setStyle(elLiner,"marginRight","");
+                }
+                                        
+                // Save state
+                this._bScrollbarX = false;
+            }
+        }
+    
+        // Sync message tbody
+        if(this._elTbody.rows.length === 0) {
+            this._elMsgTbody.parentNode.width = this.getTheadEl().parentNode.offsetWidth;
+        }
+        else {
+            this._elMsgTbody.parentNode.width = "";
+        }
+    }
+},
+
+/**
+ * Forces Gecko repaint by removing/adding the no-op class name
+ *
+ * @method _forceGeckoRedraw
+ * @private
+ */
+_forceGeckoRedraw : function() {
+    // Bug 1741322: Needed to force FF to redraw to fix squishy headers on wide tables when new content comes in
+    if(ua.gecko) {
+        var elContainer = this.getContainerEl();
+        setTimeout(function() {
+            Dom.removeClass(elContainer,"yui-dt-noop");
+        },0);
+        setTimeout(function() {
+            Dom.addClass(elContainer,"yui-dt-noop");
+        },0);
+    }
+},
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 // INIT FUNCTIONS
 
 /**
- * Initializes container element.
+ * Initializes the HTMLElement templates used to create various table child
+ * nodes.
+ * @method _initNodeTemplates
+ * @private
+ */
+_initNodeTemplates : function () {
+    var d   = document,
+        tr  = d.createElement('tr'),
+        td  = d.createElement('td'),
+        div = d.createElement('div');
+
+    // Append the liner element
+    td.appendChild(div);
+
+    this._tdElTemplate = td;
+    this._trElTemplate = tr;
+},
+
+/**
+ * Initializes the DataTable container element.
  *
  * @method _initContainerEl
  * @param elContainer {HTMLElement | String} HTML DIV element by reference or ID.
  * @private
  */
-YAHOO.widget.DataTable.prototype._initContainerEl = function(elContainer) {
-    this._elContainer = null;
-    elContainer = YAHOO.util.Dom.get(elContainer);
-    if(elContainer && elContainer.tagName && (elContainer.tagName.toLowerCase() == "div")) {
+_initContainerEl : function(elContainer) {
+    // Clear any previous container
+    if(this._elContainer) {
+        Ev.purgeElement(this._elContainer, true);
+        this._elContainer.innerHTML = "";
+    }
+
+    elContainer = Dom.get(elContainer);
+    if(elContainer && elContainer.nodeName && (elContainer.nodeName.toLowerCase() == "div")) {
+        // Esp for progressive enhancement
+        Ev.purgeElement(elContainer, true);
+        elContainer.innerHTML = "";
+
+        Dom.addClass(elContainer,"yui-dt yui-dt-noop");
+        
+        // Container for header TABLE
+        this._elTheadContainer = elContainer.appendChild(document.createElement("div"));
+        Dom.addClass(this._elTheadContainer, "yui-dt-hd");
+
+        // Container for body TABLE
+        this._elTbodyContainer = elContainer.appendChild(document.createElement("div"));
+        Dom.addClass(this._elTbodyContainer, "yui-dt-bd");
+
         this._elContainer = elContainer;
     }
-};
+},
 
 /**
  * Initializes object literal of config values.
@@ -1086,17 +6910,20 @@
  * @param oConfig {Object} Object literal of config values.
  * @private
  */
-YAHOO.widget.DataTable.prototype._initConfigs = function(oConfigs) {
+_initConfigs : function(oConfigs) {
     if(oConfigs) {
         if(oConfigs.constructor != Object) {
             oConfigs = null;
         }
         // Backward compatibility
-        else if(YAHOO.lang.isBoolean(oConfigs.paginator)) {
+        else if(lang.isBoolean(oConfigs.paginator)) {
         }
         this._oConfigs = oConfigs;
     }
-};
+    else {
+        this._oConfigs = {};
+    }
+},
 
 /**
  * Initializes ColumnSet.
@@ -1105,17 +6932,27 @@
  * @param aColumnDefs {Object[]} Array of object literal Column definitions.
  * @private
  */
-YAHOO.widget.DataTable.prototype._initColumnSet = function(aColumnDefs) {
-    this._oColumnSet = null;
-    if(YAHOO.lang.isArray(aColumnDefs)) {
+_initColumnSet : function(aColumnDefs) {
+    if(this._oColumnSet) {
+        // First clear _oStylesheetRules for existing ColumnSet
+        for(var i=0, l=this._oColumnSet.keys.length; i<l; i++) {
+            DT._oStylesheetRules[".yui-dt-col-"+this._oColumnSet.keys[i].getId()] = undefined;
+        }
+        
+        this._oColumnSet = null;
+    }
+    
+    if(lang.isArray(aColumnDefs)) {
         this._oColumnSet =  new YAHOO.widget.ColumnSet(aColumnDefs);
     }
     // Backward compatibility
     else if(aColumnDefs instanceof YAHOO.widget.ColumnSet) {
         this._oColumnSet =  aColumnDefs;
     }
-};
 
+
+},
+
 /**
  * Initializes DataSource.
  *
@@ -1123,9 +6960,9 @@
  * @param oDataSource {YAHOO.util.DataSource} DataSource instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._initDataSource = function(oDataSource) {
+_initDataSource : function(oDataSource) {
     this._oDataSource = null;
-    if(oDataSource && (oDataSource instanceof YAHOO.util.DataSource)) {
+    if(oDataSource && (oDataSource instanceof DS)) {
         this._oDataSource = oDataSource;
     }
     // Backward compatibility
@@ -1137,7 +6974,7 @@
         if(tmpContainer.hasChildNodes()) {
             var tmpChildren = tmpContainer.childNodes;
             for(i=0; i<tmpChildren.length; i++) {
-                if(tmpChildren[i].tagName && tmpChildren[i].tagName.toLowerCase() == "table") {
+                if(tmpChildren[i].nodeName && tmpChildren[i].nodeName.toLowerCase() == "table") {
                     tmpTable = tmpChildren[i];
                     break;
                 }
@@ -1148,13 +6985,13 @@
                     tmpFieldsArray.push({key:this._oColumnSet.keys[i].key});
                 }
 
-                this._oDataSource = new YAHOO.util.DataSource(tmpTable);
-                this._oDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
+                this._oDataSource = new DS(tmpTable);
+                this._oDataSource.responseType = DS.TYPE_HTMLTABLE;
                 this._oDataSource.responseSchema = {fields: tmpFieldsArray};
             }
         }
     }
-};
+},
 
 /**
  * Initializes RecordSet.
@@ -1162,14 +6999,14 @@
  * @method _initRecordSet
  * @private
  */
-YAHOO.widget.DataTable.prototype._initRecordSet = function() {
+_initRecordSet : function() {
     if(this._oRecordSet) {
         this._oRecordSet.reset();
     }
     else {
         this._oRecordSet = new YAHOO.widget.RecordSet();
     }
-};
+},
 
 /**
  * Creates HTML markup for TABLE, THEAD and TBODY elements.
@@ -1177,203 +7014,366 @@
  * @method _initTableEl
  * @private
  */
-YAHOO.widget.DataTable.prototype._initTableEl = function() {
-    // Clear the container
-    YAHOO.util.Event.purgeElement(this._elContainer, true);
-    this._elContainer.innerHTML = "";
+_initTableEl : function() {
+    var elTable;
 
+    // Destroy existing
+    if(this._elThead) {
+        var i;
+        // Destroy ColumnDDs
+        var aTree = this._oColumnSet.tree[0];
+        for(i=0; i<aTree.length; i++) {
+            if(aTree[i]._dd) {
+                aTree[i]._dd = aTree[i]._dd.unreg();
+            }
+        }
+    
+        // Destroy ColumnResizers
+        var aKeys = this._oColumnSet.keys;
+        for(i=0; i<aKeys.length; i++) {
+            if(aKeys[i]._ddResizer) {
+                aKeys[i]._ddResizer = aKeys[i]._ddResizer.unreg();
+            }
+        }
+        elTable = this._elThead.parentNode;
+        Ev.purgeElement(elTable, true);
+        elTable.parentNode.removeChild(elTable);
+        this._elThead = null;
+    }
+    if(this._elTbody) {
+        elTable = this._elTbody.parentNode;
+        Ev.purgeElement(elTable, true);
+        elTable.parentNode.removeChild(elTable);
+        this._elTbody = null;
+    }
+
+    // Create elements for header
     // Create TABLE
-    this._elTable = this._elContainer.appendChild(document.createElement("table"));
-    var elTable = this._elTable;
-    elTable.tabIndex = 0;
-    elTable.id = this.id + "-table";
-    YAHOO.util.Dom.addClass(elTable, YAHOO.widget.DataTable.CLASS_TABLE);
+    var elHeadTable = document.createElement("table");
+    elHeadTable.id = this._sId + "-headtable";
+    elHeadTable = this._elTheadContainer.appendChild(elHeadTable);
 
-    // Create THEAD
-    this._initTheadEl(elTable, this._oColumnSet);
+    // Create elements for body
+    // Create TABLE
+    var elBodyTable = document.createElement("table");
+    elBodyTable.id = this._sId + "-bodytable";
+    this._elTbodyContainer.appendChild(elBodyTable);
 
+    // Create THEAD for display and for a11y
+    this._initTheadEls();
 
+    // Create TBODY for data
+    this._elTbody = elBodyTable.appendChild(document.createElement("tbody"));
+    this._elTbody.tabIndex = 0;
+    Dom.addClass(this._elTbody,DT.CLASS_BODY);
+
     // Create TBODY for messages
     var elMsgTbody = document.createElement("tbody");
     var elMsgRow = elMsgTbody.appendChild(document.createElement("tr"));
-    YAHOO.util.Dom.addClass(elMsgRow,YAHOO.widget.DataTable.CLASS_FIRST);
-    YAHOO.util.Dom.addClass(elMsgRow,YAHOO.widget.DataTable.CLASS_LAST);
+    Dom.addClass(elMsgRow,DT.CLASS_FIRST);
+    Dom.addClass(elMsgRow,DT.CLASS_LAST);
     this._elMsgRow = elMsgRow;
     var elMsgCell = elMsgRow.appendChild(document.createElement("td"));
     elMsgCell.colSpan = this._oColumnSet.keys.length;
-    YAHOO.util.Dom.addClass(elMsgCell,YAHOO.widget.DataTable.CLASS_FIRST);
-    YAHOO.util.Dom.addClass(elMsgCell,YAHOO.widget.DataTable.CLASS_LAST);
+    Dom.addClass(elMsgCell,DT.CLASS_FIRST);
+    Dom.addClass(elMsgCell,DT.CLASS_LAST);
     this._elMsgTd = elMsgCell;
-    this._elMsgTbody = elTable.appendChild(elMsgTbody);
-    this.showTableMessage(YAHOO.widget.DataTable.MSG_LOADING, YAHOO.widget.DataTable.CLASS_LOADING);
+    this._elMsgTbody = elBodyTable.appendChild(elMsgTbody);
+    var elMsgCellLiner = elMsgCell.appendChild(document.createElement("div"));
+    Dom.addClass(elMsgCellLiner,DT.CLASS_LINER);
+    this.showTableMessage(DT.MSG_LOADING, DT.CLASS_LOADING);
 
-    // Create TBODY for data
-    this._elTbody = elTable.appendChild(document.createElement("tbody"));
-    YAHOO.util.Dom.addClass(this._elTbody,YAHOO.widget.DataTable.CLASS_BODY);
-};
+    var elContainer = this._elContainer;
+    var elThead = this._elThead;
+    var elTbody = this._elTbody;
+    
+    // IE puts focus outline in the wrong place
+    if(ua.ie) {
+        elTbody.hideFocus=true;
+    }
+    var elTbodyContainer = this._elTbodyContainer;
 
+    // Set up DOM events
+    Ev.addListener(elContainer, "focus", this._onTableFocus, this);
+    Ev.addListener(elTbody, "focus", this._onTbodyFocus, this);
+
+    Ev.addListener(elTbody, "mouseover", this._onTableMouseover, this);
+    Ev.addListener(elTbody, "mouseout", this._onTableMouseout, this);
+    Ev.addListener(elTbody, "mousedown", this._onTableMousedown, this);
+
+    Ev.addListener(elTbody, "keydown", this._onTbodyKeydown, this);
+
+    Ev.addListener(elTbody, "keypress", this._onTableKeypress, this);
+
+    // Since we can't listen for click and dblclick on the same element...
+    Ev.addListener(elTbody.parentNode, "dblclick", this._onTableDblclick, this);
+    Ev.addListener(elTbody, "click", this._onTbodyClick, this);
+
+    Ev.addListener(elTbodyContainer, "scroll", this._onScroll, this); // to sync horiz scroll headers
+},
+
 /**
- * Populates THEAD element with TH cells as defined by ColumnSet.
+ * Initializes THEAD elements for display and for screen readers.
  *
- * @method _initTheadEl
+ * @method _initTheadEls
  * @private
  */
-YAHOO.widget.DataTable.prototype._initTheadEl = function() {
-    var i,oColumn, colId;
-    var oColumnSet = this._oColumnSet;
-    this._sFirstLabelLinkId = null;
+_initTheadEls : function() {
+    var i,j, l, elThead, elA11yThead, aTheads;
     
-    // Create THEAD
-    var elThead = document.createElement("thead");
+    // First time through
+    if(!this._elThead) {
+        // Create THEADs
+        elThead     = this._elThead     = document.createElement('thead');
+        elA11yThead = this._elA11yThead = document.createElement('thead');
+        
+        aTheads = [elThead, elA11yThead];
 
-    // Iterate through each row of Column headers...
-    var colTree = oColumnSet.tree;
-    for(i=0; i<colTree.length; i++) {
-        var elTheadRow = elThead.appendChild(document.createElement("tr"));
-        elTheadRow.id = this.id+"-hdrow"+i;
-
-        var elTheadCell;
-        // ...and create THEAD cells
-        for(var j=0; j<colTree[i].length; j++) {
-            oColumn = colTree[i][j];
-            elTheadCell = elTheadRow.appendChild(document.createElement("th"));
-            elTheadCell.id = this.id+"-col" + oColumn.getId();
-            this._initThEl(elTheadCell,oColumn,i,j);
+        Ev.addListener(elThead, "focus", this._onTheadFocus, this);
+        Ev.addListener(elThead, "keydown", this._onTheadKeydown, this);
+        Ev.addListener(elThead, "mouseover", this._onTableMouseover, this);
+        Ev.addListener(elThead, "mouseout", this._onTableMouseout, this);
+        Ev.addListener(elThead, "mousedown", this._onTableMousedown, this);
+        Ev.addListener(elThead, "mouseup", this._onTableMouseup, this);
+        Ev.addListener(elThead, "click", this._onTheadClick, this);
+        Ev.addListener(elThead.parentNode, "dblclick", this._onTableDblclick, this);
+        
+        // Add the accessibility-only thead to the header table by default.
+        // The theads will be swapped for scrollable DataTables, the display
+        // thead fixed in place, and the a11y thead hidden
+        this._elTheadContainer.firstChild.appendChild(elA11yThead);
+        this._elTbodyContainer.firstChild.appendChild(elThead);
+    }
+    // Reinitialization
+    else {
+        // Clear rows from THEADs
+        elThead = this._elThead;
+        elA11yThead = this._elA11yThead;
+        aTheads = [elThead, elA11yThead];
+            
+        for(i=0; i<aTheads.length; i++) {
+            for(j=aTheads[i].rows.length-1; j>-1; j--) {
+                Ev.purgeElement(aTheads[i].rows[j], true);
+                aTheads[i].removeChild(aTheads[i].rows[j]);
+            }     
         }
-
-        // Set FIRST/LAST on THEAD rows
-        if(i === 0) {
-            YAHOO.util.Dom.addClass(elTheadRow, YAHOO.widget.DataTable.CLASS_FIRST);
-        }
-        if(i === (colTree.length-1)) {
-            YAHOO.util.Dom.addClass(elTheadRow, YAHOO.widget.DataTable.CLASS_LAST);
-        }
     }
 
-    this._elThead = this._elTable.appendChild(elThead);
+    
+    var oColumn,
+        oColumnSet = this._oColumnSet;
 
-    // Set FIRST/LAST on THEAD cells using the values in ColumnSet headers array
-    var aFirstHeaders = oColumnSet.headers[0];
-    var aLastHeaders = oColumnSet.headers[oColumnSet.headers.length-1];
-    for(i=0; i<aFirstHeaders.length; i++) {
-        YAHOO.util.Dom.addClass(YAHOO.util.Dom.get(this.id+"-col"+aFirstHeaders[i]), YAHOO.widget.DataTable.CLASS_FIRST);
-    }
-    for(i=0; i<aLastHeaders.length; i++) {
-        YAHOO.util.Dom.addClass(YAHOO.util.Dom.get(this.id+"-col"+aLastHeaders[i]), YAHOO.widget.DataTable.CLASS_LAST);
-    }
+    // Add TRs to the THEADs
+    var colTree = oColumnSet.tree;
+    var elTheadCell, id;
+    for(l=0; l<aTheads.length; l++) {
+        for(i=0; i<colTree.length; i++) {
+            var elTheadRow = aTheads[l].appendChild(document.createElement("tr"));
+            id = (l===1) ? this._sId+"-hdrow" + i + "-a11y": this._sId+"-hdrow" + i;
+            elTheadRow.id = id;
     
-    // Add Resizer only after DOM has been updated
-    var foundDD = (YAHOO.util.DD) ? true : false;
-    var needDD = false;
-    for(i=0; i<this._oColumnSet.keys.length; i++) {
-        oColumn = this._oColumnSet.keys[i];
-        var colKey = oColumn.getKey();
-        var elTheadCellId = YAHOO.util.Dom.get(this.id + "-col" + oColumn.getId());
-        if(oColumn.resizeable) {
-            if(foundDD) {
-                //TODO: fix fixed width tables
-                // Skip the last column for fixed-width tables
-                if(!this.fixedWidth || (this.fixedWidth &&
-                        (oColumn.getKeyIndex() != this._oColumnSet.keys.length-1))) {
-                    // TODO: better way to get elTheadContainer
-                    var elThContainer = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_HEADER,"div",elTheadCellId)[0];
-                    var elThResizer = elThContainer.appendChild(document.createElement("span"));
-                    elThResizer.id = this.id + "-resizer-" + colKey;
-                    YAHOO.util.Dom.addClass(elThResizer,YAHOO.widget.DataTable.CLASS_RESIZER);
-                    oColumn.ddResizer = new YAHOO.util.ColumnResizer(
-                            this, oColumn, elTheadCellId, elThResizer.id, elThResizer.id);
-                    var cancelClick = function(e) {
-                        YAHOO.util.Event.stopPropagation(e);
-                    };
-                    YAHOO.util.Event.addListener(elThResizer,"click",cancelClick);
+            // ...and create TH cells
+            for(j=0; j<colTree[i].length; j++) {
+                oColumn = colTree[i][j];
+                elTheadCell = elTheadRow.appendChild(document.createElement("th"));
+                if(l===0) {
+                    oColumn._elTh = elTheadCell;
                 }
-                if(this.fixedWidth) {
-                    //TODO: fix fixedWidth
-                    //elThContainer.style.overflow = "hidden";
-                    //TODO: better way to get elTheadText
-                    var elThLabel = (YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_LABEL,"span",elTheadCellId))[0];
-                    elThLabel.style.overflow = "hidden";
+                id = (l===1) ? this._sId+"-th" + oColumn.getId() + "-a11y": this._sId+"-th" + oColumn.getId();
+                elTheadCell.id = id;
+                elTheadCell.yuiCellIndex = j;
+                this._initThEl(elTheadCell,oColumn,i,j, (l===1));
+            }
+    
+            if(l===0) {
+                // Set FIRST/LAST on THEAD rows
+                if(i === 0) {
+                    Dom.addClass(elTheadRow, DT.CLASS_FIRST);
                 }
+                if(i === (colTree.length-1)) {
+                    Dom.addClass(elTheadRow, DT.CLASS_LAST);
+                }
             }
-            else {
-                needDD = true;
+        }
+
+        if(l===0) {
+            // Set FIRST/LAST on TH elements using the values in ColumnSet headers array
+            var aFirstHeaders = oColumnSet.headers[0];
+            var aLastHeaders = oColumnSet.headers[oColumnSet.headers.length-1];
+            for(i=0; i<aFirstHeaders.length; i++) {
+                //TODO: A better way to get th cell
+                Dom.addClass(Dom.get(this._sId+"-th"+aFirstHeaders[i]), DT.CLASS_FIRST);
             }
+            for(i=0; i<aLastHeaders.length; i++) {
+                //TODO: A better way to get th cell
+                Dom.addClass(Dom.get(this._sId+"-th"+aLastHeaders[i]), DT.CLASS_LAST);
+            }
+        
+            // Add DD features only after DOM has been updated
+            var foundDD = (util.DD) ? true : false;
+            var needDD = false;
+            // draggable
+            // HACK: Not able to use attribute since this code is run before
+            // attributes are initialized
+            if(this._oConfigs.draggableColumns) {
+                for(i=0; i<this._oColumnSet.tree[0].length; i++) {
+                    oColumn = this._oColumnSet.tree[0][i];
+                    if(foundDD) {
+                        elTheadCell = oColumn.getThEl();
+                        Dom.addClass(elTheadCell, DT.CLASS_DRAGGABLE);
+                        var elDragTarget = DT._initColumnDragTargetEl();
+                        oColumn._dd = new YAHOO.widget.ColumnDD(this, oColumn, elTheadCell, elDragTarget);
+                    }
+                    else {
+                        needDD = true;
+                    }    
+                }
+            }
+            // resizeable
+            for(i=0; i<this._oColumnSet.keys.length; i++) {
+                oColumn = this._oColumnSet.keys[i];
+                if(oColumn.resizeable) {
+                    if(foundDD) {
+                        elTheadCell = oColumn.getThEl();
+                        Dom.addClass(elTheadCell, DT.CLASS_RESIZEABLE);
+                        var elThLiner = elTheadCell.firstChild;
+                        var elThResizer = elThLiner.appendChild(document.createElement("div"));
+                        elThResizer.id = this._sId + "-colresizer" + oColumn.getId();
+                        oColumn._elResizer = elThResizer;
+                        Dom.addClass(elThResizer,DT.CLASS_RESIZER);
+                        var elResizerProxy = DT._initColumnResizerProxyEl();
+                        oColumn._ddResizer = new YAHOO.util.ColumnResizer(
+                                this, oColumn, elTheadCell, elThResizer.id, elResizerProxy);
+                        var cancelClick = function(e) {
+                            Ev.stopPropagation(e);
+                        };
+                        Ev.addListener(elThResizer,"click",cancelClick);
+                    }
+                    else {
+                        needDD = true;
+                    }
+                }
+            }
+            if(needDD) {
+            }
+            
         }
+        else {
+        }
     }
-    if(needDD) {
+
+
+     // Set widths for hidden Columns
+    for(var g=0, h=this._oColumnSet.keys.length; g<h; g++) {
+        // Hidden Columns
+        if(this._oColumnSet.keys[g].hidden) {
+            var oHiddenColumn = this._oColumnSet.keys[g];
+            var oHiddenThEl = oHiddenColumn.getThEl();
+            oHiddenColumn._nLastWidth = oHiddenThEl.offsetWidth -
+                        (parseInt(Dom.getStyle(oHiddenThEl,"paddingLeft"),10)|0) -
+                        (parseInt(Dom.getStyle(oHiddenThEl,"paddingRight"),10)|0);
+            this._setColumnWidth(oHiddenColumn, "1px"); 
+        }
     }
 
-};
 
+    // Bug 1806891
+    if(ua.webkit && ua.webkit < 420) {
+        var oSelf = this;
+        setTimeout(function() {
+            oSelf._elThead.style.display = "";
+        },0);
+        this._elThead.style.display = 'none';
+    }
+},
+
 /**
  * Populates TH cell as defined by Column.
  *
  * @method _initThEl
  * @param elTheadCell {HTMLElement} TH cell element reference.
  * @param oColumn {YAHOO.widget.Column} Column object.
- * @param row {number} Row index.
- * @param col {number} Column index.
+ * @param row {Number} Row index.
+ * @param col {Number} Column index.
+ * @param bA11y {Boolean} True if TH is for accessibility, so as not to
+ * initialize presentation elements.
  * @private
  */
-YAHOO.widget.DataTable.prototype._initThEl = function(elTheadCell,oColumn,row,col) {
+_initThEl : function(elTheadCell,oColumn,row,col, bA11y) {
     // Clear out the cell of prior content
     // TODO: purgeListeners and other validation-related things
-    var index = this._nIndex;
     var colKey = oColumn.getKey();
     var colId = oColumn.getId();
     elTheadCell.yuiColumnKey = colKey;
     elTheadCell.yuiColumnId = colId;
-    if(oColumn.abbr) {
-        elTheadCell.abbr = oColumn.abbr;
-    }
-    if(oColumn.width) {
-        elTheadCell.style.width = oColumn.width;
-    }
-
-    var aCustomClasses;
-    if(YAHOO.lang.isString(oColumn.className)) {
-        aCustomClasses = [oColumn.className];
-    }
-    else if(YAHOO.lang.isArray(oColumn.className)) {
-        aCustomClasses = oColumn.className;
-    }
-    if(aCustomClasses) {
-        for(var i=0; i<aCustomClasses.length; i++) {
-            YAHOO.util.Dom.addClass(elTheadCell,aCustomClasses[i]);
-        }
-    }
-    
-    YAHOO.util.Dom.addClass(elTheadCell, "yui-dt-col-"+colKey);
-    
     elTheadCell.innerHTML = "";
     elTheadCell.rowSpan = oColumn.getRowspan();
     elTheadCell.colSpan = oColumn.getColspan();
 
-    var elTheadContainer = elTheadCell.appendChild(document.createElement("div"));
-    elTheadContainer.id = this.id + "-container" + colId;
-    YAHOO.util.Dom.addClass(elTheadContainer,YAHOO.widget.DataTable.CLASS_HEADER);
-    var elTheadLabel = elTheadContainer.appendChild(document.createElement("span"));
-    elTheadLabel.id = this.id + "-label" + colId;
-    YAHOO.util.Dom.addClass(elTheadLabel,YAHOO.widget.DataTable.CLASS_LABEL);
+    var elTheadCellLiner = elTheadCell.appendChild(document.createElement("div"));
+    var elTheadCellLabel = elTheadCellLiner.appendChild(document.createElement("span"));
 
-    var sLabel = YAHOO.lang.isValue(oColumn.label) ? oColumn.label : colKey;
-    if(oColumn.sortable) {
-        YAHOO.util.Dom.addClass(elTheadCell,YAHOO.widget.DataTable.CLASS_SORTABLE);
-        //TODO: Make sortLink customizeable
-        //TODO: Make title configurable
-        //TODO: Separate label from an accessibility link that says
-        // "Click to sort ascending" and push it offscreen
-        var sLabelLinkId = this.id + "-labellink" + colId;
-        var sortLink = "?key=" + colKey;
-        elTheadLabel.innerHTML = "<a id=\"" + sLabelLinkId + "\" href=\"" + sortLink + "\" title=\"Click to sort\" class=\"" + YAHOO.widget.DataTable.CLASS_SORTABLE + "\">" + sLabel + "</a>";
-        if(!this._sFirstLabelLinkId) {
-            this._sFirstLabelLinkId = sLabelLinkId;
+    // Keep it basic for screen readers
+    if(bA11y) {
+        //TODO: remove IDs and form elements from label
+        if(oColumn.abbr) {
+            elTheadCell.abbr = oColumn.abbr;
         }
+        elTheadCellLabel.innerHTML = lang.isValue(oColumn.label) ? oColumn.label : colKey;
     }
+    // Visually format the elements
     else {
-        elTheadLabel.innerHTML = sLabel;
+        // Needed for resizer
+        elTheadCellLiner.id = elTheadCell.id + "-liner";
+        
+        // Add classes on the liner
+        var aClasses;
+        if(lang.isString(oColumn.className)) {
+            aClasses = [oColumn.className];
+        }
+        else if(lang.isArray(oColumn.className)) {
+            aClasses = oColumn.className;
+        }
+        else {
+            aClasses = [];
+        }
+        
+        //TODO: document special keys will get stripped here
+        aClasses[aClasses.length] = "yui-dt-col-"+colKey.replace(/[^\w\-.:]/g,"");
+        
+        aClasses[aClasses.length] = "yui-dt-col-"+oColumn.getId();
+        
+        aClasses[aClasses.length] = DT.CLASS_LINER;
+
+        Dom.addClass(elTheadCellLiner,aClasses.join(" "));
+
+        // Add classes on the label
+        Dom.addClass(elTheadCellLabel,DT.CLASS_LABEL);
+        
+        // Add classes on the cell
+        aClasses = [];
+        if(oColumn.resizeable) {
+            aClasses[aClasses.length] = DT.CLASS_RESIZEABLE;
+        }
+        if(oColumn.sortable) {
+            aClasses[aClasses.length] = DT.CLASS_SORTABLE;
+        }
+
+        //Set Column hidden
+        if(oColumn.hidden) {
+            aClasses[aClasses.length] = DT.CLASS_HIDDEN;
+        }
+        
+        // Set Column selection on TD
+        if(oColumn.selected) {
+            aClasses[aClasses.length] = DT.CLASS_SELECTED;
+        }
+
+        Dom.addClass(elTheadCell,aClasses.join(" "));
+
+        DT.formatTheadCell(elTheadCellLabel, oColumn, this);
     }
-};
+},
 
 /**
  * Creates HTML markup for Cell Editor.
@@ -1381,73 +7381,48 @@
  * @method _initCellEditorEl
  * @private
  */
-YAHOO.widget.DataTable.prototype._initCellEditorEl = function() {
-    // Attach Cell Editor container element to body
+_initCellEditorEl : function() {
+    // TODO: destroy previous instances
+
+    // Attach Cell Editor container element as first child of body
     var elCellEditor = document.createElement("div");
-    elCellEditor.id = this.id + "-celleditor";
+    elCellEditor.id = this._sId + "-celleditor";
     elCellEditor.style.display = "none";
-    YAHOO.util.Dom.addClass(elCellEditor, YAHOO.widget.DataTable.CLASS_EDITOR);
-    elCellEditor = document.body.appendChild(elCellEditor);
-
+    elCellEditor.tabIndex = 0;
+    Dom.addClass(elCellEditor, DT.CLASS_EDITOR);
+    var elFirstChild = Dom.getFirstChild(document.body);
+    if(elFirstChild) {
+        elCellEditor = Dom.insertBefore(elCellEditor, elFirstChild);
+    }
+    else {
+        elCellEditor = document.body.appendChild(elCellEditor);
+    }
+    
     // Internal tracker of Cell Editor values
     var oCellEditor = {};
     oCellEditor.container = elCellEditor;
     oCellEditor.value = null;
     oCellEditor.isActive = false;
     this._oCellEditor = oCellEditor;
+},
 
-    // Handle ESC key
-    this.subscribe("editorKeydownEvent", function(oArgs) {
-        var e = oArgs.event;
-        var elTarget = YAHOO.util.Event.getTarget(e);
+/** 	 
+  * Initializes Column sorting. 	 
+  * 	 
+  * @method _initColumnSort 	 
+  * @private 	 
+  */ 	 
+_initColumnSort : function() {
+    this.subscribe("theadCellClickEvent", this.onEventSortColumn); 	 
+}, 	 
+ 
 
-        // ESC hides Cell Editor
-        if((e.keyCode == 27)) {
-            this.cancelCellEditor();
-        }
-    });
-};
 
-/**
- * Initializes Column sorting.
- *
- * @method _initColumnSort
- * @private
- */
-YAHOO.widget.DataTable.prototype._initColumnSort = function() {
-    this.subscribe("headerCellClickEvent", this.onEventSortColumn);
-};
 
-/**
- * Initializes DOM event listeners.
- *
- * @method _initDomEvents
- * @private
- */
-YAHOO.widget.DataTable.prototype._initDomEvents = function() {
-    var elTable = this._elTable;
-    var elThead = this._elThead;
-    var elTbody = this._elTbody;
-    var elContainer = this._elContainer;
 
-    YAHOO.util.Event.addListener(document, "click", this._onDocumentClick, this);
-    YAHOO.util.Event.addListener(document, "keydown", this._onDocumentKeydown, this);
 
-    YAHOO.util.Event.addListener(elTable, "focus", this._onTableFocus, this);
-    YAHOO.util.Event.addListener(elTable, "mouseover", this._onTableMouseover, this);
-    YAHOO.util.Event.addListener(elTable, "mouseout", this._onTableMouseout, this);
-    YAHOO.util.Event.addListener(elTable, "mousedown", this._onTableMousedown, this);
-    YAHOO.util.Event.addListener(elTable, "keydown", this._onTableKeydown, this);
-    YAHOO.util.Event.addListener(elTable, "keypress", this._onTableKeypress, this);
 
-    // Since we can't listen for click and dblclick on the same element...
-    YAHOO.util.Event.addListener(elTable, "dblclick", this._onTableDblclick, this);
-    YAHOO.util.Event.addListener(elThead, "click", this._onTheadClick, this);
-    YAHOO.util.Event.addListener(elTbody, "click", this._onTbodyClick, this);
 
-    YAHOO.util.Event.addListener(elContainer, "scroll", this._onScroll, this); // for IE
-    YAHOO.util.Event.addListener(elTbody, "scroll", this._onScroll, this); // for everyone else
-};
 
 
 
@@ -1474,169 +7449,147 @@
 
 
 
+// DOM MUTATION FUNCTIONS
 
 
 
+/**
+ * Create a TR element for a given Record.
+ * @method _createTrEl
+ * @param oRecord {YAHOO.widget.Record} Record instance
+ * @return {HTMLElement} The new TR element.  This must be added to the DOM.
+ * @private 
+ */
+_createTrEl : function (oRecord) {
+    // Clone the empty tr template.  We can't clone an existing row
+    // because of the expandos and td ids that must be set in _addTdEl
+    var elRow     = this._trElTemplate.cloneNode(true);
 
+    elRow.id = this._sId+"-bdrow"+this._nTrCount;
+    this._nTrCount++;
 
+    // Call _updateTrEl to populate and align the row contents
+    return this._updateTrEl(elRow,oRecord);
+},
 
-
-
-
-
-
-// DOM MUTATION FUNCTIONS
-
-
-
-
 /**
- * Adds a TR element to the primary TBODY at the page row index if given, otherwise
- * at the end of the page. Formats TD elements within the TR element using data
- * from the given Record.
+ * Formats all TD elements of given TR element with data from the given Record.
  *
- * @method _addTrEl
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param index {Number} (optional) The page row index at which to add the TR
- * element.
- * @return {String} ID of the added TR element, or null.
+ * @method _updateTrEl
+ * @param elRow {HTMLElement} The TR element to update.
+ * @param oRecord {YAHOO.widget.Record} The associated Record instance.
+ * @return {HTMLElement} DOM reference to the new TR element.
  * @private
  */
-YAHOO.widget.DataTable.prototype._addTrEl = function(oRecord, index) {
-    this.hideTableMessage();
+_updateTrEl : function(elRow, oRecord) {
+    var oColumnSet = this._oColumnSet,
+        sortKey,
+        sortClass,
+        isSortedBy = this.get("sortedBy"),
+        i,j,len,jlen;
 
-    // It's an append if no index provided, or index is negative or too big
-    var append = (!YAHOO.lang.isNumber(index) || (index < 0) ||
-            (index >= (this._elTbody.rows.length))) ? true : false;
-            
-    var oColumnSet = this._oColumnSet;
-    var oRecordSet = this._oRecordSet;
-    var isSortedBy = this.get("sortedBy");
-    var sortedColKeyIndex  = null;
-    var sortedDir, newClass;
     if(isSortedBy) {
-        sortedColKeyIndex = (isSortedBy.column) ?
-                isSortedBy.column.getKeyIndex() :
-                this._oColumnSet.getColumn(isSortedBy.key).getKeyIndex();
-        sortedDir = isSortedBy.dir;
-        newClass = (sortedDir === "desc") ? YAHOO.widget.DataTable.CLASS_DESC :
-                YAHOO.widget.DataTable.CLASS_ASC;
-
+        sortKey = isSortedBy.key;
+        sortClass = isSortedBy.dir;
     }
 
+    // Hide the row to prevent constant reflows
+    elRow.style.display = 'none';
 
-    var elRow = (append) ? this._elTbody.appendChild(document.createElement("tr")) :
-        this._elTbody.insertBefore(document.createElement("tr"),this._elTbody.rows[index]);
+    // Remove extra TD elements
+    while(elRow.childNodes.length > oColumnSet.keys.length) {
+        elRow.removeChild(elRow.firstChild);
+    }
+    // Add more TD elements as needed
+    for (i=elRow.childNodes.length||0, len=oColumnSet.keys.length; i < len; ++i) {
+        this._addTdEl(elRow,oColumnSet.keys[i],i);
+    }
 
-    elRow.id = this.id+"-bdrow"+this._nTrCount;
-    this._nTrCount++;
-    elRow.yuiRecordId = oRecord.getId();
+    // Update TD elements with new data
+    for(i=0,len=oColumnSet.keys.length; i<len; ++i) {
+        var oColumn     = oColumnSet.keys[i],
+            elCell      = elRow.childNodes[i],
+            elCellLiner = elCell.firstChild,
+            cellHeaders = '',
+            headerType  = this.get('scrollable') ? "-a11y " : " ";
 
-    // Create TD cells
-    for(var j=0; j<oColumnSet.keys.length; j++) {
-        var oColumn = oColumnSet.keys[j];
-        var elCell = elRow.appendChild(document.createElement("td"));
-        elCell.id = elRow.id+"-cell"+j;
-        elCell.yuiColumnKey = oColumn.getKey();
-        elCell.yuiColumnId = oColumn.getId();
+        // Set the cell content
+        this.formatCell(elCellLiner, oRecord, oColumn);
 
-        for(var k=0; k<oColumnSet.headers[j].length; k++) {
-            elCell.headers += this.id + "-col" + oColumnSet.headers[j][k] + " ";
+        // Set the cell's accessibility headers
+        for(j=0,jlen=oColumnSet.headers[i].length; j < jlen; ++j) {
+            cellHeaders += this._sId + "-th" + oColumnSet.headers[i][j] + headerType;
         }
-        
-        // For SF2 cellIndex bug: http://www.webreference.com/programming/javascript/ppk2/3.html
-        elCell.yuiCellIndex = j;
+        elCell.headers = cellHeaders;
 
-        // Update UI
-        this.formatCell(elCell, oRecord, oColumn);
-
-        // Set FIRST/LAST on TD
-        if (j === 0) {
-            YAHOO.util.Dom.addClass(elCell, YAHOO.widget.DataTable.CLASS_FIRST);
+        // Set ASC/DESC on TD
+        if(oColumn.key === sortKey) {
+            Dom.replaceClass(elCell, sortClass === DT.CLASS_ASC ?
+                                     DT.CLASS_DESC : DT.CLASS_ASC, sortClass);
+        } else {
+            Dom.removeClass(elCell, DT.CLASS_ASC);
+            Dom.removeClass(elCell, DT.CLASS_DESC);
         }
-        else if (j === this._oColumnSet.keys.length-1) {
-            YAHOO.util.Dom.addClass(elCell, YAHOO.widget.DataTable.CLASS_LAST);
-        }
         
-        // Remove ASC/DESC
-        YAHOO.util.Dom.removeClass(elCell, YAHOO.widget.DataTable.CLASS_ASC);
-        YAHOO.util.Dom.removeClass(elCell, YAHOO.widget.DataTable.CLASS_DESC);
-        
-        // Set ASC/DESC on TD
-        if(j === sortedColKeyIndex) {
-            newClass = (sortedDir === "desc") ?
-                    YAHOO.widget.DataTable.CLASS_DESC :
-                    YAHOO.widget.DataTable.CLASS_ASC;
-            YAHOO.util.Dom.addClass(elCell, newClass);
+        // Set Column hidden if appropriate
+        if(oColumn.hidden) {
+            Dom.addClass(elCell, DT.CLASS_HIDDEN);
         }
+        else {
+            Dom.removeClass(elCell, DT.CLASS_HIDDEN);
+        }
 
+        // Set Column selection on TH
+        if(oColumn.selected) {
+            Dom.addClass(elCell, DT.CLASS_SELECTED);
+        }
+        else {
+            Dom.removeClass(elCell, DT.CLASS_SELECTED);
+        }
+    }
 
-        /*p.abx {word-wrap:break-word;}
-ought to solve the problem for Safari (the long words will wrap in your
-tds, instead of overflowing to the next td.
-(this is supported by IE win as well, so hide it if needed).
+    // Update Record ID
+    elRow.yuiRecordId = oRecord.getId();
+    
+    // Redisplay the row for reflow
+    elRow.style.display = '';
 
-One thing, though: it doesn't work in combination with
-'white-space:nowrap'.*/
+    return elRow;
+},
 
-// need a div wrapper for safari?
-        //TODO: fix fixedWidth
-        if(this.fixedWidth) {
-            elCell.style.overflow = "hidden";
-            //elCell.style.width = "20px";
-        }
-    }
 
-    return elRow.id;
-};
-
 /**
- * Formats all TD elements of given TR element with data from the given Record.
- *
- * @method _updateTrEl
- * @param elRow {HTMLElement} The TR element to update.
- * @param oRecord {YAHOO.widget.Record} The associated Record instance.
- * @return {String} ID of the updated TR element, or null.
+ * Creates a cell within the specified row and column.
+ * @method _addTdEl
+ * @param elRow {HTMLElement} The row to add the cell to
+ * @param oColumn {Column} The column definition to use for the cell
+ * @param index {number} (optional) the index to add the cell at (default null)
+ * @return {HTMLElement} the new cell
  * @private
  */
-YAHOO.widget.DataTable.prototype._updateTrEl = function(elRow, oRecord) {
-    this.hideTableMessage();
+_addTdEl : function (elRow,oColumn,index) {
+    var elCell      = this._tdElTemplate.cloneNode(true),
+        elCellLiner = elCell.firstChild;
 
-    var isSortedBy = this.get("sortedBy");
-    var sortedColKeyIndex  = null;
-    var sortedDir, newClass;
-    if(isSortedBy) {
-        sortedColKeyIndex = (isSortedBy.column) ?
-                isSortedBy.column.getKeyIndex() :
-                this._oColumnSet.getColumn(isSortedBy.key).getKeyIndex();
-        sortedDir = isSortedBy.dir;
-        newClass = (sortedDir === "desc") ? YAHOO.widget.DataTable.CLASS_DESC :
-                YAHOO.widget.DataTable.CLASS_ASC;
-    }
+    index = index || elRow.cells.length;
 
-    // Update TD elements with new data
-    for(var j=0; j<elRow.cells.length; j++) {
-        var oColumn = this._oColumnSet.keys[j];
-        var elCell = elRow.cells[j];
-        this.formatCell(elCell, oRecord, oColumn);
+    elCell.id           = elRow.id+"-cell"+this._nTdCount;
+    this._nTdCount++;
+    elCell.yuiColumnKey = oColumn.getKey();
+    elCell.yuiColumnId  = oColumn.getId();
 
-        // Remove ASC/DESC
-        YAHOO.util.Dom.removeClass(elCell, YAHOO.widget.DataTable.CLASS_ASC);
-        YAHOO.util.Dom.removeClass(elCell, YAHOO.widget.DataTable.CLASS_DESC);
+    // For SF2 cellIndex bug: http://www.webreference.com/programming/javascript/ppk2/3.html
+    elCell.yuiCellIndex = index;
 
-        // Set ASC/DESC on TD
-        if(j === sortedColKeyIndex) {
-            YAHOO.util.Dom.addClass(elCell, newClass);
-        }
+    // Set FIRST/LAST on TD
+    if (!(index % this._oColumnSet.keys.length - 1)) {
+        elCell.className = index ? DT.CLASS_LAST : DT.CLASS_FIRST;
     }
 
-    // Update Record ID
-    elRow.yuiRecordId = oRecord.getId();
-    
-    return elRow.id;
-};
+    var insertBeforeCell = elRow.cells[index] || null;
+    return elRow.insertBefore(elCell,insertBeforeCell);
+},
 
-
 /**
  * Deletes TR element by DOM reference or by DataTable page row index.
  *
@@ -1645,24 +7598,25 @@
  * @return {Boolean} Returns true if successful, else returns false.
  * @private
  */
-YAHOO.widget.DataTable.prototype._deleteTrEl = function(row) {
+_deleteTrEl : function(row) {
     var rowIndex;
-    
+
     // Get page row index for the element
-    if(!YAHOO.lang.isNumber(row)) {
-        rowIndex = YAHOO.util.Dom.get(row).sectionRowIndex;
+    if(!lang.isNumber(row)) {
+        rowIndex = Dom.get(row).sectionRowIndex;
     }
     else {
         rowIndex = row;
     }
-    if(YAHOO.lang.isNumber(rowIndex) && (rowIndex > -2) && (rowIndex < this._elTbody.rows.length)) {
-        this._elTbody.deleteRow(rowIndex);
-        return true;
+    if(lang.isNumber(rowIndex) && (rowIndex > -2) && (rowIndex < this._elTbody.rows.length)) {
+        // Cannot use tbody.deleteRow due to IE6 instability
+        //return this._elTbody.deleteRow(rowIndex);
+        return this._elTbody.removeChild(this.getTrEl(row));
     }
     else {
-        return false;
+        return null;
     }
-};
+},
 
 
 
@@ -1696,54 +7650,54 @@
 
 
 /**
- * Assigns the class YAHOO.widget.DataTable.CLASS_FIRST to the first TR element
+ * Assigns the class DT.CLASS_FIRST to the first TR element
  * of the DataTable page and updates internal tracker.
  *
  * @method _setFirstRow
  * @private
  */
-YAHOO.widget.DataTable.prototype._setFirstRow = function() {
+_setFirstRow : function() {
     var rowEl = this.getFirstTrEl();
     if(rowEl) {
         // Remove FIRST
         if(this._sFirstTrId) {
-            YAHOO.util.Dom.removeClass(this._sFirstTrId, YAHOO.widget.DataTable.CLASS_FIRST);
+            Dom.removeClass(this._sFirstTrId, DT.CLASS_FIRST);
         }
         // Set FIRST
-        YAHOO.util.Dom.addClass(rowEl, YAHOO.widget.DataTable.CLASS_FIRST);
+        Dom.addClass(rowEl, DT.CLASS_FIRST);
         this._sFirstTrId = rowEl.id;
     }
     else {
         this._sFirstTrId = null;
     }
-};
+},
 
 /**
- * Assigns the class YAHOO.widget.DataTable.CLASS_LAST to the last TR element
+ * Assigns the class DT.CLASS_LAST to the last TR element
  * of the DataTable page and updates internal tracker.
  *
  * @method _setLastRow
  * @private
  */
-YAHOO.widget.DataTable.prototype._setLastRow = function() {
+_setLastRow : function() {
     var rowEl = this.getLastTrEl();
     if(rowEl) {
         // Unassign previous class
         if(this._sLastTrId) {
-            YAHOO.util.Dom.removeClass(this._sLastTrId, YAHOO.widget.DataTable.CLASS_LAST);
+            Dom.removeClass(this._sLastTrId, DT.CLASS_LAST);
         }
         // Assign class
-        YAHOO.util.Dom.addClass(rowEl, YAHOO.widget.DataTable.CLASS_LAST);
+        Dom.addClass(rowEl, DT.CLASS_LAST);
         this._sLastTrId = rowEl.id;
     }
     else {
         this._sLastTrId = null;
     }
-};
+},
 
 /**
- * Assigns the classes YAHOO.widget.DataTable.CLASS_EVEN and
- * YAHOO.widget.DataTable.CLASS_ODD to alternating TR elements of the DataTable
+ * Assigns the classes DT.CLASS_EVEN and
+ * DT.CLASS_ODD to alternating TR elements of the DataTable
  * page. For performance, a subset of rows may be specified.
  *
  * @method _setRowStripes
@@ -1753,21 +7707,23 @@
  * stripe all the rows until the end.
  * @private
  */
-YAHOO.widget.DataTable.prototype._setRowStripes = function(row, range) {
+_setRowStripes : function(row, range) {
     // Default values stripe all rows
-    var allRows = this._elTbody.rows;
-    var nStartIndex = 0;
-    var nEndIndex = allRows.length;
-    
+    var allRows = this._elTbody.rows,
+        nStartIndex = 0,
+        nEndIndex = allRows.length,
+        aOdds = [], nOddIdx = 0,
+        aEvens = [], nEvenIdx = 0;
+
     // Stripe a subset
     if((row !== null) && (row !== undefined)) {
         // Validate given start row
         var elStartRow = this.getTrEl(row);
         if(elStartRow) {
             nStartIndex = elStartRow.sectionRowIndex;
-            
+
             // Validate given range
-            if(YAHOO.lang.isNumber(range) && (range > 1)) {
+            if(lang.isNumber(range) && (range > 1)) {
                 nEndIndex = nStartIndex + range;
             }
         }
@@ -1775,17 +7731,20 @@
 
     for(var i=nStartIndex; i<nEndIndex; i++) {
         if(i%2) {
-            YAHOO.util.Dom.removeClass(allRows[i], YAHOO.widget.DataTable.CLASS_EVEN);
-            YAHOO.util.Dom.addClass(allRows[i], YAHOO.widget.DataTable.CLASS_ODD);
+            aOdds[nOddIdx++] = allRows[i];
+        } else {
+            aEvens[nEvenIdx++] = allRows[i];
         }
-        else {
-            YAHOO.util.Dom.removeClass(allRows[i], YAHOO.widget.DataTable.CLASS_ODD);
-            YAHOO.util.Dom.addClass(allRows[i], YAHOO.widget.DataTable.CLASS_EVEN);
-        }
     }
-};
 
+    if (aOdds.length) {
+        Dom.replaceClass(aOdds, DT.CLASS_EVEN, DT.CLASS_ODD);
+    }
 
+    if (aEvens.length) {
+        Dom.replaceClass(aEvens, DT.CLASS_ODD, DT.CLASS_EVEN);
+    }
+},
 
 
 
@@ -1829,6 +7788,8 @@
 
 
 
+
+
 /////////////////////////////////////////////////////////////////////////////
 //
 // Private DOM Event Handlers
@@ -1836,38 +7797,39 @@
 /////////////////////////////////////////////////////////////////////////////
 
 /**
- * Handles scroll events on the CONTAINER (for IE) and TBODY elements (for everyone else).
+ * Syncs scrolltop and scrollleft of all TABLEs.
  *
  * @method _onScroll
  * @param e {HTMLEvent} The scroll event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance
  * @private
  */
-YAHOO.widget.DataTable.prototype._onScroll = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-    
-    if(oSelf._oCellEditor.isActive) {
+_onScroll : function(e, oSelf) {
+    oSelf._elTheadContainer.scrollLeft = oSelf._elTbodyContainer.scrollLeft;
+
+    if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
         oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
         oSelf.cancelCellEditor();
     }
 
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
     oSelf.fireEvent("tableScrollEvent", {event:e, target:elTarget});
-};
+},
 
 /**
  * Handles click events on the DOCUMENT.
  *
  * @method _onDocumentClick
  * @param e {HTMLEvent} The click event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onDocumentClick = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
+_onDocumentClick : function(e, oSelf) {
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
 
-    if(!YAHOO.util.Dom.isAncestor(oSelf._elTable, elTarget)) {
+    if(!Dom.isAncestor(oSelf._elContainer, elTarget)) {
         oSelf.fireEvent("tableBlurEvent");
 
         // Fires editorBlurEvent when click is not within the TABLE.
@@ -1876,1194 +7838,555 @@
         // handlers below rather than by the TABLE click handler directly.
         if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
             // Only if the click was not within the Cell Editor container
-            if(!YAHOO.util.Dom.isAncestor(oSelf._oCellEditor.container, elTarget) &&
+            if(!Dom.isAncestor(oSelf._oCellEditor.container, elTarget) &&
                     (oSelf._oCellEditor.container.id !== elTarget.id)) {
                 oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
             }
         }
     }
-};
+},
 
 /**
- * Handles keydown events on the DOCUMENT.
+ * Handles focus events on the DataTable instance.
  *
- * @method _onDocumentKeydown
- * @param e {HTMLEvent} The keydown event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @method _onTableFocus
+ * @param e {HTMLEvent} The focus event.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onDocumentKeydown = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
+_onTableFocus : function(e, oSelf) {
+    oSelf.fireEvent("tableFocusEvent");
+},
 
-    if(oSelf._oCellEditor && oSelf._oCellEditor.isActive &&
-            YAHOO.util.Dom.isAncestor(oSelf._oCellEditor.container, elTarget)) {
-        oSelf.fireEvent("editorKeydownEvent", {editor:oSelf._oCellEditor, event:e});
-    }
-};
+/**
+ * Handles focus events on the THEAD element.
+ *
+ * @method _onTheadFocus
+ * @param e {HTMLEvent} The focus event.
+ * @param oSelf {DT} DataTable instance.
+ * @private
+ */
+_onTheadFocus : function(e, oSelf) {
+    oSelf.fireEvent("theadFocusEvent");
+    oSelf.fireEvent("tableFocusEvent");
+},
 
 /**
- * Handles focus events on the TABLE element.
+ * Handles focus events on the TBODY element.
  *
- * @method _onTableFocus
+ * @method _onTbodyFocus
  * @param e {HTMLEvent} The focus event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableMouseover = function(e, oSelf) {
+_onTbodyFocus : function(e, oSelf) {
+    oSelf.fireEvent("tbodyFocusEvent");
     oSelf.fireEvent("tableFocusEvent");
-};
+},
 
 /**
- * Handles mouseover events on the TABLE element.
+ * Handles mouseover events on the DataTable instance.
  *
  * @method _onTableMouseover
  * @param e {HTMLEvent} The mouseover event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableMouseover = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
-    while(elTarget && (elTag != "table")) {
-        switch(elTag) {
-            case "body":
-                 break;
-            case "a":
-                break;
-            case "td":
-                oSelf.fireEvent("cellMouseoverEvent",{target:elTarget,event:e});
-                break;
-            case "span":
-                if(YAHOO.util.Dom.hasClass(elTarget, YAHOO.widget.DataTable.CLASS_LABEL)) {
-                    oSelf.fireEvent("headerLabelMouseoverEvent",{target:elTarget,event:e});
+_onTableMouseover : function(e, oSelf) {
+    var elTarget = Ev.getTarget(e);
+        var elTag = elTarget.nodeName.toLowerCase();
+        var bKeepBubbling = true;
+        while(elTarget && (elTag != "table")) {
+            switch(elTag) {
+                case "body":
+                     return;
+                case "a":
+                    break;
+                case "td":
+                    bKeepBubbling = oSelf.fireEvent("cellMouseoverEvent",{target:elTarget,event:e});
+                    break;
+                case "span":
+                    if(Dom.hasClass(elTarget, DT.CLASS_LABEL)) {
+                        bKeepBubbling = oSelf.fireEvent("theadLabelMouseoverEvent",{target:elTarget,event:e});
+                        // Backward compatibility
+                        bKeepBubbling = oSelf.fireEvent("headerLabelMouseoverEvent",{target:elTarget,event:e});
+                    }
+                    break;
+                case "th":
+                    bKeepBubbling = oSelf.fireEvent("theadCellMouseoverEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerCellMouseoverEvent",{target:elTarget,event:e});
+                    break;
+                case "tr":
+                    if(elTarget.parentNode.nodeName.toLowerCase() == "thead") {
+                        bKeepBubbling = oSelf.fireEvent("theadRowMouseoverEvent",{target:elTarget,event:e});
+                        // Backward compatibility
+                        bKeepBubbling = oSelf.fireEvent("headerRowMouseoverEvent",{target:elTarget,event:e});
+                    }
+                    else {
+                        bKeepBubbling = oSelf.fireEvent("rowMouseoverEvent",{target:elTarget,event:e});
+                    }
+                    break;
+                default:
+                    break;
+            }
+            if(bKeepBubbling === false) {
+                return;
+            }
+            else {
+                elTarget = elTarget.parentNode;
+                if(elTarget) {
+                    elTag = elTarget.nodeName.toLowerCase();
                 }
-                break;
-            case "th":
-                oSelf.fireEvent("headerCellMouseoverEvent",{target:elTarget,event:e});
-                break;
-            case "tr":
-                if(elTarget.parentNode.tagName.toLowerCase() == "thead") {
-                    oSelf.fireEvent("headerRowMouseoverEvent",{target:elTarget,event:e});
-                }
-                else {
-                    oSelf.fireEvent("rowMouseoverEvent",{target:elTarget,event:e});
-                }
-                break;
-            default:
-                break;
+            }
         }
-        elTarget = elTarget.parentNode;
-        if(elTarget) {
-            elTag = elTarget.tagName.toLowerCase();
-        }
-    }
-    oSelf.fireEvent("tableMouseoverEvent",{target:(elTarget || oSelf._elTable),event:e});
-};
+        oSelf.fireEvent("tableMouseoverEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
 /**
- * Handles mouseout events on the TABLE element.
+ * Handles mouseout events on the DataTable instance.
  *
  * @method _onTableMouseout
  * @param e {HTMLEvent} The mouseout event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableMouseout = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
+_onTableMouseout : function(e, oSelf) {
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
     while(elTarget && (elTag != "table")) {
         switch(elTag) {
             case "body":
-                break;
+                return;
             case "a":
                 break;
             case "td":
-                oSelf.fireEvent("cellMouseoutEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("cellMouseoutEvent",{target:elTarget,event:e});
                 break;
             case "span":
-                if(YAHOO.util.Dom.hasClass(elTarget, YAHOO.widget.DataTable.CLASS_LABEL)) {
-                    oSelf.fireEvent("headerLabelMouseoutEvent",{target:elTarget,event:e});
+                if(Dom.hasClass(elTarget, DT.CLASS_LABEL)) {
+                    bKeepBubbling = oSelf.fireEvent("theadLabelMouseoutEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerLabelMouseoutEvent",{target:elTarget,event:e});
                 }
                 break;
             case "th":
-                oSelf.fireEvent("headerCellMouseoutEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("theadCellMouseoutEvent",{target:elTarget,event:e});
+                // Backward compatibility
+                bKeepBubbling = oSelf.fireEvent("headerCellMouseoutEvent",{target:elTarget,event:e});
                 break;
             case "tr":
-                if(elTarget.parentNode.tagName.toLowerCase() == "thead") {
-                    oSelf.fireEvent("headerRowMouseoutEvent",{target:elTarget,event:e});
+                if(elTarget.parentNode.nodeName.toLowerCase() == "thead") {
+                    bKeepBubbling = oSelf.fireEvent("theadRowMouseoutEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerRowMouseoutEvent",{target:elTarget,event:e});
                 }
                 else {
-                    oSelf.fireEvent("rowMouseoutEvent",{target:elTarget,event:e});
+                    bKeepBubbling = oSelf.fireEvent("rowMouseoutEvent",{target:elTarget,event:e});
                 }
                 break;
             default:
                 break;
         }
-        elTarget = elTarget.parentNode;
-        if(elTarget) {
-            elTag = elTarget.tagName.toLowerCase();
+        if(bKeepBubbling === false) {
+            return;
         }
+        else {
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
+            }
+        }
     }
-    oSelf.fireEvent("tableMouseoutEvent",{target:(elTarget || oSelf._elTable),event:e});
-};
+    oSelf.fireEvent("tableMouseoutEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
 /**
- * Handles mousedown events on the TABLE element.
+ * Handles mousedown events on the DataTable instance.
  *
  * @method _onTableMousedown
  * @param e {HTMLEvent} The mousedown event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableMousedown = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
+_onTableMousedown : function(e, oSelf) {
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
     while(elTarget && (elTag != "table")) {
         switch(elTag) {
             case "body":
-                break;
+                return;
             case "a":
                 break;
             case "td":
-                oSelf.fireEvent("cellMousedownEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("cellMousedownEvent",{target:elTarget,event:e});
                 break;
             case "span":
-                if(YAHOO.util.Dom.hasClass(elTarget, YAHOO.widget.DataTable.CLASS_LABEL)) {
-                    oSelf.fireEvent("headerLabelMousedownEvent",{target:elTarget,event:e});
+                if(Dom.hasClass(elTarget, DT.CLASS_LABEL)) {
+                    bKeepBubbling = oSelf.fireEvent("theadLabelMousedownEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerLabelMousedownEvent",{target:elTarget,event:e});
                 }
                 break;
             case "th":
-                oSelf.fireEvent("headerCellMousedownEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("theadCellMousedownEvent",{target:elTarget,event:e});
+                // Backward compatibility
+                bKeepBubbling = oSelf.fireEvent("headerCellMousedownEvent",{target:elTarget,event:e});
                 break;
             case "tr":
-                if(elTarget.parentNode.tagName.toLowerCase() == "thead") {
-                    oSelf.fireEvent("headerRowMousedownEvent",{target:elTarget,event:e});
+                if(elTarget.parentNode.nodeName.toLowerCase() == "thead") {
+                    bKeepBubbling = oSelf.fireEvent("theadRowMousedownEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerRowMousedownEvent",{target:elTarget,event:e});
                 }
                 else {
-                    oSelf.fireEvent("rowMousedownEvent",{target:elTarget,event:e});
+                    bKeepBubbling = oSelf.fireEvent("rowMousedownEvent",{target:elTarget,event:e});
                 }
                 break;
             default:
                 break;
         }
-        elTarget = elTarget.parentNode;
-        if(elTarget) {
-            elTag = elTarget.tagName.toLowerCase();
+        if(bKeepBubbling === false) {
+            return;
         }
+        else {
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
+            }
+        }
     }
-    oSelf.fireEvent("tableMousedownEvent",{target:(elTarget || oSelf._elTable),event:e});
-};
+    oSelf.fireEvent("tableMousedownEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
 /**
- * Handles dblclick events on the TABLE element.
+ * Handles dblclick events on the DataTable instance.
  *
  * @method _onTableDblclick
  * @param e {HTMLEvent} The dblclick event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableDblclick = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
+_onTableDblclick : function(e, oSelf) {
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
     while(elTarget && (elTag != "table")) {
         switch(elTag) {
             case "body":
-                break;
+                return;
             case "td":
-                oSelf.fireEvent("cellDblclickEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("cellDblclickEvent",{target:elTarget,event:e});
                 break;
             case "span":
-                if(YAHOO.util.Dom.hasClass(elTarget, YAHOO.widget.DataTable.CLASS_LABEL)) {
-                    oSelf.fireEvent("headerLabelDblclickEvent",{target:elTarget,event:e});
+                if(Dom.hasClass(elTarget, DT.CLASS_LABEL)) {
+                    bKeepBubbling = oSelf.fireEvent("theadLabelDblclickEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerLabelDblclickEvent",{target:elTarget,event:e});
                 }
                 break;
             case "th":
-                oSelf.fireEvent("headerCellDblclickEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("theadCellDblclickEvent",{target:elTarget,event:e});
+                // Backward compatibility
+                bKeepBubbling = oSelf.fireEvent("headerCellDblclickEvent",{target:elTarget,event:e});
                 break;
             case "tr":
-                if(elTarget.parentNode.tagName.toLowerCase() == "thead") {
-                    oSelf.fireEvent("headerRowDblclickEvent",{target:elTarget,event:e});
+                if(elTarget.parentNode.nodeName.toLowerCase() == "thead") {
+                    bKeepBubbling = oSelf.fireEvent("theadRowDblclickEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerRowDblclickEvent",{target:elTarget,event:e});
                 }
                 else {
-                    oSelf.fireEvent("rowDblclickEvent",{target:elTarget,event:e});
+                    bKeepBubbling = oSelf.fireEvent("rowDblclickEvent",{target:elTarget,event:e});
                 }
                 break;
             default:
                 break;
         }
-        elTarget = elTarget.parentNode;
-        if(elTarget) {
-            elTag = elTarget.tagName.toLowerCase();
+        if(bKeepBubbling === false) {
+            return;
         }
+        else {
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
+            }
+        }
     }
-    oSelf.fireEvent("tableDblclickEvent",{target:(elTarget || oSelf._elTable),event:e});
-};
-
+    oSelf.fireEvent("tableDblclickEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 /**
- * Handles keydown events on the TABLE element. Handles arrow selection.
+ * Handles keydown events on the THEAD element.
  *
- * @method _onTableKeydown
+ * @method _onTheadKeydown
  * @param e {HTMLEvent} The key event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableKeydown = function(e, oSelf) {
-    var bSHIFT = e.shiftKey;
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    
-    // Ignore actions in the THEAD
-    if(YAHOO.util.Dom.isAncestor(oSelf._elThead, elTarget)) {
-        return;
+_onTheadKeydown : function(e, oSelf) {
+    // If tabbing to next TH label link causes THEAD to scroll,
+    // need to sync scrollLeft with TBODY
+    if(Ev.getCharCode(e) === 9) {
+        setTimeout(function() {
+            if((oSelf instanceof DT) && oSelf._sId) {
+                oSelf._elTbodyContainer.scrollLeft = oSelf._elTheadContainer.scrollLeft;
+            }
+        },0);
     }
     
-    var nKey = YAHOO.util.Event.getCharCode(e);
-    
-    // Handle TAB
-    if(nKey === 9) {
-        // From TABLE el focus first TH label link, if any
-        if(!bSHIFT && (elTarget.id === oSelf._elTable.id) && oSelf._sFirstLabelLinkId) {
-            YAHOO.util.Event.stopEvent(e);
-            
-            oSelf._focusEl(YAHOO.util.Dom.get(oSelf._sFirstLabelLinkId));
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
+    while(elTarget && (elTag != "table")) {
+        switch(elTag) {
+            case "body":
+                return;
+            case "input":
+            case "textarea":
+                // TODO
+                break;
+            case "thead":
+                bKeepBubbling = oSelf.fireEvent("theadKeyEvent",{target:elTarget,event:e});
+                break;
+            default:
+                break;
         }
-        return;
-    }
-
-    // Handle ARROW selection
-    if((nKey > 36) && (nKey < 41)) {
-        YAHOO.util.Event.stopEvent(e);
-        
-        var allRows = oSelf._elTbody.rows;
-        var sMode = oSelf.get("selectionMode");
-
-        var i, oAnchorCell, oAnchorRecord, nAnchorRecordIndex, nAnchorTrIndex, oAnchorColumn, nAnchorColKeyIndex,
-        oTriggerCell, oTriggerRecord, nTriggerRecordIndex, nTriggerTrIndex, oTriggerColumn, nTriggerColKeyIndex, elTriggerRow,
-        startIndex, endIndex, anchorPos, elNext;
-        
-        // Row mode
-        if((sMode == "standard") || (sMode == "single")) {
-            // Validate trigger row:
-            // Arrow selection only works if last selected row is on current page
-            oTriggerRecord = oSelf.getLastSelectedRecord();
-            // No selected rows found
-            if(!oTriggerRecord) {
-                    return;
-            }
-            else {
-                oTriggerRecord = oSelf.getRecord(oTriggerRecord);
-                nTriggerRecordIndex = oSelf.getRecordIndex(oTriggerRecord);
-                elTriggerRow = oSelf.getTrEl(oTriggerRecord);
-                nTriggerTrIndex = oSelf.getTrIndex(elTriggerRow);
-                
-                // Last selected row not found on this page
-                if(nTriggerTrIndex === null) {
-                    return;
-                }
-            }
-           
-            // Validate anchor row
-            oAnchorRecord = oSelf._oAnchorRecord;
-            if(!oAnchorRecord) {
-                oAnchorRecord = oSelf._oAnchorRecord = oTriggerRecord;
-            }
-            
-            nAnchorRecordIndex = oSelf.getRecordIndex(oAnchorRecord);
-            nAnchorTrIndex = oSelf.getTrIndex(oAnchorRecord);
-            // If anchor row is not on this page...
-            if(nAnchorTrIndex === null) {
-                // ...set TR index equal to top TR
-                if(nAnchorRecordIndex < oSelf.getRecordIndex(oSelf.getFirstTrEl())) {
-                    nAnchorTrIndex = 0;
-                }
-                // ...set TR index equal to bottom TR
-                else {
-                    nAnchorTrIndex = oSelf.getRecordIndex(oSelf.getLastTrEl());
-                }
-            }
-
-
-
-
-
-
-        ////////////////////////////////////////////////////////////////////////
-        //
-        // SHIFT row selection
-        //
-        ////////////////////////////////////////////////////////////////////////
-        if(bSHIFT && (sMode != "single")) {
-            if(nAnchorRecordIndex > nTriggerTrIndex) {
-                anchorPos = 1;
-            }
-            else if(nAnchorRecordIndex < nTriggerTrIndex) {
-                anchorPos = -1;
-            }
-            else {
-                anchorPos = 0;
-            }
-
-            // Arrow down
-            if(nKey == 40) {
-                // Selecting away from anchor row
-                if(anchorPos <= 0) {
-                    // Select the next row down
-                    if(nTriggerTrIndex < allRows.length-1) {
-                        oSelf.selectRow(allRows[nTriggerTrIndex+1]);
-                    }
-                }
-                // Unselecting toward anchor row
-                else {
-                    // Unselect this row towards the anchor row down
-                    oSelf.unselectRow(allRows[nTriggerTrIndex]);
-                }
-
-            }
-            // Arrow up
-            else if(nKey == 38) {
-                // Selecting away from anchor row
-                if(anchorPos >= 0) {
-                    // Select the next row up
-                    if(nTriggerTrIndex > 0) {
-                        oSelf.selectRow(allRows[nTriggerTrIndex-1]);
-                    }
-                }
-                // Unselect this row towards the anchor row up
-                else {
-                    oSelf.unselectRow(allRows[nTriggerTrIndex]);
-                }
-            }
-            // Arrow right
-            else if(nKey == 39) {
-                // Do nothing
-            }
-            // Arrow left
-            else if(nKey == 37) {
-                // Do nothing
-            }
+        if(bKeepBubbling === false) {
+            return;
         }
-        ////////////////////////////////////////////////////////////////////////
-        //
-        // Simple single row selection
-        //
-        ////////////////////////////////////////////////////////////////////////
         else {
-            // Arrow down
-            if(nKey == 40) {
-                oSelf.unselectAllRows();
-
-                // Select the next row
-                if(nTriggerTrIndex < allRows.length-1) {
-                    elNext = allRows[nTriggerTrIndex+1];
-                    oSelf.selectRow(elNext);
-                }
-                // Select only the last row
-                else {
-                    elNext = allRows[nTriggerTrIndex];
-                    oSelf.selectRow(elNext);
-                }
-
-                oSelf._oAnchorRecord = oSelf.getRecord(elNext);
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
             }
-            // Arrow up
-            else if(nKey == 38) {
-                oSelf.unselectAllRows();
+        }
+    }
+    oSelf.fireEvent("tableKeyEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
-                // Select the previous row
-                if(nTriggerTrIndex > 0) {
-                    elNext = allRows[nTriggerTrIndex-1];
-                    oSelf.selectRow(elNext);
-                }
-                // Select only the first row
-                else {
-                    elNext = allRows[nTriggerTrIndex];
-                    oSelf.selectRow(elNext);
-                }
+/**
+ * Handles keydown events on the TBODY element. Handles selection behavior,
+ * provides hooks for ENTER to edit functionality.
+ *
+ * @method _onTbodyKeydown
+ * @param e {HTMLEvent} The key event.
+ * @param oSelf {DT} DataTable instance.
+ * @private
+ */
+_onTbodyKeydown : function(e, oSelf) {
+    var sMode = oSelf.get("selectionMode");
 
-                oSelf._oAnchorRecord = oSelf.getRecord(elNext);
-            }
-            // Arrow right
-            else if(nKey == 39) {
-                // Do nothing
-            }
-            // Arrow left
-            else if(nKey == 37) {
-                // Do nothing
-            }
-
-
-
-
-
-
-
-
+    if(sMode == "standard") {
+        oSelf._handleStandardSelectionByKey(e);
     }
+    else if(sMode == "single") {
+        oSelf._handleSingleSelectionByKey(e);
+    }
+    else if(sMode == "cellblock") {
+        oSelf._handleCellBlockSelectionByKey(e);
+    }
+    else if(sMode == "cellrange") {
+        oSelf._handleCellRangeSelectionByKey(e);
+    }
+    else if(sMode == "singlecell") {
+        oSelf._handleSingleCellSelectionByKey(e);
+    }
+    
+    if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
+        oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
+    }
 
-
-
-
-
-
-
-
-
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
+    while(elTarget && (elTag != "table")) {
+        switch(elTag) {
+            case "body":
+                return;
+            case "tbody":
+                bKeepBubbling = oSelf.fireEvent("tbodyKeyEvent",{target:elTarget,event:e});
+                break;
+            default:
+                break;
         }
-        // Cell mode
+        if(bKeepBubbling === false) {
+            return;
+        }
         else {
-            // Validate trigger cell:
-            // Arrow selection only works if last selected cell is on current page
-            oTriggerCell = oSelf.getLastSelectedCell();
-            // No selected cells found
-            if(!oTriggerCell) {
-                return;
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
             }
-            else {
-                oTriggerRecord = oSelf.getRecord(oTriggerCell.recordId);
-                nTriggerRecordIndex = oSelf.getRecordIndex(oTriggerRecord);
-                elTriggerRow = oSelf.getTrEl(oTriggerRecord);
-                nTriggerTrIndex = oSelf.getTrIndex(elTriggerRow);
-
-                // Last selected cell not found on this page
-                if(nTriggerTrIndex === null) {
-                    return;
-                }
-                else {
-                    oTriggerColumn = oSelf.getColumnById(oTriggerCell.columnId);
-                    nTriggerColKeyIndex = oTriggerColumn.getKeyIndex();
-                }
-            }
-
-            // Validate anchor cell
-            oAnchorCell = oSelf._oAnchorCell;
-            if(!oAnchorCell) {
-                oAnchorCell = oSelf._oAnchorCell = oTriggerCell;
-            }
-            oAnchorRecord = oSelf._oAnchorCell.record;
-            nAnchorRecordIndex = oSelf._oRecordSet.getRecordIndex(oAnchorRecord);
-            nAnchorTrIndex = oSelf.getTrIndex(oAnchorRecord);
-            // If anchor cell is not on this page...
-            if(nAnchorTrIndex === null) {
-                // ...set TR index equal to top TR
-                if(nAnchorRecordIndex < oSelf.getRecordIndex(oSelf.getFirstTrEl())) {
-                    nAnchorTrIndex = 0;
-                }
-                // ...set TR index equal to bottom TR
-                else {
-                    nAnchorTrIndex = oSelf.getRecordIndex(oSelf.getLastTrEl());
-                }
-            }
-
-            oAnchorColumn = oSelf._oAnchorCell.column;
-            nAnchorColKeyIndex = oAnchorColumn.getKeyIndex();
-
-
-            ////////////////////////////////////////////////////////////////////////
-            //
-            // SHIFT cell block selection
-            //
-            ////////////////////////////////////////////////////////////////////////
-            if(bSHIFT && (sMode == "cellblock")) {
-                // Arrow DOWN
-                if(nKey == 40) {
-                    // Is the anchor cell above, below, or same row as trigger
-                    if(nAnchorRecordIndex > nTriggerRecordIndex) {
-                        anchorPos = 1;
-                    }
-                    else if(nAnchorRecordIndex < nTriggerRecordIndex) {
-                        anchorPos = -1;
-                    }
-                    else {
-                        anchorPos = 0;
-                    }
-
-                    // Selecting away from anchor cell
-                    if(anchorPos <= 0) {
-                        // Select the horiz block on the next row...
-                        // ...making sure there is room below the trigger row
-                        if(nTriggerTrIndex < allRows.length-1) {
-                            // Select in order from anchor to trigger...
-                            startIndex = nAnchorColKeyIndex;
-                            endIndex = nTriggerColKeyIndex;
-                            // ...going left
-                            if(startIndex > endIndex) {
-                                for(i=startIndex; i>=endIndex; i--) {
-                                    elNext = allRows[nTriggerTrIndex+1].cells[i];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                            // ... going right
-                            else {
-                                for(i=startIndex; i<=endIndex; i++) {
-                                    elNext = allRows[nTriggerTrIndex+1].cells[i];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else {
-                        startIndex = Math.min(nAnchorColKeyIndex, nTriggerColKeyIndex);
-                        endIndex = Math.max(nAnchorColKeyIndex, nTriggerColKeyIndex);
-                        // Unselect the horiz block on this row towards the next row
-                        for(i=startIndex; i<=endIndex; i++) {
-                            oSelf.unselectCell(allRows[nTriggerTrIndex].cells[i]);
-                        }
-                    }
-                }
-                // Arrow up
-                else if(nKey == 38) {
-                    // Is the anchor cell above, below, or same row as trigger
-                    if(nAnchorRecordIndex > nTriggerRecordIndex) {
-                        anchorPos = 1;
-                    }
-                    else if(nAnchorRecordIndex < nTriggerRecordIndex) {
-                        anchorPos = -1;
-                    }
-                    else {
-                        anchorPos = 0;
-                    }
-                    
-                    // Selecting away from anchor cell
-                    if(anchorPos >= 0) {
-                        // Select the horiz block on the previous row...
-                        // ...making sure there is room
-                        if(nTriggerTrIndex > 0) {
-                            // Select in order from anchor to trigger...
-                            startIndex = nAnchorColKeyIndex;
-                            endIndex = nTriggerColKeyIndex;
-                            // ...going left
-                            if(startIndex > endIndex) {
-                                for(i=startIndex; i>=endIndex; i--) {
-                                    elNext = allRows[nTriggerTrIndex-1].cells[i];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                            // ... going right
-                            else {
-                                for(i=startIndex; i<=endIndex; i++) {
-                                    elNext = allRows[nTriggerTrIndex-1].cells[i];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else {
-                        startIndex = Math.min(nAnchorColKeyIndex, nTriggerColKeyIndex);
-                        endIndex = Math.max(nAnchorColKeyIndex, nTriggerColKeyIndex);
-                        // Unselect the horiz block on this row towards the previous row
-                        for(i=startIndex; i<=endIndex; i++) {
-                            oSelf.unselectCell(allRows[nTriggerTrIndex].cells[i]);
-                        }
-                    }
-                }
-                // Arrow right
-                else if(nKey == 39) {
-                    // Is the anchor cell left, right, or same column
-                    if(nAnchorColKeyIndex > nTriggerColKeyIndex) {
-                        anchorPos = 1;
-                    }
-                    else if(nAnchorColKeyIndex < nTriggerColKeyIndex) {
-                        anchorPos = -1;
-                    }
-                    else {
-                        anchorPos = 0;
-                    }
-
-                    // Selecting away from anchor cell
-                    if(anchorPos <= 0) {
-                        // Select the next vert block to the right...
-                        // ...making sure there is room
-                        if(nTriggerColKeyIndex < allRows[nTriggerTrIndex].cells.length-1) {
-                            // Select in order from anchor to trigger...
-                            startIndex = nAnchorTrIndex;
-                            endIndex = nTriggerTrIndex;
-                            // ...going up
-                            if(startIndex > endIndex) {
-                                for(i=startIndex; i>=endIndex; i--) {
-                                    elNext = allRows[i].cells[nTriggerColKeyIndex+1];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                            // ... going down
-                            else {
-                                for(i=startIndex; i<=endIndex; i++) {
-                                    elNext = allRows[i].cells[nTriggerColKeyIndex+1];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else {
-                        // Unselect the vert block on this column towards the right
-                        startIndex = Math.min(nAnchorTrIndex, nTriggerTrIndex);
-                        endIndex = Math.max(nAnchorTrIndex, nTriggerTrIndex);
-                        for(i=startIndex; i<=endIndex; i++) {
-                            oSelf.unselectCell(allRows[i].cells[nTriggerColKeyIndex]);
-                        }
-                    }
-                }
-                // Arrow left
-                else if(nKey == 37) {
-                    // Is the anchor cell left, right, or same column
-                    if(nAnchorColKeyIndex > nTriggerColKeyIndex) {
-                        anchorPos = 1;
-                    }
-                    else if(nAnchorColKeyIndex < nTriggerColKeyIndex) {
-                        anchorPos = -1;
-                    }
-                    else {
-                        anchorPos = 0;
-                    }
-
-                    // Selecting away from anchor cell
-                    if(anchorPos >= 0) {
-                        //Select the previous vert block to the left
-                        if(nTriggerColKeyIndex > 0) {
-                            // Select in order from anchor to trigger...
-                            startIndex = nAnchorTrIndex;
-                            endIndex = nTriggerTrIndex;
-                            // ...going up
-                            if(startIndex > endIndex) {
-                                for(i=startIndex; i>=endIndex; i--) {
-                                    elNext = allRows[i].cells[nTriggerColKeyIndex-1];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                            // ... going down
-                            else {
-                                for(i=startIndex; i<=endIndex; i++) {
-                                    elNext = allRows[i].cells[nTriggerColKeyIndex-1];
-                                    oSelf.selectCell(elNext);
-                                }
-                            }
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else {
-                        // Unselect the vert block on this column towards the left
-                        startIndex = Math.min(nAnchorTrIndex, nTriggerTrIndex);
-                        endIndex = Math.max(nAnchorTrIndex, nTriggerTrIndex);
-                        for(i=startIndex; i<=endIndex; i++) {
-                            oSelf.unselectCell(allRows[i].cells[nTriggerColKeyIndex]);
-                        }
-                    }
-                }
-            }
-            ////////////////////////////////////////////////////////////////////////
-            //
-            // SHIFT cell range selection
-            //
-            ////////////////////////////////////////////////////////////////////////
-            else if(bSHIFT && (sMode == "cellrange")) {
-                // Is the anchor cell above, below, or same row as trigger
-                if(nAnchorRecordIndex > nTriggerRecordIndex) {
-                    anchorPos = 1;
-                }
-                else if(nAnchorRecordIndex < nTriggerRecordIndex) {
-                    anchorPos = -1;
-                }
-                else {
-                    anchorPos = 0;
-                }
-
-                // Arrow down
-                if(nKey == 40) {
-                    // Selecting away from anchor cell
-                    if(anchorPos <= 0) {
-                        // Select all cells to the end of this row
-                        for(i=nTriggerColKeyIndex+1; i<allRows[nTriggerTrIndex].cells.length; i++){
-                            elNext = allRows[nTriggerTrIndex].cells[i];
-                            oSelf.selectCell(elNext);
-                        }
-
-                        // Select some of the cells on the next row down
-                        if(nTriggerTrIndex < allRows.length-1) {
-                            for(i=0; i<=nTriggerColKeyIndex; i++){
-                                elNext = allRows[nTriggerTrIndex+1].cells[i];
-                                oSelf.selectCell(elNext);
-                            }
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else {
-                        // Unselect all cells to the end of this row
-                        for(i=nTriggerColKeyIndex; i<allRows[nTriggerTrIndex].cells.length; i++){
-                            oSelf.unselectCell(allRows[nTriggerTrIndex].cells[i]);
-                        }
-
-                        // Unselect some of the cells on the next row down
-                        for(i=0; i<nTriggerColKeyIndex; i++){
-                            oSelf.unselectCell(allRows[nTriggerTrIndex+1].cells[i]);
-                        }
-                    }
-                }
-                // Arrow up
-                else if(nKey == 38) {
-                    // Selecting away from anchor cell
-                    if(anchorPos >= 0) {
-                        // Select all the cells to the beginning of this row
-                        for(i=nTriggerColKeyIndex-1; i>-1; i--){
-                            elNext = allRows[nTriggerTrIndex].cells[i];
-                            oSelf.selectCell(elNext);
-                        }
-
-                        // Select some of the cells from the end of the previous row
-                        if(nTriggerTrIndex > 0) {
-                            for(i=allRows[nTriggerTrIndex].cells.length-1; i>=nTriggerColKeyIndex; i--){
-                                elNext = allRows[nTriggerTrIndex-1].cells[i];
-                                oSelf.selectCell(elNext);
-                            }
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else {
-                        // Unselect all the cells to the beginning of this row
-                        for(i=nTriggerColKeyIndex; i>-1; i--){
-                            oSelf.unselectCell(allRows[nTriggerTrIndex].cells[i]);
-                        }
-
-                        // Unselect some of the cells from the end of the previous row
-                        for(i=allRows[nTriggerTrIndex].cells.length-1; i>nTriggerColKeyIndex; i--){
-                            oSelf.unselectCell(allRows[nTriggerTrIndex-1].cells[i]);
-                        }
-                    }
-                }
-                // Arrow right
-                else if(nKey == 39) {
-                    // Selecting away from anchor cell
-                    if(anchorPos < 0) {
-                        // Select the next cell to the right
-                        if(nTriggerColKeyIndex < allRows[nTriggerTrIndex].cells.length-1) {
-                            elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex+1];
-                            oSelf.selectCell(elNext);
-                        }
-                        // Select the first cell of the next row
-                        else if(nTriggerTrIndex < allRows.length-1) {
-                            elNext = allRows[nTriggerTrIndex+1].cells[0];
-                            oSelf.selectCell(elNext);
-                        }
-                    }
-                    // Unselecting towards anchor cell
-                    else if(anchorPos > 0) {
-                        oSelf.unselectCell(allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex]);
-
-                        // Unselect this cell towards the right
-                        if(nTriggerColKeyIndex < allRows[nTriggerTrIndex].cells.length-1) {
-                        }
-                        // Unselect this cells towards the first cell of the next row
-                        else {
-                        }
-                    }
-                    // Anchor is on this row
-                    else {
-                        // Selecting away from anchor
-                        if(nAnchorColKeyIndex <= nTriggerColKeyIndex) {
-                            // Select the next cell to the right
-                            if(nTriggerColKeyIndex < allRows[nTriggerTrIndex].cells.length-1) {
-                                elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex+1];
-                                oSelf.selectCell(elNext);
-                            }
-                            // Select the first cell on the next row
-                            else if(nTriggerTrIndex < allRows.length-1){
-                                elNext = allRows[nTriggerTrIndex+1].cells[0];
-                                oSelf.selectCell(elNext);
-                            }
-                        }
-                        // Unselecting towards anchor
-                        else {
-                            // Unselect this cell towards the right
-                            oSelf.unselectCell(allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex]);
-                        }
-                    }
-                }
-                // Arrow left
-                else if(nKey == 37) {
-                    // Unselecting towards the anchor
-                    if(anchorPos < 0) {
-                        oSelf.unselectCell(allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex]);
-
-                        // Unselect this cell towards the left
-                        if(nTriggerColKeyIndex > 0) {
-                        }
-                        // Unselect this cell towards the last cell of the previous row
-                        else {
-                        }
-                    }
-                    // Selecting towards the anchor
-                    else if(anchorPos > 0) {
-                        // Select the next cell to the left
-                        if(nTriggerColKeyIndex > 0) {
-                            elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex-1];
-                            oSelf.selectCell(elNext);
-                        }
-                        // Select the last cell of the previous row
-                        else if(nTriggerTrIndex > 0){
-                            elNext = allRows[nTriggerTrIndex-1].cells[allRows[nTriggerTrIndex-1].cells.length-1];
-                            oSelf.selectCell(elNext);
-                        }
-                    }
-                    // Anchor is on this row
-                    else {
-                        // Selecting away from anchor cell
-                        if(nAnchorColKeyIndex >= nTriggerColKeyIndex) {
-                            // Select the next cell to the left
-                            if(nTriggerColKeyIndex > 0) {
-                                elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex-1];
-                                oSelf.selectCell(elNext);
-                            }
-                            // Select the last cell of the previous row
-                            else if(nTriggerTrIndex > 0){
-                                elNext = allRows[nTriggerTrIndex-1].cells[allRows[nTriggerTrIndex-1].cells.length-1];
-                                oSelf.selectCell(elNext);
-                            }
-                        }
-                        // Unselecting towards anchor cell
-                        else {
-                            oSelf.unselectCell(allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex]);
-
-                            // Unselect this cell towards the left
-                            if(nTriggerColKeyIndex > 0) {
-                            }
-                            // Unselect this cell towards the last cell of the previous row
-                            else {
-                            }
-                        }
-                    }
-                }
-            }
-            ////////////////////////////////////////////////////////////////////////
-            //
-            // Simple single cell selection
-            //
-            ////////////////////////////////////////////////////////////////////////
-            else if((sMode == "cellblock") || (sMode == "cellrange") || (sMode == "singlecell")) {
-                // Arrow down
-                if(nKey == 40) {
-                    oSelf.unselectAllCells();
-
-                    // Select the next cell down
-                    if(nTriggerTrIndex < allRows.length-1) {
-                        elNext = allRows[nTriggerTrIndex+1].cells[nTriggerColKeyIndex];
-                        oSelf.selectCell(elNext);
-                    }
-                    // Select only the bottom cell
-                    else {
-                        elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex];
-                        oSelf.selectCell(elNext);
-                    }
-
-                    oSelf._oAnchorCell = {record:oSelf.getRecord(elNext), column:oSelf.getColumn(elNext)};
-                }
-                // Arrow up
-                else if(nKey == 38) {
-                    oSelf.unselectAllCells();
-
-                    // Select the next cell up
-                    if(nTriggerTrIndex > 0) {
-                        elNext = allRows[nTriggerTrIndex-1].cells[nTriggerColKeyIndex];
-                        oSelf.selectCell(elNext);
-                    }
-                    // Select only the top cell
-                    else {
-                        elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex];
-                        oSelf.selectCell(elNext);
-                    }
-
-                    oSelf._oAnchorCell = {record:oSelf.getRecord(elNext), column:oSelf.getColumn(elNext)};
-                }
-                // Arrow right
-                else if(nKey == 39) {
-                    oSelf.unselectAllCells();
-
-                    // Select the next cell to the right
-                    if(nTriggerColKeyIndex < allRows[nTriggerTrIndex].cells.length-1) {
-                        elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex+1];
-                        oSelf.selectCell(elNext);
-                    }
-                    // Select only the right cell
-                    else {
-                        elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex];
-                        oSelf.selectCell(elNext);
-                    }
-
-                    oSelf._oAnchorCell = {record:oSelf.getRecord(elNext), column:oSelf.getColumn(elNext)};
-                }
-                // Arrow left
-                else if(nKey == 37) {
-                    oSelf.unselectAllCells();
-
-                    // Select the next cell to the left
-                    if(nTriggerColKeyIndex > 0) {
-                        elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex-1];
-                        oSelf.selectCell(elNext);
-                    }
-                    // Select only the left cell
-                    else {
-                        elNext = allRows[nTriggerTrIndex].cells[nTriggerColKeyIndex];
-                        oSelf.selectCell(elNext);
-                    }
-
-                    oSelf._oAnchorCell = {record:oSelf.getRecord(elNext), column:oSelf.getColumn(elNext)};
-                }
-            }
-
-
-
-
-
-
-
-
-
-
-
-
-
         }
     }
-    else {
-        //TODO: handle tab across cells
-        //TODO: handle backspace
-        //TODO: handle delete
-        //TODO: handle arrow selection across pages
-        return;
-    }
-};
+    oSelf.fireEvent("tableKeyEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
 /**
  * Handles keypress events on the TABLE. Mainly to support stopEvent on Mac.
  *
  * @method _onTableKeypress
  * @param e {HTMLEvent} The key event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTableKeypress = function(e, oSelf) {
-    var isMac = (navigator.userAgent.toLowerCase().indexOf("mac") != -1);
-    if(isMac) {
-        var nKey = YAHOO.util.Event.getCharCode(e);
+_onTableKeypress : function(e, oSelf) {
+    if(ua.webkit) {
+        var nKey = Ev.getCharCode(e);
         // arrow down
         if(nKey == 40) {
-            YAHOO.util.Event.stopEvent(e);
+            Ev.stopEvent(e);
         }
         // arrow up
         else if(nKey == 38) {
-            YAHOO.util.Event.stopEvent(e);
+            Ev.stopEvent(e);
         }
     }
-};
+},
 
 /**
  * Handles click events on the THEAD element.
  *
  * @method _onTheadClick
  * @param e {HTMLEvent} The click event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onTheadClick = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
+_onTheadClick : function(e, oSelf) {
+    // Always blur the cell editor
     if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
         oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
     }
 
-    while(elTarget && (elTag != "thead")) {
-            switch(elTag) {
-                case "body":
-                    break;
-                case "span":
-                    if(YAHOO.util.Dom.hasClass(elTarget, YAHOO.widget.DataTable.CLASS_LABEL)) {
-                        oSelf.fireEvent("headerLabelClickEvent",{target:elTarget,event:e});
-                    }
-                    break;
-                case "th":
-                    oSelf.fireEvent("headerCellClickEvent",{target:elTarget,event:e});
-                    break;
-                case "tr":
-                    oSelf.fireEvent("headerRowClickEvent",{target:elTarget,event:e});
-                    break;
-                default:
-                    break;
-            }
-            elTarget = elTarget.parentNode;
-            if(elTarget) {
-                elTag = elTarget.tagName.toLowerCase();
-            }
-    }
-    oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elTable),event:e});
-};
-
-/**
- * Handles click events on the primary TBODY element.
- *
- * @method _onTbodyClick
- * @param e {HTMLEvent} The click event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
- * @private
- */
-YAHOO.widget.DataTable.prototype._onTbodyClick = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
-    if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
-        oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
-    }
-
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
     while(elTarget && (elTag != "table")) {
         switch(elTag) {
             case "body":
-                break;
+                return;
             case "input":
                 if(elTarget.type.toLowerCase() == "checkbox") {
-                    oSelf.fireEvent("checkboxClickEvent",{target:elTarget,event:e});
+                    bKeepBubbling = oSelf.fireEvent("theadCheckboxClickEvent",{target:elTarget,event:e});
                 }
                 else if(elTarget.type.toLowerCase() == "radio") {
-                    oSelf.fireEvent("radioClickEvent",{target:elTarget,event:e});
+                    bKeepBubbling = oSelf.fireEvent("theadRadioClickEvent",{target:elTarget,event:e});
                 }
-                oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elTable),event:e});
-                return;
+                break;
             case "a":
-                oSelf.fireEvent("linkClickEvent",{target:elTarget,event:e});
-                oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elTable),event:e});
-                return;
+                bKeepBubbling = oSelf.fireEvent("theadLinkClickEvent",{target:elTarget,event:e});
+                break;
             case "button":
-                oSelf.fireEvent("buttonClickEvent",{target:elTarget,event:e});
-                oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elTable),event:e});
-                return;
-            case "td":
-                oSelf.fireEvent("cellClickEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("theadButtonClickEvent",{target:elTarget,event:e});
                 break;
+            case "span":
+                if(Dom.hasClass(elTarget, DT.CLASS_LABEL)) {
+                    bKeepBubbling = oSelf.fireEvent("theadLabelClickEvent",{target:elTarget,event:e});
+                    // Backward compatibility
+                    bKeepBubbling = oSelf.fireEvent("headerLabelClickEvent",{target:elTarget,event:e});
+                }
+                break;
+            case "th":
+                bKeepBubbling = oSelf.fireEvent("theadCellClickEvent",{target:elTarget,event:e});
+                // Backward compatibility
+                bKeepBubbling = oSelf.fireEvent("headerCellClickEvent",{target:elTarget,event:e});
+                break;
             case "tr":
-                oSelf.fireEvent("rowClickEvent",{target:elTarget,event:e});
+                bKeepBubbling = oSelf.fireEvent("theadRowClickEvent",{target:elTarget,event:e});
+                // Backward compatibility
+                bKeepBubbling = oSelf.fireEvent("headerRowClickEvent",{target:elTarget,event:e});
                 break;
             default:
                 break;
         }
-        elTarget = elTarget.parentNode;
-        if(elTarget) {
-            elTag = elTarget.tagName.toLowerCase();
+        if(bKeepBubbling === false) {
+            return;
         }
+        else {
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
+            }
+        }
     }
-    oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elTable),event:e});
-};
+    oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
-/*TODO: delete
- * Handles keyup events on the TBODY. Executes deletion.
- *
- * @method _onTbodyKeyup
- * @param e {HTMLEvent} The key event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
- * @private
- */
-/*YAHOO.widget.DataTable.prototype._onTbodyKeyup = function(e, oSelf) {
-   var nKey = YAHOO.util.Event.getCharCode(e);
-    // delete
-    if(nKey == 46) {//TODO: if something is selected
-        //TODO: delete row
-    }
-};*/
-
 /**
- * Handles click events on paginator links.
+ * Handles click events on the primary TBODY element.
  *
- * @method _onPaginatorLinkClick
+ * @method _onTbodyClick
  * @param e {HTMLEvent} The click event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
  */
-YAHOO.widget.DataTable.prototype._onPaginatorLinkClick = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var elTag = elTarget.tagName.toLowerCase();
-
+_onTbodyClick : function(e, oSelf) {
+    // Always blur the cell editor
     if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
         oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
     }
 
+    // Fire Custom Events
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
+    var bKeepBubbling = true;
     while(elTarget && (elTag != "table")) {
         switch(elTag) {
             case "body":
                 return;
-            case "a":
-                YAHOO.util.Event.stopEvent(e);
-                //TODO: after the showPage call, figure out which link
-                //TODO: was clicked and reset focus to the new version of it
-                switch(elTarget.className) {
-                    case YAHOO.widget.DataTable.CLASS_PAGE:
-                        oSelf.showPage(parseInt(elTarget.innerHTML,10));
-                        return;
-                    case YAHOO.widget.DataTable.CLASS_FIRST:
-                        oSelf.showPage(1);
-                        return;
-                    case YAHOO.widget.DataTable.CLASS_LAST:
-                        oSelf.showPage(oSelf.get("paginator").totalPages);
-                        return;
-                    case YAHOO.widget.DataTable.CLASS_PREVIOUS:
-                        oSelf.showPage(oSelf.get("paginator").currentPage - 1);
-                        return;
-                    case YAHOO.widget.DataTable.CLASS_NEXT:
-                        oSelf.showPage(oSelf.get("paginator").currentPage + 1);
-                        return;
+            case "input":
+                if(elTarget.type.toLowerCase() == "checkbox") {
+                    bKeepBubbling = oSelf.fireEvent("checkboxClickEvent",{target:elTarget,event:e});
                 }
+                else if(elTarget.type.toLowerCase() == "radio") {
+                    bKeepBubbling = oSelf.fireEvent("radioClickEvent",{target:elTarget,event:e});
+                }
                 break;
+            case "a":
+                bKeepBubbling = oSelf.fireEvent("linkClickEvent",{target:elTarget,event:e});
+                break;
+            case "button":
+                bKeepBubbling = oSelf.fireEvent("buttonClickEvent",{target:elTarget,event:e});
+                break;
+            case "td":
+                bKeepBubbling = oSelf.fireEvent("cellClickEvent",{target:elTarget,event:e});
+                break;
+            case "tr":
+                bKeepBubbling = oSelf.fireEvent("rowClickEvent",{target:elTarget,event:e});
+                break;
             default:
-                return;
+                break;
         }
-        elTarget = elTarget.parentNode;
-        if(elTarget) {
-            elTag = elTarget.tagName.toLowerCase();
+        if(bKeepBubbling === false) {
+            return;
         }
         else {
-            return;
+            elTarget = elTarget.parentNode;
+            if(elTarget) {
+                elTag = elTarget.nodeName.toLowerCase();
+            }
         }
     }
-};
+    oSelf.fireEvent("tableClickEvent",{target:(elTarget || oSelf._elContainer),event:e});
+},
 
-/**
- * Handles change events on paginator SELECT element.
- *
- * @method _onPaginatorDropdownChange
- * @param e {HTMLEvent} The change event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
- * @private
- */
-YAHOO.widget.DataTable.prototype._onPaginatorDropdownChange = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
-    var newValue = elTarget[elTarget.selectedIndex].value;
-
-    var newRowsPerPage = YAHOO.lang.isValue(parseInt(newValue,10)) ? parseInt(newValue,10) : null;
-    if(newRowsPerPage !== null) {
-        var newStartRecordIndex = (oSelf.get("paginator").currentPage-1) * newRowsPerPage;
-        oSelf.updatePaginator({rowsPerPage:newRowsPerPage, startRecordIndex:newStartRecordIndex});
-        oSelf.refreshView();
-    }
-    else {
-    }
-};
-
-/**
+/*TODO undeprecate?
  * Handles change events on SELECT elements within DataTable.
  *
  * @method _onDropdownChange
  * @param e {HTMLEvent} The change event.
- * @param oSelf {YAHOO.widget.DataTable} DataTable instance.
+ * @param oSelf {DT} DataTable instance.
  * @private
+ * @deprecated
  */
-YAHOO.widget.DataTable.prototype._onDropdownChange = function(e, oSelf) {
-    var elTarget = YAHOO.util.Event.getTarget(e);
+_onDropdownChange : function(e, oSelf) {
+    var elTarget = Ev.getTarget(e);
     //TODO: pass what args?
     //var value = elTarget[elTarget.selectedIndex].value;
     oSelf.fireEvent("dropdownChangeEvent", {event:e, target:elTarget});
-};
+},
 
 
 
@@ -3096,13 +8419,6 @@
 
 
 
-
-
-
-
-
-
-
 /////////////////////////////////////////////////////////////////////////////
 //
 // Public member variables
@@ -3116,18 +8432,27 @@
 //
 /////////////////////////////////////////////////////////////////////////////
 
-// OBJECT ACCESSORS
+/**
+ * Returns unique id assigned to instance, which is a useful prefix for
+ * generating unique DOM ID strings.
+ *
+ * @method getId
+ * @return {String} Unique ID of the DataSource instance.
+ */
+getId : function() {
+    return this._sId;
+},
 
 /**
- * Public accessor to the unique name of the DataSource instance.
+ * DataSource instance name, for logging.
  *
  * @method toString
  * @return {String} Unique name of the DataSource instance.
  */
 
-YAHOO.widget.DataTable.prototype.toString = function() {
-    return "DataTable " + this._sName;
-};
+toString : function() {
+    return "DataTable instance " + this._sId;
+},
 
 /**
  * Returns the DataTable instance's DataSource instance.
@@ -3135,9 +8460,9 @@
  * @method getDataSource
  * @return {YAHOO.util.DataSource} DataSource instance.
  */
-YAHOO.widget.DataTable.prototype.getDataSource = function() {
+getDataSource : function() {
     return this._oDataSource;
-};
+},
 
 /**
  * Returns the DataTable instance's ColumnSet instance.
@@ -3145,9 +8470,9 @@
  * @method getColumnSet
  * @return {YAHOO.widget.ColumnSet} ColumnSet instance.
  */
-YAHOO.widget.DataTable.prototype.getColumnSet = function() {
+getColumnSet : function() {
     return this._oColumnSet;
-};
+},
 
 /**
  * Returns the DataTable instance's RecordSet instance.
@@ -3155,9 +8480,9 @@
  * @method getRecordSet
  * @return {YAHOO.widget.RecordSet} RecordSet instance.
  */
-YAHOO.widget.DataTable.prototype.getRecordSet = function() {
+getRecordSet : function() {
     return this._oRecordSet;
-};
+},
 
 /**
  * Returns the DataTable instance's Cell Editor as an object literal with the
@@ -3196,6 +8521,10 @@
  *
  *  </dd>
  *
+ * <dt>defaultValue</dt>
+ * <dd>Dynamically settable default value</dd>
+ * </dl>
+ *
  * <dt>value</dt>
  * <dd>Current input value</dd>
  * </dl>
@@ -3204,13 +8533,12 @@
  *
  *
  *
- *
  * @method getCellEditor
  * @return {Object} Cell Editor object literal values.
  */
-YAHOO.widget.DataTable.prototype.getCellEditor = function() {
+getCellEditor : function() {
     return this._oCellEditor;
-};
+},
 
 
 
@@ -3257,14 +8585,14 @@
 // DOM ACCESSORS
 
 /**
- * Returns DOM reference to the DataTable's TABLE element.
+ * Returns DOM reference to the DataTable's container element.
  *
- * @method getTableEl
- * @return {HTMLElement} Reference to TABLE element.
+ * @method getContainerEl
+ * @return {HTMLElement} Reference to DIV element.
  */
-YAHOO.widget.DataTable.prototype.getTableEl = function() {
-    return this._elTable;
-};
+getContainerEl : function() {
+    return this._elContainer;
+},
 
 /**
  * Returns DOM reference to the DataTable's THEAD element.
@@ -3272,9 +8600,9 @@
  * @method getTheadEl
  * @return {HTMLElement} Reference to THEAD element.
  */
-YAHOO.widget.DataTable.prototype.getTheadEl = function() {
+getTheadEl : function() {
     return this._elThead;
-};
+},
 
 /**
  * Returns DOM reference to the DataTable's primary TBODY element.
@@ -3282,13 +8610,9 @@
  * @method getTbodyEl
  * @return {HTMLElement} Reference to TBODY element.
  */
-YAHOO.widget.DataTable.prototype.getTbodyEl = function() {
+getTbodyEl : function() {
     return this._elTbody;
-};
-// Backward compatibility
-YAHOO.widget.DataTable.prototype.getBody = function() {
-    return this.getTbodyEl();
-};
+},
 
 /**
  * Returns DOM reference to the DataTable's secondary TBODY element that is
@@ -3297,9 +8621,9 @@
  * @method getMsgTbodyEl
  * @return {HTMLElement} Reference to TBODY element.
  */
-YAHOO.widget.DataTable.prototype.getMsgTbodyEl = function() {
+getMsgTbodyEl : function() {
     return this._elMsgTbody;
-};
+},
 
 /**
  * Returns DOM reference to the TD element within the secondary TBODY that is
@@ -3308,9 +8632,9 @@
  * @method getMsgTdEl
  * @return {HTMLElement} Reference to TD element.
  */
-YAHOO.widget.DataTable.prototype.getMsgTdEl = function() {
+getMsgTdEl : function() {
     return this._elMsgTd;
-};
+},
 
 /**
  * Returns the corresponding TR reference for a given DOM element, ID string or
@@ -3323,9 +8647,9 @@
  * get: by element reference, ID string, page row index, or Record.
  * @return {HTMLElement} Reference to TR element, or null.
  */
-YAHOO.widget.DataTable.prototype.getTrEl = function(row) {
+getTrEl : function(row) {
     var allRows = this._elTbody.rows;
-    
+
     // By Record
     if(row instanceof YAHOO.widget.Record) {
         var nTrIndex = this.getTrIndex(row);
@@ -3338,20 +8662,20 @@
             }
     }
     // By page row index
-    else if(YAHOO.lang.isNumber(row) && (row > -1) && (row < allRows.length)) {
+    else if(lang.isNumber(row) && (row > -1) && (row < allRows.length)) {
         return allRows[row];
     }
     // By ID string or element reference
     else {
         var elRow;
-        var el = YAHOO.util.Dom.get(row);
-        
+        var el = Dom.get(row);
+
         // Validate HTML element
         if(el && (el.ownerDocument == document)) {
             // Validate TR element
-            if(el.tagName.toLowerCase() != "tr") {
+            if(el.nodeName.toLowerCase() != "tr") {
                 // Traverse up the DOM to find the corresponding TR element
-                elRow = YAHOO.util.Dom.getAncestorByTagName(el,"tr");
+                elRow = Dom.getAncestorByTagName(el,"tr");
             }
             else {
                 elRow = el;
@@ -3364,13 +8688,9 @@
             }
         }
     }
-    
+
     return null;
-};
-// Backward compatibility
-YAHOO.widget.DataTable.prototype.getRow = function(index) {
-    return this.getTrEl(index);
-};
+},
 
 /**
  * Returns DOM reference to the first TR element in the DataTable page, or null.
@@ -3378,9 +8698,9 @@
  * @method getFirstTrEl
  * @return {HTMLElement} Reference to TR element.
  */
-YAHOO.widget.DataTable.prototype.getFirstTrEl = function() {
+getFirstTrEl : function() {
     return this._elTbody.rows[0] || null;
-};
+},
 
 /**
  * Returns DOM reference to the last TR element in the DataTable page, or null.
@@ -3388,14 +8708,67 @@
  * @method getLastTrEl
  * @return {HTMLElement} Reference to last TR element.
  */
-YAHOO.widget.DataTable.prototype.getLastTrEl = function() {
+getLastTrEl : function() {
     var allRows = this._elTbody.rows;
         if(allRows.length > 0) {
             return allRows[allRows.length-1] || null;
         }
-};
+},
 
 /**
+ * Returns DOM reference to the next TR element from the given TR element, or null.
+ *
+ * @method getNextTrEl
+ * @param row {HTMLElement | String | Number | YAHOO.widget.Record} Element
+ * reference, ID string, page row index, or Record from which to get next TR element.
+ * @return {HTMLElement} Reference to next TR element.
+ */
+getNextTrEl : function(row) {
+    var nThisTrIndex = this.getTrIndex(row);
+    if(nThisTrIndex !== null) {
+        var allRows = this._elTbody.rows;
+        if(nThisTrIndex < allRows.length-1) {
+            return allRows[nThisTrIndex+1];
+        }
+    }
+
+    return null;
+},
+
+/**
+ * Returns DOM reference to the previous TR element from the given TR element, or null.
+ *
+ * @method getPreviousTrEl
+ * @param row {HTMLElement | String | Number | YAHOO.widget.Record} Element
+ * reference, ID string, page row index, or Record from which to get previous TR element.
+ * @return {HTMLElement} Reference to previous TR element.
+ */
+getPreviousTrEl : function(row) {
+    var nThisTrIndex = this.getTrIndex(row);
+    if(nThisTrIndex !== null) {
+        var allRows = this._elTbody.rows;
+        if(nThisTrIndex > 0) {
+            return allRows[nThisTrIndex-1];
+        }
+    }
+
+    return null;
+},
+
+/**
+ * Returns DOM reference to a TD liner element.
+ *
+ * @method getTdLinerEl
+ * @param cell {HTMLElement | String | Object} DOM element reference or string ID, or
+ * object literal of syntax {record:oRecord, column:oColumn}.
+ * @return {HTMLElement} Reference to TD liner element.
+ */
+getTdLinerEl : function(cell) {
+    var elCell = this.getTdEl(cell);
+    return elCell.firstChild || null;
+},
+
+/**
  * Returns DOM reference to a TD element.
  *
  * @method getTdEl
@@ -3403,16 +8776,16 @@
  * object literal of syntax {record:oRecord, column:oColumn}.
  * @return {HTMLElement} Reference to TD element.
  */
-YAHOO.widget.DataTable.prototype.getTdEl = function(cell) {
+getTdEl : function(cell) {
     var elCell;
-    var el = YAHOO.util.Dom.get(cell);
+    var el = Dom.get(cell);
 
     // Validate HTML element
     if(el && (el.ownerDocument == document)) {
         // Validate TD element
-        if(el.tagName.toLowerCase() != "td") {
+        if(el.nodeName.toLowerCase() != "td") {
             // Traverse up the DOM to find the corresponding TR element
-            elCell = YAHOO.util.Dom.getAncestorByTagName(el, "td");
+            elCell = Dom.getAncestorByTagName(el, "td");
         }
         else {
             elCell = el;
@@ -3424,60 +8797,207 @@
             return elCell;
         }
     }
-    else if(cell.record && cell.column && cell.column.getKeyIndex) {
-        var oRecord = cell.record;
+    else if(cell) {
+        var oRecord, nColKeyIndex;
+
+        if(lang.isString(cell.columnId) && lang.isString(cell.recordId)) {
+            oRecord = this.getRecord(cell.recordId);
+            var oColumn = this.getColumnById(cell.columnId);
+            if(oColumn) {
+                nColKeyIndex = oColumn.getKeyIndex();
+            }
+
+        }
+        if(cell.record && cell.column && cell.column.getKeyIndex) {
+            oRecord = cell.record;
+            nColKeyIndex = cell.column.getKeyIndex();
+        }
         var elRow = this.getTrEl(oRecord);
-        if(elRow && elRow.cells && elRow.cells.length > 0) {
-            return elRow.cells[cell.column.getKeyIndex()] || null;
+        if((nColKeyIndex !== null) && elRow && elRow.cells && elRow.cells.length > 0) {
+            return elRow.cells[nColKeyIndex] || null;
         }
     }
-    
+
     return null;
-};
+},
 
 /**
+ * Returns DOM reference to the first TD element in the DataTable page (by default),
+ * the first TD element of the optionally given row, or null.
+ *
+ * @method getFirstTdEl
+ * @param row {HTMLElement} (optional) row from which to get first TD
+ * @return {HTMLElement} Reference to TD element.
+ */
+getFirstTdEl : function(row) {
+    var elRow = this.getTrEl(row) || this.getFirstTrEl();
+    if(elRow && (elRow.cells.length > 0)) {
+        return elRow.cells[0];
+    }
+    return null;
+},
+
+/**
+ * Returns DOM reference to the last TD element in the DataTable page (by default),
+ * the first TD element of the optionally given row, or null.
+ *
+ * @method getLastTdEl
+ * @return {HTMLElement} Reference to last TD element.
+ */
+getLastTdEl : function(row) {
+    var elRow = this.getTrEl(row) || this.getLastTrEl();
+    if(elRow && (elRow.cells.length > 0)) {
+        return elRow.cells[elRow.cells.length-1];
+    }
+    return null;
+},
+
+/**
+ * Returns DOM reference to the next TD element from the given cell, or null.
+ *
+ * @method getNextTdEl
+ * @param cell {HTMLElement | String | Object} DOM element reference or string ID, or
+ * object literal of syntax {record:oRecord, column:oColumn} from which to get next TD element.
+ * @return {HTMLElement} Reference to next TD element, or null.
+ */
+getNextTdEl : function(cell) {
+    var elCell = this.getTdEl(cell);
+    if(elCell) {
+        var nThisTdIndex = elCell.yuiCellIndex;
+        var elRow = this.getTrEl(elCell);
+        if(nThisTdIndex < elRow.cells.length-1) {
+            return elRow.cells[nThisTdIndex+1];
+        }
+        else {
+            var elNextRow = this.getNextTrEl(elRow);
+            if(elNextRow) {
+                return elNextRow.cells[0];
+            }
+        }
+    }
+    return null;
+},
+
+/**
+ * Returns DOM reference to the previous TD element from the given cell, or null.
+ *
+ * @method getPreviousTdEl
+ * @param cell {HTMLElement | String | Object} DOM element reference or string ID, or
+ * object literal of syntax {record:oRecord, column:oColumn} from which to get previous TD element.
+ * @return {HTMLElement} Reference to previous TD element, or null.
+ */
+getPreviousTdEl : function(cell) {
+    var elCell = this.getTdEl(cell);
+    if(elCell) {
+        var nThisTdIndex = elCell.yuiCellIndex;
+        var elRow = this.getTrEl(elCell);
+        if(nThisTdIndex > 0) {
+            return elRow.cells[nThisTdIndex-1];
+        }
+        else {
+            var elPreviousRow = this.getPreviousTrEl(elRow);
+            if(elPreviousRow) {
+                return this.getLastTdEl(elPreviousRow);
+            }
+        }
+    }
+    return null;
+},
+
+/**
+ * Returns DOM reference to the above TD element from the given cell, or null.
+ *
+ * @method getAboveTdEl
+ * @param cell {HTMLElement | String | Object} DOM element reference or string ID, or
+ * object literal of syntax {record:oRecord, column:oColumn} from which to get next TD element.
+ * @return {HTMLElement} Reference to next TD element, or null.
+ */
+getAboveTdEl : function(cell) {
+    var elCell = this.getTdEl(cell);
+    if(elCell) {
+        var elPreviousRow = this.getPreviousTrEl(elCell);
+        if(elPreviousRow) {
+            return elPreviousRow.cells[elCell.yuiCellIndex];
+        }
+    }
+    return null;
+},
+
+/**
+ * Returns DOM reference to the below TD element from the given cell, or null.
+ *
+ * @method getBelowTdEl
+ * @param cell {HTMLElement | String | Object} DOM element reference or string ID, or
+ * object literal of syntax {record:oRecord, column:oColumn} from which to get previous TD element.
+ * @return {HTMLElement} Reference to previous TD element, or null.
+ */
+getBelowTdEl : function(cell) {
+    var elCell = this.getTdEl(cell);
+    if(elCell) {
+        var elNextRow = this.getNextTrEl(elCell);
+        if(elNextRow) {
+            return elNextRow.cells[elCell.yuiCellIndex];
+        }
+    }
+    return null;
+},
+
+/**
+ * Returns DOM reference to a TH liner element.
+ *
+ * @method getThLinerEl
+ * @param theadCell {YAHOO.widget.Column | HTMLElement | String} Column instance,
+ * DOM element reference, or string ID.
+ * @return {HTMLElement} Reference to TH liner element.
+ */
+getThLinerEl : function(theadCell) {
+    var elCell = this.getThEl(theadCell);
+    return elCell.firstChild || null;
+},
+
+/**
  * Returns DOM reference to a TH element.
  *
  * @method getThEl
- * @param header {YAHOO.widget.Column | HTMLElement | String} Column instance,
+ * @param theadCell {YAHOO.widget.Column | HTMLElement | String} Column instance,
  * DOM element reference, or string ID.
  * @return {HTMLElement} Reference to TH element.
  */
-YAHOO.widget.DataTable.prototype.getThEl = function(header) {
-    var elHeader;
-        
+getThEl : function(theadCell) {
+    var elTheadCell;
+
     // Validate Column instance
-    if(header instanceof YAHOO.widget.Column) {
-        var oColumn = header;
-        elHeader = YAHOO.util.Dom.get(this.id + "-col" + oColumn.getId());
-        if(elHeader) {
-            return elHeader;
+    if(theadCell instanceof YAHOO.widget.Column) {
+        var oColumn = theadCell;
+        elTheadCell = oColumn.getThEl();
+        if(elTheadCell) {
+            return elTheadCell;
         }
     }
     // Validate HTML element
     else {
-        var el = YAHOO.util.Dom.get(header);
+        var el = Dom.get(theadCell);
 
         if(el && (el.ownerDocument == document)) {
             // Validate TH element
-            if(el.tagName.toLowerCase() != "th") {
+            if(el.nodeName.toLowerCase() != "th") {
                 // Traverse up the DOM to find the corresponding TR element
-                elHeader = YAHOO.util.Dom.getAncestorByTagName(el,"th");
+                elTheadCell = Dom.getAncestorByTagName(el,"th");
             }
             else {
-                elHeader = el;
+                elTheadCell = el;
             }
 
             // Make sure the TH is in this THEAD
-            if(elHeader && (elHeader.parentNode.parentNode == this._elThead)) {
+            if(elTheadCell && (elTheadCell.parentNode.parentNode == this._elThead)) {
                 // Now we can return the TD element
-                return elHeader;
+                return elTheadCell;
             }
         }
     }
 
     return null;
-};
+},
 
 /**
  * Returns the page row index of given row. Returns null if the row is not on the
@@ -3489,9 +9009,9 @@
  * or a Record's RecordSet index.
  * @return {Number} Page row index, or null if row does not exist or is not on current page.
  */
-YAHOO.widget.DataTable.prototype.getTrIndex = function(row) {
+getTrIndex : function(row) {
     var nRecordIndex;
-    
+
     // By Record
     if(row instanceof YAHOO.widget.Record) {
         nRecordIndex = this._oRecordSet.getRecordIndex(row);
@@ -3501,17 +9021,28 @@
         }
     }
     // Calculate page row index from Record index
-    else if(YAHOO.lang.isNumber(row)) {
+    else if(lang.isNumber(row)) {
         nRecordIndex = row;
     }
-    if(YAHOO.lang.isNumber(nRecordIndex)) {
+    if(lang.isNumber(nRecordIndex)) {
         // Validate the number
         if((nRecordIndex > -1) && (nRecordIndex < this._oRecordSet.getLength())) {
             // DataTable is paginated
-            if(this.get("paginated")) {
+            var oPaginator = this.get('paginator');
+            if(oPaginator instanceof Pag || this.get('paginated')) {
                 // Get the first and last Record on current page
-                var startRecordIndex = this.get("paginator").startRecordIndex;
-                var endRecordIndex = startRecordIndex + this.get("paginator").rowsPerPage - 1;
+                var startRecordIndex = 0,
+                    endRecordIndex   = 0;
+
+                if (oPaginator instanceof Pag) {
+                    var rng = oPaginator.getPageRecords();
+                    startRecordIndex = rng[0];
+                    endRecordIndex   = rng[1];
+                } else {
+                    startRecordIndex = oPaginator.startRecordIndex;
+                    endRecordIndex = startRecordIndex + oPaginator.rowsPerPage - 1;
+                }
+
                 // This Record is on current page
                 if((nRecordIndex >= startRecordIndex) && (nRecordIndex <= endRecordIndex)) {
                     return nRecordIndex - startRecordIndex;
@@ -3540,9 +9071,9 @@
             return elRow.sectionRowIndex;
         }
     }
-    
+
     return null;
-};
+},
 
 
 
@@ -3593,75 +9124,81 @@
 
 /**
  * Resets a RecordSet with the given data and populates the page view
- * with the new data. Any previous data and selection states are cleared.
- * However, sort states are not cleared, so if the given data is in a particular
- * sort order, implementers should take care to reset the sortedBy property. If
- * pagination is enabled, the currentPage is shown and Paginator UI updated,
- * otherwise all rows are displayed as a single page. For performance, existing
- * DOM elements are reused when possible.
+ * with the new data. Any previous data, and selection and sort states are
+ * cleared. The render method should be called as a separate step in order
+ * to update the UI. 
  *
  * @method initializeTable
- * @param oData {Object | Object[]} An object literal of data or an array of
- * object literals containing data.
  */
-YAHOO.widget.DataTable.prototype.initializeTable = function(oData) {
+initializeTable : function() {
+    // Reset init flag
+    this._bInit = true;
+    
     // Clear the RecordSet
     this._oRecordSet.reset();
 
-    // Add data to RecordSet
-    var records = this._oRecordSet.addRecords(oData);
-
     // Clear selections
     this._unselectAllTrEls();
     this._unselectAllTdEls();
     this._aSelections = null;
     this._oAnchorRecord = null;
     this._oAnchorCell = null;
+    
+    // Clear sort
+    this.set("sortedBy", null);
+},
 
-    // Refresh the view
-    this.refreshView();
-    this.fireEvent("initEvent");
-};
-
 /**
- * Refreshes the view with existing Records from the RecordSet while
+ * Renders the view with existing Records from the RecordSet while
  * maintaining sort, pagination, and selection states. For performance, reuses
  * existing DOM elements when possible while deleting extraneous elements.
  *
- * @method refreshView
+ * @method render
  */
-YAHOO.widget.DataTable.prototype.refreshView = function() {
-    var i, j, k, l, aRecords;
-    var oPaginator = this.updatePaginator();
+render : function() {
+    this._oChainRender.stop();
+    this.showTableMessage(DT.MSG_LOADING, DT.CLASS_LOADING);
 
+    var i, j, k, l, len, allRecords;
+
     // Paginator is enabled, show a subset of Records and update Paginator UI
-    if(this.get("paginated")) {
-        var rowsPerPage = oPaginator.rowsPerPage;
-        var startRecordIndex = (oPaginator.currentPage - 1) * rowsPerPage;
-        aRecords = this._oRecordSet.getRecords(startRecordIndex, rowsPerPage);
-        this.formatPaginators();
+    var oPaginator = this.get('paginator');
+    var bPaginated = oPaginator instanceof Pag || this.get('paginated');
+    if(bPaginated) {
+        if (oPaginator instanceof Pag) {
+            allRecords = this._oRecordSet.getRecords(
+                            oPaginator.getStartIndex(),
+                            oPaginator.getRowsPerPage());
+            oPaginator.render();
+        }
+        else {
+            // Backward compatibility
+            this.updatePaginator();
+            var rowsPerPage = oPaginator.rowsPerPage;
+            var startRecordIndex = (oPaginator.currentPage - 1) * rowsPerPage;
+            allRecords = this._oRecordSet.getRecords(startRecordIndex, rowsPerPage);
+            this.formatPaginators();
+        }
     }
     // Show all records
     else {
-        aRecords = this._oRecordSet.getRecords();
+        allRecords = this._oRecordSet.getRecords();
     }
 
     var elTbody = this._elTbody;
-    var elRows = elTbody.rows;
+    var allRows = elTbody.rows;
 
-    // Has rows
-    if(YAHOO.lang.isArray(aRecords) && (aRecords.length > 0)) {
-        this.hideTableMessage();
-
+    // Should have rows
+    if(lang.isArray(allRecords) && (allRecords.length > 0)) {
         // Keep track of selected rows
-        var aSelectedRows = this.getSelectedRows();
+        var allSelectedRows = this.getSelectedRows();
         // Keep track of selected cells
-        var aSelectedCells = this.getSelectedCells();
+        var allSelectedCells = this.getSelectedCells();
         // Anything to reinstate?
-        var bReselect = (aSelectedRows.length>0) || (aSelectedCells.length > 0);
+        var bReselect = (allSelectedRows.length>0) || (allSelectedCells.length > 0);
 
         // Remove extra rows from the bottom so as to preserve ID order
-        while(elTbody.hasChildNodes() && (elRows.length > aRecords.length)) {
+        while(elTbody.hasChildNodes() && (allRows.length > allRecords.length)) {
             elTbody.deleteRow(-1);
         }
 
@@ -3671,58 +9208,149 @@
             this._unselectAllTdEls();
         }
 
-        // From the top, update in-place existing rows
-        for(i=0; i<elRows.length; i++) {
-            this._updateTrEl(elRows[i], aRecords[i]);
-        }
+        this.hideTableMessage();
 
-        // Add TR elements as necessary
-        for(i=elRows.length; i<aRecords.length; i++) {
-            this._addTrEl(aRecords[i]);
+        // How many rows to work with each loop
+        var loopN = this.get("renderLoopSize");
+        var loopStart,
+            loopEnd;
+        
+        // From the top, update in-place existing rows, so as to reuse DOM elements
+        if(allRows.length > 0) {
+            loopEnd = allRows.length; // End at last row
+            this._oChainRender.add({
+                method: function(oArg) {
+                    if((this instanceof DT) && this._sId) {
+                        var i = oArg.nCurrentRow,
+                            // Must reference allRows.length instead of loopEnd
+                            // here because loopEnd is reused below outside
+                            // this closure.
+                            len = loopN > 0 ? Math.min(i + loopN,allRows.length) : allRows.length;
+                        for(; i < len; ++i) {
+                            this._updateTrEl(allRows[i], allRecords[i]);
+                        }
+                        if (loopN > 0) {
+                            this._syncColWidths();
+                        }
+                        oArg.nCurrentRow = i;
+                    }
+                },
+                iterations: (loopN > 0) ? Math.ceil(loopEnd/loopN) : 1,
+                argument: {nCurrentRow:0}, // Start at first row
+                scope: this,
+                timeout: (loopN > 0) ? 0 : -1
+            });
         }
 
-        // Reinstate selected and sorted classes
-        if(bReselect) {
-            // Loop over each row
-            for(j=0; j<elRows.length; j++) {
-                var thisRow = elRows[j];
-                var sMode = this.get("selectionMode");
-                if ((sMode == "standard") || (sMode == "single")) {
-                    // Set SELECTED
-                    for(k=0; k<aSelectedRows.length; k++) {
-                        if(aSelectedRows[k] === thisRow.yuiRecordId) {
-                            YAHOO.util.Dom.addClass(thisRow, YAHOO.widget.DataTable.CLASS_SELECTED);
-                            if(j === elRows.length-1) {
-                                this._oAnchorRecord = this.getRecord(thisRow.yuiRecordId);
-                            }
+        // Add more TR elements as necessary
+        loopStart = allRows.length; // where to start
+        loopEnd = allRecords.length; // where to end
+        var nRowsNeeded = (loopEnd - loopStart); // how many needed
+        if(nRowsNeeded > 0) {
+            this._oChainRender.add({
+                method: function(oArg) {
+                    if((this instanceof DT) && this._sId) {
+                        var i = oArg.nCurrentRow,
+                            len = loopN > 0 ? Math.min(i + loopN,loopEnd) : loopEnd,
+                            df = document.createDocumentFragment(),
+                            tr;
+                        for(; i < len; ++i) {
+                            tr = this._createTrEl(allRecords[i]);
+                            tr.className = (i%2) ? DT.CLASS_ODD : DT.CLASS_EVEN;
+                            df.appendChild(tr);
                         }
+                        this._elTbody.appendChild(df);
+                        if (loopN > 0) {
+                            this._syncColWidths();
+                        }
+                        oArg.nCurrentRow = i;
                     }
-                }
-                else {
-                    // Loop over each cell
-                    for(k=0; k<thisRow.cells.length; k++) {
-                        var thisCell = thisRow.cells[k];
-                        // Set SELECTED
-                        for(l=0; l<aSelectedCells.length; l++) {
-                            if((aSelectedCells[l].recordId === thisRow.yuiRecordId) &&
-                                    (aSelectedCells[l].columnId === thisCell.yuiColumnId)) {
-                                YAHOO.util.Dom.addClass(thisCell, YAHOO.widget.DataTable.CLASS_SELECTED);
-                                if(k === thisRow.cells.length-1) {
-                                    this._oAnchorCell = {record:this.getRecord(thisRow.yuiRecordId), column:this.getColumnById(thisCell.yuiColumnId)};
+                },
+                iterations: (loopN > 0) ? Math.ceil(nRowsNeeded/loopN) : 1,
+                argument: {nCurrentRow:loopStart}, // start at last row
+                scope: this,
+                timeout: (loopN > 0) ? 0 : -1
+            });
+        }
+
+        this._oChainRender.add({
+            method: function(oArg) {
+                if((this instanceof DT) && this._sId) {
+                    this._setFirstRow();
+                    this._setLastRow();
+
+                    // Reinstate selected and sorted classes
+                    if(bReselect) {
+                        // Loop over each row
+                        for(j=0; j<allRows.length; j++) {
+                            var thisRow = allRows[j];
+                            var sMode = this.get("selectionMode");
+                            if ((sMode == "standard") || (sMode == "single")) {
+                                // Set SELECTED
+                                for(k=0; k<allSelectedRows.length; k++) {
+                                    if(allSelectedRows[k] === thisRow.yuiRecordId) {
+                                        Dom.addClass(thisRow, DT.CLASS_SELECTED);
+                                        if(j === allRows.length-1) {
+                                            this._oAnchorRecord = this.getRecord(thisRow.yuiRecordId);
+                                        }
+                                    }
                                 }
                             }
+                            else {
+                                // Loop over each cell
+                                for(k=0; k<thisRow.cells.length; k++) {
+                                    var thisCell = thisRow.cells[k];
+                                    // Set SELECTED
+                                    for(l=0; l<allSelectedCells.length; l++) {
+                                        if((allSelectedCells[l].recordId === thisRow.yuiRecordId) &&
+                                                (allSelectedCells[l].columnId === thisCell.yuiColumnId)) {
+                                            Dom.addClass(thisCell, DT.CLASS_SELECTED);
+                                            if(k === thisRow.cells.length-1) {
+                                                this._oAnchorCell = {record:this.getRecord(thisRow.yuiRecordId), column:this.getColumnById(thisCell.yuiColumnId)};
+                                            }
+                                        }
+                                    }
+                                }
+                            }
                         }
                     }
                 }
-            }
-        }
+                
+                if(this._bInit) {
+                    this._forceGeckoRedraw();
+
+                    this._oChainRender.add({
+                        method: function() {
+                            if((this instanceof DT) && this._sId && this._bInit) {
+                                this._bInit = false;
+                                this.fireEvent("initEvent");
+                            }
+                        },
+                        scope: this
+                    });
+                    this._oChainRender.run();
+                }
+                else {
+                    this.fireEvent("renderEvent");
+                    // Backward compatibility
+                    this.fireEvent("refreshEvent");
+                }
+            
+            },
+            scope: this,
+            timeout: (loopN > 0) ? 0 : -1
+        }); 
         
-        // Set FIRST/LAST, EVEN/ODD
-        this._setFirstRow();
-        this._setLastRow();
-        this._setRowStripes();
-
-        this.fireEvent("refreshEvent");
+        this._oChainRender.add({
+            method: function() {
+                if((this instanceof DT) && this._sId) {
+                    this._syncColWidths();
+                }
+            },
+            scope: this
+        });
+                    
+        this._oChainRender.run();  
     }
     // Empty
     else {
@@ -3731,9 +9359,9 @@
             elTbody.deleteRow(-1);
         }
 
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_EMPTY, YAHOO.widget.DataTable.CLASS_EMPTY);
+        this.showTableMessage(DT.MSG_EMPTY, DT.CLASS_EMPTY);
     }
-};
+},
 
 /**
  * Nulls out the entire DataTable instance and related objects, removes attached
@@ -3743,11 +9371,32 @@
  *
  * @method destroy
  */
-YAHOO.widget.DataTable.prototype.destroy = function() {
+destroy : function() {
+    this._oChainRender.stop();
+    
+    //TODO: destroy static resizer proxy and column proxy?
+    
+    var i;
+    // Destroy ColumnDDs
+    var aTree = this._oColumnSet.tree[0];
+    for(i=0; i<aTree.length; i++) {
+        if(aTree[i]._dd) {
+            aTree[i]._dd = aTree[i]._dd.unreg();
+        }
+    }
+
+    // Destroy ColumnResizers
+    var aKeys = this._oColumnSet.keys;
+    for(i=0; i<aKeys.length; i++) {
+        if(aKeys[i]._ddResizer) {
+            aKeys[i]._ddResizer = aKeys[i]._ddResizer.unreg();
+        }
+    }
+    
     // Destroy Cell Editor
-    YAHOO.util.Event.purgeElement(this._oCellEditor.container, true);
+    Ev.purgeElement(this._oCellEditor.container, true);
     document.body.removeChild(this._oCellEditor.container);
-    
+
     var instanceName = this.toString();
     var elContainer = this._elContainer;
 
@@ -3756,61 +9405,93 @@
     this.unsubscribeAll();
 
     // Unhook DOM events
-    YAHOO.util.Event.purgeElement(elContainer, true);
+    Ev.purgeElement(elContainer, true);
+    Ev.removeListener(document, "click", this._onDocumentClick);
 
     // Remove DOM elements
     elContainer.innerHTML = "";
 
     // Null out objects
     for(var param in this) {
-        if(YAHOO.lang.hasOwnProperty(this, param)) {
+        if(lang.hasOwnProperty(this, param)) {
             this[param] = null;
         }
     }
+    
+    // Clean up static values
+    DT._nCurrentCount--;
+    
+    if(DT._nCurrentCount < 1) {
+        if(DT._elStylesheet) {
+            document.getElementsByTagName('head')[0].removeChild(DT._elStylesheet);
+            DT._elStylesheet = null;
+        }
+    }
 
-};
+},
 
 /**
  * Displays message within secondary TBODY.
  *
  * @method showTableMessage
- * @param sHTML {String} (optional) Value for innerHTML.
+ * @param sHTML {String} (optional) Value for innerHTMlang.
  * @param sClassName {String} (optional) Classname.
  */
-YAHOO.widget.DataTable.prototype.showTableMessage = function(sHTML, sClassName) {
+showTableMessage : function(sHTML, sClassName) {
     var elCell = this._elMsgTd;
-    if(YAHOO.lang.isString(sHTML)) {
-        elCell.innerHTML = sHTML;
+    if(lang.isString(sHTML)) {
+        elCell.firstChild.innerHTML = sHTML;
     }
-    if(YAHOO.lang.isString(sClassName)) {
-        YAHOO.util.Dom.addClass(elCell, sClassName);
+    if(lang.isString(sClassName)) {
+        Dom.addClass(elCell.firstChild, sClassName);
     }
+
+    this._elMsgTbody.parentNode.style.width = this.getTheadEl().parentNode.offsetWidth+"px";
+
     this._elMsgTbody.style.display = "";
+
     this.fireEvent("tableMsgShowEvent", {html:sHTML, className:sClassName});
-};
+},
 
 /**
  * Hides secondary TBODY.
  *
  * @method hideTableMessage
  */
-YAHOO.widget.DataTable.prototype.hideTableMessage = function() {
+hideTableMessage : function() {
     if(this._elMsgTbody.style.display != "none") {
         this._elMsgTbody.style.display = "none";
+        this._elMsgTbody.parentNode.style.width = "";
         this.fireEvent("tableMsgHideEvent");
     }
-};
+},
 
 /**
- * Brings focus to DataTable instance.
+ * Brings focus to the TBODY element. Alias to focusTbodyEl.
  *
  * @method focus
  */
-YAHOO.widget.DataTable.prototype.focus = function() {
-    this._focusEl(this._elTable);
-};
+focus : function() {
+    this.focusTbodyEl();
+},
 
+/**
+ * Brings focus to the THEAD element.
+ *
+ * @method focusTheadEl
+ */
+focusTheadEl : function() {
+    this._focusEl(this._elThead);
+},
 
+/**
+ * Brings focus to the TBODY element.
+ *
+ * @method focusTbodyEl
+ */
+focusTbodyEl : function() {
+    this._focusEl(this._elTbody);
+},
 
 
 
@@ -3875,6 +9556,7 @@
 
 
 
+
 // RECORDSET FUNCTIONS
 
 /**
@@ -3885,10 +9567,10 @@
  * element reference or page row index.
  * @return {Number} Record's RecordSet index, or null.
  */
-YAHOO.widget.DataTable.prototype.getRecordIndex = function(row) {
+getRecordIndex : function(row) {
     var nTrIndex;
 
-    if(!YAHOO.lang.isNumber(row)) {
+    if(!lang.isNumber(row)) {
         // By Record
         if(row instanceof YAHOO.widget.Record) {
             return this._oRecordSet.getRecordIndex(row);
@@ -3907,17 +9589,21 @@
         nTrIndex = row;
     }
 
-    if(YAHOO.lang.isNumber(nTrIndex)) {
-        if(this.get("paginated")) {
-            return this.get("paginator").startRecordIndex + nTrIndex;
+    if(lang.isNumber(nTrIndex)) {
+        var oPaginator = this.get("paginator");
+        if(oPaginator instanceof Pag) {
+            return oPaginator.get('recordOffset') + nTrIndex;
         }
+        else if (this.get('paginated')) {
+            return oPaginator.startRecordIndex + nTrIndex;
+        }
         else {
             return nTrIndex;
         }
     }
 
     return null;
-};
+},
 
 /**
  * For the given identifier, returns the associated Record instance.
@@ -3927,9 +9613,9 @@
  * child of a TR element), RecordSet position index, or Record ID.
  * @return {YAHOO.widget.Record} Record instance.
  */
-YAHOO.widget.DataTable.prototype.getRecord = function(row) {
+getRecord : function(row) {
     var oRecord = this._oRecordSet.getRecord(row);
-    
+
     if(!oRecord) {
         // Validate TR element
         var elRow = this.getTrEl(row);
@@ -3937,14 +9623,14 @@
             oRecord = this._oRecordSet.getRecord(elRow.yuiRecordId);
         }
     }
-    
+
     if(oRecord instanceof YAHOO.widget.Record) {
         return this._oRecordSet.getRecord(oRecord);
     }
     else {
         return null;
     }
-};
+},
 
 
 
@@ -4002,9 +9688,9 @@
  * TH/TD element (or child of a TH/TD element), a Column key, or a ColumnSet key index.
  * @return {YAHOO.widget.Column} Column instance.
  */
- YAHOO.widget.DataTable.prototype.getColumn = function(column) {
+getColumn : function(column) {
     var oColumn = this._oColumnSet.getColumn(column);
-    
+
     if(!oColumn) {
         // Validate TD element
         var elCell = this.getTdEl(column);
@@ -4022,7 +9708,7 @@
     if(!oColumn) {
     }
     return oColumn;
-};
+},
 
 /**
  * For the given Column ID, returns the associated Column instance. Note: For
@@ -4032,95 +9718,627 @@
  * @param column {String} Column ID string.
  * @return {YAHOO.widget.Column} Column instance.
  */
- YAHOO.widget.DataTable.prototype.getColumnById = function(column) {
+getColumnById : function(column) {
     return this._oColumnSet.getColumnById(column);
-};
+},
 
 /**
+ * For the given Column instance, returns next direction to sort.
+ *
+ * @method getColumnSortDir
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @return {String} DataTable.widget.CLASS_ASC or DataTable.widget.CLASS_DESC.
+ */
+getColumnSortDir : function(oColumn) {
+    // Backward compatibility
+    if(oColumn.sortOptions && oColumn.sortOptions.defaultOrder) {
+        if(oColumn.sortOptions.defaultOrder == "asc") {
+            oColumn.sortOptions.defaultDir = DT.CLASS_ASC;
+        }
+        else if (oColumn.sortOptions.defaultOrder == "desc") {
+            oColumn.sortOptions.defaultDir = DT.CLASS_DESC;
+        }
+    }
+    
+    // What is the Column's default sort direction?
+    var sortDir = (oColumn.sortOptions && oColumn.sortOptions.defaultDir) ? oColumn.sortOptions.defaultDir : DT.CLASS_ASC;
+
+    // Already sorted?
+    var bSorted = false;
+    var oSortedBy = this.get("sortedBy");
+    if(oSortedBy && (oSortedBy.key === oColumn.key)) {
+        bSorted = true;
+        if(oSortedBy.dir) {
+            sortDir = (oSortedBy.dir == DT.CLASS_ASC) ? DT.CLASS_DESC : DT.CLASS_ASC;
+        }
+        else {
+            sortDir = (sortDir == DT.CLASS_ASC) ? DT.CLASS_DESC : DT.CLASS_ASC;
+        }
+    }
+    return sortDir;
+},
+
+/**
  * Sorts given Column.
  *
  * @method sortColumn
  * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @param sDir {String} (Optional) DT.CLASS_ASC or
+ * DT.CLASS_DESC
  */
-YAHOO.widget.DataTable.prototype.sortColumn = function(oColumn) {
+sortColumn : function(oColumn, sDir) {
     if(oColumn && (oColumn instanceof YAHOO.widget.Column)) {
         if(!oColumn.sortable) {
-            YAHOO.util.Dom.addClass(this.getThEl(oColumn), YAHOO.widget.DataTable.CLASS_SORTABLE);
+            Dom.addClass(this.getThEl(oColumn), DT.CLASS_SORTABLE);
         }
-        // What is the default sort direction?
-        var sortDir = (oColumn.sortOptions && oColumn.sortOptions.defaultOrder) ? oColumn.sortOptions.defaultOrder : "asc";
-
-        // Already sorted?
-        var oSortedBy = this.get("sortedBy");
-        if(oSortedBy && (oSortedBy.key === oColumn.key)) {
-            if(oSortedBy.dir) {
-                sortDir = (oSortedBy.dir == "asc") ? "desc" : "asc";
-            }
-            else {
-                sortDir = (sortDir == "asc") ? "desc" : "asc";
-            }
+        
+        // Validate given direction
+        if(sDir && (sDir !== DT.CLASS_ASC) && (sDir !== DT.CLASS_DESC)) {
+            sDir = null;
         }
+        
+        // Get the sort dir
+        var sortDir = sDir || this.getColumnSortDir(oColumn);
 
-        // Is there a custom sort handler function defined?
-        var sortFnc = (oColumn.sortOptions && YAHOO.lang.isFunction(oColumn.sortOptions.sortFunction)) ?
-                oColumn.sortOptions.sortFunction : function(a, b, desc) {
-                    var sorted = YAHOO.util.Sort.compare(a.getData(oColumn.key),b.getData(oColumn.key), desc);
-                    if(sorted === 0) {
-                        return YAHOO.util.Sort.compare(a.getId(),b.getId(), desc);
-                    }
-                    else {
-                        return sorted;
-                    }
-        };
-
         // Do the actual sort
-        var desc = (sortDir == "desc") ? true : false;
-        this._oRecordSet.sortRecords(sortFnc, desc);
+        var oSortedBy = this.get("sortedBy") || {};
+        var bSorted = (oSortedBy.key === oColumn.key) ? true : false;
+        if(!bSorted || sDir) {
+            // Is there a custom sort handler function defined?
+            var sortFnc = (oColumn.sortOptions && lang.isFunction(oColumn.sortOptions.sortFunction)) ?
+                    // Custom sort function
+                    oColumn.sortOptions.sortFunction :
 
+                    // Default sort function
+                    function(a, b, desc) {
+                        var sorted = YAHOO.util.Sort.compare(a.getData(oColumn.key),b.getData(oColumn.key), desc);
+                        if(sorted === 0) {
+                            return YAHOO.util.Sort.compare(a.getId(),b.getId(), desc);
+                        }
+                        else {
+                            return sorted;
+                        }
+                    };
+
+            this._oRecordSet.sortRecords(sortFnc, ((sortDir == DT.CLASS_DESC) ? true : false));
+        }
+        else {
+            this._oRecordSet.reverseRecords();
+        }
+
         // Update sortedBy tracker
         this.set("sortedBy", {key:oColumn.key, dir:sortDir, column:oColumn});
 
         // Reset to first page
         //TODO: Keep selection in view
-        this.updatePaginator({currentPage:1});
+        var oPaginator = this.get('paginator');
+        if (oPaginator instanceof Pag) {
+            // TODO : is this server-side op safe?  Will fire changeRequest
+            // event mechanism
+            oPaginator.setPage(1,true);
+        }
+        else if (this.get('paginated')) {
+            // Backward compatibility
+            this.updatePaginator({currentPage:1});
+        }
 
         // Update the UI
-        this.refreshView();
+        DT.formatTheadCell(oColumn.getThEl().firstChild.firstChild, oColumn, this);
+        this.render();
 
         this.fireEvent("columnSortEvent",{column:oColumn,dir:sortDir});
     }
     else {
     }
-};
+},
 
+/**
+ * Sets DOM elements of given Column to given pixel width. No validations
+ * against minimum width and no updating Column.width value.
+ *
+ * @method _setColumnWidth
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @param sWidth {String} New width value.
+ * @private
+ */
+_setColumnWidth : function(oColumn, sWidth) {
+    oColumn = this.getColumn(oColumn);
+    if(oColumn) {
+        // Create STYLE node
+        if(!DT._bStylesheetFallback) {
+            var s;
+            if(!DT._elStylesheet) {
+                    s = document.createElement('style');
+                    s.type = 'text/css';
+                    DT._elStylesheet = document.getElementsByTagName('head').item(0).appendChild(s);
+            }
+                
+            if(DT._elStylesheet) {
+                s = DT._elStylesheet;
+                
+                var sClassname = ".yui-dt-col-" + oColumn.getId();
+                
+                // Create rule for the Column
+                var rule = DT._oStylesheetRules[sClassname];
+                if (!rule) {
+                    if (s.styleSheet && s.styleSheet.addRule) {
+                        s.styleSheet.addRule(sClassname,"overflow:hidden");
+                        s.styleSheet.addRule(sClassname,"width:"+sWidth);
+                        rule = s.styleSheet.rules[s.styleSheet.rules.length-1];
+                    } else if (s.sheet && s.sheet.insertRule) {
+                        s.sheet.insertRule(sClassname+" {overflow:hidden;width:"+sWidth+";}",s.sheet.cssRules.length);
+                        rule = s.sheet.cssRules[s.sheet.cssRules.length-1];
+                    } else {
+                        DT._bStylesheetFallback = true;
+                    }
+                    DT._oStylesheetRules[sClassname] = rule;
+                }
+                
+                // Update existing rule for the Column
+                else {
+                    rule.style.width = sWidth;
+                } 
+                return;
+            }
+            
+            DT._bStylesheetFallback = true;
+        }
+        // Do it the old fashioned way
+        if(DT._bStylesheetFallback) {           
+            if(sWidth == "auto") {
+                sWidth = ""; 
+            }
 
+            if (!this._aFallbackColResizer[this._elTbody.rows.length]) {
+                /*
+                Compile a custom function to do all the cell width
+                assignments at the same time.  A new resizer function is created
+                for each new unique number of rows in _elTbody.  This will
+                result in a function declaration like:
+                function (oColumn,sWidth) {
+                    var colIdx = oColumn.getKeyIndex();
+                    oColumn.getThEl().firstChild.style.width =
+                    this._elTbody.rows[0].cells[colIdx].firstChild.style.width =
+                    this._elTbody.rows[0].cells[colIdx].style.width =
+                    this._elTbody.rows[1].cells[colIdx].firstChild.style.width =
+                    this._elTbody.rows[1].cells[colIdx].style.width =
+                    ... (for all row indices in this._elTbody.rows.length - 1)
+                    this._elTbody.rows[99].cells[colIdx].firstChild.style.width =
+                    this._elTbody.rows[99].cells[colIdx].style.width = sWidth;
+                    ending with the sWidth as the initial assignment   ^
+                }
+                */
+                var i,j,k;
+                var resizerDef = [
+                    'var colIdx=oColumn.getKeyIndex();',
+                    'oColumn.getThEl().firstChild.style.width='
+                ];
+                for (i=this._elTbody.rows.length-1, j=2; i >= 0; --i) {
+                    resizerDef[j++] = 'this._elTbody.rows[';
+                    resizerDef[j++] = i;
+                    resizerDef[j++] = '].cells[colIdx].firstChild.style.width=';
+                    resizerDef[j++] = 'this._elTbody.rows[';
+                    resizerDef[j++] = i;
+                    resizerDef[j++] = '].cells[colIdx].style.width=';
+                }
+                resizerDef[j] = 'sWidth;';
+                resizerDef[j+1] = 'oColumn.getThEl().firstChild.style.overflow=';
+                for (i=this._elTbody.rows.length-1, k=j+2; i >= 0; --i) {
+                    resizerDef[k++] = 'this._elTbody.rows[';
+                    resizerDef[k++] = i;
+                    resizerDef[k++] = '].cells[colIdx].firstChild.style.overflow=';
+                    resizerDef[k++] = 'this._elTbody.rows[';
+                    resizerDef[k++] = i;
+                    resizerDef[k++] = '].cells[colIdx].style.overflow=';
+                }
+                resizerDef[k] = '"hidden";';
+                this._aFallbackColResizer[this._elTbody.rows.length] =
+                    new Function('oColumn','sWidth',resizerDef.join(''));
+            }
+            var resizerFn = this._aFallbackColResizer[this._elTbody.rows.length];
 
+            if (resizerFn) {
+                resizerFn.call(this,oColumn,sWidth);
+                //this._syncScrollPadding();
+                return;
+            }
+        }
+    }
+    else {
+    }
+},
 
+/**
+ * Sets given Column to given pixel width. If new width is less than minimum
+ * width, sets to minimum width. Updates oColumn.width value.
+ *
+ * @method setColumnWidth
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @param nWidth {Number} New width in pixels.
+ */
+setColumnWidth : function(oColumn, nWidth) {
+    oColumn = this.getColumn(oColumn);
+    if(oColumn) {
+        // Validate new width against minimum width
+        if(lang.isNumber(nWidth)) {
+            nWidth = (nWidth > oColumn.minWidth) ? nWidth : oColumn.minWidth;
 
+            // Save state
+            oColumn.width = nWidth;
+            
+            // Resize the DOM elements
+            //this._oChainSync.stop();
+            this._setColumnWidth(oColumn, nWidth+"px");
+            this._syncScrollPadding();
+            
+            this.fireEvent("columnSetWidthEvent",{column:oColumn,width:nWidth});
+            return;
+        }
+    }
+},
 
 
+/**
+ * Hides given Column. NOTE: You cannot hide/show nested Columns. You can only
+ * hide/show non-nested Columns, and top-level parent Columns (which will
+ * hide/show all children Columns).
+ *
+ * @method hideColumn
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ */
+hideColumn : function(oColumn) {
+    oColumn = this.getColumn(oColumn);
+    if(oColumn && !oColumn.hidden) {
+        // Only top-level Columns can get hidden
+        if(oColumn.getTreeIndex() !== null) {
+            var allrows = this.getTbodyEl().rows;
+            var l = allrows.length;
+            var allDescendants = this._oColumnSet.getDescendants(oColumn);
+            for(var i=0; i<allDescendants.length; i++) {
+                var thisColumn = allDescendants[i];
+                thisColumn.hidden = true;
 
+                var elTheadCell = thisColumn.getThEl();
+                var elTheadCellLiner = elTheadCell.firstChild;
+                // Store to reinstate later
+                thisColumn._nLastWidth = elTheadCellLiner.offsetWidth - 
+                        (parseInt(Dom.getStyle(elTheadCellLiner,"paddingLeft"),10)|0) -
+                        (parseInt(Dom.getStyle(elTheadCellLiner,"paddingRight"),10)|0);
+                Dom.addClass(elTheadCell,DT.CLASS_HIDDEN);
 
+                // Adjust body cells (if key Column)
+                var thisKeyIndex = thisColumn.getKeyIndex();
+                if(thisKeyIndex !== null) {
+                    for(var j=0;j<l;j++) {
+                        Dom.addClass(allrows[j].cells[thisKeyIndex],DT.CLASS_HIDDEN);
+                    }
 
+                    this._setColumnWidth(thisColumn, "1px");
+                    
+                    // Disable interactive features
+                    if(thisColumn.resizeable) {
+                        Dom.removeClass(thisColumn.getResizerEl(),DT.CLASS_RESIZER);
+                    }
+                    if(thisColumn.sortable) {
+                        Dom.removeClass(thisColumn.getThEl(),DT.CLASS_SORTABLE);
+                        thisColumn.getThEl().firstChild.firstChild.firstChild.style.display = "none";
+                    }
+                }
+                // Just set thead cell width directly for parent Column
+                else {
+                    elTheadCell.firstChild.style.width = "1px";
+                }
+                
+                this.fireEvent("columnHideEvent",{column:thisColumn});
+            }
+        }
+        else {
+        }
+    }
+},
 
+/**
+ * Shows given Column. NOTE: You cannot hide/show nested Columns. You can only
+ * hide/show non-nested Columns, and top-level parent Columns (which will
+ * hide/show all children Columns).
+ *
+ * @method showColumn
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ */
+showColumn : function(oColumn) {
+    oColumn = this.getColumn(oColumn);
+    if(oColumn && oColumn.hidden) {
+        // Only top-level Columns can get hidden
+        if(oColumn.getTreeIndex() !== null) {
+            var allrows = this.getTbodyEl().rows;
+            var l = allrows.length;
+            var allDescendants = this._oColumnSet.getDescendants(oColumn);
+            for(var i=0; i<allDescendants.length; i++) {
+                var thisColumn = allDescendants[i];
+                thisColumn.hidden = false;
+                
+                var elTheadCell = thisColumn.getThEl();
+                Dom.removeClass(elTheadCell,DT.CLASS_HIDDEN);
 
+                // Adjust body cells (if key Column)
+                var thisKeyIndex = thisColumn.getKeyIndex();
+                if(thisKeyIndex !== null) {
+                    for(var j=0;j<l;j++) {
+                        Dom.removeClass(allrows[j].cells[thisKeyIndex],DT.CLASS_HIDDEN);
+                    }
+                    
+                    this.setColumnWidth(thisColumn, (thisColumn._nLastWidth || thisColumn.minWidth), true);
 
+                    // Enable interactive features
+                    if(thisColumn.sortable) {
+                        thisColumn.getThEl().firstChild.firstChild.firstChild.style.display = "";
+                        Dom.removeClass(thisColumn.getThEl(),DT.CLASS_SORTABLE);
+                    }
+                    if(thisColumn.resizeable) {
+                        thisColumn._ddResizer.resetResizerEl();
+                        Dom.addClass(thisColumn.getResizerEl(),DT.CLASS_RESIZER);
+                    }
+                }
+                else {
+                    elTheadCell.firstChild.style.width = "";
+                }
 
+                thisColumn._nLastWidth = null;
+                this.fireEvent("columnShowEvent",{column:thisColumn});
+            }
+        }
+        else {
+        }
+    }
+},
 
+/**
+ * Removes given Column. NOTE: You cannot remove nested Columns. You can only remove
+ * non-nested Columns, and top-level parent Columns (which will remove all
+ * children Columns).
+ *
+ * @method removeColumn
+ * @param oColumn {YAHOO.widget.Column} Column instance.
+ * @return oColumn {YAHOO.widget.Column} Removed Column instance.
+ */
+removeColumn : function(oColumn) {
+    var nColTreeIndex = oColumn.getTreeIndex();
+    if(nColTreeIndex !== null) {
+        this._oChainRender.stop();
+        var aOrigColumnDefs = this._oColumnSet.getDefinitions();
 
+        oColumn = aOrigColumnDefs.splice(nColTreeIndex,1)[0];
+        this._initColumnSet(aOrigColumnDefs);
+        this._initTheadEls();
 
+        this.render();
+        this.fireEvent("columnRemoveEvent",{column:oColumn});
+        return oColumn;
+    }
+},
 
+/**
+ * Inserts given Column at the index if given, otherwise at the end. NOTE: You
+ * can only add non-nested Columns and top-level parent Columns. You cannot add
+ * a nested Column to an existing parent.
+ *
+ * @method insertColumn
+ * @param oColumn {Object | YAHOO.widget.Column} Object literal Column
+ * definition or a Column instance.
+ * @param index {Number} (optional) Column key index.
+ */
+insertColumn : function(oColumn, index) {
+    // Validate Column
+    if(oColumn instanceof YAHOO.widget.Column) {
+        oColumn = oColumn.getDefinition();
+    }
+    else if(oColumn.constructor !== Object) {
+        return;
+    }
+    
+    var oColumnSet = this._oColumnSet;
 
+    // Validate index
+    if(!lang.isValue(index) || !lang.isNumber(index)) {
+        index = oColumnSet.tree[0].length;
+    }
+    
+    this._oChainRender.stop();
+    var aNewColumnDefs = this._oColumnSet.getDefinitions();
+    aNewColumnDefs.splice(index, 0, oColumn);
+    this._initColumnSet(aNewColumnDefs);
+    this._initTheadEls();
+    this.render();
+    this.fireEvent("columnInsertEvent",{column:oColumn,index:index});
+},
 
+/**
+ * Selects given Column. NOTE: You cannot select/unselect nested Columns. You can only
+ * select/unselect non-nested Columns, and bottom-level key Columns.
+ *
+ * @method selectColumn
+ * @param column {HTMLElement | String | Number} DOM reference or ID string to a
+ * TH/TD element (or child of a TH/TD element), a Column key, or a ColumnSet key index.
+ */
+selectColumn : function(oColumn) {
+    oColumn = this.getColumn(oColumn);
+    if(oColumn && !oColumn.selected) {
+        // Only bottom-level Columns can get hidden
+        if(oColumn.getKeyIndex() !== null) {
+            oColumn.selected = true;
+            
+            // Update head cell
+            var elTh = oColumn.getThEl();
+            Dom.addClass(elTh,DT.CLASS_SELECTED);
 
+            // Update body cells
+            var allRows = this.getTbodyEl().rows;
+            var oChainRender = this._oChainRender;
+            oChainRender.add({
+                method: function(oArg) {
+                    if((this instanceof DT) && this._sId && allRows[oArg.rowIndex] && allRows[oArg.rowIndex].cells[oArg.cellIndex]) {
+                        Dom.addClass(allRows[oArg.rowIndex].cells[oArg.cellIndex],DT.CLASS_SELECTED);                    
+                    }
+                    oArg.rowIndex++;
+                },
+                scope: this,
+                iterations: allRows.length,
+                argument: {rowIndex:0,cellIndex:oColumn.getKeyIndex()}
+            });
+            oChainRender.run();       
+            
+            this.fireEvent("columnSelectEvent",{column:oColumn});
+        }
+        else {
+        }
+    }
+},
 
+/**
+ * Unselects given Column. NOTE: You cannot select/unselect nested Columns. You can only
+ * select/unselect non-nested Columns, and bottom-level key Columns.
+ *
+ * @method unSelectColumn
+ * @param column {HTMLElement | String | Number} DOM reference or ID string to a
+ * TH/TD element (or child of a TH/TD element), a Column key, or a ColumnSet key index.
+ */
+unselectColumn : function(oColumn) {
+    oColumn = this.getColumn(oColumn);
+    if(oColumn && oColumn.selected) {
+        // Only bottom-level Columns can get hidden
+        if(oColumn.getKeyIndex() !== null) {
+            oColumn.selected = false;
+            
+            // Update head cell
+            var elTh = oColumn.getThEl();
+            Dom.removeClass(elTh,DT.CLASS_SELECTED);
 
+            // Update body cells
+            var allRows = this.getTbodyEl().rows;
+            var oChainRender = this._oChainRender;
+            oChainRender.add({
+                method: function(oArg) {
+                    if((this instanceof DT) && this._sId && allRows[oArg.rowIndex] && allRows[oArg.rowIndex].cells[oArg.cellIndex]) {
+                        Dom.removeClass(allRows[oArg.rowIndex].cells[oArg.cellIndex],DT.CLASS_SELECTED); 
+                    }                   
+                    oArg.rowIndex++;
+                },
+                scope: this,
+                iterations:allRows.length,
+                argument: {rowIndex:0,cellIndex:oColumn.getKeyIndex()}
+            });
+            oChainRender.run();       
+            
+            this.fireEvent("columnUnselectEvent",{column:oColumn});
+        }
+        else {
+        }
+    }
+},
 
+/**
+ * Returns an array selected Column instances.
+ *
+ * @method getSelectedColumns
+ * @return {YAHOO.widget.Column[]} Array of Column instances.
+ */
+getSelectedColumns : function(oColumn) {
+    var selectedColumns = [];
+    var aKeys = this._oColumnSet.keys;
+    for(var i=0,len=aKeys.length; i<len; i++) {
+        if(aKeys[i].selected) {
+            selectedColumns[selectedColumns.length] = aKeys[i];
+        }
+    }
+    return selectedColumns;
+},
 
+/**
+ * Assigns the class DT.CLASS_HIGHLIGHTED to cells of the given Column.
+ * NOTE: You cannot highlight/unhighlight nested Columns. You can only
+ * highlight/unhighlight non-nested Columns, and bottom-level key Columns.
+ *
+ * @method highlightColumn
+ * @param column {HTMLElement | String | Number} DOM reference or ID string to a
+ * TH/TD element (or child of a TH/TD element), a Column key, or a ColumnSet key index.
+ */
+highlightColumn : function(column) {
+    var oColumn = this.getColumn(column);
+    // Only bottom-level Columns can get highlighted
+    if(oColumn && (oColumn.getKeyIndex() !== null)) {
+        /*// Make sure previous row is unhighlighted
+        var sId = oColumn.getId();
+        var sLastId = this._sLastHighlightedColumnId;
+        if(sLastId && (sLastId !== sId)) {
+            this.unhighlightColumn(this.getColumn(sLastId));
+        }*/
 
+        //this._sLastHighlightedColumnId = sId;
+            
+        // Update head cell
+        var elTh = oColumn.getThEl();
+        Dom.addClass(elTh,DT.CLASS_HIGHLIGHTED);
 
+        // Update body cells
+        var allRows = this.getTbodyEl().rows;
+        var oChainRender = this._oChainRender;
+        oChainRender.add({
+            method: function(oArg) {
+                if((this instanceof DT) && this._sId && allRows[oArg.rowIndex] && allRows[oArg.rowIndex].cells[oArg.cellIndex]) {
+                    Dom.addClass(allRows[oArg.rowIndex].cells[oArg.cellIndex],DT.CLASS_HIGHLIGHTED);   
+                }                 
+                oArg.rowIndex++;
+            },
+            scope: this,
+            iterations:allRows.length,
+            argument: {rowIndex:0,cellIndex:oColumn.getKeyIndex()}
+        });
+        oChainRender.run();       
+            
+        this.fireEvent("columnHighlightEvent",{column:oColumn});
+    }
+    else {
+    }
+},
 
+/**
+ * Removes the class DT.CLASS_HIGHLIGHTED to cells of the given Column.
+ * NOTE: You cannot highlight/unhighlight nested Columns. You can only
+ * highlight/unhighlight non-nested Columns, and bottom-level key Columns.
+ *
+ * @method unhighlightColumn
+ * @param column {HTMLElement | String | Number} DOM reference or ID string to a
+ * TH/TD element (or child of a TH/TD element), a Column key, or a ColumnSet key index.
+ */
+unhighlightColumn : function(column) {
+    var oColumn = this.getColumn(column);
+    // Only bottom-level Columns can get highlighted
+    if(oColumn && (oColumn.getKeyIndex() !== null)) {
+        // Update head cell
+        var elTh = oColumn.getThEl();
+        Dom.removeClass(elTh,DT.CLASS_HIGHLIGHTED);
 
+        // Update body cells
+        var allRows = this.getTbodyEl().rows;
+        var oChainRender = this._oChainRender;
+        oChainRender.add({
+            method: function(oArg) {
+                if((this instanceof DT) && this._sId && allRows[oArg.rowIndex] && allRows[oArg.rowIndex].cells[oArg.cellIndex]) {
+                    Dom.removeClass(allRows[oArg.rowIndex].cells[oArg.cellIndex],DT.CLASS_HIGHLIGHTED);
+                }                 
+                oArg.rowIndex++;
+            },
+            scope: this,
+            iterations:allRows.length,
+            argument: {rowIndex:0,cellIndex:oColumn.getKeyIndex()}
+        });
+        oChainRender.run();       
+            
+        this.fireEvent("columnUnhighlightEvent",{column:oColumn});
+    }
+    else {
+    }
+},
 
 
 
@@ -4137,8 +10355,63 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 // ROW FUNCTIONS
 
+/**
+ * Adds one TR element at the given index and populates with given Record data.
+ *
+ * @method _addTrEl
+ * @param oRecord {YAHOO.widget.Record} Record instance. 
+ * @param index {Number} TR index.
+ * @return {HTMLElement} Reference to new TR element. 
+ * @private 
+ */
+_addTrEl : function(oRecord, index) {
+    var elNewTr = this._createTrEl(oRecord);
+    if(elNewTr) {
+        if (index >= 0 && index < this._elTbody.rows.length) {
+            this._elTbody.insertBefore(elNewTr,
+                this._elTbody.rows[index]);
+            if (!index) {
+                this._setFirstRow();
+            }
+        } else {
+            this._elTbody.appendChild(elNewTr);
+            this._setLastRow();
+            index = this._elTbody.rows.length - 1;
+        }
+        this._setRowStripes(index);
+    }
+    return elNewTr;
+},
 
 /**
  * Adds one new Record of data into the RecordSet at the index if given,
@@ -4149,66 +10422,68 @@
  * @param oData {Object} Object literal of data for the row.
  * @param index {Number} (optional) RecordSet position index at which to add data.
  */
-YAHOO.widget.DataTable.prototype.addRow = function(oData, index) {
+addRow : function(oData, index) {
     if(oData && (oData.constructor == Object)) {
         var oRecord = this._oRecordSet.addRecord(oData, index);
         if(oRecord) {
-            var nTrIndex = this.getTrIndex(oRecord);
+            var recIndex;
+            var oPaginator = this.get('paginator');
 
-            // Row is on current page
-            if(YAHOO.lang.isNumber(nTrIndex)) {
-                // Paginated so just refresh the view to keep pagination state
-                if(this.get("paginated")) {
-                    this.refreshView();
+            // Paginated
+            if (oPaginator instanceof Pag || this.get('paginated')) {
+                recIndex = this.getRecordIndex(oRecord);
+                var endRecIndex;
+                if (oPaginator instanceof Pag) {
+                    // Update the paginator's totalRecords
+                    var totalRecords = oPaginator.get('totalRecords');
+                    if (totalRecords !== Pag.VALUE_UNLIMITED) {
+                        oPaginator.set('totalRecords',totalRecords + 1);
+                    }
+
+                    endRecIndex = (oPaginator.getPageRecords())[1];
                 }
-                // Add the TR element
+                // Backward compatibility
                 else {
-                    var newTrId = this._addTrEl(oRecord, nTrIndex);
-                    if(newTrId) {
-                        // Is this an insert or an append?
-                        var append = (YAHOO.lang.isNumber(nTrIndex) &&
-                                (nTrIndex == this._elTbody.rows.length-1)) ? true : false;
+                    endRecIndex = oPaginator.startRecordIndex +
+                                  oPaginator.rowsPerPage - 1;
+                    this.updatePaginator();
+                }
 
-                        // Stripe the one new row
-                        if(append) {
-                            if((this._elTbody.rows.length-1)%2) {
-                                YAHOO.util.Dom.addClass(newTrId, YAHOO.widget.DataTable.CLASS_ODD);
-                            }
-                            else {
-                                YAHOO.util.Dom.addClass(newTrId, YAHOO.widget.DataTable.CLASS_EVEN);
-                            }
-                        }
-                        // Restripe all the rows after the new one
-                        else {
-                            this._setRowStripes(nTrIndex);
-                        }
-
-                        // If new row is at the bottom
-                        if(append) {
-                            this._setLastRow();
-                        }
-                        // If new row is at the top
-                        else if(YAHOO.lang.isNumber(index) && (nTrIndex === 0)) {
-                            this._setFirstRow();
-                        }
-                    }
+                // New record affects the view
+                if (recIndex <= endRecIndex) {
+                    // Defer UI updates to the render method
+                    this.render();
                 }
+                
+                this.fireEvent("rowAddEvent", {record:oRecord});
+                return;
             }
-            // Record is not on current page so just update pagination UI
+            // Not paginated
             else {
-                this.updatePaginator();
-            }
-
-            // TODO: what args to pass?
-            this.fireEvent("rowAddEvent", {record:oRecord});
-
-            // For log message
-            nTrIndex = (YAHOO.lang.isValue(nTrIndex))? nTrIndex : "n/a";
-
-            return;
+                recIndex = this.getTrIndex(oRecord);
+                if(lang.isNumber(recIndex)) {
+                    // Add the TR element
+                    this._oChainRender.add({
+                        method: function(oArg) {
+                            if((this instanceof DT) && this._sId) {
+                                var elNewTr = this._addTrEl(oRecord, recIndex);
+                                if(elNewTr) {
+                                    this.hideTableMessage();
+            
+                                    this.fireEvent("rowAddEvent", {record:oRecord});
+                                }
+                            }
+                        },
+                        scope: this,
+                        timeout: (this.get("renderLoopSize") > 0) ? 0 : -1
+                    });
+                    this._oChainRender.run();
+                    return;
+                }
+            }            
         }
     }
-};
+},
 
 /**
  * Convenience method to add multiple rows.
@@ -4217,23 +10492,79 @@
  * @param aData {Object[]} Array of object literal data for the rows.
  * @param index {Number} (optional) RecordSet position index at which to add data.
  */
-YAHOO.widget.DataTable.prototype.addRows = function(aData, index) {
-    if(YAHOO.lang.isArray(aData)) {
-        var i;
-        if(YAHOO.lang.isNumber(index)) {
-            for(i=aData.length-1; i>-1; i--) {
-                this.addRow(aData[i], index);
+addRows : function(aData, index) {
+    if(lang.isArray(aData)) {
+        var aRecords = this._oRecordSet.addRecords(aData, index);
+        if(aRecords) {
+            var recIndex = this.getRecordIndex(aRecords[0]);
+            
+            // Paginated
+            var oPaginator = this.get('paginator');
+            if (oPaginator instanceof Pag ||
+                this.get('paginated')) {
+                var endRecIndex;
+                if (oPaginator instanceof Pag) {
+                    // Update the paginator's totalRecords
+                    var totalRecords = oPaginator.get('totalRecords');
+                    if (totalRecords !== Pag.VALUE_UNLIMITED) {
+                        oPaginator.set('totalRecords',totalRecords + aRecords.length);
+                    }
+
+                    endRecIndex = (oPaginator.getPageRecords())[1];
+                }
+                // Backward compatibility
+                else {
+                    endRecIndex = oPaginator.startRecordIndex +
+                                  oPaginator.rowsPerPage - 1;
+                    this.updatePaginator();
+                }
+
+                // At least one of the new records affects the view
+                if (recIndex <= endRecIndex) {
+                    this.render();
+                }
+                
+                this.fireEvent("rowsAddEvent", {records:aRecords});
+                return;
             }
+            // Not paginated
+            else {
+                // Add the TR elements
+                var loopN = this.get("renderLoopSize");
+                var loopEnd = recIndex + aData.length;
+                var nRowsNeeded = (loopEnd - recIndex); // how many needed
+                this._oChainRender.add({
+                    method: function(oArg) {
+                        if((this instanceof DT) && this._sId) {
+                            var i = oArg.nCurrentRow,
+                                j = oArg.nCurrentRecord,
+                                len = loopN > 0 ? Math.min(i + loopN,loopEnd) : loopEnd;
+                            for(; i < len; ++i,++j) {
+                                this._addTrEl(aRecords[j], i);
+                            }
+                            oArg.nCurrentRow = i;
+                            oArg.nCurrentRecord = j;
+                        }
+                    },
+                    iterations: (loopN > 0) ? Math.ceil(loopEnd/loopN) : 1,
+                    argument: {nCurrentRow:recIndex,nCurrentRecord:0},
+                    scope: this,
+                    timeout: (loopN > 0) ? 0 : -1
+                });
+                this._oChainRender.add({
+                    method: function() {
+                        this.fireEvent("rowsAddEvent", {records:aRecords});
+                    },
+                    scope: this,
+                    timeout: -1 // Needs to run immediately after the DOM insertions above
+                });
+                this._oChainRender.run();
+                this.hideTableMessage();                
+                return;
+            }            
         }
-        else {
-            for(i=0; i<aData.length; i++) {
-                this.addRow(aData[i]);
-            }
-        }
     }
-    else {
-    }
-};
+},
 
 /**
  * For the given row, updates the associated Record with the given data. If the
@@ -4246,14 +10577,14 @@
  * of the TR element.
  * @param oData {Object} Object literal of data for the row.
  */
-YAHOO.widget.DataTable.prototype.updateRow = function(row, oData) {
+updateRow : function(row, oData) {
     var oldRecord, oldData, updatedRecord, elRow;
 
     // Get the Record directly
-    if((row instanceof YAHOO.widget.Record) || (YAHOO.lang.isNumber(row))) {
+    if((row instanceof YAHOO.widget.Record) || (lang.isNumber(row))) {
             // Get the Record directly
             oldRecord = this._oRecordSet.getRecord(row);
-            
+
             // Is this row on current page?
             elRow = this.getTrEl(oldRecord);
     }
@@ -4269,10 +10600,7 @@
     if(oldRecord) {
         // Copy data from the Record for the event that gets fired later
         var oRecordData = oldRecord.getData();
-        oldData = {};
-        for(var param in oRecordData) {
-            oldData[param] = oRecordData[param];
-        }
+        oldData = YAHOO.widget.DataTable._cloneObject(oRecordData);
 
         updatedRecord = this._oRecordSet.updateRecord(oldRecord, oData);
     }
@@ -4280,15 +10608,27 @@
         return;
 
     }
-    
+
     // Update the TR only if row is on current page
     if(elRow) {
-        this._updateTrEl(elRow, updatedRecord);
+        this._oChainRender.add({
+            method: function() {
+                if((this instanceof DT) && this._sId) {
+                    this._updateTrEl(elRow, updatedRecord);
+                    //this._oChainSync.run();
+                    this.fireEvent("rowUpdateEvent", {record:updatedRecord, oldData:oldData});
+                }
+            },
+            scope: this,
+            timeout: (this.get("renderLoopSize") > 0) ? 0 : -1
+        });
+        this._oChainRender.run();
     }
+    else {
+        this.fireEvent("rowUpdateEvent", {record:updatedRecord, oldData:oldData});
+    }
+},
 
-    this.fireEvent("rowUpdateEvent", {record:updatedRecord, oldData:oldData});
-};
-
 /**
  * Deletes the given row's Record from the RecordSet. If the row is on current page,
  * the corresponding DOM elements are also deleted.
@@ -4297,79 +10637,100 @@
  * @param row {HTMLElement | String | Number} DOM element reference or ID string
  * to DataTable page element or RecordSet index.
  */
-YAHOO.widget.DataTable.prototype.deleteRow = function(row) {
-    // Get the Record index...
-    var oRecord = null;
-    // ...by Record index
-    if(YAHOO.lang.isNumber(row)) {
-        oRecord = this._oRecordSet.getRecord(row);
-    }
-    // ...by element reference
-    else {
-        var elRow = YAHOO.util.Dom.get(row);
-        elRow = this.getTrEl(elRow);
-        if(elRow) {
-            oRecord = this.getRecord(elRow);
-        }
-    }
-    if(oRecord) {
-        var sRecordId = oRecord.getId();
+deleteRow : function(row) {
+    var nRecordIndex = this.getRecordIndex(row);
+    if(lang.isNumber(nRecordIndex)) {
+        var oRecord = this.getRecord(nRecordIndex);
+        if(oRecord) {
+            var nTrIndex = this.getTrIndex(nRecordIndex);
+            
+            // Remove from selection tracker if there
+            var sRecordId = oRecord.getId();
+            var tracker = this._aSelections || [];
+            for(var j=tracker.length-1; j>-1; j--) {
+                if((lang.isNumber(tracker[j]) && (tracker[j] === sRecordId)) ||
+                        ((tracker[j].constructor == Object) && (tracker[j].recordId === sRecordId))) {
+                    tracker.splice(j,1);
+                }
+            }
+    
+            // Delete Record from RecordSet
+            var oData = this._oRecordSet.deleteRecord(nRecordIndex);
+    
+            // Update the UI
+            if(oData) {
+                // If paginated and the deleted row was on this or a prior page, just
+                // re-render
+                var oPaginator = this.get('paginator');
+                if (oPaginator instanceof Pag ||
+                    this.get('paginated')) {
         
-        // Remove from selection tracker if there
-        var tracker = this._aSelections || [];
-        for(var j=tracker.length-1; j>-1; j--) {
-            if((YAHOO.lang.isNumber(tracker[j]) && (tracker[j] === sRecordId)) ||
-                    ((tracker[j].constructor == Object) && (tracker[j].recordId === sRecordId))) {
-                tracker.splice(j,1);
-            }
-        }
-
-        // Copy data from the Record for the event that gets fired later
-        var nRecordIndex = this.getRecordIndex(oRecord);
-        var oRecordData = oRecord.getData();
-        var oData = {};
-        for(var param in oRecordData) {
-            oData[param] = oRecordData[param];
-        }
-
-        // Grab the TR index before deleting the Record
-        var nTrIndex = this.getTrIndex(oRecord);
-
-        // Delete Record from RecordSet
-        this._oRecordSet.deleteRecord(nRecordIndex);
-
-        // If row is on current page, delete the TR element
-        if(YAHOO.lang.isNumber(nTrIndex)) {
-            var isLast = (nTrIndex == this.getLastTrEl().sectionRowIndex) ?
-                    true : false;
-            this._deleteTrEl(nTrIndex);
-
-            // Empty body
-            if(this._elTbody.rows.length === 0) {
-                this.showTableMessage(YAHOO.widget.DataTable.MSG_EMPTY, YAHOO.widget.DataTable.CLASS_EMPTY);
-            }
-            // Update UI
-            else {
-                // Set FIRST/LAST
-                if(nTrIndex === 0) {
-                    this._setFirstRow();
+                    var endRecIndex;
+                    if (oPaginator instanceof Pag) {
+                        // Update the paginator's totalRecords
+                        var totalRecords = oPaginator.get('totalRecords');
+                        if (totalRecords !== Pag.VALUE_UNLIMITED) {
+                            oPaginator.set('totalRecords',totalRecords - 1);
+                        }
+        
+                        endRecIndex = (oPaginator.getPageRecords())[1];
+                    } else {
+                        // Backward compatibility
+                        endRecIndex = oPaginator.startRecordIndex +
+                                      oPaginator.rowsPerPage - 1;
+        
+                        this.updatePaginator();
+                    }
+        
+                    // If the deleted record was on this or a prior page, re-render
+                    if (nRecordIndex <= endRecIndex) {
+                        this.render();
+                    }
+                    return;
                 }
-                if(isLast) {
-                    this._setLastRow();
+                else {
+                    if(lang.isNumber(nTrIndex)) {
+                        this._oChainRender.add({
+                            method: function() {
+                                if((this instanceof DT) && this._sId) {
+                                    var isLast = (nTrIndex == this.getLastTrEl().sectionRowIndex);
+                                    this._deleteTrEl(nTrIndex);
+                    
+                                    // Empty body
+                                    if(this._elTbody.rows.length === 0) {
+                                        this.showTableMessage(DT.MSG_EMPTY, DT.CLASS_EMPTY);
+                                    }
+                                    // Update UI
+                                    else {
+                                        // Set FIRST/LAST
+                                        if(nTrIndex === 0) {
+                                            this._setFirstRow();
+                                        }
+                                        if(isLast) {
+                                            this._setLastRow();
+                                        }
+                                        // Set EVEN/ODD
+                                        if(nTrIndex != this._elTbody.rows.length) {
+                                            this._setRowStripes(nTrIndex);
+                                        }                                
+                                    }
+                    
+                                    this.fireEvent("rowDeleteEvent", {recordIndex:nRecordIndex,
+                                    oldData:oData, trElIndex:nTrIndex});
+                                }
+                            },
+                            scope: this,
+                            timeout: (this.get("renderLoopSize") > 0) ? 0 : -1
+                        });
+                        this._oChainRender.run();
+                        return;
+                    }
                 }
-                // Set EVEN/ODD
-                if(nTrIndex != this._elTbody.rows.length) {
-                    this._setRowStripes(nTrIndex);
-                }
             }
         }
-
-        this.fireEvent("rowDeleteEvent", {recordIndex:nRecordIndex,
-                oldData:oData, trElIndex:nTrIndex});
     }
-    else {
-    }
-};
+    return null;
+},
 
 /**
  * Convenience method to delete multiple rows.
@@ -4380,37 +10741,119 @@
  * @param count {Number} (optional) How many rows to delete. A negative value
  * will delete towards the beginning.
  */
-YAHOO.widget.DataTable.prototype.deleteRows = function(row, count) {
-    // Get the Record index...
-    var nRecordIndex = null;
-    // ...by Record index
-    if(YAHOO.lang.isNumber(row)) {
-        nRecordIndex = row;
-    }
-    // ...by element reference
-    else {
-        var elRow = YAHOO.util.Dom.get(row);
-        elRow = this.getTrEl(elRow);
-        if(elRow) {
-            nRecordIndex = this.getRecordIndex(elRow);
-        }
-    }
-    if(nRecordIndex !== null) {
-        if(count && YAHOO.lang.isNumber(count)) {
-            // Start with highest index and work down
-            var startIndex = (count > 0) ? nRecordIndex + count -1 : nRecordIndex;
-            var endIndex = (count > 0) ? nRecordIndex : nRecordIndex + count + 1;
-            for(var i=startIndex; i>endIndex-1; i--) {
-                this.deleteRow(i);
+deleteRows : function(row, count) {
+    var nRecordIndex = this.getRecordIndex(row);
+    if(lang.isNumber(nRecordIndex)) {
+        var oRecord = this.getRecord(nRecordIndex);
+        if(oRecord) {
+            var nTrIndex = this.getTrIndex(nRecordIndex);
+            
+            // Remove from selection tracker if there
+            var sRecordId = oRecord.getId();
+            var tracker = this._aSelections || [];
+            for(var j=tracker.length-1; j>-1; j--) {
+                if((lang.isNumber(tracker[j]) && (tracker[j] === sRecordId)) ||
+                        ((tracker[j].constructor == Object) && (tracker[j].recordId === sRecordId))) {
+                    tracker.splice(j,1);
+                }
             }
+    
+            // Delete Record from RecordSet
+            var highIndex = nRecordIndex+1;
+            var lowIndex = nRecordIndex;
+        
+            // Validate count and account for negative value
+            if(count && lang.isNumber(count)) {
+                highIndex = (count > 0) ? nRecordIndex + count -1 : nRecordIndex;
+                lowIndex = (count > 0) ? nRecordIndex : nRecordIndex + count + 1;
+                count = (count > 0) ? count : count*-1;
+            }
+            else {
+                count = 1;
+            }
+            
+            var aData = this._oRecordSet.deleteRecords(lowIndex, count);
+    
+            // Update the UI
+            if(aData) {
+                // If paginated and the deleted row was on this or a prior page, just
+                // re-render
+                var oPaginator = this.get('paginator');
+                if (oPaginator instanceof Pag ||
+                    this.get('paginated')) {
+        
+                    var endRecIndex;
+                    if (oPaginator instanceof Pag) {
+                        // Update the paginator's totalRecords
+                        var totalRecords = oPaginator.get('totalRecords');
+                        if (totalRecords !== Pag.VALUE_UNLIMITED) {
+                            oPaginator.set('totalRecords',totalRecords - 1);
+                        }
+        
+                        endRecIndex = (oPaginator.getPageRecords())[1];
+                    } else {
+                        // Backward compatibility
+                        endRecIndex = oPaginator.startRecordIndex +
+                                      oPaginator.rowsPerPage - 1;
+        
+                        this.updatePaginator();
+                    }
+        
+                    // If the lowest deleted record was on this or a prior page, re-render
+                    if (lowIndex <= endRecIndex) {
+                        this.render();
+                    }
+                    return;
+                }
+                else {
+                    if(lang.isNumber(nTrIndex)) {
+                        // Delete the TR elements starting with highest index
+                        var loopN = this.get("renderLoopSize");
+                        var loopEnd = lowIndex;
+                        var nRowsNeeded = count; // how many needed
+                        this._oChainRender.add({
+                            method: function(oArg) {
+                                if((this instanceof DT) && this._sId) {
+                                    var i = oArg.nCurrentRow,
+                                        len = (loopN > 0) ? (Math.max(i - loopN,loopEnd)-1) : loopEnd-1;
+                                    for(; i>len; --i) {
+                                        this._deleteTrEl(i);
+                                    }
+                                    oArg.nCurrentRow = i;
+                                }
+                            },
+                            iterations: (loopN > 0) ? Math.ceil(count/loopN) : 1,
+                            argument: {nCurrentRow:highIndex},
+                            scope: this,
+                            timeout: (loopN > 0) ? 0 : -1
+                        });
+                        this._oChainRender.add({
+                            method: function() {    
+                                // Empty body
+                                if(this._elTbody.rows.length === 0) {
+                                    this.showTableMessage(DT.MSG_EMPTY, DT.CLASS_EMPTY);
+                                }
+                                else {
+                                    this._setFirstRow();
+                                    this._setLastRow();
+                                    this._setRowStripes();
+                                }
+                                
+                                this.fireEvent("rowsDeleteEvent", {recordIndex:count,
+                                oldData:aData, count:nTrIndex});
+                            },
+                            scope: this,
+                            timeout: -1 // Needs to run immediately after the DOM deletions above
+                        });
+                        this._oChainRender.run();
+                        return;
+                    }
+                }
+            }
         }
-        else {
-            this.deleteRow(nRecordIndex);
-        }
     }
-    else {
-    }
-};
+    return null;
+},
 
 
 
@@ -4463,395 +10906,138 @@
  * Outputs markup into the given TD based on given Record.
  *
  * @method formatCell
- * @param elCell {HTMLElement} TD Element.
+ * @param elCell {HTMLElement} The liner DIV element within the TD.
  * @param oRecord {YAHOO.widget.Record} (Optional) Record instance.
  * @param oColumn {YAHOO.widget.Column} (Optional) Column instance.
- * @return {HTML} Markup.
  */
-YAHOO.widget.DataTable.prototype.formatCell = function(elCell, oRecord, oColumn) {
+formatCell : function(elCell, oRecord, oColumn) {
     if(!(oRecord instanceof YAHOO.widget.Record)) {
         oRecord = this.getRecord(elCell);
     }
     if(!(oColumn instanceof YAHOO.widget.Column)) {
-        oColumn = this._oColumnSet.getColumn(elCell.yuiColumnKey);
+        oColumn = this._oColumnSet.getColumn(elCell.parentNode.yuiColumnKey);
     }
-    
+
     if(oRecord && oColumn) {
         var sKey = oColumn.key;
         var oData = oRecord.getData(sKey);
 
-        var fnFormatter;
-        if(YAHOO.lang.isString(oColumn.formatter)) {
-            switch(oColumn.formatter) {
-                case "button":
-                    fnFormatter = YAHOO.widget.DataTable.formatButton;
-                    break;
-                case "checkbox":
-                    fnFormatter = YAHOO.widget.DataTable.formatCheckbox;
-                    break;
-                case "currency":
-                    fnFormatter = YAHOO.widget.DataTable.formatCurrency;
-                    break;
-                case "date":
-                    fnFormatter = YAHOO.widget.DataTable.formatDate;
-                    break;
-                case "dropdown":
-                    fnFormatter = YAHOO.widget.DataTable.formatDropdown;
-                    break;
-                case "email":
-                    fnFormatter = YAHOO.widget.DataTable.formatEmail;
-                    break;
-                case "link":
-                    fnFormatter = YAHOO.widget.DataTable.formatLink;
-                    break;
-                case "number":
-                    fnFormatter = YAHOO.widget.DataTable.formatNumber;
-                    break;
-                case "radio":
-                    fnFormatter = YAHOO.widget.DataTable.formatRadio;
-                    break;
-                case "text":
-                    fnFormatter = YAHOO.widget.DataTable.formatText;
-                    break;
-                case "textarea":
-                    fnFormatter = YAHOO.widget.DataTable.formatTextarea;
-                    break;
-                case "textbox":
-                    fnFormatter = YAHOO.widget.DataTable.formatTextbox;
-                    break;
-                case "html":
-                    // This is the default
-                    break;
-                default:
-                    fnFormatter = null;
-            }
+        // Add classNames
+        var aClasses;
+        if(lang.isString(oColumn.className)) {
+            aClasses = [oColumn.className];
         }
-        else if(YAHOO.lang.isFunction(oColumn.formatter)) {
-            fnFormatter = oColumn.formatter;
+        else if(lang.isArray(oColumn.className)) {
+            aClasses = oColumn.className;
         }
+        else {
+            aClasses = [];
+        }
 
+        //TODO: document special keys will get stripped here
+        aClasses[aClasses.length] = "yui-dt-col-"+sKey.replace(/[^\w\-.:]/g,"");
+        
+        aClasses[aClasses.length] = "yui-dt-col-"+oColumn.getId();
+        
+        aClasses[aClasses.length] = DT.CLASS_LINER;
+
+        if(oColumn.sortable) {
+            aClasses[aClasses.length] = DT.CLASS_SORTABLE;
+        }
+        if(oColumn.resizeable) {
+            aClasses[aClasses.length] = DT.CLASS_RESIZEABLE;
+        }
+        if(oColumn.editor) {
+            aClasses[aClasses.length] = DT.CLASS_EDITABLE;
+        }
+
+        elCell.className = "";
+        Dom.addClass(elCell, aClasses.join(" "));
+
+
+        var fnFormatter = typeof oColumn.formatter === 'function' ?
+                          oColumn.formatter :
+                          DT.Formatter[oColumn.formatter+''];
+
         // Apply special formatter
         if(fnFormatter) {
             fnFormatter.call(this, elCell, oRecord, oColumn, oData);
         }
         else {
-            elCell.innerHTML = (YAHOO.lang.isValue(oData)) ? oData.toString() : "";
+            elCell.innerHTML = oData === undefined ||
+                               oData === null ||
+                               (typeof oData === 'number' && isNaN(oData)) ?
+                                "" : oData.toString();
         }
 
-        // Add custom classNames
-        var aCustomClasses = null;
-        if(YAHOO.lang.isString(oColumn.className)) {
-            aCustomClasses = [oColumn.className];
-        }
-        else if(YAHOO.lang.isArray(oColumn.className)) {
-            aCustomClasses = oColumn.className;
-        }
-        if(aCustomClasses) {
-            for(var i=0; i<aCustomClasses.length; i++) {
-                YAHOO.util.Dom.addClass(elCell, aCustomClasses[i]);
-            }
-        }
-        
-        YAHOO.util.Dom.addClass(elCell, "yui-dt-col-"+sKey);
-
-        // Is editable?
-        if(oColumn.editor) {
-            YAHOO.util.Dom.addClass(elCell,YAHOO.widget.DataTable.CLASS_EDITABLE);
-        }
-        
         this.fireEvent("cellFormatEvent", {record:oRecord, column:oColumn, key:sKey, el:elCell});
     }
     else {
     }
-};
+},
 
 
-/**
- * Formats a BUTTON element.
- *
- * @method DataTable.formatButton
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object | Boolean} Data value for the cell. By default, the value
- * is what gets written to the BUTTON.
- * @static
- */
-YAHOO.widget.DataTable.formatButton= function(el, oRecord, oColumn, oData) {
-    var sValue = YAHOO.lang.isValue(oData) ? oData : "Click";
-    //TODO: support YAHOO.widget.Button
-    //if(YAHOO.widget.Button) {
-    
-    //}
-    //else {
-        el.innerHTML = "<button type=\"button\" class=\""+
-                YAHOO.widget.DataTable.CLASS_BUTTON + "\">" + sValue + "</button>";
-    //}
-};
 
-/**
- * Formats a CHECKBOX element.
- *
- * @method DataTable.formatCheckbox
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object | Boolean} Data value for the cell. Can be a simple
- * Boolean to indicate whether checkbox is checked or not. Can be object literal
- * {checked:bBoolean, label:sLabel}. Other forms of oData require a custom
- * formatter.
- * @static
- */
-YAHOO.widget.DataTable.formatCheckbox = function(el, oRecord, oColumn, oData) {
-    var bChecked = oData;
-    bChecked = (bChecked) ? " checked" : "";
-    el.innerHTML = "<input type=\"checkbox\"" + bChecked +
-            " class=\"" + YAHOO.widget.DataTable.CLASS_CHECKBOX + "\">";
-};
 
-/**
- * Formats currency. Default unit is USD.
- *
- * @method DataTable.formatCurrency
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Number} Data value for the cell.
- * @static
- */
-YAHOO.widget.DataTable.formatCurrency = function(el, oRecord, oColumn, oData) {
-    if(YAHOO.lang.isNumber(oData)) {
-        var nAmount = oData;
-        var markup;
 
-        // Round to the penny
-        nAmount = Math.round(nAmount*100)/100;
 
-        // Default currency is USD
-        markup = "$"+nAmount;
 
-        // Normalize digits
-        var dotIndex = markup.indexOf(".");
-        if(dotIndex < 0) {
-            markup += ".00";
-        }
-        else {
-            while(dotIndex > markup.length-3) {
-                markup += "0";
-            }
-        }
-        el.innerHTML = markup;
-    }
-    else {
-        el.innerHTML = YAHOO.lang.isValue(oData) ? oData : "";
-    }
-};
 
-/**
- * Formats JavaScript Dates.
- *
- * @method DataTable.formatDate
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} Data value for the cell, or null.
- * @static
- */
-YAHOO.widget.DataTable.formatDate = function(el, oRecord, oColumn, oData) {
-    var oDate = oData;
-    if(oDate instanceof Date) {
-        el.innerHTML = (oDate.getMonth()+1) + "/" + oDate.getDate()  + "/" + oDate.getFullYear();
-    }
-    else {
-        el.innerHTML = YAHOO.lang.isValue(oData) ? oData : "";
-    }
-};
 
-/**
- * Formats SELECT elements.
- *
- * @method DataTable.formatDropdown
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} Data value for the cell, or null.
- * @static
- */
-YAHOO.widget.DataTable.formatDropdown = function(el, oRecord, oColumn, oData) {
-    var selectedValue = (YAHOO.lang.isValue(oData)) ? oData : oRecord.getData(oColumn.key);
-    var options = (YAHOO.lang.isArray(oColumn.dropdownOptions)) ?
-            oColumn.dropdownOptions : null;
 
-    var selectEl;
-    var collection = el.getElementsByTagName("select");
-    
-    // Create the form element only once, so we can attach the onChange listener
-    if(collection.length === 0) {
-        // Create SELECT element
-        selectEl = document.createElement("select");
-        YAHOO.util.Dom.addClass(selectEl, YAHOO.widget.DataTable.CLASS_DROPDOWN);
-        selectEl = el.appendChild(selectEl);
 
-        // Add event listener
-        YAHOO.util.Event.addListener(selectEl,"change",this._onDropdownChange,this);
-    }
 
-    selectEl = collection[0];
 
-    // Update the form element
-    if(selectEl) {
-        // Clear out previous options
-        selectEl.innerHTML = "";
-        
-        // We have options to populate
-        if(options) {
-            // Create OPTION elements
-            for(var i=0; i<options.length; i++) {
-                var option = options[i];
-                var optionEl = document.createElement("option");
-                optionEl.value = (YAHOO.lang.isValue(option.value)) ?
-                        option.value : option;
-                optionEl.innerHTML = (YAHOO.lang.isValue(option.text)) ?
-                        option.text : option;
-                optionEl = selectEl.appendChild(optionEl);
-            }
-        }
-        // Selected value is our only option
-        else {
-            selectEl.innerHTML = "<option value=\"" + selectedValue + "\">" + selectedValue + "</option>";
-        }
-    }
-    else {
-        el.innerHTML = YAHOO.lang.isValue(oData) ? oData : "";
-    }
-};
 
-/**
- * Formats emails.
- *
- * @method DataTable.formatEmail
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} Data value for the cell, or null.
- * @static
- */
-YAHOO.widget.DataTable.formatEmail = function(el, oRecord, oColumn, oData) {
-    if(YAHOO.lang.isString(oData)) {
-        el.innerHTML = "<a href=\"mailto:" + oData + "\">" + oData + "</a>";
-    }
-    else {
-        el.innerHTML = YAHOO.lang.isValue(oData) ? oData : "";
-    }
-};
 
-/**
- * Formats links.
- *
- * @method DataTable.formatLink
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} Data value for the cell, or null.
- * @static
- */
-YAHOO.widget.DataTable.formatLink = function(el, oRecord, oColumn, oData) {
-    if(YAHOO.lang.isString(oData)) {
-        el.innerHTML = "<a href=\"" + oData + "\">" + oData + "</a>";
-    }
-    else {
-        el.innerHTML = YAHOO.lang.isValue(oData) ? oData : "";
-    }
-};
 
-/**
- * Formats numbers.
- *
- * @method DataTable.formatNumber
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} Data value for the cell, or null.
- * @static
- */
-YAHOO.widget.DataTable.formatNumber = function(el, oRecord, oColumn, oData) {
-    if(YAHOO.lang.isNumber(oData)) {
-        el.innerHTML = oData;
-    }
-    else {
-        el.innerHTML = YAHOO.lang.isValue(oData) ? oData : "";
-    }
-};
 
-/**
- * Formats INPUT TYPE=RADIO elements.
- *
- * @method DataTable.formatRadio
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} (Optional) Data value for the cell.
- * @static
- */
-YAHOO.widget.DataTable.formatRadio = function(el, oRecord, oColumn, oData) {
-    var bChecked = oData;
-    bChecked = (bChecked) ? " checked" : "";
-    el.innerHTML = "<input type=\"radio\"" + bChecked +
-            " name=\"" + oColumn.getKey() + "-radio\"" +
-            " class=\"" + YAHOO.widget.DataTable.CLASS_RADIO+ "\">";
-};
 
-/**
- * Formats text strings.
- *
- * @method DataTable.formatText
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} (Optional) Data value for the cell.
- * @static
- */
-YAHOO.widget.DataTable.formatText = function(el, oRecord, oColumn, oData) {
-    var value = (YAHOO.lang.isValue(oRecord.getData(oColumn.key))) ?
-            oRecord.getData(oColumn.key) : "";
-    //TODO: move to util function
-    el.innerHTML = value.toString().replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
-};
 
-/**
- * Formats TEXTAREA elements.
- *
- * @method DataTable.formatTextarea
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} (Optional) Data value for the cell.
- * @static
- */
-YAHOO.widget.DataTable.formatTextarea = function(el, oRecord, oColumn, oData) {
-    var value = (YAHOO.lang.isValue(oRecord.getData(oColumn.key))) ?
-            oRecord.getData(oColumn.key) : "";
-    var markup = "<textarea>" + value + "</textarea>";
-    el.innerHTML = markup;
-};
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// PAGINATION
+
 /**
- * Formats INPUT TYPE=TEXT elements.
- *
- * @method DataTable.formatTextbox
- * @param el {HTMLElement} The element to format with markup.
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param oData {Object} (Optional) Data value for the cell.
- * @static
+ * Delegates the Pag changeRequest events to the configured
+ * handler.
+ * @method onPaginatorChange
+ * @param {Object} an object literal describing the proposed pagination state
  */
-YAHOO.widget.DataTable.formatTextbox = function(el, oRecord, oColumn, oData) {
-    var value = (YAHOO.lang.isValue(oRecord.getData(oColumn.key))) ?
-            oRecord.getData(oColumn.key) : "";
-    var markup = "<input type=\"text\" value=\"" + value + "\">";
-    el.innerHTML = markup;
-};
+onPaginatorChange : function (oState) {
+    var handler = this.get('paginationEventHandler');
 
+    handler(oState,this);
+},
 
 
 
@@ -4899,344 +11085,1549 @@
 
 
 
-// PAGINATION
 
+
+
+// SELECTION/HIGHLIGHTING
+
 /**
- * Updates Paginator values in response to RecordSet changes and/or DOM events.
- * Pass in all, a subset, or no values.
+ * ID string of last highlighted cell element
  *
- * @method updatePaginator
- * @param oNewValues {Object} (Optional) Object literal of Paginator values, or
- * a subset of Paginator values.
- * @param {Object} Object literal of all Paginator values.
+ * @property _sLastHighlightedTdElId
+ * @type String
+ * @private
  */
+//_sLastHighlightedTdElId : null,
 
-YAHOO.widget.DataTable.prototype.updatePaginator = function(oNewValues) {
-    // Complete the set
-    var oValidPaginator = this.get("paginator");
-    var nOrigCurrentPage = oValidPaginator.currentPage;
-    for(var param in oNewValues) {
-        if(YAHOO.lang.hasOwnProperty(oValidPaginator, param)) {
-            oValidPaginator[param] = oNewValues[param];
-        }
-    }
-    
-    oValidPaginator.totalRecords = this._oRecordSet.getLength();
-    oValidPaginator.rowsThisPage = Math.min(oValidPaginator.rowsPerPage, oValidPaginator.totalRecords);
-    oValidPaginator.totalPages = Math.ceil(oValidPaginator.totalRecords / oValidPaginator.rowsThisPage);
-    if(isNaN(oValidPaginator.totalPages)) {
-        oValidPaginator.totalPages = 0;
-    }
-    if(oValidPaginator.currentPage > oValidPaginator.totalPages) {
-        if(oValidPaginator.totalPages < 1) {
-            oValidPaginator.currentPage = 1;
-        }
-        else {
-            oValidPaginator.currentPage = oValidPaginator.totalPages;
-        }
-    }
+/**
+ * ID string of last highlighted row element
+ *
+ * @property _sLastHighlightedTrElId
+ * @type String
+ * @private
+ */
+//_sLastHighlightedTrElId : null,
 
-    if(oValidPaginator.currentPage !== nOrigCurrentPage) {
-        oValidPaginator.startRecordIndex = (oValidPaginator.currentPage-1)*oValidPaginator.rowsPerPage;
-    }
+/**
+ * Array to track row selections (by sRecordId) and/or cell selections
+ * (by {recordId:sRecordId, columnId:sColumnId})
+ *
+ * @property _aSelections
+ * @type Object[]
+ * @private
+ */
+_aSelections : null,
 
+/**
+ * Record instance of the row selection anchor.
+ *
+ * @property _oAnchorRecord
+ * @type YAHOO.widget.Record
+ * @private
+ */
+_oAnchorRecord : null,
 
-    this.set("paginator", oValidPaginator);
-    return this.get("paginator");
-};
+/**
+ * Object literal representing cell selection anchor:
+ * {recordId:sRecordId, columnId:sColumnId}.
+ *
+ * @property _oAnchorCell
+ * @type Object
+ * @private
+ */
+_oAnchorCell : null,
 
 /**
- * Displays given page of a paginated DataTable.
+ * Convenience method to remove the class DT.CLASS_SELECTED
+ * from all TR elements on the page.
  *
- * @method showPage
- * @param nPage {Number} Which page.
+ * @method _unselectAllTrEls
+ * @private
  */
-YAHOO.widget.DataTable.prototype.showPage = function(nPage) {
-    // Validate input
-    if(!YAHOO.lang.isNumber(nPage) || (nPage < 1) || (nPage > this.get("paginator").totalPages)) {
-        nPage = 1;
-    }
-    this.updatePaginator({currentPage:nPage});
-    this.refreshView();
-};
+_unselectAllTrEls : function() {
+    var selectedRows = Dom.getElementsByClassName(DT.CLASS_SELECTED,"tr",this._elTbody);
+    Dom.removeClass(selectedRows, DT.CLASS_SELECTED);
+},
 
 /**
- * Updates Paginator containers with markup. Override this method to customize pagination UI.
+ * Returns object literal of values that represent the selection trigger. Used
+ * to determine selection behavior resulting from a key event.
  *
- * @method formatPaginators
+ * @method _getSelectionTrigger
+ * @private
  */
- YAHOO.widget.DataTable.prototype.formatPaginators = function() {
-    var pag = this.get("paginator");
-    var i;
+_getSelectionTrigger : function() {
+    var sMode = this.get("selectionMode");
+    var oTrigger = {};
+    var oTriggerCell, oTriggerRecord, nTriggerRecordIndex, elTriggerRow, nTriggerTrIndex;
 
-    // For Opera workaround
-    var dropdownEnabled = false;
+    // Cell mode
+    if((sMode == "cellblock") || (sMode == "cellrange") || (sMode == "singlecell")) {
+        oTriggerCell = this.getLastSelectedCell();
+        // No selected cells found
+        if(!oTriggerCell) {
+            return null;
+        }
+        else {
+            oTriggerRecord = this.getRecord(oTriggerCell.recordId);
+            nTriggerRecordIndex = this.getRecordIndex(oTriggerRecord);
+            elTriggerRow = this.getTrEl(oTriggerRecord);
+            nTriggerTrIndex = this.getTrIndex(elTriggerRow);
 
-    // Links are enabled
-    if(pag.pageLinks > -1) {
-        for(i=0; i<pag.links.length; i++) {
-            this.formatPaginatorLinks(pag.links[i], pag.currentPage, pag.pageLinksStart, pag.pageLinks, pag.totalPages);
+            // Selected cell not found on this page
+            if(nTriggerTrIndex === null) {
+                return null;
+            }
+            else {
+                oTrigger.record = oTriggerRecord;
+                oTrigger.recordIndex = nTriggerRecordIndex;
+                oTrigger.el = this.getTdEl(oTriggerCell);
+                oTrigger.trIndex = nTriggerTrIndex;
+                oTrigger.column = this.getColumnById(oTriggerCell.columnId);
+                oTrigger.colKeyIndex = oTrigger.column.getKeyIndex();
+                oTrigger.cell = oTriggerCell;
+                return oTrigger;
+            }
         }
     }
-
-    // Dropdown is enabled
-    for(i=0; i<pag.dropdowns.length; i++) {
-         if(pag.dropdownOptions) {
-            dropdownEnabled = true;
-            this.formatPaginatorDropdown(pag.dropdowns[i], pag.dropdownOptions);
+    // Row mode
+    else {
+        oTriggerRecord = this.getLastSelectedRecord();
+        // No selected rows found
+        if(!oTriggerRecord) {
+                return null;
         }
         else {
-            pag.dropdowns[i].style.display = "none";
+            // Selected row found, but is it on current page?
+            oTriggerRecord = this.getRecord(oTriggerRecord);
+            nTriggerRecordIndex = this.getRecordIndex(oTriggerRecord);
+            elTriggerRow = this.getTrEl(oTriggerRecord);
+            nTriggerTrIndex = this.getTrIndex(elTriggerRow);
+
+            // Selected row not found on this page
+            if(nTriggerTrIndex === null) {
+                return null;
+            }
+            else {
+                oTrigger.record = oTriggerRecord;
+                oTrigger.recordIndex = nTriggerRecordIndex;
+                oTrigger.el = elTriggerRow;
+                oTrigger.trIndex = nTriggerTrIndex;
+                return oTrigger;
+            }
         }
     }
+},
 
-    // For Opera artifacting in dropdowns
-    if(dropdownEnabled && navigator.userAgent.toLowerCase().indexOf("opera") != -1) {
-        document.body.style += '';
-    }
-};
-
 /**
- * Updates Paginator dropdown. If dropdown doesn't exist, the markup is created.
- * Sets dropdown elements's "selected" value.
+ * Returns object literal of values that represent the selection anchor. Used
+ * to determine selection behavior resulting from a user event.
  *
- * @method formatPaginatorDropdown
- * @param elDropdown {HTMLElement} The SELECT element.
- * @param dropdownOptions {Object[]} OPTION values for display in the SELECT element.
+ * @method _getSelectionAnchor
+ * @param oTrigger {Object} (Optional) Object literal of selection trigger values
+ * (for key events).
+ * @private
  */
-YAHOO.widget.DataTable.prototype.formatPaginatorDropdown = function(elDropdown, dropdownOptions) {
-    if(elDropdown && (elDropdown.ownerDocument == document)) {
-        // Clear OPTION elements
-        while (elDropdown.firstChild) {
-            elDropdown.removeChild(elDropdown.firstChild);
+_getSelectionAnchor : function(oTrigger) {
+    var sMode = this.get("selectionMode");
+    var oAnchor = {};
+    var oAnchorRecord, nAnchorRecordIndex, nAnchorTrIndex;
+
+    // Cell mode
+    if((sMode == "cellblock") || (sMode == "cellrange") || (sMode == "singlecell")) {
+        // Validate anchor cell
+        var oAnchorCell = this._oAnchorCell;
+        if(!oAnchorCell) {
+            if(oTrigger) {
+                oAnchorCell = this._oAnchorCell = oTrigger.cell;
+            }
+            else {
+                return null;
+            }
         }
+        oAnchorRecord = this._oAnchorCell.record;
+        nAnchorRecordIndex = this._oRecordSet.getRecordIndex(oAnchorRecord);
+        nAnchorTrIndex = this.getTrIndex(oAnchorRecord);
+        // If anchor cell is not on this page...
+        if(nAnchorTrIndex === null) {
+            // ...set TR index equal to top TR
+            if(nAnchorRecordIndex < this.getRecordIndex(this.getFirstTrEl())) {
+                nAnchorTrIndex = 0;
+            }
+            // ...set TR index equal to bottom TR
+            else {
+                nAnchorTrIndex = this.getRecordIndex(this.getLastTrEl());
+            }
+        }
 
-        // Create OPTION elements
-        for(var j=0; j<dropdownOptions.length; j++) {
-            var dropdownOption = dropdownOptions[j];
-            var optionEl = document.createElement("option");
-            optionEl.value = (YAHOO.lang.isValue(dropdownOption.value)) ?
-                    dropdownOption.value : dropdownOption;
-            optionEl.innerHTML = (YAHOO.lang.isValue(dropdownOption.text)) ?
-                    dropdownOption.text : dropdownOption;
-            optionEl = elDropdown.appendChild(optionEl);
+        oAnchor.record = oAnchorRecord;
+        oAnchor.recordIndex = nAnchorRecordIndex;
+        oAnchor.trIndex = nAnchorTrIndex;
+        oAnchor.column = this._oAnchorCell.column;
+        oAnchor.colKeyIndex = oAnchor.column.getKeyIndex();
+        oAnchor.cell = oAnchorCell;
+        return oAnchor;
+    }
+    // Row mode
+    else {
+        oAnchorRecord = this._oAnchorRecord;
+        if(!oAnchorRecord) {
+            if(oTrigger) {
+                oAnchorRecord = this._oAnchorRecord = oTrigger.record;
+            }
+            else {
+                return null;
+            }
         }
 
-        var options = elDropdown.options;
-        // Update dropdown's "selected" value
-        if(options.length) {
-            for(var i=options.length-1; i>-1; i--) {
-                if((this.get("paginator").rowsPerPage + "") === options[i].value) {
-                    options[i].selected = true;
-                }
+        nAnchorRecordIndex = this.getRecordIndex(oAnchorRecord);
+        nAnchorTrIndex = this.getTrIndex(oAnchorRecord);
+        // If anchor row is not on this page...
+        if(nAnchorTrIndex === null) {
+            // ...set TR index equal to top TR
+            if(nAnchorRecordIndex < this.getRecordIndex(this.getFirstTrEl())) {
+                nAnchorTrIndex = 0;
             }
+            // ...set TR index equal to bottom TR
+            else {
+                nAnchorTrIndex = this.getRecordIndex(this.getLastTrEl());
+            }
         }
 
-        // Show the dropdown
-        elDropdown.style.display = "";
-        return;
+        oAnchor.record = oAnchorRecord;
+        oAnchor.recordIndex = nAnchorRecordIndex;
+        oAnchor.trIndex = nAnchorTrIndex;
+        return oAnchor;
     }
-};
+},
 
 /**
- * Updates Paginator links container with markup.
+ * Determines selection behavior resulting from a mouse event when selection mode
+ * is set to "standard".
  *
- * @method formatPaginatorLinks
- * @param elContainer {HTMLElement} The link container element.
- * @param nCurrentPage {Number} Current page.
- * @param nPageLinksStart {Number} First page link to display.
- * @param nPageLinksLength {Number} How many page links to display.
- * @param nTotalPages {Number} Total number of pages.
+ * @method _handleStandardSelectionByMouse
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
+ * @private
  */
-YAHOO.widget.DataTable.prototype.formatPaginatorLinks = function(elContainer, nCurrentPage, nPageLinksStart, nPageLinksLength, nTotalPages) {
-    if(elContainer && (elContainer.ownerDocument == document) &&
-            YAHOO.lang.isNumber(nCurrentPage) && YAHOO.lang.isNumber(nPageLinksStart) &&
-            YAHOO.lang.isNumber(nTotalPages)) {
-        // Set up markup for first/last/previous/next
-        var bIsFirstPage = (nCurrentPage == 1) ? true : false;
-        var bIsLastPage = (nCurrentPage == nTotalPages) ? true : false;
-        var sFirstLinkMarkup = (bIsFirstPage) ?
-                " <span class=\"" + YAHOO.widget.DataTable.CLASS_DISABLED +
-                " " + YAHOO.widget.DataTable.CLASS_FIRST + "\"><<</span> " :
-                " <a href=\"#\" class=\"" + YAHOO.widget.DataTable.CLASS_FIRST + "\"><<</a> ";
-        var sPrevLinkMarkup = (bIsFirstPage) ?
-                " <span class=\"" + YAHOO.widget.DataTable.CLASS_DISABLED +
-                " " + YAHOO.widget.DataTable.CLASS_PREVIOUS + "\"><</span> " :
-                " <a href=\"#\" class=\"" + YAHOO.widget.DataTable.CLASS_PREVIOUS + "\"><</a> " ;
-        var sNextLinkMarkup = (bIsLastPage) ?
-                " <span class=\"" + YAHOO.widget.DataTable.CLASS_DISABLED +
-                " " + YAHOO.widget.DataTable.CLASS_NEXT + "\">></span> " :
-                " <a href=\"#\" class=\"" + YAHOO.widget.DataTable.CLASS_NEXT + "\">></a> " ;
-        var sLastLinkMarkup = (bIsLastPage) ?
-                " <span class=\"" + YAHOO.widget.DataTable.CLASS_DISABLED +
-                " " + YAHOO.widget.DataTable.CLASS_LAST +  "\">>></span> " :
-                " <a href=\"#\" class=\"" + YAHOO.widget.DataTable.CLASS_LAST + "\">>></a> ";
+_handleStandardSelectionByMouse : function(oArgs) {
+    var elTarget = oArgs.target;
 
-        // Start with first and previous
-        var sMarkup = sFirstLinkMarkup + sPrevLinkMarkup;
-        
-        // Ok to show all links
-        var nMaxLinks = nTotalPages;
-        var nFirstLink = 1;
-        var nLastLink = nTotalPages;
+    // Validate target row
+    var elTargetRow = this.getTrEl(elTarget);
+    if(elTargetRow) {
+        var e = oArgs.event;
+        var bSHIFT = e.shiftKey;
+        var bCTRL = e.ctrlKey || ((navigator.userAgent.toLowerCase().indexOf("mac") != -1) && e.metaKey);
 
-        if(nPageLinksLength > 0) {
-        // Calculate how many links to show
-            nMaxLinks = (nPageLinksStart+nPageLinksLength < nTotalPages) ?
-                    nPageLinksStart+nPageLinksLength-1 : nTotalPages;
+        var oTargetRecord = this.getRecord(elTargetRow);
+        var nTargetRecordIndex = this._oRecordSet.getRecordIndex(oTargetRecord);
 
-            // Try to keep the current page in the middle
-            nFirstLink = (nCurrentPage - Math.floor(nMaxLinks/2) > 0) ? nCurrentPage - Math.floor(nMaxLinks/2) : 1;
-            nLastLink = (nCurrentPage + Math.floor(nMaxLinks/2) <= nTotalPages) ? nCurrentPage + Math.floor(nMaxLinks/2) : nTotalPages;
+        var oAnchor = this._getSelectionAnchor();
 
-            // Keep the last link in range
-            if(nFirstLink === 1) {
-                nLastLink = nMaxLinks;
+        var i;
+
+        // Both SHIFT and CTRL
+        if(bSHIFT && bCTRL) {
+            // Validate anchor
+            if(oAnchor) {
+                if(this.isSelected(oAnchor.record)) {
+                    // Select all rows between anchor row and target row, including target row
+                    if(oAnchor.recordIndex < nTargetRecordIndex) {
+                        for(i=oAnchor.recordIndex+1; i<=nTargetRecordIndex; i++) {
+                            if(!this.isSelected(i)) {
+                                this.selectRow(i);
+                            }
+                        }
+                    }
+                    // Select all rows between target row and anchor row, including target row
+                    else {
+                        for(i=oAnchor.recordIndex-1; i>=nTargetRecordIndex; i--) {
+                            if(!this.isSelected(i)) {
+                                this.selectRow(i);
+                            }
+                        }
+                    }
+                }
+                else {
+                    // Unselect all rows between anchor row and target row
+                    if(oAnchor.recordIndex < nTargetRecordIndex) {
+                        for(i=oAnchor.recordIndex+1; i<=nTargetRecordIndex-1; i++) {
+                            if(this.isSelected(i)) {
+                                this.unselectRow(i);
+                            }
+                        }
+                    }
+                    // Unselect all rows between target row and anchor row
+                    else {
+                        for(i=nTargetRecordIndex+1; i<=oAnchor.recordIndex-1; i++) {
+                            if(this.isSelected(i)) {
+                                this.unselectRow(i);
+                            }
+                        }
+                    }
+                    // Select the target row
+                    this.selectRow(oTargetRecord);
+                }
             }
-            // Keep the first link in range
-            else if(nLastLink === nTotalPages) {
-                nFirstLink = nTotalPages - nMaxLinks + 1;
+            // Invalid anchor
+            else {
+                // Set anchor
+                this._oAnchorRecord = oTargetRecord;
+
+                // Toggle selection of target
+                if(this.isSelected(oTargetRecord)) {
+                    this.unselectRow(oTargetRecord);
+                }
+                else {
+                    this.selectRow(oTargetRecord);
+                }
             }
+        }
+         // Only SHIFT
+        else if(bSHIFT) {
+            this.unselectAllRows();
 
-            // An even number of links can get funky
-            if(nLastLink - nFirstLink === nMaxLinks) {
-                nLastLink--;
+            // Validate anchor
+            if(oAnchor) {
+                // Select all rows between anchor row and target row,
+                // including the anchor row and target row
+                if(oAnchor.recordIndex < nTargetRecordIndex) {
+                    for(i=oAnchor.recordIndex; i<=nTargetRecordIndex; i++) {
+                        this.selectRow(i);
+                    }
+                }
+                // Select all rows between target row and anchor row,
+                // including the target row and anchor row
+                else {
+                    for(i=oAnchor.recordIndex; i>=nTargetRecordIndex; i--) {
+                        this.selectRow(i);
+                    }
+                }
             }
-      }
-        
-        // Generate markup for each page
-        for(var i=nFirstLink; i<=nLastLink; i++) {
-            if(i != nCurrentPage) {
-                sMarkup += " <a href=\"#\" class=\"" + YAHOO.widget.DataTable.CLASS_PAGE + "\">" + i + "</a> ";
+            // Invalid anchor
+            else {
+                // Set anchor
+                this._oAnchorRecord = oTargetRecord;
+
+                // Select target row only
+                this.selectRow(oTargetRecord);
             }
+        }
+        // Only CTRL
+        else if(bCTRL) {
+            // Set anchor
+            this._oAnchorRecord = oTargetRecord;
+
+            // Toggle selection of target
+            if(this.isSelected(oTargetRecord)) {
+                this.unselectRow(oTargetRecord);
+            }
             else {
-                sMarkup += " <span class=\"" + YAHOO.widget.DataTable.CLASS_SELECTED + "\">" + i + "</span>";
+                this.selectRow(oTargetRecord);
             }
         }
-        sMarkup += sNextLinkMarkup + sLastLinkMarkup;
-        elContainer.innerHTML = sMarkup;
-        return;
+        // Neither SHIFT nor CTRL
+        else {
+            this._handleSingleSelectionByMouse(oArgs);
+            return;
+        }
     }
-};
+},
 
+/**
+ * Determines selection behavior resulting from a key event when selection mode
+ * is set to "standard".
+ *
+ * @method _handleStandardSelectionByKey
+ * @param e {HTMLEvent} Event object.
+ * @private
+ */
+_handleStandardSelectionByKey : function(e) {
+    var nKey = Ev.getCharCode(e);
 
+    if((nKey == 38) || (nKey == 40)) {
+        var bSHIFT = e.shiftKey;
 
+        // Validate trigger
+        var oTrigger = this._getSelectionTrigger();
+        // Arrow selection only works if last selected row is on current page
+        if(!oTrigger) {
+            return null;
+        }
 
+        Ev.stopEvent(e);
 
+        // Validate anchor
+        var oAnchor = this._getSelectionAnchor(oTrigger);
 
+        // Determine which direction we're going to
+        if(bSHIFT) {
+            // Selecting down away from anchor row
+            if((nKey == 40) && (oAnchor.recordIndex <= oTrigger.trIndex)) {
+                this.selectRow(this.getNextTrEl(oTrigger.el));
+            }
+            // Selecting up away from anchor row
+            else if((nKey == 38) && (oAnchor.recordIndex >= oTrigger.trIndex)) {
+                this.selectRow(this.getPreviousTrEl(oTrigger.el));
+            }
+            // Unselect trigger
+            else {
+                this.unselectRow(oTrigger.el);
+            }
+        }
+        else {
+            this._handleSingleSelectionByKey(e);
+        }
+    }
+},
 
+/**
+ * Determines selection behavior resulting from a mouse event when selection mode
+ * is set to "single".
+ *
+ * @method _handleSingleSelectionByMouse
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
+ * @private
+ */
+_handleSingleSelectionByMouse : function(oArgs) {
+    var elTarget = oArgs.target;
 
+    // Validate target row
+    var elTargetRow = this.getTrEl(elTarget);
+    if(elTargetRow) {
+        var oTargetRecord = this.getRecord(elTargetRow);
 
+        // Set anchor
+        this._oAnchorRecord = oTargetRecord;
 
+        // Select only target
+        this.unselectAllRows();
+        this.selectRow(oTargetRecord);
+    }
+},
 
+/**
+ * Determines selection behavior resulting from a key event when selection mode
+ * is set to "single".
+ *
+ * @method _handleSingleSelectionByKey
+ * @param e {HTMLEvent} Event object.
+ * @private
+ */
+_handleSingleSelectionByKey : function(e) {
+    var nKey = Ev.getCharCode(e);
 
+    if((nKey == 38) || (nKey == 40)) {
+        // Validate trigger
+        var oTrigger = this._getSelectionTrigger();
+        // Arrow selection only works if last selected row is on current page
+        if(!oTrigger) {
+            return null;
+        }
 
+        Ev.stopEvent(e);
 
+        // Determine the new row to select
+        var elNew;
+        if(nKey == 38) { // arrow up
+            elNew = this.getPreviousTrEl(oTrigger.el);
 
+            // Validate new row
+            if(elNew === null) {
+                //TODO: wrap around to last tr on current page
+                //elNew = this.getLastTrEl();
 
+                //TODO: wrap back to last tr of previous page
 
+                // Top row selection is sticky
+                elNew = this.getFirstTrEl();
+            }
+        }
+        else if(nKey == 40) { // arrow down
+            elNew = this.getNextTrEl(oTrigger.el);
 
+            // Validate new row
+            if(elNew === null) {
+                //TODO: wrap around to first tr on current page
+                //elNew = this.getFirstTrEl();
 
+                //TODO: wrap forward to first tr of previous page
 
+                // Bottom row selection is sticky
+                elNew = this.getLastTrEl();
+            }
+        }
 
+        // Unselect all rows
+        this.unselectAllRows();
 
+        // Select the new row
+        this.selectRow(elNew);
 
+        // Set new anchor
+        this._oAnchorRecord = this.getRecord(elNew);
+    }
+},
 
+/**
+ * Determines selection behavior resulting from a mouse event when selection mode
+ * is set to "cellblock".
+ *
+ * @method _handleCellBlockSelectionByMouse
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
+ * @private
+ */
+_handleCellBlockSelectionByMouse : function(oArgs) {
+    var elTarget = oArgs.target;
 
+    // Validate target cell
+    var elTargetCell = this.getTdEl(elTarget);
+    if(elTargetCell) {
+        var e = oArgs.event;
+        var bSHIFT = e.shiftKey;
+        var bCTRL = e.ctrlKey || ((navigator.userAgent.toLowerCase().indexOf("mac") != -1) && e.metaKey);
 
+        var elTargetRow = this.getTrEl(elTargetCell);
+        var nTargetTrIndex = this.getTrIndex(elTargetRow);
+        var oTargetColumn = this.getColumn(elTargetCell);
+        var nTargetColKeyIndex = oTargetColumn.getKeyIndex();
+        var oTargetRecord = this.getRecord(elTargetRow);
+        var nTargetRecordIndex = this._oRecordSet.getRecordIndex(oTargetRecord);
+        var oTargetCell = {record:oTargetRecord, column:oTargetColumn};
 
+        var oAnchor = this._getSelectionAnchor();
 
+        var allRows = this.getTbodyEl().rows;
+        var startIndex, endIndex, currentRow, i, j;
 
+        // Both SHIFT and CTRL
+        if(bSHIFT && bCTRL) {
 
+            // Validate anchor
+            if(oAnchor) {
+                // Anchor is selected
+                if(this.isSelected(oAnchor.cell)) {
+                    // All cells are on the same row
+                    if(oAnchor.recordIndex === nTargetRecordIndex) {
+                        // Select all cells between anchor cell and target cell, including target cell
+                        if(oAnchor.colKeyIndex < nTargetColKeyIndex) {
+                            for(i=oAnchor.colKeyIndex+1; i<=nTargetColKeyIndex; i++) {
+                                this.selectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                        // Select all cells between target cell and anchor cell, including target cell
+                        else if(nTargetColKeyIndex < oAnchor.colKeyIndex) {
+                            for(i=nTargetColKeyIndex; i<oAnchor.colKeyIndex; i++) {
+                                this.selectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                    }
+                    // Anchor row is above target row
+                    else if(oAnchor.recordIndex < nTargetRecordIndex) {
+                        startIndex = Math.min(oAnchor.colKeyIndex, nTargetColKeyIndex);
+                        endIndex = Math.max(oAnchor.colKeyIndex, nTargetColKeyIndex);
 
+                        // Select all cells from startIndex to endIndex on rows between anchor row and target row
+                        for(i=oAnchor.trIndex; i<=nTargetTrIndex; i++) {
+                            for(j=startIndex; j<=endIndex; j++) {
+                                this.selectCell(allRows[i].cells[j]);
+                            }
+                        }
+                    }
+                    // Anchor row is below target row
+                    else {
+                        startIndex = Math.min(oAnchor.trIndex, nTargetColKeyIndex);
+                        endIndex = Math.max(oAnchor.trIndex, nTargetColKeyIndex);
 
+                        // Select all cells from startIndex to endIndex on rows between target row and anchor row
+                        for(i=oAnchor.trIndex; i>=nTargetTrIndex; i--) {
+                            for(j=endIndex; j>=startIndex; j--) {
+                                this.selectCell(allRows[i].cells[j]);
+                            }
+                        }
+                    }
+                }
+                // Anchor cell is unselected
+                else {
+                    // All cells are on the same row
+                    if(oAnchor.recordIndex === nTargetRecordIndex) {
+                        // Unselect all cells between anchor cell and target cell
+                        if(oAnchor.colKeyIndex < nTargetColKeyIndex) {
+                            for(i=oAnchor.colKeyIndex+1; i<nTargetColKeyIndex; i++) {
+                                this.unselectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                        // Select all cells between target cell and anchor cell
+                        else if(nTargetColKeyIndex < oAnchor.colKeyIndex) {
+                            for(i=nTargetColKeyIndex+1; i<oAnchor.colKeyIndex; i++) {
+                                this.unselectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                    }
+                    // Anchor row is above target row
+                    if(oAnchor.recordIndex < nTargetRecordIndex) {
+                        // Unselect all cells from anchor cell to target cell
+                        for(i=oAnchor.trIndex; i<=nTargetTrIndex; i++) {
+                            currentRow = allRows[i];
+                            for(j=0; j<currentRow.cells.length; j++) {
+                                // This is the anchor row, only unselect cells after the anchor cell
+                                if(currentRow.sectionRowIndex === oAnchor.trIndex) {
+                                    if(j>oAnchor.colKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // This is the target row, only unelect cells before the target cell
+                                else if(currentRow.sectionRowIndex === nTargetTrIndex) {
+                                    if(j<nTargetColKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // Unselect all cells on this row
+                                else {
+                                    this.unselectCell(currentRow.cells[j]);
+                                }
+                            }
+                        }
+                    }
+                    // Anchor row is below target row
+                    else {
+                        // Unselect all cells from target cell to anchor cell
+                        for(i=nTargetTrIndex; i<=oAnchor.trIndex; i++) {
+                            currentRow = allRows[i];
+                            for(j=0; j<currentRow.cells.length; j++) {
+                                // This is the target row, only unselect cells after the target cell
+                                if(currentRow.sectionRowIndex == nTargetTrIndex) {
+                                    if(j>nTargetColKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // This is the anchor row, only unselect cells before the anchor cell
+                                else if(currentRow.sectionRowIndex == oAnchor.trIndex) {
+                                    if(j<oAnchor.colKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // Unselect all cells on this row
+                                else {
+                                    this.unselectCell(currentRow.cells[j]);
+                                }
+                            }
+                        }
+                    }
 
+                    // Select the target cell
+                    this.selectCell(elTargetCell);
+                }
+            }
+            // Invalid anchor
+            else {
+                // Set anchor
+                this._oAnchorCell = oTargetCell;
 
+                // Toggle selection of target
+                if(this.isSelected(oTargetCell)) {
+                    this.unselectCell(oTargetCell);
+                }
+                else {
+                    this.selectCell(oTargetCell);
+                }
+            }
 
+        }
+         // Only SHIFT
+        else if(bSHIFT) {
+            this.unselectAllCells();
 
+            // Validate anchor
+            if(oAnchor) {
+                // All cells are on the same row
+                if(oAnchor.recordIndex === nTargetRecordIndex) {
+                    // Select all cells between anchor cell and target cell,
+                    // including the anchor cell and target cell
+                    if(oAnchor.colKeyIndex < nTargetColKeyIndex) {
+                        for(i=oAnchor.colKeyIndex; i<=nTargetColKeyIndex; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+                    }
+                    // Select all cells between target cell and anchor cell
+                    // including the target cell and anchor cell
+                    else if(nTargetColKeyIndex < oAnchor.colKeyIndex) {
+                        for(i=nTargetColKeyIndex; i<=oAnchor.colKeyIndex; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+                    }
+                }
+                // Anchor row is above target row
+                else if(oAnchor.recordIndex < nTargetRecordIndex) {
+                    // Select the cellblock from anchor cell to target cell
+                    // including the anchor cell and the target cell
+                    startIndex = Math.min(oAnchor.colKeyIndex, nTargetColKeyIndex);
+                    endIndex = Math.max(oAnchor.colKeyIndex, nTargetColKeyIndex);
 
+                    for(i=oAnchor.trIndex; i<=nTargetTrIndex; i++) {
+                        for(j=startIndex; j<=endIndex; j++) {
+                            this.selectCell(allRows[i].cells[j]);
+                        }
+                    }
+                }
+                // Anchor row is below target row
+                else {
+                    // Select the cellblock from target cell to anchor cell
+                    // including the target cell and the anchor cell
+                    startIndex = Math.min(oAnchor.colKeyIndex, nTargetColKeyIndex);
+                    endIndex = Math.max(oAnchor.colKeyIndex, nTargetColKeyIndex);
 
+                    for(i=nTargetTrIndex; i<=oAnchor.trIndex; i++) {
+                        for(j=startIndex; j<=endIndex; j++) {
+                            this.selectCell(allRows[i].cells[j]);
+                        }
+                    }
+                }
+            }
+            // Invalid anchor
+            else {
+                // Set anchor
+                this._oAnchorCell = oTargetCell;
 
+                // Select target only
+                this.selectCell(oTargetCell);
+            }
+        }
+        // Only CTRL
+        else if(bCTRL) {
 
+            // Set anchor
+            this._oAnchorCell = oTargetCell;
 
+            // Toggle selection of target
+            if(this.isSelected(oTargetCell)) {
+                this.unselectCell(oTargetCell);
+            }
+            else {
+                this.selectCell(oTargetCell);
+            }
 
+        }
+        // Neither SHIFT nor CTRL
+        else {
+            this._handleSingleCellSelectionByMouse(oArgs);
+        }
+    }
+},
 
+/**
+ * Determines selection behavior resulting from a key event when selection mode
+ * is set to "cellblock".
+ *
+ * @method _handleCellBlockSelectionByKey
+ * @param e {HTMLEvent} Event object.
+ * @private
+ */
+_handleCellBlockSelectionByKey : function(e) {
+    var nKey = Ev.getCharCode(e);
+    var bSHIFT = e.shiftKey;
+    if((nKey == 9) || !bSHIFT) {
+        this._handleSingleCellSelectionByKey(e);
+        return;
+    }
 
+    if((nKey > 36) && (nKey < 41)) {
+        // Validate trigger
+        var oTrigger = this._getSelectionTrigger();
+        // Arrow selection only works if last selected row is on current page
+        if(!oTrigger) {
+            return null;
+        }
 
+        Ev.stopEvent(e);
 
+        // Validate anchor
+        var oAnchor = this._getSelectionAnchor(oTrigger);
 
+        var i, startIndex, endIndex, elNew, elNewRow;
+        var allRows = this.getTbodyEl().rows;
+        var elThisRow = oTrigger.el.parentNode;
 
+        // Determine which direction we're going to
 
-// SELECTION/HIGHLIGHTING
+        if(nKey == 40) { // arrow down
+            // Selecting away from anchor cell
+            if(oAnchor.recordIndex <= oTrigger.recordIndex) {
+                // Select the horiz block on the next row...
+                // ...making sure there is room below the trigger row
+                elNewRow = this.getNextTrEl(oTrigger.el);
+                if(elNewRow) {
+                    startIndex = oAnchor.colKeyIndex;
+                    endIndex = oTrigger.colKeyIndex;
+                    // ...going left
+                    if(startIndex > endIndex) {
+                        for(i=startIndex; i>=endIndex; i--) {
+                            elNew = elNewRow.cells[i];
+                            this.selectCell(elNew);
+                        }
+                    }
+                    // ... going right
+                    else {
+                        for(i=startIndex; i<=endIndex; i++) {
+                            elNew = elNewRow.cells[i];
+                            this.selectCell(elNew);
+                        }
+                    }
+                }
+            }
+            // Unselecting towards anchor cell
+            else {
+                startIndex = Math.min(oAnchor.colKeyIndex, oTrigger.colKeyIndex);
+                endIndex = Math.max(oAnchor.colKeyIndex, oTrigger.colKeyIndex);
+                // Unselect the horiz block on this row towards the next row
+                for(i=startIndex; i<=endIndex; i++) {
+                    this.unselectCell(elThisRow.cells[i]);
+                }
+            }
+        }
+        // Arrow up
+        else if(nKey == 38) {
+            // Selecting away from anchor cell
+            if(oAnchor.recordIndex >= oTrigger.recordIndex) {
+                // Select the horiz block on the previous row...
+                // ...making sure there is room
+                elNewRow = this.getPreviousTrEl(oTrigger.el);
+                if(elNewRow) {
+                    // Select in order from anchor to trigger...
+                    startIndex = oAnchor.colKeyIndex;
+                    endIndex = oTrigger.colKeyIndex;
+                    // ...going left
+                    if(startIndex > endIndex) {
+                        for(i=startIndex; i>=endIndex; i--) {
+                            elNew = elNewRow.cells[i];
+                            this.selectCell(elNew);
+                        }
+                    }
+                    // ... going right
+                    else {
+                        for(i=startIndex; i<=endIndex; i++) {
+                            elNew = elNewRow.cells[i];
+                            this.selectCell(elNew);
+                        }
+                    }
+                }
+            }
+            // Unselecting towards anchor cell
+            else {
+                startIndex = Math.min(oAnchor.colKeyIndex, oTrigger.colKeyIndex);
+                endIndex = Math.max(oAnchor.colKeyIndex, oTrigger.colKeyIndex);
+                // Unselect the horiz block on this row towards the previous row
+                for(i=startIndex; i<=endIndex; i++) {
+                    this.unselectCell(elThisRow.cells[i]);
+                }
+            }
+        }
+        // Arrow right
+        else if(nKey == 39) {
+            // Selecting away from anchor cell
+            if(oAnchor.colKeyIndex <= oTrigger.colKeyIndex) {
+                // Select the next vert block to the right...
+                // ...making sure there is room
+                if(oTrigger.colKeyIndex < elThisRow.cells.length-1) {
+                    // Select in order from anchor to trigger...
+                    startIndex = oAnchor.trIndex;
+                    endIndex = oTrigger.trIndex;
+                    // ...going up
+                    if(startIndex > endIndex) {
+                        for(i=startIndex; i>=endIndex; i--) {
+                            elNew = allRows[i].cells[oTrigger.colKeyIndex+1];
+                            this.selectCell(elNew);
+                        }
+                    }
+                    // ... going down
+                    else {
+                        for(i=startIndex; i<=endIndex; i++) {
+                            elNew = allRows[i].cells[oTrigger.colKeyIndex+1];
+                            this.selectCell(elNew);
+                        }
+                    }
+                }
+            }
+            // Unselecting towards anchor cell
+            else {
+                // Unselect the vert block on this column towards the right
+                startIndex = Math.min(oAnchor.trIndex, oTrigger.trIndex);
+                endIndex = Math.max(oAnchor.trIndex, oTrigger.trIndex);
+                for(i=startIndex; i<=endIndex; i++) {
+                    this.unselectCell(allRows[i].cells[oTrigger.colKeyIndex]);
+                }
+            }
+        }
+        // Arrow left
+        else if(nKey == 37) {
+            // Selecting away from anchor cell
+            if(oAnchor.colKeyIndex >= oTrigger.colKeyIndex) {
+                //Select the previous vert block to the left
+                if(oTrigger.colKeyIndex > 0) {
+                    // Select in order from anchor to trigger...
+                    startIndex = oAnchor.trIndex;
+                    endIndex = oTrigger.trIndex;
+                    // ...going up
+                    if(startIndex > endIndex) {
+                        for(i=startIndex; i>=endIndex; i--) {
+                            elNew = allRows[i].cells[oTrigger.colKeyIndex-1];
+                            this.selectCell(elNew);
+                        }
+                    }
+                    // ... going down
+                    else {
+                        for(i=startIndex; i<=endIndex; i++) {
+                            elNew = allRows[i].cells[oTrigger.colKeyIndex-1];
+                            this.selectCell(elNew);
+                        }
+                    }
+                }
+            }
+            // Unselecting towards anchor cell
+            else {
+                // Unselect the vert block on this column towards the left
+                startIndex = Math.min(oAnchor.trIndex, oTrigger.trIndex);
+                endIndex = Math.max(oAnchor.trIndex, oTrigger.trIndex);
+                for(i=startIndex; i<=endIndex; i++) {
+                    this.unselectCell(allRows[i].cells[oTrigger.colKeyIndex]);
+                }
+            }
+        }
+    }
+},
 
 /**
- * ID string of last highlighted cell element
+ * Determines selection behavior resulting from a mouse event when selection mode
+ * is set to "cellrange".
  *
- * @property _sLastHighlightedTdElId
- * @type String
+ * @method _handleCellRangeSelectionByMouse
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
  * @private
  */
-YAHOO.widget.DataTable.prototype._sLastHighlightedTdElId = null;
+_handleCellRangeSelectionByMouse : function(oArgs) {
+    var elTarget = oArgs.target;
 
-/**
- * ID string of last highlighted row element
- *
- * @property _sLastHighlightedTrElId
- * @type String
- * @private
- */
-YAHOO.widget.DataTable.prototype._sLastHighlightedTrElId = null;
+    // Validate target cell
+    var elTargetCell = this.getTdEl(elTarget);
+    if(elTargetCell) {
+        var e = oArgs.event;
+        var bSHIFT = e.shiftKey;
+        var bCTRL = e.ctrlKey || ((navigator.userAgent.toLowerCase().indexOf("mac") != -1) && e.metaKey);
 
-/**
- * Array to track row selections (by sRecordId) and/or cell selections
- * (by {recordId:sRecordId, columnId:sColumnId})
- *
- * @property _aSelections
- * @type Object[]
- * @private
- */
-YAHOO.widget.DataTable.prototype._aSelections = null;
+        var elTargetRow = this.getTrEl(elTargetCell);
+        var nTargetTrIndex = this.getTrIndex(elTargetRow);
+        var oTargetColumn = this.getColumn(elTargetCell);
+        var nTargetColKeyIndex = oTargetColumn.getKeyIndex();
+        var oTargetRecord = this.getRecord(elTargetRow);
+        var nTargetRecordIndex = this._oRecordSet.getRecordIndex(oTargetRecord);
+        var oTargetCell = {record:oTargetRecord, column:oTargetColumn};
 
+        var oAnchor = this._getSelectionAnchor();
+
+        var allRows = this.getTbodyEl().rows;
+        var currentRow, i, j;
+
+        // Both SHIFT and CTRL
+        if(bSHIFT && bCTRL) {
+
+            // Validate anchor
+            if(oAnchor) {
+                // Anchor is selected
+                if(this.isSelected(oAnchor.cell)) {
+                    // All cells are on the same row
+                    if(oAnchor.recordIndex === nTargetRecordIndex) {
+                        // Select all cells between anchor cell and target cell, including target cell
+                        if(oAnchor.colKeyIndex < nTargetColKeyIndex) {
+                            for(i=oAnchor.colKeyIndex+1; i<=nTargetColKeyIndex; i++) {
+                                this.selectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                        // Select all cells between target cell and anchor cell, including target cell
+                        else if(nTargetColKeyIndex < oAnchor.colKeyIndex) {
+                            for(i=nTargetColKeyIndex; i<oAnchor.colKeyIndex; i++) {
+                                this.selectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                    }
+                    // Anchor row is above target row
+                    else if(oAnchor.recordIndex < nTargetRecordIndex) {
+                        // Select all cells on anchor row from anchor cell to the end of the row
+                        for(i=oAnchor.colKeyIndex+1; i<elTargetRow.cells.length; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+
+                        // Select all cells on all rows between anchor row and target row
+                        for(i=oAnchor.trIndex+1; i<nTargetTrIndex; i++) {
+                            for(j=0; j<allRows[i].cells.length; j++){
+                                this.selectCell(allRows[i].cells[j]);
+                            }
+                        }
+
+                        // Select all cells on target row from first cell to the target cell
+                        for(i=0; i<=nTargetColKeyIndex; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+                    }
+                    // Anchor row is below target row
+                    else {
+                        // Select all cells on target row from target cell to the end of the row
+                        for(i=nTargetColKeyIndex; i<elTargetRow.cells.length; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+
+                        // Select all cells on all rows between target row and anchor row
+                        for(i=nTargetTrIndex+1; i<oAnchor.trIndex; i++) {
+                            for(j=0; j<allRows[i].cells.length; j++){
+                                this.selectCell(allRows[i].cells[j]);
+                            }
+                        }
+
+                        // Select all cells on anchor row from first cell to the anchor cell
+                        for(i=0; i<oAnchor.colKeyIndex; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+                    }
+                }
+                // Anchor cell is unselected
+                else {
+                    // All cells are on the same row
+                    if(oAnchor.recordIndex === nTargetRecordIndex) {
+                        // Unselect all cells between anchor cell and target cell
+                        if(oAnchor.colKeyIndex < nTargetColKeyIndex) {
+                            for(i=oAnchor.colKeyIndex+1; i<nTargetColKeyIndex; i++) {
+                                this.unselectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                        // Select all cells between target cell and anchor cell
+                        else if(nTargetColKeyIndex < oAnchor.colKeyIndex) {
+                            for(i=nTargetColKeyIndex+1; i<oAnchor.colKeyIndex; i++) {
+                                this.unselectCell(elTargetRow.cells[i]);
+                            }
+                        }
+                    }
+                    // Anchor row is above target row
+                    if(oAnchor.recordIndex < nTargetRecordIndex) {
+                        // Unselect all cells from anchor cell to target cell
+                        for(i=oAnchor.trIndex; i<=nTargetTrIndex; i++) {
+                            currentRow = allRows[i];
+                            for(j=0; j<currentRow.cells.length; j++) {
+                                // This is the anchor row, only unselect cells after the anchor cell
+                                if(currentRow.sectionRowIndex === oAnchor.trIndex) {
+                                    if(j>oAnchor.colKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // This is the target row, only unelect cells before the target cell
+                                else if(currentRow.sectionRowIndex === nTargetTrIndex) {
+                                    if(j<nTargetColKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // Unselect all cells on this row
+                                else {
+                                    this.unselectCell(currentRow.cells[j]);
+                                }
+                            }
+                        }
+                    }
+                    // Anchor row is below target row
+                    else {
+                        // Unselect all cells from target cell to anchor cell
+                        for(i=nTargetTrIndex; i<=oAnchor.trIndex; i++) {
+                            currentRow = allRows[i];
+                            for(j=0; j<currentRow.cells.length; j++) {
+                                // This is the target row, only unselect cells after the target cell
+                                if(currentRow.sectionRowIndex == nTargetTrIndex) {
+                                    if(j>nTargetColKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // This is the anchor row, only unselect cells before the anchor cell
+                                else if(currentRow.sectionRowIndex == oAnchor.trIndex) {
+                                    if(j<oAnchor.colKeyIndex) {
+                                        this.unselectCell(currentRow.cells[j]);
+                                    }
+                                }
+                                // Unselect all cells on this row
+                                else {
+                                    this.unselectCell(currentRow.cells[j]);
+                                }
+                            }
+                        }
+                    }
+
+                    // Select the target cell
+                    this.selectCell(elTargetCell);
+                }
+            }
+            // Invalid anchor
+            else {
+                // Set anchor
+                this._oAnchorCell = oTargetCell;
+
+                // Toggle selection of target
+                if(this.isSelected(oTargetCell)) {
+                    this.unselectCell(oTargetCell);
+                }
+                else {
+                    this.selectCell(oTargetCell);
+                }
+            }
+        }
+         // Only SHIFT
+        else if(bSHIFT) {
+
+            this.unselectAllCells();
+
+            // Validate anchor
+            if(oAnchor) {
+                // All cells are on the same row
+                if(oAnchor.recordIndex === nTargetRecordIndex) {
+                    // Select all cells between anchor cell and target cell,
+                    // including the anchor cell and target cell
+                    if(oAnchor.colKeyIndex < nTargetColKeyIndex) {
+                        for(i=oAnchor.colKeyIndex; i<=nTargetColKeyIndex; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+                    }
+                    // Select all cells between target cell and anchor cell
+                    // including the target cell and anchor cell
+                    else if(nTargetColKeyIndex < oAnchor.colKeyIndex) {
+                        for(i=nTargetColKeyIndex; i<=oAnchor.colKeyIndex; i++) {
+                            this.selectCell(elTargetRow.cells[i]);
+                        }
+                    }
+                }
+                // Anchor row is above target row
+                else if(oAnchor.recordIndex < nTargetRecordIndex) {
+                    // Select all cells from anchor cell to target cell
+                    // including the anchor cell and target cell
+                    for(i=oAnchor.trIndex; i<=nTargetTrIndex; i++) {
+                        currentRow = allRows[i];
+                        for(j=0; j<currentRow.cells.length; j++) {
+                            // This is the anchor row, only select the anchor cell and after
+                            if(currentRow.sectionRowIndex == oAnchor.trIndex) {
+                                if(j>=oAnchor.colKeyIndex) {
+                                    this.selectCell(currentRow.cells[j]);
+                                }
+                            }
+                            // This is the target row, only select the target cell and before
+                            else if(currentRow.sectionRowIndex == nTargetTrIndex) {
+                                if(j<=nTargetColKeyIndex) {
+                                    this.selectCell(currentRow.cells[j]);
+                                }
+                            }
+                            // Select all cells on this row
+                            else {
+                                this.selectCell(currentRow.cells[j]);
+                            }
+                        }
+                    }
+                }
+                // Anchor row is below target row
+                else {
+                    // Select all cells from target cell to anchor cell,
+                    // including the target cell and anchor cell
+                    for(i=nTargetTrIndex; i<=oAnchor.trIndex; i++) {
+                        currentRow = allRows[i];
+                        for(j=0; j<currentRow.cells.length; j++) {
+                            // This is the target row, only select the target cell and after
+                            if(currentRow.sectionRowIndex == nTargetTrIndex) {
+                                if(j>=nTargetColKeyIndex) {
+                                    this.selectCell(currentRow.cells[j]);
+                                }
+                            }
+                            // This is the anchor row, only select the anchor cell and before
+                            else if(currentRow.sectionRowIndex == oAnchor.trIndex) {
+                                if(j<=oAnchor.colKeyIndex) {
+                                    this.selectCell(currentRow.cells[j]);
+                                }
+                            }
+                            // Select all cells on this row
+                            else {
+                                this.selectCell(currentRow.cells[j]);
+                            }
+                        }
+                    }
+                }
+            }
+            // Invalid anchor
+            else {
+                // Set anchor
+                this._oAnchorCell = oTargetCell;
+
+                // Select target only
+                this.selectCell(oTargetCell);
+            }
+
+
+        }
+        // Only CTRL
+        else if(bCTRL) {
+
+            // Set anchor
+            this._oAnchorCell = oTargetCell;
+
+            // Toggle selection of target
+            if(this.isSelected(oTargetCell)) {
+                this.unselectCell(oTargetCell);
+            }
+            else {
+                this.selectCell(oTargetCell);
+            }
+
+        }
+        // Neither SHIFT nor CTRL
+        else {
+            this._handleSingleCellSelectionByMouse(oArgs);
+        }
+    }
+},
+
 /**
- * Record instance of the row selection anchor.
+ * Determines selection behavior resulting from a key event when selection mode
+ * is set to "cellrange".
  *
- * @property _oAnchorRecord
- * @type YAHOO.widget.Record
+ * @method _handleCellRangeSelectionByKey
+ * @param e {HTMLEvent} Event object.
  * @private
  */
-YAHOO.widget.DataTable.prototype._oAnchorRecord = null;
+_handleCellRangeSelectionByKey : function(e) {
+    var nKey = Ev.getCharCode(e);
+    var bSHIFT = e.shiftKey;
+    if((nKey == 9) || !bSHIFT) {
+        this._handleSingleCellSelectionByKey(e);
+        return;
+    }
 
+    if((nKey > 36) && (nKey < 41)) {
+        // Validate trigger
+        var oTrigger = this._getSelectionTrigger();
+        // Arrow selection only works if last selected row is on current page
+        if(!oTrigger) {
+            return null;
+        }
+
+        Ev.stopEvent(e);
+
+        // Validate anchor
+        var oAnchor = this._getSelectionAnchor(oTrigger);
+
+        var i, elNewRow, elNew;
+        var allRows = this.getTbodyEl().rows;
+        var elThisRow = oTrigger.el.parentNode;
+
+        // Arrow down
+        if(nKey == 40) {
+            elNewRow = this.getNextTrEl(oTrigger.el);
+
+            // Selecting away from anchor cell
+            if(oAnchor.recordIndex <= oTrigger.recordIndex) {
+                // Select all cells to the end of this row
+                for(i=oTrigger.colKeyIndex+1; i<elThisRow.cells.length; i++){
+                    elNew = elThisRow.cells[i];
+                    this.selectCell(elNew);
+                }
+
+                // Select some of the cells on the next row down
+                if(elNewRow) {
+                    for(i=0; i<=oTrigger.colKeyIndex; i++){
+                        elNew = elNewRow.cells[i];
+                        this.selectCell(elNew);
+                    }
+                }
+            }
+            // Unselecting towards anchor cell
+            else {
+                // Unselect all cells to the end of this row
+                for(i=oTrigger.colKeyIndex; i<elThisRow.cells.length; i++){
+                    this.unselectCell(elThisRow.cells[i]);
+                }
+
+                // Unselect some of the cells on the next row down
+                if(elNewRow) {
+                    for(i=0; i<oTrigger.colKeyIndex; i++){
+                        this.unselectCell(elNewRow.cells[i]);
+                    }
+                }
+            }
+        }
+        // Arrow up
+        else if(nKey == 38) {
+            elNewRow = this.getPreviousTrEl(oTrigger.el);
+
+            // Selecting away from anchor cell
+            if(oAnchor.recordIndex >= oTrigger.recordIndex) {
+                // Select all the cells to the beginning of this row
+                for(i=oTrigger.colKeyIndex-1; i>-1; i--){
+                    elNew = elThisRow.cells[i];
+                    this.selectCell(elNew);
+                }
+
+                // Select some of the cells from the end of the previous row
+                if(elNewRow) {
+                    for(i=elThisRow.cells.length-1; i>=oTrigger.colKeyIndex; i--){
+                        elNew = elNewRow.cells[i];
+                        this.selectCell(elNew);
+                    }
+                }
+            }
+            // Unselecting towards anchor cell
+            else {
+                // Unselect all the cells to the beginning of this row
+                for(i=oTrigger.colKeyIndex; i>-1; i--){
+                    this.unselectCell(elThisRow.cells[i]);
+                }
+
+                // Unselect some of the cells from the end of the previous row
+                if(elNewRow) {
+                    for(i=elThisRow.cells.length-1; i>oTrigger.colKeyIndex; i--){
+                        this.unselectCell(elNewRow.cells[i]);
+                    }
+                }
+            }
+        }
+        // Arrow right
+        else if(nKey == 39) {
+            elNewRow = this.getNextTrEl(oTrigger.el);
+
+            // Selecting away from anchor cell
+            if(oAnchor.recordIndex < oTrigger.recordIndex) {
+                // Select the next cell to the right
+                if(oTrigger.colKeyIndex < elThisRow.cells.length-1) {
+                    elNew = elThisRow.cells[oTrigger.colKeyIndex+1];
+                    this.selectCell(elNew);
+                }
+                // Select the first cell of the next row
+                else if(elNewRow) {
+                    elNew = elNewRow.cells[0];
+                    this.selectCell(elNew);
+                }
+            }
+            // Unselecting towards anchor cell
+            else if(oAnchor.recordIndex > oTrigger.recordIndex) {
+                this.unselectCell(elThisRow.cells[oTrigger.colKeyIndex]);
+
+                // Unselect this cell towards the right
+                if(oTrigger.colKeyIndex < elThisRow.cells.length-1) {
+                }
+                // Unselect this cells towards the first cell of the next row
+                else {
+                }
+            }
+            // Anchor is on this row
+            else {
+                // Selecting away from anchor
+                if(oAnchor.colKeyIndex <= oTrigger.colKeyIndex) {
+                    // Select the next cell to the right
+                    if(oTrigger.colKeyIndex < elThisRow.cells.length-1) {
+                        elNew = elThisRow.cells[oTrigger.colKeyIndex+1];
+                        this.selectCell(elNew);
+                    }
+                    // Select the first cell on the next row
+                    else if(oTrigger.trIndex < allRows.length-1){
+                        elNew = elNewRow.cells[0];
+                        this.selectCell(elNew);
+                    }
+                }
+                // Unselecting towards anchor
+                else {
+                    // Unselect this cell towards the right
+                    this.unselectCell(elThisRow.cells[oTrigger.colKeyIndex]);
+                }
+            }
+        }
+        // Arrow left
+        else if(nKey == 37) {
+            elNewRow = this.getPreviousTrEl(oTrigger.el);
+
+            // Unselecting towards the anchor
+            if(oAnchor.recordIndex < oTrigger.recordIndex) {
+                this.unselectCell(elThisRow.cells[oTrigger.colKeyIndex]);
+
+                // Unselect this cell towards the left
+                if(oTrigger.colKeyIndex > 0) {
+                }
+                // Unselect this cell towards the last cell of the previous row
+                else {
+                }
+            }
+            // Selecting towards the anchor
+            else if(oAnchor.recordIndex > oTrigger.recordIndex) {
+                // Select the next cell to the left
+                if(oTrigger.colKeyIndex > 0) {
+                    elNew = elThisRow.cells[oTrigger.colKeyIndex-1];
+                    this.selectCell(elNew);
+                }
+                // Select the last cell of the previous row
+                else if(oTrigger.trIndex > 0){
+                    elNew = elNewRow.cells[elNewRow.cells.length-1];
+                    this.selectCell(elNew);
+                }
+            }
+            // Anchor is on this row
+            else {
+                // Selecting away from anchor cell
+                if(oAnchor.colKeyIndex >= oTrigger.colKeyIndex) {
+                    // Select the next cell to the left
+                    if(oTrigger.colKeyIndex > 0) {
+                        elNew = elThisRow.cells[oTrigger.colKeyIndex-1];
+                        this.selectCell(elNew);
+                    }
+                    // Select the last cell of the previous row
+                    else if(oTrigger.trIndex > 0){
+                        elNew = elNewRow.cells[elNewRow.cells.length-1];
+                        this.selectCell(elNew);
+                    }
+                }
+                // Unselecting towards anchor cell
+                else {
+                    this.unselectCell(elThisRow.cells[oTrigger.colKeyIndex]);
+
+                    // Unselect this cell towards the left
+                    if(oTrigger.colKeyIndex > 0) {
+                    }
+                    // Unselect this cell towards the last cell of the previous row
+                    else {
+                    }
+                }
+            }
+        }
+    }
+},
+
 /**
- * Object literal representing cell selection anchor:
- * {recordId:sRecordId, columnId:sColumnId}.
+ * Determines selection behavior resulting from a mouse event when selection mode
+ * is set to "singlecell".
  *
- * @property _oAnchorCell
- * @type Object
+ * @method _handleSingleCellSelectionByMouse
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
  * @private
  */
-YAHOO.widget.DataTable.prototype._oAnchorCell = null;
+_handleSingleCellSelectionByMouse : function(oArgs) {
+    var elTarget = oArgs.target;
 
+    // Validate target cell
+    var elTargetCell = this.getTdEl(elTarget);
+    if(elTargetCell) {
+        var elTargetRow = this.getTrEl(elTargetCell);
+        var oTargetRecord = this.getRecord(elTargetRow);
+        var oTargetColumn = this.getColumn(elTargetCell);
+        var oTargetCell = {record:oTargetRecord, column:oTargetColumn};
+
+        // Set anchor
+        this._oAnchorCell = oTargetCell;
+
+        // Select only target
+        this.unselectAllCells();
+        this.selectCell(oTargetCell);
+    }
+},
+
 /**
- * Convenience method to remove the class YAHOO.widget.DataTable.CLASS_SELECTED
- * from all TR elements on the page.
+ * Determines selection behavior resulting from a key event when selection mode
+ * is set to "singlecell".
  *
- * @method _unselectAllTrEls
+ * @method _handleSingleCellSelectionByKey
+ * @param e {HTMLEvent} Event object.
  * @private
  */
-YAHOO.widget.DataTable.prototype._unselectAllTrEls = function() {
-    var selectedRows = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"tr",this._elTbody);
-    YAHOO.util.Dom.removeClass(selectedRows, YAHOO.widget.DataTable.CLASS_SELECTED);
-};
+_handleSingleCellSelectionByKey : function(e) {
+    var nKey = Ev.getCharCode(e);
+    if((nKey == 9) || ((nKey > 36) && (nKey < 41))) {
+        var bSHIFT = e.shiftKey;
 
+        // Validate trigger
+        var oTrigger = this._getSelectionTrigger();
+        // Arrow selection only works if last selected row is on current page
+        if(!oTrigger) {
+            return null;
+        }
+
+        // Determine the new cell to select
+        var elNew;
+        if(nKey == 40) { // Arrow down
+            elNew = this.getBelowTdEl(oTrigger.el);
+
+            // Validate new cell
+            if(elNew === null) {
+                //TODO: wrap around to first tr on current page
+
+                //TODO: wrap forward to first tr of next page
+
+                // Bottom selection is sticky
+                elNew = oTrigger.el;
+            }
+        }
+        else if(nKey == 38) { // Arrow up
+            elNew = this.getAboveTdEl(oTrigger.el);
+
+            // Validate new cell
+            if(elNew === null) {
+                //TODO: wrap around to last tr on current page
+
+                //TODO: wrap back to last tr of previous page
+
+                // Top selection is sticky
+                elNew = oTrigger.el;
+            }
+        }
+        else if((nKey == 39) || (!bSHIFT && (nKey == 9))) { // Arrow right or tab
+            elNew = this.getNextTdEl(oTrigger.el);
+
+            // Validate new cell
+            if(elNew === null) {
+                //TODO: wrap around to first td on current page
+
+                //TODO: wrap forward to first td of next page
+
+                // Top-left selection is sticky, and release TAB focus
+                //elNew = oTrigger.el;
+                return;
+            }
+        }
+        else if((nKey == 37) || (bSHIFT && (nKey == 9))) { // Arrow left or shift-tab
+            elNew = this.getPreviousTdEl(oTrigger.el);
+
+            // Validate new cell
+            if(elNew === null) {
+                //TODO: wrap around to last td on current page
+
+                //TODO: wrap back to last td of previous page
+
+                // Bottom-right selection is sticky, and release TAB focus
+                //elNew = oTrigger.el;
+                return;
+            }
+        }
+
+        Ev.stopEvent(e);
+        
+        // Unselect all cells
+        this.unselectAllCells();
+
+        // Select the new cell
+        this.selectCell(elNew);
+
+        // Set new anchor
+        this._oAnchorCell = {record:this.getRecord(elNew), column:this.getColumn(elNew)};
+    }
+},
+
 /**
  * Returns array of selected TR elements on the page.
  *
  * @method getSelectedTrEls
  * @return {HTMLElement[]} Array of selected TR elements.
  */
-YAHOO.widget.DataTable.prototype.getSelectedTrEls = function() {
-    return YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"tr",this._elTbody);
-};
+getSelectedTrEls : function() {
+    return Dom.getElementsByClassName(DT.CLASS_SELECTED,"tr",this._elTbody);
+},
 
 /**
  * Sets given row to the selected state.
@@ -5245,14 +12636,14 @@
  * @param row {HTMLElement | String | YAHOO.widget.Record | Number} HTML element
  * reference or ID string, Record instance, or RecordSet position index.
  */
-YAHOO.widget.DataTable.prototype.selectRow = function(row) {
+selectRow : function(row) {
     var oRecord, elRow;
-    
+
     if(row instanceof YAHOO.widget.Record) {
         oRecord = this._oRecordSet.getRecord(row);
         elRow = this.getTrEl(oRecord);
     }
-    else if(YAHOO.lang.isNumber(row)) {
+    else if(lang.isNumber(row)) {
         oRecord = this.getRecord(row);
         elRow = this.getTrEl(oRecord);
     }
@@ -5260,26 +12651,35 @@
         elRow = this.getTrEl(row);
         oRecord = this.getRecord(elRow);
     }
-    
+
     if(oRecord) {
         // Update selection trackers
         var tracker = this._aSelections || [];
         var sRecordId = oRecord.getId();
+        var index = -1;
 
         // Remove if already there:
         // Use Array.indexOf if available...
-        if(tracker.indexOf && (tracker.indexOf(sRecordId) >  -1)) {
+        /*if(tracker.indexOf && (tracker.indexOf(sRecordId) >  -1)) {
             tracker.splice(tracker.indexOf(sRecordId),1);
+        }*/
+        if(tracker.indexOf) {
+            index = tracker.indexOf(sRecordId);
+            
         }
         // ...or do it the old-fashioned way
         else {
             for(var j=tracker.length-1; j>-1; j--) {
-               if(tracker[j] === sRecordId){
-                    tracker.splice(j,1);
+                if(tracker[j] === sRecordId){
+                    index = j;
                     break;
                 }
             }
         }
+        if(index > -1) {
+            tracker.splice(index,1);
+        }
+        
         // Add to the end
         tracker.push(sRecordId);
         this._aSelections = tracker;
@@ -5291,37 +12691,30 @@
 
         // Update UI
         if(elRow) {
-            YAHOO.util.Dom.addClass(elRow, YAHOO.widget.DataTable.CLASS_SELECTED);
+            Dom.addClass(elRow, DT.CLASS_SELECTED);
         }
 
         this.fireEvent("rowSelectEvent", {record:oRecord, el:elRow});
     }
-};
-// Backward compatibility
-YAHOO.widget.DataTable.prototype.select = function(els) {
-    if(!YAHOO.lang.isArray(els)) {
-        els = [els];
+    else {
     }
-    for(var i=0; i<els.length; i++) {
-        this.selectRow(els[i]);
-    }
-};
+},
 
 /**
  * Sets given row to the selected state.
  *
- * @method selectRow
+ * @method unselectRow
  * @param row {HTMLElement | String | YAHOO.widget.Record | Number} HTML element
  * reference or ID string, Record instance, or RecordSet position index.
  */
-YAHOO.widget.DataTable.prototype.unselectRow = function(row) {
+unselectRow : function(row) {
     var elRow = this.getTrEl(row);
 
     var oRecord;
     if(row instanceof YAHOO.widget.Record) {
         oRecord = this._oRecordSet.getRecord(row);
     }
-    else if(YAHOO.lang.isNumber(row)) {
+    else if(lang.isNumber(row)) {
         oRecord = this.getRecord(row);
     }
     else {
@@ -5332,30 +12725,34 @@
         // Update selection trackers
         var tracker = this._aSelections || [];
         var sRecordId = oRecord.getId();
+        var index = -1;
 
         // Remove if found
         var bFound = false;
-        
+
         // Use Array.indexOf if available...
-        if(tracker.indexOf && (tracker.indexOf(sRecordId) >  -1)) {
-            tracker.splice(tracker.indexOf(sRecordId),1);
+        if(tracker.indexOf) {
+            index = tracker.indexOf(sRecordId);
         }
         // ...or do it the old-fashioned way
         else {
             for(var j=tracker.length-1; j>-1; j--) {
-               if(tracker[j] === sRecordId){
-                    tracker.splice(j,1);
+                if(tracker[j] === sRecordId){
+                    index = j;
                     break;
                 }
             }
         }
-        
+        if(index > -1) {
+            tracker.splice(index,1);
+        }
+
         if(bFound) {
             // Update tracker
             this._aSelections = tracker;
 
             // Update the UI
-            YAHOO.util.Dom.removeClass(elRow, YAHOO.widget.DataTable.CLASS_SELECTED);
+            Dom.removeClass(elRow, DT.CLASS_SELECTED);
 
             this.fireEvent("rowUnselectEvent", {record:oRecord, el:elRow});
 
@@ -5363,22 +12760,22 @@
         }
 
         // Update the UI
-        YAHOO.util.Dom.removeClass(elRow, YAHOO.widget.DataTable.CLASS_SELECTED);
+        Dom.removeClass(elRow, DT.CLASS_SELECTED);
 
         this.fireEvent("rowUnselectEvent", {record:oRecord, el:elRow});
     }
-};
+},
 
 /**
  * Clears out all row selections.
  *
  * @method unselectAllRows
  */
-YAHOO.widget.DataTable.prototype.unselectAllRows = function() {
+unselectAllRows : function() {
     // Remove all rows from tracker
     var tracker = this._aSelections || [];
     for(var j=tracker.length-1; j>-1; j--) {
-       if(YAHOO.lang.isString(tracker[j])){
+       if(lang.isString(tracker[j])){
             tracker.splice(j,1);
         }
     }
@@ -5393,19 +12790,19 @@
     //TODO: or convert this to an unselectRows method
     //TODO: that takes an array of rows or unselects all if none given
     this.fireEvent("unselectAllRowsEvent");
-};
+},
 
 /**
- * Convenience method to remove the class YAHOO.widget.DataTable.CLASS_SELECTED
+ * Convenience method to remove the class DT.CLASS_SELECTED
  * from all TD elements in the internal tracker.
  *
  * @method _unselectAllTdEls
  * @private
  */
-YAHOO.widget.DataTable.prototype._unselectAllTdEls = function() {
-    var selectedCells = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"td",this._elTbody);
-    YAHOO.util.Dom.removeClass(selectedCells, YAHOO.widget.DataTable.CLASS_SELECTED);
-};
+_unselectAllTdEls : function() {
+    var selectedCells = Dom.getElementsByClassName(DT.CLASS_SELECTED,"td",this._elTbody);
+    Dom.removeClass(selectedCells, DT.CLASS_SELECTED);
+},
 
 /**
  * Returns array of selected TD elements on the page.
@@ -5413,9 +12810,9 @@
  * @method getSelectedTdEls
  * @return {HTMLElement[]} Array of selected TD elements.
  */
-YAHOO.widget.DataTable.prototype.getSelectedTdEls = function() {
-    return YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_SELECTED,"td",this._elTbody);
-};
+getSelectedTdEls : function() {
+    return Dom.getElementsByClassName(DT.CLASS_SELECTED,"td",this._elTbody);
+},
 
 /**
  * Sets given cell to the selected state.
@@ -5424,12 +12821,12 @@
  * @param cell {HTMLElement | String} DOM element reference or ID string
  * to DataTable page element or RecordSet index.
  */
-YAHOO.widget.DataTable.prototype.selectCell = function(cell) {
+selectCell : function(cell) {
 /*TODO:
 accept {record}
 */
     var elCell = this.getTdEl(cell);
-    
+
     if(elCell) {
         var oRecord = this.getRecord(elCell);
         var sColumnId = elCell.yuiColumnId;
@@ -5457,13 +12854,13 @@
             }
 
             // Update the UI
-            YAHOO.util.Dom.addClass(elCell, YAHOO.widget.DataTable.CLASS_SELECTED);
+            Dom.addClass(elCell, DT.CLASS_SELECTED);
 
             this.fireEvent("cellSelectEvent", {record:oRecord, column:this.getColumnById(sColumnId), key: elCell.yuiColumnKey, el:elCell});
             return;
         }
     }
-};
+},
 
 /**
  * Sets given cell to the unselected state.
@@ -5472,7 +12869,7 @@
  * @param cell {HTMLElement | String} DOM element reference or ID string
  * to DataTable page element or RecordSet index.
  */
-YAHOO.widget.DataTable.prototype.unselectCell = function(cell) {
+unselectCell : function(cell) {
     var elCell = this.getTdEl(cell);
 
     if(elCell) {
@@ -5489,12 +12886,12 @@
                 if((tracker[j].recordId === id) && (tracker[j].columnId === sColumnId)){
                     // Remove from tracker
                     tracker.splice(j,1);
-                    
+
                     // Update tracker
                     this._aSelections = tracker;
 
                     // Update the UI
-                    YAHOO.util.Dom.removeClass(elCell, YAHOO.widget.DataTable.CLASS_SELECTED);
+                    Dom.removeClass(elCell, DT.CLASS_SELECTED);
 
                     this.fireEvent("cellUnselectEvent", {record:oRecord, column: this.getColumnById(sColumnId), key:elCell.yuiColumnKey, el:elCell});
                     return;
@@ -5502,14 +12899,14 @@
             }
         }
     }
-};
+},
 
 /**
  * Clears out all cell selections.
  *
  * @method unselectAllCells
  */
-YAHOO.widget.DataTable.prototype.unselectAllCells= function() {
+unselectAllCells: function() {
     // Remove all cells from tracker
     var tracker = this._aSelections || [];
     for(var j=tracker.length-1; j>-1; j--) {
@@ -5523,11 +12920,11 @@
 
     // Update UI
     this._unselectAllTdEls();
-    
+
     //TODO: send data
     //TODO: or fire individual cellUnselectEvent
     this.fireEvent("unselectAllCellsEvent");
-};
+},
 
 /**
  * Returns true if given item is selected, false otherwise.
@@ -5540,21 +12937,19 @@
  * of a cell.
  * @return {Boolean} True if item is selected.
  */
-YAHOO.widget.DataTable.prototype.isSelected = function(o) {
-    var oRecord, sRecordId, j;
-
-    var el = this.getTrEl(o) || this.getTdEl(o);
-    if(el) {
-        return YAHOO.util.Dom.hasClass(el,YAHOO.widget.DataTable.CLASS_SELECTED);
+isSelected : function(o) {
+    if(o && (o.ownerDocument == document)) {
+        return (Dom.hasClass(this.getTdEl(o),DT.CLASS_SELECTED) || Dom.hasClass(this.getTrEl(o),DT.CLASS_SELECTED));
     }
     else {
+        var oRecord, sRecordId, j;
         var tracker = this._aSelections;
-        if(tracker && tracker.length > 1) {
+        if(tracker && tracker.length > 0) {
             // Looking for a Record?
             if(o instanceof YAHOO.widget.Record) {
                 oRecord = o;
             }
-            else if(YAHOO.lang.isNumber(o)) {
+            else if(lang.isNumber(o)) {
                 oRecord = this.getRecord(o);
             }
             if(oRecord) {
@@ -5562,8 +12957,10 @@
 
                 // Is it there?
                 // Use Array.indexOf if available...
-                if(tracker.indexOf && (tracker.indexOf(sRecordId) >  -1)) {
-                    return true;
+                if(tracker.indexOf) {
+                    if(tracker.indexOf(sRecordId) >  -1) {
+                        return true;
+                    }
                 }
                 // ...or do it the old-fashioned way
                 else {
@@ -5588,7 +12985,7 @@
         }
     }
     return false;
-};
+},
 
 /**
  * Returns selected rows as an array of Record IDs.
@@ -5596,16 +12993,16 @@
  * @method getSelectedRows
  * @return {String[]} Array of selected rows by Record ID.
  */
-YAHOO.widget.DataTable.prototype.getSelectedRows = function() {
+getSelectedRows : function() {
     var aSelectedRows = [];
     var tracker = this._aSelections || [];
     for(var j=0; j<tracker.length; j++) {
-       if(YAHOO.lang.isString(tracker[j])){
+       if(lang.isString(tracker[j])){
             aSelectedRows.push(tracker[j]);
         }
     }
     return aSelectedRows;
-};
+},
 
 /**
  * Returns selected cells as an array of object literals:
@@ -5614,7 +13011,7 @@
  * @method getSelectedCells
  * @return {Object[]} Array of selected cells by Record ID and Column ID.
  */
-YAHOO.widget.DataTable.prototype.getSelectedCells = function() {
+getSelectedCells : function() {
     var aSelectedCells = [];
     var tracker = this._aSelections || [];
     for(var j=0; j<tracker.length; j++) {
@@ -5623,7 +13020,7 @@
         }
     }
     return aSelectedCells;
-};
+},
 
 /**
  * Returns last selected Record ID.
@@ -5631,16 +13028,16 @@
  * @method getLastSelectedRecord
  * @return {String} Record ID of last selected row.
  */
-YAHOO.widget.DataTable.prototype.getLastSelectedRecord = function() {
+getLastSelectedRecord : function() {
     var tracker = this._aSelections;
-    if(tracker.length > 0) {
+    if(tracker && tracker.length > 0) {
         for(var i=tracker.length-1; i>-1; i--) {
-           if(YAHOO.lang.isString(tracker[i])){
+           if(lang.isString(tracker[i])){
                 return tracker[i];
             }
         }
     }
-};
+},
 
 /**
  * Returns last selected cell as an object literal:
@@ -5649,96 +13046,96 @@
  * @method getLastSelectedCell
  * @return {Object} Object literal representation of a cell.
  */
-YAHOO.widget.DataTable.prototype.getLastSelectedCell = function() {
+getLastSelectedCell : function() {
     var tracker = this._aSelections;
-    if(tracker.length > 0) {
+    if(tracker && tracker.length > 0) {
         for(var i=tracker.length-1; i>-1; i--) {
            if(tracker[i].recordId && tracker[i].columnId){
                 return tracker[i];
             }
         }
     }
-};
+},
 
 /**
- * Assigns the class YAHOO.widget.DataTable.CLASS_HIGHLIGHTED to the given row.
+ * Assigns the class DT.CLASS_HIGHLIGHTED to the given row.
  *
  * @method highlightRow
  * @param row {HTMLElement | String} DOM element reference or ID string.
  */
-YAHOO.widget.DataTable.prototype.highlightRow = function(row) {
+highlightRow : function(row) {
     var elRow = this.getTrEl(row);
 
     if(elRow) {
         // Make sure previous row is unhighlighted
-        if(this._sLastHighlightedTrElId) {
-            YAHOO.util.Dom.removeClass(this._sLastHighlightedTrElId,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);
-        }
+/*        if(this._sLastHighlightedTrElId) {
+            Dom.removeClass(this._sLastHighlightedTrElId,DT.CLASS_HIGHLIGHTED);
+        }*/
         var oRecord = this.getRecord(elRow);
-        YAHOO.util.Dom.addClass(elRow,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);
-        this._sLastHighlightedTrElId = elRow.id;
+        Dom.addClass(elRow,DT.CLASS_HIGHLIGHTED);
+        //this._sLastHighlightedTrElId = elRow.id;
         this.fireEvent("rowHighlightEvent", {record:oRecord, el:elRow});
         return;
     }
-};
+},
 
 /**
- * Removes the class YAHOO.widget.DataTable.CLASS_HIGHLIGHTED from the given row.
+ * Removes the class DT.CLASS_HIGHLIGHTED from the given row.
  *
  * @method unhighlightRow
  * @param row {HTMLElement | String} DOM element reference or ID string.
  */
-YAHOO.widget.DataTable.prototype.unhighlightRow = function(row) {
+unhighlightRow : function(row) {
     var elRow = this.getTrEl(row);
 
     if(elRow) {
         var oRecord = this.getRecord(elRow);
-        YAHOO.util.Dom.removeClass(elRow,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);
+        Dom.removeClass(elRow,DT.CLASS_HIGHLIGHTED);
         this.fireEvent("rowUnhighlightEvent", {record:oRecord, el:elRow});
         return;
     }
-};
+},
 
 /**
- * Assigns the class YAHOO.widget.DataTable.CLASS_HIGHLIGHTED to the given cell.
+ * Assigns the class DT.CLASS_HIGHLIGHTED to the given cell.
  *
  * @method highlightCell
  * @param cell {HTMLElement | String} DOM element reference or ID string.
  */
-YAHOO.widget.DataTable.prototype.highlightCell = function(cell) {
+highlightCell : function(cell) {
     var elCell = this.getTdEl(cell);
 
     if(elCell) {
         // Make sure previous cell is unhighlighted
-        if(this._sLastHighlightedTdElId) {
-            YAHOO.util.Dom.removeClass(this._sLastHighlightedTdElId,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);
-        }
-        
+        /*if(this._sLastHighlightedTdElId) {
+            Dom.removeClass(this._sLastHighlightedTdElId,DT.CLASS_HIGHLIGHTED);
+        }*/
+
         var oRecord = this.getRecord(elCell);
         var sColumnId = elCell.yuiColumnId;
-        YAHOO.util.Dom.addClass(elCell,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);
-        this._sLastHighlightedTdElId = elCell.id;
+        Dom.addClass(elCell,DT.CLASS_HIGHLIGHTED);
+        //this._sLastHighlightedTdElId = elCell.id;
         this.fireEvent("cellHighlightEvent", {record:oRecord, column:this.getColumnById(sColumnId), key:elCell.yuiColumnKey, el:elCell});
         return;
     }
-};
+},
 
 /**
- * Removes the class YAHOO.widget.DataTable.CLASS_HIGHLIGHTED from the given cell.
+ * Removes the class DT.CLASS_HIGHLIGHTED from the given cell.
  *
  * @method unhighlightCell
  * @param cell {HTMLElement | String} DOM element reference or ID string.
  */
-YAHOO.widget.DataTable.prototype.unhighlightCell = function(cell) {
+unhighlightCell : function(cell) {
     var elCell = this.getTdEl(cell);
 
     if(elCell) {
         var oRecord = this.getRecord(elCell);
-        YAHOO.util.Dom.removeClass(elCell,YAHOO.widget.DataTable.CLASS_HIGHLIGHTED);
+        Dom.removeClass(elCell,DT.CLASS_HIGHLIGHTED);
         this.fireEvent("cellUnhighlightEvent", {record:oRecord, column:this.getColumnById(elCell.yuiColumnId), key:elCell.yuiColumnKey, el:elCell});
         return;
     }
-};
+},
 
 
 
@@ -5786,26 +13183,17 @@
 
 // INLINE EDITING
 
-/*TODO: for TAB handling
- * Shows Cell Editor for next cell.
- *
- * @method editNextCell
- * @param elCell {HTMLElement} Cell element from which to edit next cell.
- */
-//YAHOO.widget.DataTable.prototype.editNextCell = function(elCell) {
-//};
-
 /**
  * Shows Cell Editor for given cell.
  *
  * @method showCellEditor
- * @param elCell {HTMLElement | String} Cell element to edit.
+ * @param elCell {HTMLElement | String} Cell to edit.
  * @param oRecord {YAHOO.widget.Record} (Optional) Record instance.
  * @param oColumn {YAHOO.widget.Column} (Optional) Column instance.
  */
-YAHOO.widget.DataTable.prototype.showCellEditor = function(elCell, oRecord, oColumn) {
-    elCell = YAHOO.util.Dom.get(elCell);
-    
+showCellEditor : function(elCell, oRecord, oColumn) {
+    elCell = Dom.get(elCell);
+
     if(elCell && (elCell.ownerDocument === document)) {
         if(!oRecord || !(oRecord instanceof YAHOO.widget.Record)) {
             oRecord = this.getRecord(elCell);
@@ -5815,7 +13203,7 @@
         }
         if(oRecord && oColumn) {
             var oCellEditor = this._oCellEditor;
-            
+
             // Clear previous Editor
             if(oCellEditor.isActive) {
                 this.cancelCellEditor();
@@ -5825,90 +13213,104 @@
             if(!oColumn.editor) {
                 return;
             }
-            
+
             // Update Editor values
             oCellEditor.cell = elCell;
             oCellEditor.record = oRecord;
             oCellEditor.column = oColumn;
             oCellEditor.validator = (oColumn.editorOptions &&
-                    YAHOO.lang.isFunction(oColumn.editorOptions.validator)) ?
+                    lang.isFunction(oColumn.editorOptions.validator)) ?
                     oColumn.editorOptions.validator : null;
             oCellEditor.value = oRecord.getData(oColumn.key);
+            oCellEditor.defaultValue = null;
 
             // Move Editor
             var elContainer = oCellEditor.container;
-            var x = YAHOO.util.Dom.getX(elCell);
-            var y = YAHOO.util.Dom.getY(elCell);
+            var x = Dom.getX(elCell);
+            var y = Dom.getY(elCell);
 
             // SF doesn't get xy for cells in scrolling table
             // when tbody display is set to block
             if(isNaN(x) || isNaN(y)) {
                 x = elCell.offsetLeft + // cell pos relative to table
-                        YAHOO.util.Dom.getX(this._elTable) - // plus table pos relative to document
+                        Dom.getX(this._elTbody.parentNode) - // plus table pos relative to document
                         this._elTbody.scrollLeft; // minus tbody scroll
                 y = elCell.offsetTop + // cell pos relative to table
-                        YAHOO.util.Dom.getY(this._elTable) - // plus table pos relative to document
+                        Dom.getY(this._elTbody.parentNode) - // plus table pos relative to document
                         this._elTbody.scrollTop + // minus tbody scroll
-                        this._elThead.offsetHeight; // account for fixed headers
+                        this._elThead.offsetHeight; // account for fixed THEAD cells
             }
-            
+
             elContainer.style.left = x + "px";
             elContainer.style.top = y + "px";
 
+            // Hook to customize the UI
+            this.doBeforeShowCellEditor(this._oCellEditor);
+
+            //TODO: This is temporarily up here due so elements can be focused
             // Show Editor
             elContainer.style.display = "";
-            
+
+            // Handle ESC key
+            Ev.addListener(elContainer, "keydown", function(e, oSelf) {
+                // ESC hides Cell Editor
+                if((e.keyCode == 27)) {
+                    oSelf.cancelCellEditor();
+                    oSelf.focusTbodyEl();
+                }
+                else {
+                    oSelf.fireEvent("editorKeydownEvent", {editor:oSelf._oCellEditor, event:e});
+                }
+            }, this);
+
             // Render Editor markup
             var fnEditor;
-            if(YAHOO.lang.isString(oColumn.editor)) {
+            if(lang.isString(oColumn.editor)) {
                 switch(oColumn.editor) {
                     case "checkbox":
-                        fnEditor = YAHOO.widget.DataTable.editCheckbox;
+                        fnEditor = DT.editCheckbox;
                         break;
                     case "date":
-                        fnEditor = YAHOO.widget.DataTable.editDate;
+                        fnEditor = DT.editDate;
                         break;
                     case "dropdown":
-                        fnEditor = YAHOO.widget.DataTable.editDropdown;
+                        fnEditor = DT.editDropdown;
                         break;
                     case "radio":
-                        fnEditor = YAHOO.widget.DataTable.editRadio;
+                        fnEditor = DT.editRadio;
                         break;
                     case "textarea":
-                        fnEditor = YAHOO.widget.DataTable.editTextarea;
+                        fnEditor = DT.editTextarea;
                         break;
                     case "textbox":
-                        fnEditor = YAHOO.widget.DataTable.editTextbox;
+                        fnEditor = DT.editTextbox;
                         break;
                     default:
                         fnEditor = null;
                 }
             }
-            else if(YAHOO.lang.isFunction(oColumn.editor)) {
+            else if(lang.isFunction(oColumn.editor)) {
                 fnEditor = oColumn.editor;
             }
 
             if(fnEditor) {
                 // Create DOM input elements
                 fnEditor(this._oCellEditor, this);
-                
+
                 // Show Save/Cancel buttons
                 if(!oColumn.editorOptions || !oColumn.editorOptions.disableBtns) {
                     this.showCellEditorBtns(elContainer);
                 }
 
-                // Hook to customize the UI
-                this.doBeforeShowCellEditor(this._oCellEditor);
+                oCellEditor.isActive = true;
 
-                oCellEditor.isActive = true;
-                
                 //TODO: verify which args to pass
                 this.fireEvent("editorShowEvent", {editor:oCellEditor});
                 return;
             }
         }
     }
-};
+},
 
 /**
  * Overridable abstract method to customize Cell Editor UI.
@@ -5916,8 +13318,8 @@
  * @method doBeforeShowCellEditor
  * @param oCellEditor {Object} Cell Editor object literal.
  */
-YAHOO.widget.DataTable.prototype.doBeforeShowCellEditor = function(oCellEditor) {
-};
+doBeforeShowCellEditor : function(oCellEditor) {
+},
 
 /**
  * Adds Save/Cancel buttons to Cell Editor.
@@ -5925,22 +13327,28 @@
  * @method showCellEditorBtns
  * @param elContainer {HTMLElement} Cell Editor container.
  */
-YAHOO.widget.DataTable.prototype.showCellEditorBtns = function(elContainer) {
+showCellEditorBtns : function(elContainer) {
     // Buttons
     var elBtnsDiv = elContainer.appendChild(document.createElement("div"));
-    YAHOO.util.Dom.addClass(elBtnsDiv, YAHOO.widget.DataTable.CLASS_BUTTON);
+    Dom.addClass(elBtnsDiv, DT.CLASS_BUTTON);
 
     // Save button
     var elSaveBtn = elBtnsDiv.appendChild(document.createElement("button"));
-    YAHOO.util.Dom.addClass(elSaveBtn, YAHOO.widget.DataTable.CLASS_DEFAULT);
+    Dom.addClass(elSaveBtn, DT.CLASS_DEFAULT);
     elSaveBtn.innerHTML = "OK";
-    YAHOO.util.Event.addListener(elSaveBtn, "click", this.saveCellEditor, this, true);
+    Ev.addListener(elSaveBtn, "click", function(oArgs, oSelf) {
+        oSelf.onEventSaveCellEditor(oArgs, oSelf);
+        oSelf.focusTbodyEl();
+    }, this, true);
 
     // Cancel button
     var elCancelBtn = elBtnsDiv.appendChild(document.createElement("button"));
     elCancelBtn.innerHTML = "Cancel";
-    YAHOO.util.Event.addListener(elCancelBtn, "click", this.cancelCellEditor, this, true);
-};
+    Ev.addListener(elCancelBtn, "click", function(oArgs, oSelf) {
+        oSelf.onEventCancelCellEditor(oArgs, oSelf);
+        oSelf.focusTbodyEl();
+    }, this, true);
+},
 
 /**
  * Clears Cell Editor of all state and UI.
@@ -5948,43 +13356,50 @@
  * @method resetCellEditor
  */
 
-YAHOO.widget.DataTable.prototype.resetCellEditor = function() {
+resetCellEditor : function() {
     var elContainer = this._oCellEditor.container;
     elContainer.style.display = "none";
-    YAHOO.util.Event.purgeElement(elContainer, true);
+    Ev.purgeElement(elContainer, true);
     elContainer.innerHTML = "";
     this._oCellEditor.value = null;
     this._oCellEditor.isActive = false;
-};
+    
+},
 
 /**
  * Saves Cell Editor input to Record.
  *
  * @method saveCellEditor
  */
-YAHOO.widget.DataTable.prototype.saveCellEditor = function() {
-    //TODO: Copy the editor's values to pass to the event
+saveCellEditor : function() {
     if(this._oCellEditor.isActive) {
         var newData = this._oCellEditor.value;
-        var oldData = this._oCellEditor.record.getData(this._oCellEditor.column.key);
+        // Copy the data to pass to the event
+        var oldData = YAHOO.widget.DataTable._cloneObject(this._oCellEditor.record.getData(this._oCellEditor.column.key));
 
         // Validate input data
         if(this._oCellEditor.validator) {
-            this._oCellEditor.value = this._oCellEditor.validator.call(this, newData, oldData, this._oCellEditor);
-            if(this._oCellEditor.value === null ) {
+            newData = this._oCellEditor.value = this._oCellEditor.validator.call(this, newData, oldData, this._oCellEditor);
+            if(newData === null ) {
                 this.resetCellEditor();
                 this.fireEvent("editorRevertEvent",
                         {editor:this._oCellEditor, oldData:oldData, newData:newData});
                 return;
             }
         }
-
         // Update the Record
-        this._oRecordSet.updateKey(this._oCellEditor.record, this._oCellEditor.column.key, this._oCellEditor.value);
-
+        this._oRecordSet.updateRecordValue(this._oCellEditor.record, this._oCellEditor.column.key, this._oCellEditor.value);
         // Update the UI
-        this.formatCell(this._oCellEditor.cell);
-
+        this.formatCell(this._oCellEditor.cell.firstChild);
+        
+        // Bug fix 1764044
+        this._oChainRender.add({
+            method: function() {
+                this._syncColWidths();
+            },
+            scope: this
+        });
+        this._oChainRender.run();
         // Clear out the Cell Editor
         this.resetCellEditor();
 
@@ -5993,14 +13408,14 @@
     }
     else {
     }
-};
+},
 
 /**
  * Cancels Cell Editor.
  *
  * @method cancelCellEditor
  */
-YAHOO.widget.DataTable.prototype.cancelCellEditor = function() {
+cancelCellEditor : function() {
     if(this._oCellEditor.isActive) {
         this.resetCellEditor();
         //TODO: preserve values for the event?
@@ -6008,299 +13423,24 @@
     }
     else {
     }
-};
+},
 
-/**
- * Enables CHECKBOX Editor.
- *
- * @method editCheckbox
- * @param oEditor {Object} Object literal representation of Editor values.
- * @param oSelf {YAHOO.widget.DataTable} Reference back to DataTable instance.
- * @static
- */
-//YAHOO.widget.DataTable.editCheckbox = function(elContainer, oRecord, oColumn, oEditor, oSelf) {
-YAHOO.widget.DataTable.editCheckbox = function(oEditor, oSelf) {
-    var elCell = oEditor.cell;
-    var oRecord = oEditor.record;
-    var oColumn = oEditor.column;
-    var elContainer = oEditor.container;
-    var aCheckedValues = oRecord.getData(oColumn.key);
-    if(!YAHOO.lang.isArray(aCheckedValues)) {
-        aCheckedValues = [aCheckedValues];
-    }
 
-    // Checkboxes
-    if(oColumn.editorOptions && YAHOO.lang.isArray(oColumn.editorOptions.checkboxOptions)) {
-        var checkboxOptions = oColumn.editorOptions.checkboxOptions;
-        var checkboxValue, checkboxId, elLabel, j, k;
-        // First create the checkbox buttons in an IE-friendly way
-        for(j=0; j<checkboxOptions.length; j++) {
-            checkboxValue = YAHOO.lang.isValue(checkboxOptions[j].label) ?
-                    checkboxOptions[j].label : checkboxOptions[j];
-            checkboxId =  oSelf.id + "-editor-checkbox" + j;
-            elContainer.innerHTML += "<input type=\"checkbox\"" +
-                    " name=\"" + oSelf.id + "-editor-checkbox\"" +
-                    " value=\"" + checkboxValue + "\"" +
-                    " id=\"" +  checkboxId + "\">";
-            // Then create the labels in an IE-friendly way
-            elLabel = elContainer.appendChild(document.createElement("label"));
-            elLabel.htmlFor = checkboxId;
-            elLabel.innerHTML = checkboxValue;
-        }
-        var aCheckboxEls = [];
-        var checkboxEl;
-        // Loop through checkboxes to check them
-        for(j=0; j<checkboxOptions.length; j++) {
-            checkboxEl = YAHOO.util.Dom.get(oSelf.id + "-editor-checkbox" + j);
-            aCheckboxEls.push(checkboxEl);
-            for(k=0; k<aCheckedValues.length; k++) {
-                if(checkboxEl.value === aCheckedValues[k]) {
-                    checkboxEl.checked = true;
-                }
-            }
-            // Focus the first checkbox
-            if(j===0) {
-                oSelf._focusEl(checkboxEl);
-            }
-        }
-        // Loop through checkboxes to assign click handlers
-        for(j=0; j<checkboxOptions.length; j++) {
-            checkboxEl = YAHOO.util.Dom.get(oSelf.id + "-editor-checkbox" + j);
-            YAHOO.util.Event.addListener(checkboxEl, "click", function(){
-                var aNewValues = [];
-                for(var m=0; m<aCheckboxEls.length; m++) {
-                    if(aCheckboxEls[m].checked) {
-                        aNewValues.push(aCheckboxEls[m].value);
-                    }
-                }
-                oSelf._oCellEditor.value = aNewValues;
-                oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
-            });
-        }
-    }
-};
 
-/**
- * Enables Date Editor.
- *
- * @method editDate
- * @param oEditor {Object} Object literal representation of Editor values.
- * @param oSelf {YAHOO.widget.DataTable} Reference back to DataTable instance.
- * @static
- */
-YAHOO.widget.DataTable.editDate = function(oEditor, oSelf) {
-    var elCell = oEditor.cell;
-    var oRecord = oEditor.record;
-    var oColumn = oEditor.column;
-    var elContainer = oEditor.container;
-    var value = oRecord.getData(oColumn.key);
 
-    // Calendar widget
-    if(YAHOO.widget.Calendar) {
-        var selectedValue = (value.getMonth()+1)+"/"+value.getDate()+"/"+value.getFullYear();
-        var calContainer = elContainer.appendChild(document.createElement("div"));
-        calContainer.id = oSelf.id + "-col" + oColumn.getId() + "-dateContainer";
-        var calendar =
-                new YAHOO.widget.Calendar(oSelf.id + "-col" + oColumn.getId() + "-date",
-                calContainer.id,
-                {selected:selectedValue, pagedate:value});
-        calendar.render();
-        calContainer.style.cssFloat = "none";
 
-        //var calFloatClearer = elContainer.appendChild(document.createElement("br"));
-        //calFloatClearer.style.clear = "both";
-        
-        calendar.selectEvent.subscribe(function(type, args, obj) {
-            oSelf._oCellEditor.value = new Date(args[0][0][0], args[0][0][1]-1, args[0][0][2]);
-            oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
-        });
-    }
-    else {
-        //TODO;
-    }
-};
 
-/**
- * Enables SELECT Editor.
- *
- * @method editDropdown
- * @param oEditor {Object} Object literal representation of Editor values.
- * @param oSelf {YAHOO.widget.DataTable} Reference back to DataTable instance.
- * @static
- */
-YAHOO.widget.DataTable.editDropdown = function(oEditor, oSelf) {
-    var elCell = oEditor.cell;
-    var oRecord = oEditor.record;
-    var oColumn = oEditor.column;
-    var elContainer = oEditor.container;
-    var value = oRecord.getData(oColumn.key);
 
-    // Textbox
-    var elDropdown = elContainer.appendChild(document.createElement("select"));
-    var dropdownOptions = (oColumn.editorOptions && YAHOO.lang.isArray(oColumn.editorOptions.dropdownOptions)) ?
-            oColumn.editorOptions.dropdownOptions : [];
-    for(var j=0; j<dropdownOptions.length; j++) {
-        var dropdownOption = dropdownOptions[j];
-        var elOption = document.createElement("option");
-        elOption.value = (YAHOO.lang.isValue(dropdownOption.value)) ?
-                dropdownOption.value : dropdownOption;
-        elOption.innerHTML = (YAHOO.lang.isValue(dropdownOption.text)) ?
-                dropdownOption.text : dropdownOption;
-        elOption = elDropdown.appendChild(elOption);
-        if(value === elDropdown.options[j].value) {
-            elDropdown.options[j].selected = true;
-        }
-    }
-    
-    // Set up a listener on each check box to track the input value
-    YAHOO.util.Event.addListener(elDropdown, "change",
-        function(){
-            oSelf._oCellEditor.value = elDropdown[elDropdown.selectedIndex].value;
-            oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
-    });
-            
-    // Focus the dropdown
-    oSelf._focusEl(elDropdown);
-};
 
-/**
- * Enables INPUT TYPE=RADIO Editor.
- *
- * @method editRadio
- * @param oEditor {Object} Object literal representation of Editor values.
- * @param oSelf {YAHOO.widget.DataTable} Reference back to DataTable instance.
- * @static
- */
-YAHOO.widget.DataTable.editRadio = function(oEditor, oSelf) {
-    var elCell = oEditor.cell;
-    var oRecord = oEditor.record;
-    var oColumn = oEditor.column;
-    var elContainer = oEditor.container;
-    var value = oRecord.getData(oColumn.key);
 
-    // Radios
-    if(oColumn.editorOptions && YAHOO.lang.isArray(oColumn.editorOptions.radioOptions)) {
-        var radioOptions = oColumn.editorOptions.radioOptions;
-        var radioValue, radioId, elLabel, j;
-        // First create the radio buttons in an IE-friendly way
-        for(j=0; j<radioOptions.length; j++) {
-            radioValue = YAHOO.lang.isValue(radioOptions[j].label) ?
-                    radioOptions[j].label : radioOptions[j];
-            radioId =  oSelf.id + "-editor-radio" + j;
-            elContainer.innerHTML += "<input type=\"radio\"" +
-                    " name=\"" + oSelf.id + "-editor-radio\"" +
-                    " value=\"" + radioValue + "\"" +
-                    " id=\"" +  radioId + "\">";
-            // Then create the labels in an IE-friendly way
-            elLabel = elContainer.appendChild(document.createElement("label"));
-            elLabel.htmlFor = radioId;
-            elLabel.innerHTML = radioValue;
-        }
-        // Then check one, and assign click handlers
-        for(j=0; j<radioOptions.length; j++) {
-            var radioEl = YAHOO.util.Dom.get(oSelf.id + "-editor-radio" + j);
-            if(value === radioEl.value) {
-                radioEl.checked = true;
-                oSelf._focusEl(radioEl);
-            }
-            YAHOO.util.Event.addListener(radioEl, "click",
-                function(){
-                    oSelf._oCellEditor.value = this.value;
-                    oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
-            });
-        }
-    }
-};
 
-/**
- * Enables TEXTAREA Editor.
- *
- * @method editTextarea
- * @param oEditor {Object} Object literal representation of Editor values.
- * @param oSelf {YAHOO.widget.DataTable} Reference back to DataTable instance.
- * @static
- */
-YAHOO.widget.DataTable.editTextarea = function(oEditor, oSelf) {
-   var elCell = oEditor.cell;
-   var oRecord = oEditor.record;
-   var oColumn = oEditor.column;
-   var elContainer = oEditor.container;
-   var value = oRecord.getData(oColumn.key);
 
-    // Textarea
-    var elTextarea = elContainer.appendChild(document.createElement("textarea"));
-    elTextarea.style.width = elCell.offsetWidth + "px"; //(parseInt(elCell.offsetWidth,10)) + "px";
-    elTextarea.style.height = "3em"; //(parseInt(elCell.offsetHeight,10)) + "px";
-    elTextarea.value = YAHOO.lang.isValue(value) ? value : "";
-    
-    // Set up a listener on each check box to track the input value
-    YAHOO.util.Event.addListener(elTextarea, "keyup", function(){
-        //TODO: set on a timeout
-        oSelf._oCellEditor.value = elTextarea.value;
-        oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
-    });
-    
-    // Select the text
-    elTextarea.focus();
-    elTextarea.select();
-};
 
-/**
- * Enables INPUT TYPE=TEXT Editor.
- *
- * @method editTextbox
- * @param oEditor {Object} Object literal representation of Editor values.
- * @param oSelf {YAHOO.widget.DataTable} Reference back to DataTable instance.
- * @static
- */
-YAHOO.widget.DataTable.editTextbox = function(oEditor, oSelf) {
-   var elCell = oEditor.cell;
-   var oRecord = oEditor.record;
-   var oColumn = oEditor.column;
-   var elContainer = oEditor.container;
-   var value = YAHOO.lang.isValue(oRecord.getData(oColumn.key)) ? oRecord.getData(oColumn.key) : "";
 
-    // Textbox
-    var elTextbox = elContainer.appendChild(document.createElement("input"));
-    elTextbox.type = "text";
-    elTextbox.style.width = elCell.offsetWidth + "px"; //(parseInt(elCell.offsetWidth,10)) + "px";
-    //elTextbox.style.height = "1em"; //(parseInt(elCell.offsetHeight,10)) + "px";
-    elTextbox.value = value;
 
-    // Set up a listener on each textbox to track the input value
-    YAHOO.util.Event.addListener(elTextbox, "keyup", function(){
-        //TODO: set on a timeout
-        oSelf._oCellEditor.value = elTextbox.value;
-        oSelf.fireEvent("editorUpdateEvent",{editor:oSelf._oCellEditor});
-    });
 
-    // Select the text
-    elTextbox.focus();
-    elTextbox.select();
-};
 
-/*
- * Validates Editor input value to type Number, doing type conversion as
- * necessary. A valid Number value is return, else the previous value is returned
- * if input value does not validate.
- * 
- *
- * @method validateNumber
- * @param oData {Object} Data to validate.
- * @static
-*/
-YAHOO.widget.DataTable.validateNumber = function(oData) {
-    //Convert to number
-    var number = oData * 1;
 
-    // Validate
-    if(YAHOO.lang.isNumber(number)) {
-        return number;
-    }
-    else {
-        return null;
-    }
-};
 
 
 
@@ -6323,22 +13463,6 @@
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 // ABSTRACT METHODS
 
 /**
@@ -6348,12 +13472,13 @@
  * @method doBeforeLoadData
  * @param sRequest {String} Original request.
  * @param oResponse {Object} Response object.
+ * @param oPayload {MIXED} additional arguments
  * @return {Boolean} Return true to continue loading data into RecordSet and
  * updating DataTable with new Records, false to cancel.
  */
-YAHOO.widget.DataTable.prototype.doBeforeLoadData = function(sRequest, oResponse) {
+doBeforeLoadData : function(sRequest, oResponse, oPayload) {
     return true;
-};
+},
 
 
 
@@ -6430,210 +13555,80 @@
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventSortColumn = function(oArgs) {
-//TODO: support nested header column sorting
+onEventSortColumn : function(oArgs) {
+//TODO: support form elements in sortable columns
     var evt = oArgs.event;
     var target = oArgs.target;
-    YAHOO.util.Event.stopEvent(evt);
-    
+
     var el = this.getThEl(target) || this.getTdEl(target);
     if(el && el.yuiColumnKey) {
         var oColumn = this.getColumn(el.yuiColumnKey);
         if(oColumn.sortable) {
+            Ev.stopEvent(evt);
             this.sortColumn(oColumn);
         }
-        else {
-        }
     }
     else {
     }
-};
+},
 
 /**
+ * Overridable custom event handler to select Column.
+ *
+ * @method onEventSelectColumn
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
+ */
+onEventSelectColumn : function(oArgs) {
+    this.selectColumn(oArgs.target);
+},
+
+/**
+ * Overridable custom event handler to highlight Column. Accounts for spurious
+ * caused-by-child events. 
+ *
+ * @method onEventHighlightColumn
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
+ */
+onEventHighlightColumn : function(oArgs) {
+    //TODO: filter for all spurious events at a lower level
+    if(!Dom.isAncestor(oArgs.target,Ev.getRelatedTarget(oArgs.event))) {
+        this.highlightColumn(oArgs.target);
+    }
+},
+
+/**
+ * Overridable custom event handler to unhighlight Column. Accounts for spurious
+ * caused-by-child events. 
+ *
+ * @method onEventUnhighlightColumn
+ * @param oArgs.event {HTMLEvent} Event object.
+ * @param oArgs.target {HTMLElement} Target element.
+ */
+onEventUnhighlightColumn : function(oArgs) {
+    //TODO: filter for all spurious events at a lower level
+    if(!Dom.isAncestor(oArgs.target,Ev.getRelatedTarget(oArgs.event))) {
+        this.unhighlightColumn(oArgs.target);
+    }
+},
+
+/**
  * Overridable custom event handler to manage selection according to desktop paradigm.
  *
  * @method onEventSelectRow
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventSelectRow = function(oArgs) {
+onEventSelectRow : function(oArgs) {
     var sMode = this.get("selectionMode");
-    if ((sMode == "singlecell") || (sMode == "cellblock") || (sMode == "cellrange")) {
-        return;
+    if(sMode == "single") {
+        this._handleSingleSelectionByMouse(oArgs);
     }
-
-    var evt = oArgs.event;
-    var elTarget = oArgs.target;
-
-    var bSHIFT = evt.shiftKey;
-    var bCTRL = evt.ctrlKey || ((navigator.userAgent.toLowerCase().indexOf("mac") != -1) && evt.metaKey);
-    var i;
-    //var nAnchorPos;
-
-    // Validate target row
-    var elTargetRow = this.getTrEl(elTarget);
-    if(elTargetRow) {
-        var nAnchorRecordIndex, nAnchorTrIndex;
-        var allRows = this._elTbody.rows;
-        var oTargetRecord = this.getRecord(elTargetRow);
-        var nTargetRecordIndex = this._oRecordSet.getRecordIndex(oTargetRecord);
-        var nTargetTrIndex = this.getTrIndex(elTargetRow);
-
-        var oAnchorRecord = this._oAnchorRecord;
-        if(oAnchorRecord) {
-            nAnchorRecordIndex = this._oRecordSet.getRecordIndex(oAnchorRecord);
-            nAnchorTrIndex = this.getTrIndex(oAnchorRecord);
-            if(nAnchorTrIndex === null) {
-                if(nAnchorRecordIndex < this.getRecordIndex(this.getFirstTrEl())) {
-                    nAnchorTrIndex = 0;
-                }
-                else {
-                    nAnchorTrIndex = this.getRecordIndex(this.getLastTrEl());
-                }
-            }
-        }
-
-        // Both SHIFT and CTRL
-        if((sMode != "single") && bSHIFT && bCTRL) {
-            // Validate anchor
-            if(oAnchorRecord) {
-                if(this.isSelected(oAnchorRecord)) {
-                    // Select all rows between anchor row and target row, including target row
-                    if(nAnchorRecordIndex < nTargetRecordIndex) {
-                        for(i=nAnchorRecordIndex+1; i<=nTargetRecordIndex; i++) {
-                            if(!this.isSelected(i)) {
-                                this.selectRow(i);
-                            }
-                        }
-                    }
-                    // Select all rows between target row and anchor row, including target row
-                    else {
-                        for(i=nAnchorRecordIndex-1; i>=nTargetRecordIndex; i--) {
-                            if(!this.isSelected(i)) {
-                                this.selectRow(i);
-                            }
-                        }
-                    }
-                }
-                else {
-                    // Unselect all rows between anchor row and target row
-                    if(nAnchorRecordIndex < nTargetRecordIndex) {
-                        for(i=nAnchorRecordIndex+1; i<=nTargetRecordIndex-1; i++) {
-                            if(this.isSelected(i)) {
-                                this.unselectRow(i);
-                            }
-                        }
-                    }
-                    // Unselect all rows between target row and anchor row
-                    else {
-                        for(i=nTargetRecordIndex+1; i<=nAnchorRecordIndex-1; i++) {
-                            if(this.isSelected(i)) {
-                                this.unselectRow(i);
-                            }
-                        }
-                    }
-                    // Select the target row
-                    this.selectRow(oTargetRecord);
-                }
-            }
-            // Invalid anchor
-            else {
-                // Set anchor
-                this._oAnchorRecord = oTargetRecord;
-
-                // Toggle selection of target
-                if(this.isSelected(oTargetRecord)) {
-                    this.unselectRow(oTargetRecord);
-                }
-                else {
-                    this.selectRow(oTargetRecord);
-                }
-            }
-        }
-        // Only SHIFT
-        else if((sMode != "single") && bSHIFT) {
-            this.unselectAllRows();
-
-            // Validate anchor
-            if(oAnchorRecord) {
-                // Select all rows between anchor row and target row,
-                // including the anchor row and target row
-                if(nAnchorRecordIndex < nTargetRecordIndex) {
-                    for(i=nAnchorRecordIndex; i<=nTargetRecordIndex; i++) {
-                        this.selectRow(i);
-                    }
-                }
-                // Select all rows between target row and anchor row,
-                // including the target row and anchor row
-                else {
-                    for(i=nAnchorRecordIndex; i>=nTargetRecordIndex; i--) {
-                        this.selectRow(i);
-                    }
-                }
-            }
-            // Invalid anchor
-            else {
-                // Set anchor
-                this._oAnchorRecord = oTargetRecord;
-
-                // Select target row only
-                this.selectRow(oTargetRecord);
-            }
-        }
-        // Only CTRL
-        else if((sMode != "single") && bCTRL) {
-            // Set anchor
-            this._oAnchorRecord = oTargetRecord;
-
-            // Toggle selection of target
-            if(this.isSelected(oTargetRecord)) {
-                this.unselectRow(oTargetRecord);
-            }
-            else {
-                this.selectRow(oTargetRecord);
-            }
-        }
-        // Neither SHIFT nor CTRL and "single" mode
-        else if(sMode == "single") {
-            this.unselectAllRows();
-            this.selectRow(oTargetRecord);
-        }
-        // Neither SHIFT nor CTRL
-        else {
-            // Set anchor
-            this._oAnchorRecord = oTargetRecord;
-
-            // Select only target
-            this.unselectAllRows();
-            this.selectRow(oTargetRecord);
-        }
-
-        // Clear any selections that are a byproduct of the click or dblclick
-        var sel;
-        if(window.getSelection) {
-        	sel = window.getSelection();
-        }
-        else if(document.getSelection) {
-        	sel = document.getSelection();
-        }
-        else if(document.selection) {
-        	sel = document.selection;
-        }
-        if(sel) {
-            if(sel.empty) {
-                sel.empty();
-            }
-            else if (sel.removeAllRanges) {
-                sel.removeAllRanges();
-            }
-            else if(sel.collapse) {
-                sel.collapse();
-            }
-        }
-    }
     else {
+        this._handleStandardSelectionByMouse(oArgs);
     }
-};
+},
 
 /**
  * Overridable custom event handler to select cell.
@@ -6642,446 +13637,78 @@
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventSelectCell = function(oArgs) {
+onEventSelectCell : function(oArgs) {
     var sMode = this.get("selectionMode");
-    if ((sMode == "standard") || (sMode == "single")) {
-        return;
+    if(sMode == "cellblock") {
+        this._handleCellBlockSelectionByMouse(oArgs);
     }
-
-    var evt = oArgs.event;
-    var elTarget = oArgs.target;
-
-    var bSHIFT = evt.shiftKey;
-    var bCTRL = evt.ctrlKey  || ((navigator.userAgent.toLowerCase().indexOf("mac") != -1) && evt.metaKey);
-    var i, j, currentRow, startIndex, endIndex;
-    
-    var elTargetCell = this.getTdEl(elTarget);
-    if(elTargetCell) {
-        var nAnchorRecordIndex, nAnchorTrIndex, oAnchorColumn, nAnchorColKeyIndex;
-        
-        var elTargetRow = this.getTrEl(elTargetCell);
-        var allRows = this._elTbody.rows;
-        
-        var oTargetRecord = this.getRecord(elTargetRow);
-        var nTargetRecordIndex = this._oRecordSet.getRecordIndex(oTargetRecord);
-        var oTargetColumn = this.getColumn(elTargetCell);
-        var nTargetColKeyIndex = oTargetColumn.getKeyIndex();
-        var nTargetTrIndex = this.getTrIndex(elTargetRow);
-        var oTargetCell = {record:oTargetRecord, column:oTargetColumn};
-
-        var oAnchorRecord = (this._oAnchorCell) ? this._oAnchorCell.record : null;
-        if(oAnchorRecord) {
-            nAnchorRecordIndex = this._oRecordSet.getRecordIndex(oAnchorRecord);
-            oAnchorColumn = this._oAnchorCell.column;
-            nAnchorColKeyIndex = oAnchorColumn.getKeyIndex();
-            nAnchorTrIndex = this.getTrIndex(oAnchorRecord);
-            if(nAnchorTrIndex === null) {
-                if(nAnchorRecordIndex < this.getRecordIndex(this.getFirstTrEl())) {
-                    nAnchorTrIndex = 0;
-                }
-                else {
-                    nAnchorTrIndex = this.getRecordIndex(this.getLastTrEl());
-                }
-            }
-        }
-        var oAnchorCell = {record:oAnchorRecord, column:oAnchorColumn};
-
-        // Both SHIFT and CTRL
-        if((sMode != "singlecell") && bSHIFT && bCTRL) {
-            // Validate anchor
-            if(oAnchorRecord && oAnchorColumn) {
-                // Anchor is selected
-                if(this.isSelected(this._oAnchorCell)) {
-                    // All cells are on the same row
-                    if(nAnchorRecordIndex === nTargetRecordIndex) {
-                        // Select all cells between anchor cell and target cell, including target cell
-                        if(nAnchorColKeyIndex < nTargetColKeyIndex) {
-                            for(i=nAnchorColKeyIndex+1; i<=nTargetColKeyIndex; i++) {
-                                this.selectCell(allRows[nTargetTrIndex].cells[i]);
-                            }
-                        }
-                        // Select all cells between target cell and anchor cell, including target cell
-                        else if(nTargetColKeyIndex < nAnchorColKeyIndex) {
-                            for(i=nTargetColKeyIndex; i<nAnchorColKeyIndex; i++) {
-                                this.selectCell(allRows[nTargetTrIndex].cells[i]);
-                            }
-                        }
-                    }
-                    // Anchor row is above target row
-                    else if(nAnchorRecordIndex < nTargetRecordIndex) {
-                        if(sMode == "cellrange") {
-                            // Select all cells on anchor row from anchor cell to the end of the row
-                            for(i=nAnchorColKeyIndex+1; i<allRows[nAnchorTrIndex].cells.length; i++) {
-                                this.selectCell(allRows[nAnchorTrIndex].cells[i]);
-                            }
-                            
-                            // Select all cells on all rows between anchor row and target row
-                            for(i=nAnchorTrIndex+1; i<nTargetTrIndex; i++) {
-                                for(j=0; j<allRows[i].cells.length; j++){
-                                    this.selectCell(allRows[i].cells[j]);
-                                }
-                            }
-
-                            // Select all cells on target row from first cell to the target cell
-                            for(i=0; i<=nTargetColKeyIndex; i++) {
-                                this.selectCell(allRows[nTargetTrIndex].cells[i]);
-                            }
-                        }
-                        else if(sMode == "cellblock") {
-                            startIndex = Math.min(nAnchorColKeyIndex, nTargetColKeyIndex);
-                            endIndex = Math.max(nAnchorColKeyIndex, nTargetColKeyIndex);
-                            
-                            // Select all cells from startIndex to endIndex on rows between anchor row and target row
-                            for(i=nAnchorTrIndex; i<=nTargetTrIndex; i++) {
-                                for(j=startIndex; j<=endIndex; j++) {
-                                    this.selectCell(allRows[i].cells[j]);
-                                }
-                            }
-                        }
-                    }
-                    // Anchor row is below target row
-                    else {
-                        if(sMode == "cellrange") {
-                            // Select all cells on target row from target cell to the end of the row
-                            for(i=nTargetColKeyIndex; i<allRows[nTargetTrIndex].cells.length; i++) {
-                                this.selectCell(allRows[nTargetTrIndex].cells[i]);
-                            }
-
-                            // Select all cells on all rows between target row and anchor row
-                            for(i=nTargetTrIndex+1; i<nAnchorTrIndex; i++) {
-                                for(j=0; j<allRows[i].cells.length; j++){
-                                    this.selectCell(allRows[i].cells[j]);
-                                }
-                            }
-
-                            // Select all cells on anchor row from first cell to the anchor cell
-                            for(i=0; i<nAnchorColKeyIndex; i++) {
-                                this.selectCell(allRows[nAnchorTrIndex].cells[i]);
-                            }
-                        }
-                        else if(sMode == "cellblock") {
-                            startIndex = Math.min(nAnchorTrIndex, nTargetColKeyIndex);
-                            endIndex = Math.max(nAnchorTrIndex, nTargetColKeyIndex);
-
-                            // Select all cells from startIndex to endIndex on rows between target row and anchor row
-                            for(i=nAnchorTrIndex; i>=nTargetTrIndex; i--) {
-                                for(j=endIndex; j>=startIndex; j--) {
-                                    this.selectCell(allRows[i].cells[j]);
-                                }
-                            }
-                        }
-                    }
-                }
-                // Anchor cell is unselected
-                else {
-                    // All cells are on the same row
-                    if(nAnchorRecordIndex === nTargetRecordIndex) {
-                        // Unselect all cells between anchor cell and target cell
-                        if(nAnchorColKeyIndex < nTargetColKeyIndex) {
-                            for(i=nAnchorColKeyIndex+1; i<nTargetColKeyIndex; i++) {
-                                this.unselectCell(allRows[nTargetTrIndex].cells[i]);
-                            }
-                        }
-                        // Select all cells between target cell and anchor cell
-                        else if(nTargetColKeyIndex < nAnchorColKeyIndex) {
-                            for(i=nTargetColKeyIndex+1; i<nAnchorColKeyIndex; i++) {
-                                this.unselectCell(allRows[nTargetTrIndex].cells[i]);
-                            }
-                        }
-                    }
-                    // Anchor row is above target row
-                    if(nAnchorRecordIndex < nTargetRecordIndex) {
-                        // Unselect all cells from anchor cell to target cell
-                        for(i=nAnchorTrIndex; i<=nTargetTrIndex; i++) {
-                            currentRow = allRows[i];
-                            for(j=0; j<currentRow.cells.length; j++) {
-                                // This is the anchor row, only unselect cells after the anchor cell
-                                if(currentRow.sectionRowIndex === nAnchorTrIndex) {
-                                    if(j>nAnchorColKeyIndex) {
-                                        this.unselectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // This is the target row, only unelect cells before the target cell
-                                else if(currentRow.sectionRowIndex === nTargetTrIndex) {
-                                    if(j<nTargetColKeyIndex) {
-                                        this.unselectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // Unselect all cells on this row
-                                else {
-                                    this.unselectCell(currentRow.cells[j]);
-                                }
-                            }
-                        }
-                    }
-                    // Anchor row is below target row
-                    else {
-                        // Unselect all cells from target cell to anchor cell
-                        for(i=nTargetTrIndex; i<=nAnchorTrIndex; i++) {
-                            currentRow = allRows[i];
-                            for(j=0; j<currentRow.cells.length; j++) {
-                                // This is the target row, only unselect cells after the target cell
-                                if(currentRow.sectionRowIndex == nTargetTrIndex) {
-                                    if(j>nTargetColKeyIndex) {
-                                        this.unselectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // This is the anchor row, only unselect cells before the anchor cell
-                                else if(currentRow.sectionRowIndex == nAnchorTrIndex) {
-                                    if(j<nAnchorColKeyIndex) {
-                                        this.unselectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // Unselect all cells on this row
-                                else {
-                                    this.unselectCell(currentRow.cells[j]);
-                                }
-                            }
-                        }
-                    }
-
-                    // Select the target cell
-                    this.selectCell(elTargetCell);
-                }
-            }
-            // Invalid anchor
-            else {
-                // Set anchor
-                this._oAnchorCell = oTargetCell;
-
-                // Toggle selection of target
-                if(this.isSelected(oTargetCell)) {
-                    this.unselectCell(oTargetCell);
-                }
-                else {
-                    this.selectCell(oTargetCell);
-                }
-            }
-        }
-        // Only SHIFT
-        else if((sMode != "singlecell") && bSHIFT) {
-            this.unselectAllCells();
-
-            // Validate anchor
-            if(oAnchorCell) {
-                // All cells are on the same row
-                if(nAnchorRecordIndex === nTargetRecordIndex) {
-                    // Select all cells between anchor cell and target cell,
-                    // including the anchor cell and target cell
-                    if(nAnchorColKeyIndex < nTargetColKeyIndex) {
-                        for(i=nAnchorColKeyIndex; i<=nTargetColKeyIndex; i++) {
-                            this.selectCell(allRows[nTargetTrIndex].cells[i]);
-                        }
-                    }
-                    // Select all cells between target cell and anchor cell
-                    // including the target cell and anchor cell
-                    else if(nTargetColKeyIndex < nAnchorColKeyIndex) {
-                        for(i=nTargetColKeyIndex; i<=nAnchorColKeyIndex; i++) {
-                            this.selectCell(allRows[nTargetTrIndex].cells[i]);
-                        }
-                    }
-                }
-                // Anchor row is above target row
-                else if(nAnchorRecordIndex < nTargetRecordIndex) {
-                    if(sMode == "cellrange") {
-                        // Select all cells from anchor cell to target cell
-                        // including the anchor cell and target cell
-                        for(i=nAnchorTrIndex; i<=nTargetTrIndex; i++) {
-                            currentRow = allRows[i];
-                            for(j=0; j<currentRow.cells.length; j++) {
-                                // This is the anchor row, only select the anchor cell and after
-                                if(currentRow.sectionRowIndex == nAnchorTrIndex) {
-                                    if(j>=nAnchorColKeyIndex) {
-                                        this.selectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // This is the target row, only select the target cell and before
-                                else if(currentRow.sectionRowIndex == nTargetTrIndex) {
-                                    if(j<=nTargetColKeyIndex) {
-                                        this.selectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // Select all cells on this row
-                                else {
-                                    this.selectCell(currentRow.cells[j]);
-                                }
-                            }
-                        }
-                    }
-                    else if(sMode == "cellblock") {
-                        // Select the cellblock from anchor cell to target cell
-                        // including the anchor cell and the target cell
-                        startIndex = Math.min(nAnchorColKeyIndex, nTargetColKeyIndex);
-                        endIndex = Math.max(nAnchorColKeyIndex, nTargetColKeyIndex);
-
-                        for(i=nAnchorTrIndex; i<=nTargetTrIndex; i++) {
-                            for(j=startIndex; j<=endIndex; j++) {
-                                this.selectCell(allRows[i].cells[j]);
-                            }
-                        }
-                    }
-                }
-                // Anchor row is below target row
-                else {
-                    if(sMode == "cellrange") {
-                        // Select all cells from target cell to anchor cell,
-                        // including the target cell and anchor cell
-                        for(i=nTargetTrIndex; i<=nAnchorTrIndex; i++) {
-                            currentRow = allRows[i];
-                            for(j=0; j<currentRow.cells.length; j++) {
-                                // This is the target row, only select the target cell and after
-                                if(currentRow.sectionRowIndex == nTargetTrIndex) {
-                                    if(j>=nTargetColKeyIndex) {
-                                        this.selectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // This is the anchor row, only select the anchor cell and before
-                                else if(currentRow.sectionRowIndex == nAnchorTrIndex) {
-                                    if(j<=nAnchorColKeyIndex) {
-                                        this.selectCell(currentRow.cells[j]);
-                                    }
-                                }
-                                // Select all cells on this row
-                                else {
-                                    this.selectCell(currentRow.cells[j]);
-                                }
-                            }
-                        }
-                    }
-                    else if(sMode == "cellblock") {
-                        // Select the cellblock from target cell to anchor cell
-                        // including the target cell and the anchor cell
-                        startIndex = Math.min(nAnchorColKeyIndex, nTargetColKeyIndex);
-                        endIndex = Math.max(nAnchorColKeyIndex, nTargetColKeyIndex);
-
-                        for(i=nTargetTrIndex; i<=nAnchorTrIndex; i++) {
-                            for(j=startIndex; j<=endIndex; j++) {
-                                this.selectCell(allRows[i].cells[j]);
-                            }
-                        }
-                    }
-                }
-            }
-            // Invalid anchor
-            else {
-                // Set anchor
-                this._oAnchorCell = oTargetCell;
-
-                // Select target only
-                this.selectCell(oTargetCell);
-            }
-        }
-        // Only CTRL
-        else if((sMode != "singlecell") && bCTRL) {
-            // Set anchor
-            this._oAnchorCell = oTargetCell;
-
-            // Toggle selection of target
-            if(this.isSelected(oTargetCell)) {
-                this.unselectCell(oTargetCell);
-            }
-            else {
-                this.selectCell(oTargetCell);
-            }
-        }
-        // Neither SHIFT nor CTRL, or multi-selection has been disabled
-        else {
-            // Set anchor
-            this._oAnchorCell = oTargetCell;
-
-            // Select only target
-            this.unselectAllCells();
-            this.selectCell(oTargetCell);
-        }
-
-        // Clear any selections that are a byproduct of the click or dblclick
-        var sel;
-        if(window.getSelection) {
-        	sel = window.getSelection();
-        }
-        else if(document.getSelection) {
-        	sel = document.getSelection();
-        }
-        else if(document.selection) {
-        	sel = document.selection;
-        }
-        if(sel) {
-            if(sel.empty) {
-                sel.empty();
-            }
-            else if (sel.removeAllRanges) {
-                sel.removeAllRanges();
-            }
-            else if(sel.collapse) {
-                sel.collapse();
-            }
-        }
+    else if(sMode == "cellrange") {
+        this._handleCellRangeSelectionByMouse(oArgs);
     }
     else {
+        this._handleSingleCellSelectionByMouse(oArgs);
     }
-};
+},
 
-
-
-
-
-
-
-
-
-
-
 /**
- * Overridable custom event handler to highlight row.
+ * Overridable custom event handler to highlight row. Accounts for spurious
+ * caused-by-child events. 
  *
  * @method onEventHighlightRow
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventHighlightRow = function(oArgs) {
-    var evt = oArgs.event;
-    var elTarget = oArgs.target;
-    this.highlightRow(elTarget);
-};
+onEventHighlightRow : function(oArgs) {
+    //TODO: filter for all spurious events at a lower level
+    if(!Dom.isAncestor(oArgs.target,Ev.getRelatedTarget(oArgs.event))) {
+        this.highlightRow(oArgs.target);
+    }
+},
 
 /**
- * Overridable custom event handler to unhighlight row.
+ * Overridable custom event handler to unhighlight row. Accounts for spurious
+ * caused-by-child events. 
  *
  * @method onEventUnhighlightRow
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventUnhighlightRow = function(oArgs) {
-    var evt = oArgs.event;
-    var elTarget = oArgs.target;
-    this.unhighlightRow(elTarget);
-};
+onEventUnhighlightRow : function(oArgs) {
+    //TODO: filter for all spurious events at a lower level
+    if(!Dom.isAncestor(oArgs.target,Ev.getRelatedTarget(oArgs.event))) {
+        this.unhighlightRow(oArgs.target);
+    }
+},
 
 /**
- * Overridable custom event handler to highlight cell.
+ * Overridable custom event handler to highlight cell. Accounts for spurious
+ * caused-by-child events. 
  *
  * @method onEventHighlightCell
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventHighlightCell = function(oArgs) {
-    var evt = oArgs.event;
-    var elTarget = oArgs.target;
-    this.highlightCell(elTarget);
-};
+onEventHighlightCell : function(oArgs) {
+    //TODO: filter for all spurious events at a lower level
+    if(!Dom.isAncestor(oArgs.target,Ev.getRelatedTarget(oArgs.event))) {
+        this.highlightCell(oArgs.target);
+    }
+},
 
 /**
- * Overridable custom event handler to unhighlight cell.
+ * Overridable custom event handler to unhighlight cell. Accounts for spurious
+ * caused-by-child events. 
  *
  * @method onEventUnhighlightCell
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventUnhighlightCell = function(oArgs) {
-    var evt = oArgs.event;
-    var elTarget = oArgs.target;
-    this.unhighlightCell(elTarget);
-};
+onEventUnhighlightCell : function(oArgs) {
+    //TODO: filter for all spurious events at a lower level
+    if(!Dom.isAncestor(oArgs.target,Ev.getRelatedTarget(oArgs.event))) {
+        this.unhighlightCell(oArgs.target);
+    }
+},
 
 /**
  * Overridable custom event handler to format cell.
@@ -7090,19 +13717,17 @@
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventFormatCell = function(oArgs) {
-    var evt = oArgs.event;
+onEventFormatCell : function(oArgs) {
     var target = oArgs.target;
-    var elTag = target.tagName.toLowerCase();
 
     var elCell = this.getTdEl(target);
     if(elCell && elCell.yuiColumnKey) {
         var oColumn = this.getColumn(elCell.yuiColumnKey);
-        this.formatCell(elCell, this.getRecord(elCell), oColumn);
+        this.formatCell(elCell.firstChild, this.getRecord(elCell), oColumn);
     }
     else {
     }
-};
+},
 
 /**
  * Overridable custom event handler to edit cell.
@@ -7111,10 +13736,8 @@
  * @param oArgs.event {HTMLEvent} Event object.
  * @param oArgs.target {HTMLElement} Target element.
  */
-YAHOO.widget.DataTable.prototype.onEventShowCellEditor = function(oArgs) {
-    var evt = oArgs.event;
+onEventShowCellEditor : function(oArgs) {
     var target = oArgs.target;
-    var elTag = target.tagName.toLowerCase();
 
     var elCell = this.getTdEl(target);
     if(elCell) {
@@ -7122,11 +13745,7 @@
     }
     else {
     }
-};
-// Backward compatibility
-YAHOO.widget.DataTable.prototype.onEventEditCell = function(oArgs) {
-    this.onEventShowCellEditor(oArgs);
-};
+},
 
 /**
  * Overridable custom event handler to save Cell Editor input.
@@ -7134,58 +13753,20 @@
  * @method onEventSaveCellEditor
  * @param oArgs.editor {Object} Cell Editor object literal.
  */
-YAHOO.widget.DataTable.prototype.onEventSaveCellEditor = function(oArgs) {
+onEventSaveCellEditor : function(oArgs) {
     this.saveCellEditor();
-};
+},
 
 /**
- * Callback function for creating a progressively enhanced DataTable first
- * receives data from DataSource and populates the RecordSet, then initializes
- * DOM elements.
+ * Overridable custom event handler to cancel Cell Editor.
  *
- * @method _onDataReturnEnhanceTable
- * @param sRequest {String} Original request.
- * @param oResponse {Object} Response object.
- * @param bError {Boolean} (optional) True if there was a data error.
- * @private
+ * @method onEventCancelCellEditor
+ * @param oArgs.editor {Object} Cell Editor object literal.
  */
-YAHOO.widget.DataTable.prototype._onDataReturnEnhanceTable = function(sRequest, oResponse) {
-    // Pass data through abstract method for any transformations
-    var ok = this.doBeforeLoadData(sRequest, oResponse);
+onEventCancelCellEditor : function(oArgs) {
+    this.cancelCellEditor();
+},
 
-    // Data ok to populate
-    if(ok && oResponse && !oResponse.error && YAHOO.lang.isArray(oResponse.results)) {
-        // Update RecordSet
-        this._oRecordSet.addRecords(oResponse.results);
-
-        // Initialize DOM elements
-        this._initTableEl();
-        if(!this._elTable || !this._elThead || !this._elTbody) {
-            return;
-        }
-
-        // Call Element's constructor after DOM elements are created
-        // but *before* UI is updated with data
-        YAHOO.widget.DataTable.superclass.constructor.call(this, this._elContainer, this._oConfigs);
-
-        //HACK: Set the Paginator values
-        if(this._oConfigs.paginator) {
-            this.updatePaginator(this._oConfigs.paginator);
-        }
-
-        // Update the UI
-        this.refreshView();
-    }
-    // Error
-    else if(ok && oResponse.error) {
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_ERROR, YAHOO.widget.DataTable.CLASS_ERROR);
-    }
-    // Empty
-    else if(ok){
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_EMPTY, YAHOO.widget.DataTable.CLASS_EMPTY);
-    }
-};
-    
 /**
  * Callback function receives data from DataSource and populates an entire
  * DataTable with Records and TR elements, clearing previous Records, if any.
@@ -7193,32 +13774,14 @@
  * @method onDataReturnInitializeTable
  * @param sRequest {String} Original request.
  * @param oResponse {Object} Response object.
- * @param bError {Boolean} (optional) True if there was a data error.
+ * @param oPayload {MIXED} (optional) Additional argument(s)
  */
-YAHOO.widget.DataTable.prototype.onDataReturnInitializeTable = function(sRequest, oResponse) {
-    this.fireEvent("dataReturnEvent", {request:sRequest,response:oResponse});
+onDataReturnInitializeTable : function(sRequest, oResponse, oPayload) {
+    this.initializeTable();
 
-    // Pass data through abstract method for any transformations
-    var ok = this.doBeforeLoadData(sRequest, oResponse);
+    this.onDataReturnSetRows(sRequest,oResponse,oPayload);
+},
 
-    // Data ok to populate
-    if(ok && oResponse && !oResponse.error && YAHOO.lang.isArray(oResponse.results)) {
-        this.initializeTable(oResponse.results);
-    }
-    // Error
-    else if(ok && oResponse.error) {
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_ERROR, YAHOO.widget.DataTable.CLASS_ERROR);
-    }
-    // Empty
-    else if(ok){
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_EMPTY, YAHOO.widget.DataTable.CLASS_EMPTY);
-    }
-};
-// Backward compatibility
-YAHOO.widget.DataTable.prototype.onDataReturnReplaceRows = function(sRequest, oResponse) {
-    this.onDataReturnInitializeTable(sRequest, oResponse);
-};
-
 /**
  * Callback function receives data from DataSource and appends to an existing
  * DataTable new Records and, if applicable, creates or updates
@@ -7227,64 +13790,203 @@
  * @method onDataReturnAppendRows
  * @param sRequest {String} Original request.
  * @param oResponse {Object} Response object.
- * @param bError {Boolean} (optional) True if there was a data error.
+ * @param oPayload {MIXED} (optional) Additional argument(s)
  */
-YAHOO.widget.DataTable.prototype.onDataReturnAppendRows = function(sRequest, oResponse) {
-    this.fireEvent("dataReturnEvent", {request:sRequest,response:oResponse});
-    
+onDataReturnAppendRows : function(sRequest, oResponse, oPayload) {
+    this.fireEvent("dataReturnEvent", {request:sRequest,response:oResponse,payload:oPayload});
+
     // Pass data through abstract method for any transformations
-    var ok = this.doBeforeLoadData(sRequest, oResponse);
-    
+    var ok = this.doBeforeLoadData(sRequest, oResponse, oPayload);
+
     // Data ok to append
-    if(ok && oResponse && !oResponse.error && YAHOO.lang.isArray(oResponse.results)) {
+    if(ok && oResponse && !oResponse.error && lang.isArray(oResponse.results)) {
+
         this.addRows(oResponse.results);
+
+        // Handle the meta && payload
+        this._handleDataReturnPayload(sRequest, oResponse,
+            this._mergeResponseMeta(oPayload, oResponse.meta));
+
+        // Default the Paginator's totalRecords from the RecordSet length
+        var oPaginator = this.get('paginator');
+        if (oPaginator && oPaginator instanceof Pag &&
+            oPaginator.get('totalRecords') < this._oRecordSet.getLength()) {
+            oPaginator.set('totalRecords',this._oRecordSet.getLength());
+        }
     }
     // Error
     else if(ok && oResponse.error) {
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_ERROR, YAHOO.widget.DataTable.CLASS_ERROR);
+        this.showTableMessage(DT.MSG_ERROR, DT.CLASS_ERROR);
     }
-};
+},
 
 /**
- * Callback function receives data from DataSource and inserts into top of an
- * existing DataTable new Records and, if applicable, creates or updates
- * corresponding TR elements.
+ * Callback function receives data from DataSource and inserts new records
+ * starting at the index specified in oPayload.insertIndex.  If applicable,
+ * creates or updates corresponding TR elements.
  *
  * @method onDataReturnInsertRows
  * @param sRequest {String} Original request.
  * @param oResponse {Object} Response object.
- * @param bError {Boolean} (optional) True if there was a data error.
+ * @param oPayload {MIXED} (optional) Additional argument(s)
  */
-YAHOO.widget.DataTable.prototype.onDataReturnInsertRows = function(sRequest, oResponse) {
-    this.fireEvent("dataReturnEvent", {request:sRequest,response:oResponse});
-    
+onDataReturnInsertRows : function(sRequest, oResponse, oPayload) {
+    this.fireEvent("dataReturnEvent", {request:sRequest,response:oResponse,payload:oPayload});
+
     // Pass data through abstract method for any transformations
-    var ok = this.doBeforeLoadData(sRequest, oResponse);
-    
+    var ok = this.doBeforeLoadData(sRequest, oResponse, oPayload);
+
     // Data ok to append
-    if(ok && oResponse && !oResponse.error && YAHOO.lang.isArray(oResponse.results)) {
-        this.addRows(oResponse.results, 0);
+    if(ok && oResponse && !oResponse.error && lang.isArray(oResponse.results)) {
+        var meta = this._mergeResponseMeta({
+                // backward compatibility
+                recordInsertIndex: (oPayload ? oPayload.insertIndex || 0 : 0) },
+                oPayload, oResponse.meta);
+
+        this.addRows(oResponse.results, meta.insertIndex);
+
+        // Handle the magic meta values
+        this._handleDataReturnPayload(sRequest,oResponse,meta);
+
+        // Default the Paginator's totalRecords from the RecordSet length
+        var oPaginator = this.get('paginator');
+        if (oPaginator && oPaginator instanceof Pag &&
+            oPaginator.get('totalRecords') < this._oRecordSet.getLength()) {
+            oPaginator.set('totalRecords',this._oRecordSet.getLength());
+        }
     }
     // Error
     else if(ok && oResponse.error) {
-        this.showTableMessage(YAHOO.widget.DataTable.MSG_ERROR, YAHOO.widget.DataTable.CLASS_ERROR);
+        this.showTableMessage(DT.MSG_ERROR, DT.CLASS_ERROR);
     }
-};
+},
 
+/**
+ * Receives reponse from DataSource and populates the RecordSet with the
+ * results.
+ * @method onDataReturnSetRows
+ * @param oRequest {MIXED} Original generated request.
+ * @param oResponse {Object} Response object.
+ * @param oPayload {MIXED} (optional) Additional argument(s)
+ */
+onDataReturnSetRows : function(oRequest, oResponse, oPayload) {
+    this.fireEvent("dataReturnEvent", {request:oRequest,response:oResponse,payload:oPayload});
 
+    // Pass data through abstract method for any transformations
+    var ok = this.doBeforeLoadData(oRequest, oResponse, oPayload);
 
+    // Data ok to set
+    if(ok && oResponse && !oResponse.error && lang.isArray(oResponse.results)) {
+        var oPaginator = this.get('paginator');
+        if (!(oPaginator instanceof Pag)) {
+            oPaginator = null;
+        }
 
+        var meta = this._mergeResponseMeta({
+                // backward compatibility
+                recordStartIndex: oPayload ? oPayload.startIndex : null },
+                oPayload, oResponse.meta);
 
+        if (!lang.isNumber(meta.recordStartIndex)) {
+            // Default to the current page offset if paginating; 0 if not.
+            meta.recordStartIndex = oPaginator && meta.pagination ?
+                meta.pagination.recordOffset || 0 : 0;
+        }
 
+        this._oRecordSet.setRecords(oResponse.results, meta.recordStartIndex);
 
+        // Handle the magic meta values
+        this._handleDataReturnPayload(oRequest,oResponse,meta);
 
+        // Default the Paginator's totalRecords from the RecordSet length
+        if (oPaginator && oPaginator.get('totalRecords') < this._oRecordSet.getLength()) {
+            oPaginator.set('totalRecords',this._oRecordSet.getLength());
+        }
 
+        this.render();
+    }
+    // Error
+    else if(ok && oResponse.error) {
+        this.showTableMessage(DT.MSG_ERROR, DT.CLASS_ERROR);
+    }
+},
 
+/**
+ * Merges meta information from the response (as defined in the DataSource's
+ * responseSchema.metaFields member) into the payload.  A few magic keys are
+ * given special treatment: sortKey and sortDir => sorting.key|dir and all
+ * keys paginationFoo => pagination.foo.  Merging is shallow with the exception
+ * of the magic keys being added to their respective nested objects.
+ *
+ * @method _mergeResponseMeta
+ * @param * {object} Any number of objects to merge together.  Last in wins.
+ * @return {object} A new object containing the combined keys of all objects.
+ * @private
+ */
+_mergeResponseMeta : function () {
+    var meta = {},
+        a = arguments,
+        i = 0,len = a.length,
+        k,o;
 
+    for (; i < len; ++i) {
+        o = a[i];
+        if (lang.isObject(o)) {
+            for (k in o) {
+                if (lang.hasOwnProperty(o,k)) {
+                    if (k.indexOf('pagination') === 0 && k.charAt(10)) {
+                        if (!meta.pagination) {
+                            meta.pagination = {};
+                        }
+                        meta.pagination[k.substr(10,1).toLowerCase()+k.substr(11)] = o[k];
+                    } else if (/^sort(Key|Dir)/.test(k)) {
+                        if (!meta.sorting) {
+                            var curSort = this.get('sortedBy');
+                            meta.sorting = curSort ? { key : curSort.key } : {};
+                        }
+                        meta.sorting[RegExp.$1.toLowerCase()] = o[k];
+                    } else {
+                        meta[k] = o[k];
+                    }
+                }
+            }
+        }
+    }
 
+    return meta;
+},
 
+/**
+ * Updates the DataTable with data sent in an onDataReturn* payload
+ * @method _handleDataReturnPayload
+ * @param oRequest {MIXED} Original generated request.
+ * @param oResponse {Object} Response object.
+ * @param meta {MIXED} Argument(s) provided in payload or response meta
+ * @private
+ */
+_handleDataReturnPayload : function (oRequest, oResponse, meta) {
+    if (meta) {
+        // Update with any pagination information
+        var oPaginator = this.get('paginator');
+        if (oPaginator instanceof Pag) {
+            if (!lang.isUndefined(meta.totalRecords)) {
+                oPaginator.set('totalRecords',parseInt(meta.totalRecords,10)|0);
+            }
 
+            if (lang.isObject(meta.pagination)) {
+                // Set the paginator values in preparation for refresh
+                oPaginator.set('rowsPerPage',meta.pagination.rowsPerPage);
+                oPaginator.set('recordOffset',meta.pagination.recordOffset);
+            }
+        }
 
+        // Update with any sorting information
+        if (meta.sorting) {
+            // Set the sorting values in preparation for refresh
+            this.set('sortedBy', meta.sorting);
+        }
+    }
+},
 
 
 
@@ -7305,6 +14007,19 @@
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
     /////////////////////////////////////////////////////////////////////////////
     //
     // Custom Events
@@ -7318,9 +14033,9 @@
      */
 
     /**
-     * Fired when the DataTable's view is refreshed.
+     * Fired when the DataTable's view is rendered.
      *
-     * @event refreshEvent
+     * @event renderEvent
      */
 
     /**
@@ -7333,18 +14048,66 @@
      */
 
     /**
-     * Fired when the DataTable has a focus.
+     * Fired when the DataTable has a focus event.
      *
      * @event tableFocusEvent
      */
 
     /**
-     * Fired when the DataTable has a blur.
+     * Fired when the DataTable THEAD element has a focus event.
      *
+     * @event theadFocusEvent
+     */
+
+    /**
+     * Fired when the DataTable TBODY element has a focus event.
+     *
+     * @event tbodyFocusEvent
+     */
+
+    /**
+     * Fired when the DataTable has a blur event.
+     *
      * @event tableBlurEvent
      */
 
+    /*TODO
+     * Fired when the DataTable THEAD element has a blur event.
+     *
+     * @event theadBlurEvent
+     */
+
+    /*TODO
+     * Fired when the DataTable TBODY element has a blur event.
+     *
+     * @event tbodyBlurEvent
+     */
+
     /**
+     * Fired when the DataTable has a key event.
+     *
+     * @event tableKeyEvent
+     * @param oArgs.event {HTMLEvent} The event object.
+     * @param oArgs.target {HTMLElement} The DataTable's TABLE element.
+     */
+
+    /**
+     * Fired when the DataTable THEAD element has a key event.
+     *
+     * @event theadKeyEvent
+     * @param oArgs.event {HTMLEvent} The event object.
+     * @param oArgs.target {HTMLElement} The DataTable's TABLE element.
+     */
+
+    /**
+     * Fired when the DataTable TBODY element has a key event.
+     *
+     * @event tbodyKeyEvent
+     * @param oArgs.event {HTMLEvent} The event object.
+     * @param oArgs.target {HTMLElement} The DataTable's TABLE element.
+     */
+
+    /**
      * Fired when the DataTable has a mouseover.
      *
      * @event tableMouseoverEvent
@@ -7415,125 +14178,125 @@
      */
 
     /**
-     * Fired when a header row has a mouseover.
+     * Fired when a THEAD row has a mouseover.
      *
-     * @event headerRowMouseoverEvent
+     * @event theadRowMouseoverEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TR element.
      */
 
     /**
-     * Fired when a header row has a mouseout.
+     * Fired when a THEAD row has a mouseout.
      *
-     * @event headerRowMouseoutEvent
+     * @event theadRowMouseoutEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TR element.
      */
 
     /**
-     * Fired when a header row has a mousedown.
+     * Fired when a THEAD row has a mousedown.
      *
-     * @event headerRowMousedownEvent
+     * @event theadRowMousedownEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TR element.
      */
 
     /**
-     * Fired when a header row has a click.
+     * Fired when a THEAD row has a click.
      *
-     * @event headerRowClickEvent
+     * @event theadRowClickEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TR element.
      */
 
     /**
-     * Fired when a header row has a dblclick.
+     * Fired when a THEAD row has a dblclick.
      *
-     * @event headerRowDblclickEvent
+     * @event theadRowDblclickEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TR element.
      */
 
     /**
-     * Fired when a header cell has a mouseover.
+     * Fired when a THEAD cell has a mouseover.
      *
-     * @event headerCellMouseoverEvent
+     * @event theadCellMouseoverEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TH element.
      *
      */
 
     /**
-     * Fired when a header cell has a mouseout.
+     * Fired when a THEAD cell has a mouseout.
      *
-     * @event headerCellMouseoutEvent
+     * @event theadCellMouseoutEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TH element.
      *
      */
 
     /**
-     * Fired when a header cell has a mousedown.
+     * Fired when a THEAD cell has a mousedown.
      *
-     * @event headerCellMousedownEvent
+     * @event theadCellMousedownEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TH element.
      */
 
     /**
-     * Fired when a header cell has a click.
+     * Fired when a THEAD cell has a click.
      *
-     * @event headerCellClickEvent
+     * @event theadCellClickEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TH element.
      */
 
     /**
-     * Fired when a header cell has a dblclick.
+     * Fired when a THEAD cell has a dblclick.
      *
-     * @event headerCellDblclickEvent
+     * @event theadCellDblclickEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The TH element.
      */
 
     /**
-     * Fired when a header label has a mouseover.
+     * Fired when a THEAD label has a mouseover.
      *
-     * @event headerLabelMouseoverEvent
+     * @event theadLabelMouseoverEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The SPAN element.
      *
      */
 
     /**
-     * Fired when a header label has a mouseout.
+     * Fired when a THEAD label has a mouseout.
      *
-     * @event headerLabelMouseoutEvent
+     * @event theadLabelMouseoutEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The SPAN element.
      *
      */
 
     /**
-     * Fired when a header label has a mousedown.
+     * Fired when a THEAD label has a mousedown.
      *
-     * @event headerLabelMousedownEvent
+     * @event theadLabelMousedownEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The SPAN element.
      */
 
     /**
-     * Fired when a header label has a click.
+     * Fired when a THEAD label has a click.
      *
-     * @event headerLabelClickEvent
+     * @event theadLabelClickEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The SPAN element.
      */
 
     /**
-     * Fired when a header label has a dblclick.
+     * Fired when a THEAD label has a dblclick.
      *
-     * @event headerLabelDblclickEvent
+     * @event theadLabelDblclickEvent
      * @param oArgs.event {HTMLEvent} The event object.
      * @param oArgs.target {HTMLElement} The SPAN element.
      */
@@ -7543,18 +14306,91 @@
      *
      * @event columnSortEvent
      * @param oArgs.column {YAHOO.widget.Column} The Column instance.
-     * @param oArgs.dir {String} Sort direction "asc" or "desc".
+     * @param oArgs.dir {String} Sort direction: YAHOO.widget.DataTable.CLASS_ASC
+     * or YAHOO.widget.DataTable.CLASS_DESC.
      */
 
     /**
-     * Fired when a column is resized.
+     * Fired when a column width is set.
      *
+     * @event columnSetWidthEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     * @param oArgs.width {Number} The width in pixels.
+     */
+
+    /**
+     * Fired when a column is drag-resized.
+     *
      * @event columnResizeEvent
      * @param oArgs.column {YAHOO.widget.Column} The Column instance.
      * @param oArgs.target {HTMLElement} The TH element.
+     * @param oArgs.width {Number} Width in pixels.     
      */
 
     /**
+     * Fired when a ColumnSet is re-initialized due to a Column being drag-reordered.
+     *
+     * @event columnReorderEvent
+     */
+
+    /**
+     * Fired when a column is hidden.
+     *
+     * @event columnHideEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     */
+
+    /**
+     * Fired when a column is shown.
+     *
+     * @event columnShowEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     */
+
+    /**
+     * Fired when a column is selected.
+     *
+     * @event columnSelectEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     */
+
+    /**
+     * Fired when a column is unselected.
+     *
+     * @event columnUnselectEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     */
+    /**
+     * Fired when a column is removed.
+     *
+     * @event columnRemoveEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     */
+
+    /**
+     * Fired when a column is inserted.
+     *
+     * @event columnInsertEvent
+     * @param oArgs.column {YAHOO.widget.Column} The Column instance.
+     * @param oArgs.index {Number} The index position.
+     */
+
+    /**
+     * Fired when a column is highlighted.
+     *
+     * @event columnHighlightEvent
+     * @param oArgs.column {YAHOO.widget.Column} The highlighted Column.
+     */
+
+    /**
+     * Fired when a column is unhighlighted.
+     *
+     * @event columnUnhighlightEvent
+     * @param oArgs.column {YAHOO.widget.Column} The unhighlighted Column.
+     */
+
+
+    /**
      * Fired when a row has a mouseover.
      *
      * @event rowMouseoverEvent
@@ -7600,6 +14436,13 @@
      * @event rowAddEvent
      * @param oArgs.record {YAHOO.widget.Record} The added Record.
      */
+     
+    /**
+     * Fired when rows are added.
+     *
+     * @event rowsAddEvent
+     * @param oArgs.record {YAHOO.widget.Record[]} The added Records.
+     */
 
     /**
      * Fired when a row is updated.
@@ -7617,6 +14460,15 @@
      * @param oArgs.recordIndex {Number} Index of the deleted Record.
      * @param oArgs.trElIndex {Number} Index of the deleted TR element, if on current page.
      */
+     
+    /**
+     * Fired when rows are deleted.
+     *
+     * @event rowsDeleteEvent
+     * @param oArgs.oldData {Object[]} Array of object literals of the deleted data.
+     * @param oArgs.recordIndex {Number} Index of the first deleted Record.
+     * @param oArgs.count {Number} Number of deleted Records.
+     */
 
     /**
      * Fired when a row is selected.
@@ -7634,13 +14486,13 @@
      * @param oArgs.record {YAHOO.widget.Record} The unselected Record.
      */
 
-    /*TODO: delete and use rowUnselectEvent?
+    /**
      * Fired when all row selections are cleared.
      *
      * @event unselectAllRowsEvent
      */
 
-    /*
+    /**
      * Fired when a row is highlighted.
      *
      * @event rowHighlightEvent
@@ -7648,7 +14500,7 @@
      * @param oArgs.record {YAHOO.widget.Record} The highlighted Record.
      */
 
-    /*
+    /**
      * Fired when a row is unhighlighted.
      *
      * @event rowUnhighlightEvent
@@ -7749,19 +14601,12 @@
 
      */
 
-    /*TODO: hide from doc and use cellUnselectEvent
+    /**
      * Fired when all cell selections are cleared.
      *
      * @event unselectAllCellsEvent
      */
 
-    /*TODO: implement
-     * Fired when DataTable paginator is updated.
-     *
-     * @event paginatorUpdateEvent
-     * @param paginator {Object} Object literal of Paginator values.
-     */
-
     /**
      * Fired when an Editor is activated.
      *
@@ -7782,7 +14627,7 @@
      *
      * @event editorRevertEvent
      * @param oArgs.editor {Object} The Editor object literal.
-     * @param oArgs.newData {Object} New data value.
+     * @param oArgs.newData {Object} New data value from form input field.
      * @param oArgs.oldData {Object} Old data value.
      */
 
@@ -7791,7 +14636,7 @@
      *
      * @event editorSaveEvent
      * @param oArgs.editor {Object} The Editor object literal.
-     * @param oArgs.newData {Object} New data value.
+     * @param oArgs.newData {Object} New data value from form input field.
      * @param oArgs.oldData {Object} Old data value.
      */
 
@@ -7856,1507 +14701,478 @@
      */
 
 
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
 
-/**
- * The ColumnSet class defines and manages a DataTable's Columns,
- * including nested hierarchies and access to individual Column instances.
- *
- * @namespace YAHOO.widget
- * @class ColumnSet
- * @uses YAHOO.util.EventProvider
- * @constructor
- * @param aHeaders {Object[]} Array of object literals that define header cells.
- */
-YAHOO.widget.ColumnSet = function(aHeaders) {
-    this._sName = "instance" + YAHOO.widget.ColumnSet._nCount;
 
-    // DOM tree representation of all Columns
-    var tree = [];
-    // Flat representation of all Columns
-    var flat = [];
-    // Flat representation of only Columns that are meant to display data
-    var keys = [];
-    // Array of HEADERS attribute values for all keys in the "keys" array
-    var headers = [];
 
-    // Tracks current node list depth being tracked
-    var nodeDepth = -1;
 
-    // Internal recursive function to defined Column instances
-    var oSelf = this;
-    var parseColumns = function(nodeList, parent) {
-        // One level down
-        nodeDepth++;
 
-        // Create corresponding tree node if not already there for this depth
-        if(!tree[nodeDepth]) {
-            tree[nodeDepth] = [];
-        }
 
 
-        // Parse each node at this depth for attributes and any children
-        for(var j=0; j<nodeList.length; j++) {
-            var currentNode = nodeList[j];
 
-            // Instantiate a new Column for each node
-            var oColumn = new YAHOO.widget.Column(currentNode);
-            oColumn._sId = YAHOO.widget.Column._nCount + "";
-            oColumn._sName = "Column instance" + YAHOO.widget.Column._nCount;
-            // Assign a key if not found
-            if(!YAHOO.lang.isValue(oColumn.key)) {
-                oColumn.key = "yui-dt-col" + YAHOO.widget.Column._nCount;
-            }
-            // Increment counter
-            YAHOO.widget.Column._nCount++;
 
-            // Add the new Column to the flat list
-            flat.push(oColumn);
 
-            // Assign its parent as an attribute, if applicable
-            if(parent) {
-                oColumn.parent = parent;
-            }
 
-            // The Column has descendants
-            if(YAHOO.lang.isArray(currentNode.children)) {
-                oColumn.children = currentNode.children;
 
-                // Determine COLSPAN value for this Column
-                var terminalChildNodes = 0;
-                var countTerminalChildNodes = function(ancestor) {
-                    var descendants = ancestor.children;
-                    // Drill down each branch and count terminal nodes
-                    for(var k=0; k<descendants.length; k++) {
-                        // Keep drilling down
-                        if(YAHOO.lang.isArray(descendants[k].children)) {
-                            countTerminalChildNodes(descendants[k]);
-                        }
-                        // Reached branch terminus
-                        else {
-                            terminalChildNodes++;
-                        }
-                    }
-                };
-                countTerminalChildNodes(currentNode);
-                oColumn._colspan = terminalChildNodes;
 
-                // Cascade certain properties to children if not defined on their own
-                var currentChildren = currentNode.children;
-                for(var k=0; k<currentChildren.length; k++) {
-                    var child = currentChildren[k];
-                    if(oColumn.className && (child.className === undefined)) {
-                        child.className = oColumn.className;
-                    }
-                    if(oColumn.editor && (child.editor === undefined)) {
-                        child.editor = oColumn.editor;
-                    }
-                    if(oColumn.editorOptions && (child.editorOptions === undefined)) {
-                        child.editorOptions = oColumn.editorOptions;
-                    }
-                    if(oColumn.formatter && (child.formatter === undefined)) {
-                        child.formatter = oColumn.formatter;
-                    }
-                    if(oColumn.resizeable && (child.resizeable === undefined)) {
-                        child.resizeable = oColumn.resizeable;
-                    }
-                    if(oColumn.sortable && (child.sortable === undefined)) {
-                        child.sortable = oColumn.sortable;
-                    }
-                    if(oColumn.width && (child.width === undefined)) {
-                        child.width = oColumn.width;
-                    }
-                    // Backward compatibility
-                    if(oColumn.type && (child.type === undefined)) {
-                        child.type = oColumn.type;
-                    }
-                    if(oColumn.type && !oColumn.formatter) {
-                        oColumn.formatter = oColumn.type;
-                    }
-                    if(oColumn.text && !YAHOO.lang.isValue(oColumn.label)) {
-                        oColumn.label = oColumn.text;
-                    }
-                    if(oColumn.parser) {
-                    }
-                    if(oColumn.sortOptions && ((oColumn.sortOptions.ascFunction) ||
-                            (oColumn.sortOptions.descFunction))) {
-                    }
-                }
 
-                // The children themselves must also be parsed for Column instances
-                if(!tree[nodeDepth+1]) {
-                    tree[nodeDepth+1] = [];
-                }
-                parseColumns(currentChildren, oColumn);
-            }
-            // This Column does not have any children
-            else {
-                oColumn._nKeyIndex = keys.length;
-                oColumn._colspan = 1;
-                keys.push(oColumn);
-            }
 
-            // Add the Column to the top-down tree
-            tree[nodeDepth].push(oColumn);
-        }
-        nodeDepth--;
-    };
 
-    // Parse out Column instances from the array of object literals
-    if(YAHOO.lang.isArray(aHeaders)) {
-        parseColumns(aHeaders);
-    }
 
-    // Determine ROWSPAN value for each Column in the tree
-    var parseTreeForRowspan = function(tree) {
-        var maxRowDepth = 1;
-        var currentRow;
-        var currentColumn;
 
-        // Calculate the max depth of descendants for this row
-        var countMaxRowDepth = function(row, tmpRowDepth) {
-            tmpRowDepth = tmpRowDepth || 1;
 
-            for(var n=0; n<row.length; n++) {
-                var col = row[n];
-                // Column has children, so keep counting
-                if(YAHOO.lang.isArray(col.children)) {
-                    tmpRowDepth++;
-                    countMaxRowDepth(col.children, tmpRowDepth);
-                    tmpRowDepth--;
-                }
-                // No children, is it the max depth?
-                else {
-                    if(tmpRowDepth > maxRowDepth) {
-                        maxRowDepth = tmpRowDepth;
-                    }
-                }
 
-            }
-        };
 
-        // Count max row depth for each row
-        for(var m=0; m<tree.length; m++) {
-            currentRow = tree[m];
-            countMaxRowDepth(currentRow);
 
-            // Assign the right ROWSPAN values to each Column in the row
-            for(var p=0; p<currentRow.length; p++) {
-                currentColumn = currentRow[p];
-                if(!YAHOO.lang.isArray(currentColumn.children)) {
-                    currentColumn._rowspan = maxRowDepth;
-                }
-                else {
-                    currentColumn._rowspan = 1;
-                }
-            }
 
-            // Reset counter for next row
-            maxRowDepth = 1;
-        }
-    };
-    parseTreeForRowspan(tree);
 
-
-
-
-
-    // Store header relationships in an array for HEADERS attribute
-    var recurseAncestorsForHeaders = function(i, oColumn) {
-        headers[i].push(oColumn._sId);
-        if(oColumn.parent) {
-            recurseAncestorsForHeaders(i, oColumn.parent);
-        }
-    };
-    for(var i=0; i<keys.length; i++) {
-        headers[i] = [];
-        recurseAncestorsForHeaders(i, keys[i]);
-        headers[i] = headers[i].reverse();
-    }
-
-    // Save to the ColumnSet instance
-    this.tree = tree;
-    this.flat = flat;
-    this.keys = keys;
-    this.headers = headers;
-
-    YAHOO.widget.ColumnSet._nCount++;
-};
-
 /////////////////////////////////////////////////////////////////////////////
 //
-// Public member variables
+// Deprecated APIs
 //
 /////////////////////////////////////////////////////////////////////////////
 
 /**
- * Internal class variable to index multiple ColumnSet instances.
- *
- * @property ColumnSet._nCount
- * @type Number
- * @private
- * @static
+ * @method getBody
+ * @deprecated Use getTbodyEl().
  */
-YAHOO.widget.ColumnSet._nCount = 0;
+getBody : function() {
+    // Backward compatibility
+    return this.getTbodyEl();
+},
 
 /**
- * Unique instance name.
- *
- * @property _sName
- * @type String
- * @private
+ * @method getCell
+ * @deprecated Use getTdEl().
  */
-YAHOO.widget.ColumnSet.prototype._sName = null;
+getCell : function(index) {
+    // Backward compatibility
+    return this.getTdEl(index);
+},
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public member variables
-//
-/////////////////////////////////////////////////////////////////////////////
-
 /**
- * Top-down tree representation of Column hierarchy.
- *
- * @property tree
- * @type YAHOO.widget.Column[]
+ * @method getRow
+ * @deprecated Use getTrEl().
  */
-YAHOO.widget.ColumnSet.prototype.tree = null;
+getRow : function(index) {
+    // Backward compatibility
+    return this.getTrEl(index);
+},
 
 /**
- * Flattened representation of all Columns.
- *
- * @property flat
- * @type YAHOO.widget.Column[]
- * @default []
+ * @method refreshView
+ * @deprecated Use render.
  */
-YAHOO.widget.ColumnSet.prototype.flat = null;
+refreshView : function() {
+    // Backward compatibility
+    this.render();
+},
 
 /**
- * Array of Columns that map one-to-one to a table column.
- *
- * @property keys
- * @type YAHOO.widget.Column[]
- * @default []
+ * @method select
+ * @deprecated Use selectRow.
  */
-YAHOO.widget.ColumnSet.prototype.keys = null;
+select : function(els) {
+    // Backward compatibility
+    if(!lang.isArray(els)) {
+        els = [els];
+    }
+    for(var i=0; i<els.length; i++) {
+        this.selectRow(els[i]);
+    }
+},
 
 /**
- * ID index of nested parent hierarchies for HEADERS accessibility attribute.
- *
- * @property headers
- * @type String[]
- * @default []
+ * @method updatePaginator
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.widget.ColumnSet.prototype.headers = null;
+updatePaginator : function(oNewValues) {
+    // Complete the set (default if not present)
+    var oValidPaginator = this.get("paginator");
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public methods
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Public accessor to the unique name of the ColumnSet instance.
- *
- * @method toString
- * @return {String} Unique name of the ColumnSet instance.
- */
-
-YAHOO.widget.ColumnSet.prototype.toString = function() {
-    return "ColumnSet " + this._sName;
-};
-
-/**
- * Returns Column instance with given ID.
- *
- * @method getColumnById
- * @param column {String} Column ID.
- * @return {YAHOO.widget.Column} Column instance.
- */
-
-YAHOO.widget.ColumnSet.prototype.getColumnById = function(column) {
-    if(YAHOO.lang.isString(column)) {
-        var allColumns = this.flat;
-        for(var i=allColumns.length-1; i>-1; i--) {
-            if(allColumns[i]._sId === column) {
-                return allColumns[i];
-            }
+    var nOrigCurrentPage = oValidPaginator.currentPage;
+    for(var param in oNewValues) {
+        if(lang.hasOwnProperty(oValidPaginator, param)) {
+            oValidPaginator[param] = oNewValues[param];
         }
     }
-    return null;
-};
 
-/**
- * Returns Column instance with given key or ColumnSet key index.
- *
- * @method getColumn
- * @param column {String | Number} Column key or ColumnSet key index.
- * @return {YAHOO.widget.Column} Column instance.
- */
-
-YAHOO.widget.ColumnSet.prototype.getColumn = function(column) {
-    if(YAHOO.lang.isNumber(column) && this.keys[column]) {
-        return this.keys[column];
+    oValidPaginator.totalRecords = this._oRecordSet.getLength();
+    oValidPaginator.rowsThisPage = Math.min(oValidPaginator.rowsPerPage, oValidPaginator.totalRecords);
+    oValidPaginator.totalPages = Math.ceil(oValidPaginator.totalRecords / oValidPaginator.rowsThisPage);
+    if(isNaN(oValidPaginator.totalPages)) {
+        oValidPaginator.totalPages = 0;
     }
-    else if(YAHOO.lang.isString(column)) {
-        var allColumns = this.flat;
-        var aColumns = [];
-        for(var i=0; i<allColumns.length; i++) {
-            if(allColumns[i].key === column) {
-                aColumns.push(allColumns[i]);
-            }
+    if(oValidPaginator.currentPage > oValidPaginator.totalPages) {
+        if(oValidPaginator.totalPages < 1) {
+            oValidPaginator.currentPage = 1;
         }
-        if(aColumns.length === 1) {
-            return aColumns[0];
+        else {
+            oValidPaginator.currentPage = oValidPaginator.totalPages;
         }
-        else if(aColumns.length > 1) {
-            return aColumns;
-        }
     }
-    return null;
-};
 
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
+    if(oValidPaginator.currentPage !== nOrigCurrentPage) {
+        oValidPaginator.startRecordIndex = (oValidPaginator.currentPage-1)*oValidPaginator.rowsPerPage;
+    }
 
+
+    this.set("paginator", oValidPaginator);
+    return this.get("paginator");
+},
+
 /**
- * The Column class defines and manages attributes of DataTable Columns
- *
- * @namespace YAHOO.widget
- * @class Column
- * @constructor
- * @param oConfigs {Object} Object literal of configuration values.
+ * @method showPage
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.widget.Column = function(oConfigs) {
-    // Object literal defines Column attributes
-    if(oConfigs && (oConfigs.constructor == Object)) {
-        for(var sConfig in oConfigs) {
-            if(sConfig) {
-                this[sConfig] = oConfigs[sConfig];
+showPage : function(nPage) {
+    var oPaginator = this.get('paginator');
+    // Validate input
+    if(!lang.isNumber(nPage) || (nPage < 1)) {
+        if (oPaginator instanceof Pag) {
+            if (!oPaginator.hasPage(nPage)) {
+                nPage = 1;
             }
+        } else if (nPage > oPaginator.totalPages) {
+            nPage = 1;
         }
     }
-};
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Private member variables
-//
-/////////////////////////////////////////////////////////////////////////////
+    if (oPaginator instanceof Pag) {
+        oPaginator.setPage(nPage);
+    } else {
+        this.updatePaginator({currentPage:nPage});
+        this.render();
+    }
+},
 
 /**
- * Internal class variable to index multiple Column instances.
- *
- * @property Column._nCount
- * @type Number
- * @private
- * @static
+ * @method formatPaginators
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.widget.Column._nCount = 0;
+formatPaginators : function() {
+    var pag = this.get("paginator");
+    if (pag instanceof Pag) {
+        pag.update();
+        return;
+    }
 
-/**
- * Unique instance name.
- *
- * @property _sName
- * @type String
- * @private
- */
-YAHOO.widget.Column.prototype._sName = null;
+    var i;
 
-/**
- * Unique String identifier assigned at instantiation.
- *
- * @property _sId
- * @type String
- * @private
- */
-YAHOO.widget.Column.prototype._sId = null;
+    // For Opera workaround
+    var dropdownEnabled = false;
 
-/**
- * Reference to Column's current position index within its ColumnSet's keys array, if applicable.
- *
- * @property _nKeyIndex
- * @type Number
- * @private
- */
-YAHOO.widget.Column.prototype._nKeyIndex = null;
+    // Links are enabled
+    if(pag.pageLinks > -1) {
+        for(i=0; i<pag.links.length; i++) {
+            this.formatPaginatorLinks(pag.links[i], pag.currentPage, pag.pageLinksStart, pag.pageLinks, pag.totalPages);
+        }
+    }
 
-/**
- * Number of table cells the Column spans.
- *
- * @property _colspan
- * @type Number
- * @private
- */
-YAHOO.widget.Column.prototype._colspan = 1;
+    // Dropdown is enabled
+    for(i=0; i<pag.dropdowns.length; i++) {
+         if(pag.dropdownOptions) {
+            dropdownEnabled = true;
+            this.formatPaginatorDropdown(pag.dropdowns[i], pag.dropdownOptions);
+        }
+        else {
+            pag.dropdowns[i].style.display = "none";
+        }
+    }
 
-/**
- * Number of table rows the Column spans.
- *
- * @property _rowspan
- * @type Number
- * @private
- */
-YAHOO.widget.Column.prototype._rowspan = 1;
+    // For Opera artifacting in dropdowns
+    if(dropdownEnabled && ua.opera) {
+        document.body.style += '';
+    }
+},
 
 /**
- * Column's parent Column instance, or null.
- *
- * @property _parent
- * @type YAHOO.widget.Column
- * @private
+ * @method formatPaginatorDropdown
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.widget.Column.prototype._parent = null;
+formatPaginatorDropdown : function(elDropdown, dropdownOptions) {
+    if(elDropdown && (elDropdown.ownerDocument == document)) {
+        // Clear OPTION elements
+        while (elDropdown.firstChild) {
+            elDropdown.removeChild(elDropdown.firstChild);
+        }
 
-/**
- * Current offsetWidth of the Column (in pixels).
- *
- * @property _width
- * @type Number
- * @private
- */
-YAHOO.widget.Column.prototype._width = null;
+        // Create OPTION elements
+        for(var j=0; j<dropdownOptions.length; j++) {
+            var dropdownOption = dropdownOptions[j];
+            var optionEl = document.createElement("option");
+            optionEl.value = (lang.isValue(dropdownOption.value)) ?
+                    dropdownOption.value : dropdownOption;
+            optionEl.innerHTML = (lang.isValue(dropdownOption.text)) ?
+                    dropdownOption.text : dropdownOption;
+            optionEl = elDropdown.appendChild(optionEl);
+        }
 
-/**
- * Minimum width the Column can support (in pixels). Value is populated only if table
- * is fixedWidth, null otherwise.
- *
- * @property _minWidth
- * @type Number
- * @private
- */
-YAHOO.widget.Column.prototype._minWidth = null;
+        var options = elDropdown.options;
+        // Update dropdown's "selected" value
+        if(options.length) {
+            for(var i=options.length-1; i>-1; i--) {
+                if((this.get("paginator").rowsPerPage + "") === options[i].value) {
+                    options[i].selected = true;
+                }
+            }
+        }
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public member variables
-//
-/////////////////////////////////////////////////////////////////////////////
+        // Show the dropdown
+        elDropdown.style.display = "";
+        return;
+    }
+},
 
 /**
- * Associated database field, or null.
- *
- * @property key
- * @type String
+ * @method formatPaginatorLinks
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.widget.Column.prototype.key = null;
+formatPaginatorLinks : function(elContainer, nCurrentPage, nPageLinksStart, nPageLinksLength, nTotalPages) {
+    if(elContainer && (elContainer.ownerDocument == document) &&
+            lang.isNumber(nCurrentPage) && lang.isNumber(nPageLinksStart) &&
+            lang.isNumber(nTotalPages)) {
+        // Set up markup for first/last/previous/next
+        var bIsFirstPage = (nCurrentPage == 1) ? true : false;
+        var bIsLastPage = (nCurrentPage == nTotalPages) ? true : false;
+        var sFirstLinkMarkup = (bIsFirstPage) ?
+                " <span class=\"" + DT.CLASS_DISABLED +
+                " " + DT.CLASS_FIRST + "\"><<</span> " :
+                " <a href=\"#\" class=\"" + DT.CLASS_FIRST + "\"><<</a> ";
+        var sPrevLinkMarkup = (bIsFirstPage) ?
+                " <span class=\"" + DT.CLASS_DISABLED +
+                " " + DT.CLASS_PREVIOUS + "\"><</span> " :
+                " <a href=\"#\" class=\"" + DT.CLASS_PREVIOUS + "\"><</a> " ;
+        var sNextLinkMarkup = (bIsLastPage) ?
+                " <span class=\"" + DT.CLASS_DISABLED +
+                " " + DT.CLASS_NEXT + "\">></span> " :
+                " <a href=\"#\" class=\"" + DT.CLASS_NEXT + "\">></a> " ;
+        var sLastLinkMarkup = (bIsLastPage) ?
+                " <span class=\"" + DT.CLASS_DISABLED +
+                " " + DT.CLASS_LAST +  "\">>></span> " :
+                " <a href=\"#\" class=\"" + DT.CLASS_LAST + "\">>></a> ";
 
-/**
- * Text or HTML for display as Column's label in the TH element.
- *
- * @property label
- * @type String
- */
-YAHOO.widget.Column.prototype.label = null;
+        // Start with first and previous
+        var sMarkup = sFirstLinkMarkup + sPrevLinkMarkup;
 
-/**
- * Column head cell ABBR for accessibility.
- *
- * @property abbr
- * @type String
- */
-YAHOO.widget.Column.prototype.abbr = null;
+        // Ok to show all links
+        var nMaxLinks = nTotalPages;
+        var nFirstLink = 1;
+        var nLastLink = nTotalPages;
 
-/**
- * Array of object literals that define children (nested headers) of a Column.
- *
- * @property children
- * @type Object[]
- */
-YAHOO.widget.Column.prototype.children = null;
+        if(nPageLinksLength > 0) {
+        // Calculate how many links to show
+            nMaxLinks = (nPageLinksStart+nPageLinksLength < nTotalPages) ?
+                    nPageLinksStart+nPageLinksLength-1 : nTotalPages;
 
-/**
- * Column width.
- *
- * @property width
- * @type String
- */
-YAHOO.widget.Column.prototype.width = null;
+            // Try to keep the current page in the middle
+            nFirstLink = (nCurrentPage - Math.floor(nMaxLinks/2) > 0) ? nCurrentPage - Math.floor(nMaxLinks/2) : 1;
+            nLastLink = (nCurrentPage + Math.floor(nMaxLinks/2) <= nTotalPages) ? nCurrentPage + Math.floor(nMaxLinks/2) : nTotalPages;
 
-/**
- * Custom CSS class or array of classes to be applied to every cell in the Column.
- *
- * @property className
- * @type String || String[]
- */
-YAHOO.widget.Column.prototype.className = null;
+            // Keep the last link in range
+            if(nFirstLink === 1) {
+                nLastLink = nMaxLinks;
+            }
+            // Keep the first link in range
+            else if(nLastLink === nTotalPages) {
+                nFirstLink = nTotalPages - nMaxLinks + 1;
+            }
 
-/**
- * Defines a format function.
- *
- * @property formatter
- * @type String || HTMLFunction
- */
-YAHOO.widget.Column.prototype.formatter = null;
+            // An even number of links can get funky
+            if(nLastLink - nFirstLink === nMaxLinks) {
+                nLastLink--;
+            }
+      }
 
-/**
- * Defines an editor function, otherwise Column is not editable.
- *
- * @property editor
- * @type String || HTMLFunction
- */
-YAHOO.widget.Column.prototype.editor = null;
-
-/**
- * Defines editor options for Column in an object literal of param:value pairs.
- *
- * @property editorOptions
- * @type Object
- */
-YAHOO.widget.Column.prototype.editorOptions = null;
-
-/**
- * True if Column is resizeable, false otherwise.
- *
- * @property resizeable
- * @type Boolean
- * @default false
- */
-YAHOO.widget.Column.prototype.resizeable = false;
-
-/**
- * True if Column is sortable, false otherwise.
- *
- * @property sortable
- * @type Boolean
- * @default false
- */
-YAHOO.widget.Column.prototype.sortable = false;
-
-/**
- * Default sort order for Column: "asc" or "desc".
- *
- * @property sortOptions.defaultOrder
- * @type String
- * @default null
- */
-/**
- * Custom sort handler.
- *
- * @property sortOptions.sortFunction
- * @type Function
- * @default null
- */
-YAHOO.widget.Column.prototype.sortOptions = null;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public methods
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Public accessor to the unique name of the Column instance.
- *
- * @method toString
- * @return {String} Column's unique name.
- */
-YAHOO.widget.Column.prototype.toString = function() {
-    return this._sName;
-};
-
-/**
- * Returns unique ID string.
- *
- * @method getId
- * @return {String} Unique ID string.
- */
-YAHOO.widget.Column.prototype.getId = function() {
-    return this._sId;
-};
-
-/**
- * Returns unique Column key.
- *
- * @method getKey
- * @return {String} Column key.
- */
-YAHOO.widget.Column.prototype.getKey = function() {
-    return this.key;
-};
-
-/**
- * Public accessor returns Column's current position index within its ColumnSet's keys array, if applicable.
- *
- * @method getKeyIndex
- * @return {Number} Position index, or null.
- */
-YAHOO.widget.Column.prototype.getKeyIndex = function() {
-    return this._nKeyIndex;
-};
-
-/**
- * Public accessor returns Column's parent instance if any, or null otherwise.
- *
- * @method getParent
- * @return {YAHOO.widget.Column} Column's parent instance.
- */
-YAHOO.widget.Column.prototype.getParent = function() {
-    return this._parent;
-};
-
-/**
- * Public accessor returns Column's calculated COLSPAN value.
- *
- * @method getColspan
- * @return {Number} Column's COLSPAN value.
- */
-YAHOO.widget.Column.prototype.getColspan = function() {
-    return this._colspan;
-};
-// Backward compatibility
-YAHOO.widget.Column.prototype.getColSpan = function() {
-    return this.getColspan();
-};
-
-/**
- * Public accessor returns Column's calculated ROWSPAN value.
- *
- * @method getRowspan
- * @return {Number} Column's ROWSPAN value.
- */
-YAHOO.widget.Column.prototype.getRowspan = function() {
-    return this._rowspan;
-};
-
-// Backward compatibility
-YAHOO.widget.Column.prototype.getIndex = function() {
-    return this.getKeyIndex();
-};
-YAHOO.widget.Column.prototype.format = function() {
-};
-YAHOO.widget.Column.formatCheckbox = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.widget.DataTable.formatCheckbox(elCell, oRecord, oColumn, oData);
-};
-YAHOO.widget.Column.formatCurrency = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.widget.DataTable.formatCurrency(elCell, oRecord, oColumn, oData);
-};
-YAHOO.widget.Column.formatDate = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.widget.DataTable.formatDate(elCell, oRecord, oColumn, oData);
-};
-YAHOO.widget.Column.formatEmail = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.widget.DataTable.formatEmail(elCell, oRecord, oColumn, oData);
-};
-YAHOO.widget.Column.formatLink = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.widget.DataTable.formatLink(elCell, oRecord, oColumn, oData);
-};
-YAHOO.widget.Column.formatNumber = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.widget.DataTable.formatNumber(elCell, oRecord, oColumn, oData);
-};
-YAHOO.widget.Column.formatSelect = function(elCell, oRecord, oColumn, oData) {
-    YAHOO.widget.DataTable.formatDropdown(elCell, oRecord, oColumn, oData);
-};
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
-/**
- * Sort static utility to support Column sorting.
- *
- * @namespace YAHOO.util
- * @class Sort
- * @static
- */
-YAHOO.util.Sort = {
-    /////////////////////////////////////////////////////////////////////////////
-    //
-    // Public methods
-    //
-    /////////////////////////////////////////////////////////////////////////////
-
-    /**
-     * Comparator function for simple case-insensitive string sorting.
-     *
-     * @method compare
-     * @param a {Object} First sort argument.
-     * @param b {Object} Second sort argument.
-     * @param desc {Boolean} True if sort direction is descending, false if
-     * sort direction is ascending.
-     */
-    compare: function(a, b, desc) {
-        if((a === null) || (typeof a == "undefined")) {
-            if((b === null) || (typeof b == "undefined")) {
-                return 0;
+        // Generate markup for each page
+        for(var i=nFirstLink; i<=nLastLink; i++) {
+            if(i != nCurrentPage) {
+                sMarkup += " <a href=\"#\" class=\"" + DT.CLASS_PAGE + "\">" + i + "</a> ";
             }
             else {
-                return 1;
+                sMarkup += " <span class=\"" + DT.CLASS_SELECTED + "\">" + i + "</span>";
             }
         }
-        else if((b === null) || (typeof b == "undefined")) {
-            return -1;
-        }
-
-        if(a.constructor == String) {
-            a = a.toLowerCase();
-        }
-        if(b.constructor == String) {
-            b = b.toLowerCase();
-        }
-        if(a < b) {
-            return (desc) ? 1 : -1;
-        }
-        else if (a > b) {
-            return (desc) ? -1 : 1;
-        }
-        else {
-            return 0;
-        }
+        sMarkup += sNextLinkMarkup + sLastLinkMarkup;
+        elContainer.innerHTML = sMarkup;
+        return;
     }
-};
+},
 
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
 /**
- * ColumnResizer subclasses DragDrop to support resizeable Columns.
- *
- * @namespace YAHOO.util
- * @class ColumnResizer
- * @extends YAHOO.util.DragDrop
- * @constructor
- * @param oDataTable {YAHOO.widget.DataTable} DataTable instance.
- * @param oColumn {YAHOO.widget.Column} Column instance.
- * @param elThead {HTMLElement} TH element reference.
- * @param sHandleElId {String} DOM ID of the handle element that causes the resize.
- * @param sGroup {String} Group name of related DragDrop items.
- * @param oConfig {Object} (Optional) Object literal of config values.
+ * @method _onPaginatorLinkClick
+ * @private
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.util.ColumnResizer = function(oDataTable, oColumn, elThead, sHandleId, sGroup, oConfig) {
-    if(oDataTable && oColumn && elThead && sHandleId) {
-        this.datatable = oDataTable;
-        this.column = oColumn;
-        this.cell = elThead;
-        this.init(sHandleId, sGroup, oConfig);
-        //this.initFrame();
-        this.setYConstraint(0,0);
-    }
-    else {
-    }
-};
+_onPaginatorLinkClick : function(e, oSelf) {
+    // Backward compatibility
+    var elTarget = Ev.getTarget(e);
+    var elTag = elTarget.nodeName.toLowerCase();
 
-if(YAHOO.util.DD) {
-    YAHOO.extend(YAHOO.util.ColumnResizer, YAHOO.util.DD);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public DOM event handlers
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Handles mousedown events on the Column resizer.
- *
- * @method onMouseDown
- * @param e {string} The mousedown event
- */
-YAHOO.util.ColumnResizer.prototype.onMouseDown = function(e) {
-    this.startWidth = this.cell.offsetWidth;
-    this.startPos = YAHOO.util.Dom.getX(this.getDragEl());
-
-    if(this.datatable.fixedWidth) {
-        var cellLabel = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_LABEL,"span",this.cell)[0];
-        this.minWidth = cellLabel.offsetWidth + 6;
-        var sib = this.cell.nextSibling;
-        var sibCellLabel = YAHOO.util.Dom.getElementsByClassName(YAHOO.widget.DataTable.CLASS_LABEL,"span",sib)[0];
-        this.sibMinWidth = sibCellLabel.offsetWidth + 6;
-//!!
-        var left = ((this.startWidth - this.minWidth) < 0) ? 0 : (this.startWidth - this.minWidth);
-        var right = ((sib.offsetWidth - this.sibMinWidth) < 0) ? 0 : (sib.offsetWidth - this.sibMinWidth);
-        this.setXConstraint(left, right);
+    if(oSelf._oCellEditor && oSelf._oCellEditor.isActive) {
+        oSelf.fireEvent("editorBlurEvent", {editor:oSelf._oCellEditor});
     }
 
-};
-
-/**
- * Handles mouseup events on the Column resizer.
- *
- * @method onMouseUp
- * @param e {string} The mouseup event
- */
-YAHOO.util.ColumnResizer.prototype.onMouseUp = function(e) {
-    //TODO: replace the resizer where it belongs:
-    var resizeStyle = YAHOO.util.Dom.get(this.handleElId).style;
-    resizeStyle.left = "auto";
-    resizeStyle.right = 0;
-    resizeStyle.marginRight = "-6px";
-    resizeStyle.width = "6px";
-    //.yui-dt-headresizer {position:absolute;margin-right:-6px;right:0;bottom:0;width:6px;height:100%;cursor:w-resize;cursor:col-resize;}
-
-
-    //var cells = this.datatable._elTable.tHead.rows[this.datatable._elTable.tHead.rows.length-1].cells;
-    //for(var i=0; i<cells.length; i++) {
-        //cells[i].style.width = "5px";
-    //}
-
-    //TODO: set new ColumnSet width values
-    this.datatable.fireEvent("columnResizeEvent", {column:this.column,target:this.cell});
-};
-
-/**
- * Handles drag events on the Column resizer.
- *
- * @method onDrag
- * @param e {string} The drag event
- */
-YAHOO.util.ColumnResizer.prototype.onDrag = function(e) {
-    try {
-        var newPos = YAHOO.util.Dom.getX(this.getDragEl());
-        var offsetX = newPos - this.startPos;
-        var newWidth = this.startWidth + offsetX;
-
-        if(newWidth < this.minWidth) {
-            newWidth = this.minWidth;
+    while(elTarget && (elTag != "table")) {
+        switch(elTag) {
+            case "body":
+                return;
+            case "a":
+                Ev.stopEvent(e);
+                //TODO: after the showPage call, figure out which link
+                //TODO: was clicked and reset focus to the new version of it
+                //TODO: support multiple custom classnames
+                switch(elTarget.className) {
+                    case DT.CLASS_PAGE:
+                        oSelf.showPage(parseInt(elTarget.innerHTML,10));
+                        return;
+                    case DT.CLASS_FIRST:
+                        oSelf.showPage(1);
+                        return;
+                    case DT.CLASS_LAST:
+                        oSelf.showPage(oSelf.get("paginator").totalPages);
+                        return;
+                    case DT.CLASS_PREVIOUS:
+                        oSelf.showPage(oSelf.get("paginator").currentPage - 1);
+                        return;
+                    case DT.CLASS_NEXT:
+                        oSelf.showPage(oSelf.get("paginator").currentPage + 1);
+                        return;
+                }
+                break;
+            default:
+                return;
         }
-
-        // Resize the Column
-        var oDataTable = this.datatable;
-        var elCell = this.cell;
-
-
-        // Resize the other Columns
-        if(oDataTable.fixedWidth) {
-            // Moving right or left?
-            var sib = elCell.nextSibling;
-            //var sibIndex = elCell.index + 1;
-            var sibnewwidth = sib.offsetWidth - offsetX;
-            if(sibnewwidth < this.sibMinWidth) {
-                sibnewwidth = this.sibMinWidth;
-            }
-
-            //TODO: how else to cycle through all the Columns without having to use an index property?
-            for(var i=0; i<oDataTable._oColumnSet.length; i++) {
-                //if((i != elCell.index) &&  (i!=sibIndex)) {
-                //    YAHOO.util.Dom.get(oDataTable._oColumnSet.keys[i].id).style.width = oDataTable._oColumnSet.keys[i].width + "px";
-                //}
-            }
-            sib.style.width = sibnewwidth;
-            elCell.style.width = newWidth + "px";
-            //oDataTable._oColumnSet.flat[sibIndex].width = sibnewwidth;
-            //oDataTable._oColumnSet.flat[elCell.index].width = newWidth;
-
+        elTarget = elTarget.parentNode;
+        if(elTarget) {
+            elTag = elTarget.nodeName.toLowerCase();
         }
         else {
-            elCell.style.width = newWidth + "px";
+            return;
         }
     }
-    catch(e) {
-    }
-};
+},
 
-
-
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
 /**
- * A RecordSet defines and manages a set of Records.
- *
- * @namespace YAHOO.widget
- * @class RecordSet
- * @param data {Object || Object[]} An object literal or an array of data.
- * @constructor
- */
-YAHOO.widget.RecordSet = function(data) {
-    // Internal variables
-    this._sName = "RecordSet instance" + YAHOO.widget.RecordSet._nCount;
-    YAHOO.widget.RecordSet._nCount++;
-    this._records = [];
-    this._length = 0;
-    
-    if(data) {
-        if(YAHOO.lang.isArray(data)) {
-            this.addRecords(data);
-        }
-        else if(data.constructor == Object) {
-            this.addRecord(data);
-        }
-    }
-
-    /**
-     * Fired when a new Record is added to the RecordSet.
-     *
-     * @event recordAddEvent
-     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
-     * @param oArgs.data {Object} Data added.
-     */
-    this.createEvent("recordAddEvent");
-
-    /**
-     * Fired when multiple Records are added to the RecordSet at once.
-     *
-     * @event recordsAddEvent
-     * @param oArgs.records {YAHOO.widget.Record[]} An array of Record instances.
-     * @param oArgs.data {Object[]} Data added.
-     */
-    this.createEvent("recordsAddEvent");
-
-    /**
-     * Fired when a Record is updated with new data.
-     *
-     * @event recordUpdateEvent
-     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
-     * @param oArgs.newData {Object} New data.
-     * @param oArgs.oldData {Object} Old data.
-     */
-    this.createEvent("recordUpdateEvent");
-    
-    /**
-     * Fired when a Record is deleted from the RecordSet.
-     *
-     * @event recordDeleteEvent
-     * @param oArgs.data {Object} A copy of the data held by the Record,
-     * or an array of data object literals if multiple Records were deleted at once.
-     * @param oArgs.index {Object} Index of the deleted Record.
-     */
-    this.createEvent("recordDeleteEvent");
-
-    /**
-     * Fired when multiple Records are deleted from the RecordSet at once.
-     *
-     * @event recordsDeleteEvent
-     * @param oArgs.data {Object[]} An array of data object literals copied
-     * from the Records.
-     * @param oArgs.index {Object} Index of the first deleted Record.
-     */
-    this.createEvent("recordsDeleteEvent");
-    
-    /**
-     * Fired when all Records are deleted from the RecordSet at once.
-     *
-     * @event resetEvent
-     */
-    this.createEvent("resetEvent");
-
-    /**
-     * Fired when a Record Key is updated with new data.
-     *
-     * @event keyUpdateEvent
-     * @param oArgs.record {YAHOO.widget.Record} The Record instance.
-     * @param oArgs.key {String} The updated key.
-     * @param oArgs.newData {Object} New data.
-     * @param oArgs.oldData {Object} Old data.
-     *
-     */
-    this.createEvent("keyUpdateEvent");
-
-};
-
-if(YAHOO.util.EventProvider) {
-    YAHOO.augment(YAHOO.widget.RecordSet, YAHOO.util.EventProvider);
-}
-else {
-}
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Private member variables
-//
-/////////////////////////////////////////////////////////////////////////////
-/**
- * Internal class variable to name multiple Recordset instances.
- *
- * @property RecordSet._nCount
- * @type Number
+ * @method _onPaginatorDropdownChange
  * @private
- * @static
+ * @deprecated Use Paginator class APIs.
  */
-YAHOO.widget.RecordSet._nCount = 0;
+_onPaginatorDropdownChange : function(e, oSelf) {
+    // Backward compatibility
+    var elTarget = Ev.getTarget(e);
+    var newValue = elTarget[elTarget.selectedIndex].value;
 
-/**
- * Unique instance name.
- *
- * @property _sName
- * @type String
- * @private
- */
-YAHOO.widget.RecordSet.prototype._sName = null;
-
-/**
- * Internal counter of how many Records are in the RecordSet.
- *
- * @property _length
- * @type Number
- * @private
- */
-YAHOO.widget.RecordSet.prototype._length = null;
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Private methods
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Adds one Record to the RecordSet at the given index. If index is null,
- * then adds the Record to the end of the RecordSet.
- *
- * @method _addRecord
- * @param oData {Object} An object literal of data.
- * @param index {Number} (optional) Position index.
- * @return {YAHOO.widget.Record} A Record instance.
- * @private
- */
-YAHOO.widget.RecordSet.prototype._addRecord = function(oData, index) {
-    var oRecord = new YAHOO.widget.Record(oData);
-    
-    if(YAHOO.lang.isNumber(index) && (index > -1)) {
-        this._records.splice(index,0,oRecord);
+    var newRowsPerPage = lang.isValue(parseInt(newValue,10)) ? parseInt(newValue,10) : null;
+    if(newRowsPerPage !== null) {
+        var newStartRecordIndex = (oSelf.get("paginator").currentPage-1) * newRowsPerPage;
+        oSelf.updatePaginator({rowsPerPage:newRowsPerPage, startRecordIndex:newStartRecordIndex});
+        oSelf.render();
     }
     else {
-        index = this.getLength();
-        this._records.push(oRecord);
     }
-    this._length++;
-    return oRecord;
-};
+},
 
 /**
- * Deletes Records from the RecordSet at the given index. If range is null,
- * then only one Record is deleted.
- *
- * @method _deleteRecord
- * @param index {Number} Position index.
- * @param range {Number} (optional) How many Records to delete
- * @private
+ * @method onEventEditCell
+ * @deprecated Use onEventShowCellEditor.
  */
-YAHOO.widget.RecordSet.prototype._deleteRecord = function(index, range) {
-    if(!YAHOO.lang.isNumber(range) || (range < 0)) {
-        range = 1;
-    }
-    this._records.splice(index, range);
-    this._length = this._length - range;
-};
+onEventEditCell : function(oArgs) {
+    // Backward compatibility
+    this.onEventShowCellEditor(oArgs);
+},
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public methods
-//
-/////////////////////////////////////////////////////////////////////////////
-
 /**
- * Public accessor to the unique name of the RecordSet instance.
- *
- * @method toString
- * @return {String} Unique name of the RecordSet instance.
+ * @method onDataReturnReplaceRows
+ * @deprecated Use onDataReturnInitializeTable.
  */
-YAHOO.widget.RecordSet.prototype.toString = function() {
-    return this._sName;
-};
+onDataReturnReplaceRows : function(sRequest, oResponse) {
+    // Backward compatibility
+    this.onDataReturnInitializeTable(sRequest, oResponse);
+}
 
 /**
- * Returns the number of Records held in the RecordSet.
- *
- * @method getLength
- * @return {Number} Number of records in the RecordSet.
+ * @event headerRowMouseoverEvent
+ * @deprecated Use theadRowMouseoverEvent.
  */
-YAHOO.widget.RecordSet.prototype.getLength = function() {
-        return this._length;
-};
 
 /**
- * Returns Record by ID or RecordSet position index.
- *
- * @method getRecord
- * @param record {YAHOO.widget.Record | Number | String} Record instance,
- * RecordSet position index, or Record ID.
- * @return {YAHOO.widget.Record} Record object.
+ * @event headerRowMouseoutEvent
+ * @deprecated Use theadRowMouseoutEvent.
  */
-YAHOO.widget.RecordSet.prototype.getRecord = function(record) {
-    var i;
-    if(record instanceof YAHOO.widget.Record) {
-        for(i=0; i<this._records.length; i++) {
-            if(this._records[i]._sId === record._sId) {
-                return record;
-            }
-        }
-    }
-    else if(YAHOO.lang.isNumber(record)) {
-        if((record > -1) && (record < this.getLength())) {
-            return this._records[record];
-        }
-    }
-    else if(YAHOO.lang.isString(record)) {
-        for(i=0; i<this._records.length; i++) {
-            if(this._records[i]._sId === record) {
-                return this._records[i];
-            }
-        }
-    }
-    // Not a valid Record for this RecordSet
-    return null;
 
-};
-
 /**
- * Returns an array of Records from the RecordSet.
- *
- * @method getRecords
- * @param index {Number} (optional) Recordset position index of which Record to
- * start at.
- * @param range {Number} (optional) Number of Records to get.
- * @return {YAHOO.widget.Record[]} Array of Records starting at given index and
- * length equal to given range. If index is not given, all Records are returned.
+ * @event headerRowMousedownEvent
+ * @deprecated Use theadRowMousedownEvent.
  */
-YAHOO.widget.RecordSet.prototype.getRecords = function(index, range) {
-    if(!YAHOO.lang.isNumber(index)) {
-        return this._records;
-    }
-    if(!YAHOO.lang.isNumber(range)) {
-        return this._records.slice(index);
-    }
-    return this._records.slice(index, index+range);
-};
 
 /**
- * Returns current position index for the given Record.
- *
- * @method getRecordIndex
- * @param oRecord {YAHOO.widget.Record} Record instance.
- * @return {Number} Record's RecordSet position index.
+ * @event headerRowClickEvent
+ * @deprecated Use theadRowClickEvent.
  */
 
-YAHOO.widget.RecordSet.prototype.getRecordIndex = function(oRecord) {
-    if(oRecord) {
-        for(var i=this._records.length-1; i>-1; i--) {
-            if(oRecord.getId() === this._records[i].getId()) {
-                return i;
-            }
-        }
-    }
-    return null;
-
-};
-
 /**
- * Adds one Record to the RecordSet at the given index. If index is null,
- * then adds the Record to the end of the RecordSet.
- *
- * @method addRecord
- * @param oData {Object} An object literal of data.
- * @param index {Number} (optional) Position index.
- * @return {YAHOO.widget.Record} A Record instance.
+ * @event headerRowDblclickEvent
+ * @deprecated Use theadRowDblclickEvent.
  */
-YAHOO.widget.RecordSet.prototype.addRecord = function(oData, index) {
-    if(oData && (oData.constructor == Object)) {
-        var oRecord = this._addRecord(oData, index);
-        this.fireEvent("recordAddEvent",{record:oRecord,data:oData});
-        return oRecord;
-    }
-    else {
-        return null;
-    }
-};
 
 /**
- * Adds multiple Records at once to the RecordSet at the given index with the
- * given data. If index is null, then the new Records are added to the end of
- * the RecordSet.
- *
- * @method addRecords
- * @param aData {Object[]} An array of object literal data.
- * @param index {Number} (optional) Position index.
- * @return {YAHOO.widget.Record[]} An array of Record instances.
+ * @event headerCellMouseoverEvent
+ * @deprecated Use theadCellMouseoverEvent.
  */
-YAHOO.widget.RecordSet.prototype.addRecords = function(aData, index) {
-    if(YAHOO.lang.isArray(aData)) {
-        var newRecords = [];
-        // Can't go backwards bc we need to preserve order
-        for(var i=0; i<aData.length; i++) {
-            if(aData[i] && (aData[i].constructor == Object)) {
-                var record = this._addRecord(aData[i], index);
-                newRecords.push(record);
-            }
-       }
-        this.fireEvent("recordsAddEvent",{records:newRecords,data:aData});
-       return newRecords;
-    }
-    else if(aData && (aData.constructor == Object)) {
-        var oRecord = this._addRecord(aData);
-        this.fireEvent("recordsAddEvent",{records:[oRecord],data:aData});
-        return oRecord;
-    }
-    else {
-    }
-};
 
 /**
- * Updates given Record with given data.
- *
- * @method updateRecord
- * @param record {YAHOO.widget.Record | Number | String} A Record instance,
- * a RecordSet position index, or a Record ID.
- * @param oData {Object) Object literal of new data.
- * @return {YAHOO.widget.Record} Updated Record, or null.
+ * @event headerCellMouseoutEvent
+ * @deprecated Use theadCellMouseoutEvent.
  */
-YAHOO.widget.RecordSet.prototype.updateRecord = function(record, oData) {
-    var oRecord = this.getRecord(record);
-    if(oRecord && oData && (oData.constructor == Object)) {
-        // Copy data from the Record for the event that gets fired later
-        var oldData = {};
-        for(var key in oRecord._oData) {
-            oldData[key] = oRecord._oData[key];
-        }
-        oRecord._oData = oData;
-        this.fireEvent("recordUpdateEvent",{record:oRecord,newData:oData,oldData:oldData});
-        return oRecord;
-    }
-    else {
-        return null;
-    }
-};
 
 /**
- * Updates given Record at given key with given data.
- *
- * @method updateKey
- * @param record {YAHOO.widget.Record | Number | String} A Record instance,
- * a RecordSet position index, or a Record ID.
- * @param sKey {String} Key name.
- * @param oData {Object) New data.
+ * @event headerCellMousedownEvent
+ * @deprecated Use theadCellMousedownEvent.
  */
-YAHOO.widget.RecordSet.prototype.updateKey = function(record, sKey, oData) {
-    var oRecord = this.getRecord(record);
-    if(oRecord) {
-        var oldData = null;
-        var keyValue = oRecord._oData[sKey];
-        // Copy data from the Record for the event that gets fired later
-        if(keyValue && keyValue.constructor == Object) {
-            oldData = {};
-            for(var key in keyValue) {
-                oldData[key] = keyValue[key];
-            }
-        }
-        // Copy by value
-        else {
-            oldData = keyValue;
-        }
 
-        oRecord._oData[sKey] = oData;
-        this.fireEvent("keyUpdateEvent",{record:oRecord,key:sKey,newData:oData,oldData:oldData});
-    }
-    else {
-    }
-};
-
 /**
- * Replaces all Records in RecordSet with new data.
- *
- * @method replaceRecords
- * @param data {Object || Object[]} An object literal of data or an array of
- * object literal data.
- * @return {YAHOO.widget.Record || YAHOO.widget.Record[]} A Record instance or
- * an array of Records.
+ * @event headerCellClickEvent
+ * @deprecated Use theadCellClickEvent.
  */
-YAHOO.widget.RecordSet.prototype.replaceRecords = function(data) {
-    this.reset();
-    return this.addRecords(data);
-};
 
 /**
- * Sorts all Records by given function. Records keep their unique IDs but will
- * have new RecordSet position indexes.
- *
- * @method sortRecords
- * @param fnSort {Function} Reference to a sort function.
- * @param desc {Boolean} True if sort direction is descending, false if sort
- * direction is ascending.
- * @return {YAHOO.widget.Record[]} Sorted array of Records.
+ * @event headerCellDblclickEvent
+ * @deprecated Use theadCellDblclickEvent.
  */
-YAHOO.widget.RecordSet.prototype.sortRecords = function(fnSort, desc) {
-    return this._records.sort(function(a, b) {return fnSort(a, b, desc);});
-};
 
-
 /**
- * Removes the Record at the given position index from the RecordSet. If a range
- * is also provided, removes that many Records, starting from the index. Length
- * of RecordSet is correspondingly shortened.
- *
- * @method deleteRecord
- * @param index {Number} Record's RecordSet position index.
- * @param range {Number} (optional) How many Records to delete.
- * @return {Object} A copy of the data held by the deleted Record.
+ * @event headerLabelMouseoverEvent
+ * @deprecated Use theadLabelMouseoverEvent.
  */
-YAHOO.widget.RecordSet.prototype.deleteRecord = function(index) {
-    if(YAHOO.lang.isNumber(index) && (index > -1) && (index < this.getLength())) {
-        // Copy data from the Record for the event that gets fired later
-        var oRecordData = this.getRecord(index).getData();
-        var oData = {};
-        for(var key in oRecordData) {
-            oData[key] = oRecordData[key];
-        }
-        
-        this._deleteRecord(index);
-        this.fireEvent("recordDeleteEvent",{data:oData,index:index});
-        return oData;
-    }
-    else {
-        return null;
-    }
-};
 
 /**
- * Removes the Record at the given position index from the RecordSet. If a range
- * is also provided, removes that many Records, starting from the index. Length
- * of RecordSet is correspondingly shortened.
- *
- * @method deleteRecords
- * @param index {Number} Record's RecordSet position index.
- * @param range {Number} (optional) How many Records to delete.
+ * @event headerLabelMouseoutEvent
+ * @deprecated Use theadLabelMouseoutEvent.
  */
-YAHOO.widget.RecordSet.prototype.deleteRecords = function(index, range) {
-    if(!YAHOO.lang.isNumber(range)) {
-        range = 1;
-    }
-    if(YAHOO.lang.isNumber(index) && (index > -1) && (index < this.getLength())) {
-        var recordsToDelete = this.getRecords(index, range);
-        // Copy data from each Record for the event that gets fired later
-        var deletedData = [];
-        for(var i=0; i<recordsToDelete.length; i++) {
-            var oData = {};
-            for(var key in recordsToDelete[i]) {
-                oData[key] = recordsToDelete[i][key];
-            }
-            deletedData.push(oData);
-        }
-        this._deleteRecord(index, range);
 
-        this.fireEvent("recordsDeleteEvent",{data:deletedData,index:index});
-
-    }
-    else {
-    }
-};
-
 /**
- * Deletes all Records from the RecordSet.
- *
- * @method reset
+ * @event headerLabelMousedownEvent
+ * @deprecated Use theadLabelMousedownEvent.
  */
-YAHOO.widget.RecordSet.prototype.reset = function() {
-    this._records = [];
-    this._length = 0;
-    this.fireEvent("resetEvent");
-};
 
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
 /**
- * The Record class defines a DataTable record.
- *
- * @namespace YAHOO.widget
- * @class Record
- * @constructor
- * @param oConfigs {Object} (optional) Object literal of key/value pairs.
+ * @event headerLabelClickEvent
+ * @deprecated Use theadLabelClickEvent.
  */
-YAHOO.widget.Record = function(oLiteral) {
-    this._sId = YAHOO.widget.Record._nCount + "";
-    YAHOO.widget.Record._nCount++;
-    this._oData = {};
-    if(oLiteral && (oLiteral.constructor == Object)) {
-        for(var sKey in oLiteral) {
-            this._oData[sKey] = oLiteral[sKey];
-        }
-    }
-};
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Private member variables
-//
-/////////////////////////////////////////////////////////////////////////////
-
 /**
- * Internal class variable to give unique IDs to Record instances.
- *
- * @property Record._nCount
- * @type Number
- * @private
+ * @event headerLabelDbllickEvent
+ * @deprecated Use theadLabelDblclickEvent.
  */
-YAHOO.widget.Record._nCount = 0;
 
-/**
- * Immutable unique ID assigned at instantiation. Remains constant while a
- * Record's position index can change from sorting.
- *
- * @property _sId
- * @type String
- * @private
- */
-YAHOO.widget.Record.prototype._sId = null;
+});
 
 /**
- * Holds data for the Record in an object literal.
- *
- * @property _oData
- * @type Object
- * @private
+ * Alias for onDataReturnSetRows for backward compatibility
+ * @method onDataReturnSetRecords
+ * @deprecated Use onDataReturnSetRows
  */
-YAHOO.widget.Record.prototype._oData = null;
+DT.prototype.onDataReturnSetRecords = DT.prototype.onDataReturnSetRows;
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public member variables
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public methods
-//
-/////////////////////////////////////////////////////////////////////////////
-
-/**
- * Returns unique ID assigned at instantiation.
- *
- * @method getId
- * @return String
- */
-YAHOO.widget.Record.prototype.getId = function() {
-    return this._sId;
-};
-
-/**
- * Returns data for the Record for a key if given, or the entire object
- * literal otherwise.
- *
- * @method getData
- * @param sKey {String} (Optional) The key to retrieve a single data value.
- * @return Object
- */
-YAHOO.widget.Record.prototype.getData = function(sKey) {
-    if(YAHOO.lang.isString(sKey)) {
-        return this._oData[sKey];
-    }
-    else {
-        return this._oData;
-    }
-};
-
-
-YAHOO.register("datatable", YAHOO.widget.DataTable, {version: "2.4.1", build: "742"});
+})();
+YAHOO.register("datatable", YAHOO.widget.DataTable, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/dom/README
===================================================================
--- trunk/root/static/yui/dom/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/dom/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -7,9 +7,11 @@
 
 ----------------------------
 
-*** version 2.4.1 ***
+*** version 2.5.1 ***
+* getStyle fix for getting computedStyle across documents
 
-No change
+*** version 2.5.0 ***
+* get() now correctly handles textNodes
 
 *** version 2.4.0 ***
 * no longer accounting for safari body margin when offsetParent == body

Modified: trunk/root/static/yui/dom/dom-debug.js
===================================================================
--- trunk/root/static/yui/dom/dom-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/dom/dom-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The dom module provides helper methods for manipulating Dom elements.
@@ -14,11 +14,12 @@
     var Y = YAHOO.util,     // internal shorthand
         getStyle,           // for load time browser branching
         setStyle,           // ditto
-        id_counter = 0,     // for use with generateId
         propertyCache = {}, // for faster hyphen converts
         reClassNameCache = {},          // cache regexes for className
         document = window.document;     // cache for faster lookups
     
+    YAHOO.env._id_counter = YAHOO.env._id_counter || 0;     // for use with generateId (global to save state if Dom is overwritten)
+
     // brower detection
     var isOpera = YAHOO.env.ua.opera,
         isSafari = YAHOO.env.ua.webkit, 
@@ -28,7 +29,8 @@
     // regex cache
     var patterns = {
         HYPHEN: /(-[a-z])/i, // to normalize get/setStyle
-        ROOT_TAG: /^body|html$/i // body for quirks mode, html for standards
+        ROOT_TAG: /^body|html$/i, // body for quirks mode, html for standards,
+        OP_SCROLL:/^(?:inline|table-row)$/i
     };
 
     var toCamel = function(property) {
@@ -70,7 +72,7 @@
                 property = 'cssFloat';
             }
 
-            var computed = document.defaultView.getComputedStyle(el, '');
+            var computed = el.ownerDocument.defaultView.getComputedStyle(el, '');
             if (computed) { // test computed before touching for safari
                 value = computed[toCamel(property)];
             }
@@ -150,11 +152,11 @@
          * @return {HTMLElement | Array} A DOM reference to an HTML element or an array of HTMLElements.
          */
         get: function(el) {
-            if (el && (el.tagName || el.item)) { // HTMLElement, or HTMLCollection
+            if (el && (el.nodeType || el.item)) { // Node, or NodeList
                 return el;
             }
 
-            if (YAHOO.lang.isString(el) || !el) { // HTMLElement or null
+            if (YAHOO.lang.isString(el) || !el) { // id or null
                 return document.getElementById(el);
             }
             
@@ -341,7 +343,7 @@
         getRegion: function(el) {
             var f = function(el) {
                 if ( (el.parentNode === null || el.offsetParent === null ||
-                        this.getStyle(el, 'display') == 'none') && el != document.body) {
+                        this.getStyle(el, 'display') == 'none') && el != el.ownerDocument.body) {
                     YAHOO.log('getRegion failed: element not available', 'error', 'Dom');
                     return false;
                 }
@@ -458,7 +460,7 @@
             var re = getClassRegEx(className);
             
             var f = function(el) {
-                if (!this.hasClass(el, className)) {
+                if (!className || !this.hasClass(el, className)) {
                     return false; // not present
                 }                 
 
@@ -530,7 +532,7 @@
                     return el.id;
                 } 
 
-                var id = prefix + id_counter++;
+                var id = prefix + YAHOO.env._id_counter++;
                 YAHOO.log('generateId generating ' + id, 'info', 'Dom');
 
                 if (el) {
@@ -1057,10 +1059,14 @@
                 // account for any scrolled ancestors
                 while ( parentNode.tagName && !patterns.ROOT_TAG.test(parentNode.tagName) ) 
                 {
-                   // work around opera inline/table scrollLeft/Top bug
-                   if (Y.Dom.getStyle(parentNode, 'display').search(/^inline|table-row.*$/i)) { 
-                        pos[0] -= parentNode.scrollLeft;
-                        pos[1] -= parentNode.scrollTop;
+                    if (parentNode.scrollTop || parentNode.scrollLeft) {
+                        // work around opera inline/table scrollLeft/Top bug (false reports offset as scroll)
+                        if (!patterns.OP_SCROLL.test(Y.Dom.getStyle(parentNode, 'display'))) { 
+                            if (!isOpera || Y.Dom.getStyle(parentNode, 'overflow') !== 'visible') { // opera inline-block misreports when visible
+                                pos[0] -= parentNode.scrollLeft;
+                                pos[1] -= parentNode.scrollTop;
+                            }
+                        }
                     }
                     
                     parentNode = parentNode.parentNode; 
@@ -1257,4 +1263,4 @@
 
 YAHOO.util.Point.prototype = new YAHOO.util.Region();
 
-YAHOO.register("dom", YAHOO.util.Dom, {version: "2.4.1", build: "742"});
+YAHOO.register("dom", YAHOO.util.Dom, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/dom/dom-min.js
===================================================================
--- trunk/root/static/yui/dom/dom-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/dom/dom-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-(function(){var B=YAHOO.util,L,J,H=0,K={},F={},N=window.document;var C=YAHOO.env.ua.opera,M=YAHOO.env.ua.webkit,A=YAHOO.env.ua.gecko,G=YAHOO.env.ua.ie;var E={HYPHEN:/(-[a-z])/i,ROOT_TAG:/^body|html$/i};var O=function(Q){if(!E.HYPHEN.test(Q)){return Q;}if(K[Q]){return K[Q];}var R=Q;while(E.HYPHEN.exec(R)){R=R.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());}K[Q]=R;return R;};var P=function(R){var Q=F[R];if(!Q){Q=new RegExp("(?:^|\\s+)"+R+"(?:\\s+|$)");F[R]=Q;}return Q;};if(N.defaultView&&N.defaultView.getComputedStyle){L=function(Q,T){var S=null;if(T=="float"){T="cssFloat";}var R=N.defaultView.getComputedStyle(Q,"");if(R){S=R[O(T)];}return Q.style[T]||S;};}else{if(N.documentElement.currentStyle&&G){L=function(Q,S){switch(O(S)){case"opacity":var U=100;try{U=Q.filters["DXImageTransform.Microsoft.Alpha"].opacity;}catch(T){try{U=Q.filters("alpha").opacity;}catch(T){}}return U/100;case"float":S="styleFloat";default:var R=Q.currentStyle?Q.currentStyle[S]:null;return(Q.style[S!
 ]||R);}};}else{L=function(Q,R){return Q.style[R];};}}if(G){J=function(Q,R,S){switch(R){case"opacity":if(YAHOO.lang.isString(Q.style.filter)){Q.style.filter="alpha(opacity="+S*100+")";if(!Q.currentStyle||!Q.currentStyle.hasLayout){Q.style.zoom=1;}}break;case"float":R="styleFloat";default:Q.style[R]=S;}};}else{J=function(Q,R,S){if(R=="float"){R="cssFloat";}Q.style[R]=S;};}var D=function(Q,R){return Q&&Q.nodeType==1&&(!R||R(Q));};YAHOO.util.Dom={get:function(S){if(S&&(S.tagName||S.item)){return S;}if(YAHOO.lang.isString(S)||!S){return N.getElementById(S);}if(S.length!==undefined){var T=[];for(var R=0,Q=S.length;R<Q;++R){T[T.length]=B.Dom.get(S[R]);}return T;}return S;},getStyle:function(Q,S){S=O(S);var R=function(T){return L(T,S);};return B.Dom.batch(Q,R,B.Dom,true);},setStyle:function(Q,S,T){S=O(S);var R=function(U){J(U,S,T);};B.Dom.batch(Q,R,B.Dom,true);},getXY:function(Q){var R=function(S){if((S.parentNode===null||S.offsetParent===null||this.getStyle(S,"display")=="none")&&!
 S!=S.ownerDocument.body){return false;}return I(S);};return B.!
 Dom.batc
h(Q,R,B.Dom,true);},getX:function(Q){var R=function(S){return B.Dom.getXY(S)[0];};return B.Dom.batch(Q,R,B.Dom,true);},getY:function(Q){var R=function(S){return B.Dom.getXY(S)[1];};return B.Dom.batch(Q,R,B.Dom,true);},setXY:function(Q,T,S){var R=function(W){var V=this.getStyle(W,"position");if(V=="static"){this.setStyle(W,"position","relative");V="relative";}var Y=this.getXY(W);if(Y===false){return false;}var X=[parseInt(this.getStyle(W,"left"),10),parseInt(this.getStyle(W,"top"),10)];if(isNaN(X[0])){X[0]=(V=="relative")?0:W.offsetLeft;}if(isNaN(X[1])){X[1]=(V=="relative")?0:W.offsetTop;}if(T[0]!==null){W.style.left=T[0]-Y[0]+X[0]+"px";}if(T[1]!==null){W.style.top=T[1]-Y[1]+X[1]+"px";}if(!S){var U=this.getXY(W);if((T[0]!==null&&U[0]!=T[0])||(T[1]!==null&&U[1]!=T[1])){this.setXY(W,T,true);}}};B.Dom.batch(Q,R,B.Dom,true);},setX:function(R,Q){B.Dom.setXY(R,[Q,null]);},setY:function(Q,R){B.Dom.setXY(Q,[null,R]);},getRegion:function(Q){var R=function(S){if((S.parentNode===null||S!
 .offsetParent===null||this.getStyle(S,"display")=="none")&&S!=N.body){return false;}var T=B.Region.getRegion(S);return T;};return B.Dom.batch(Q,R,B.Dom,true);},getClientWidth:function(){return B.Dom.getViewportWidth();},getClientHeight:function(){return B.Dom.getViewportHeight();},getElementsByClassName:function(U,Y,V,W){Y=Y||"*";V=(V)?B.Dom.get(V):null||N;if(!V){return[];}var R=[],Q=V.getElementsByTagName(Y),X=P(U);for(var S=0,T=Q.length;S<T;++S){if(X.test(Q[S].className)){R[R.length]=Q[S];if(W){W.call(Q[S],Q[S]);}}}return R;},hasClass:function(S,R){var Q=P(R);var T=function(U){return Q.test(U.className);};return B.Dom.batch(S,T,B.Dom,true);},addClass:function(R,Q){var S=function(T){if(this.hasClass(T,Q)){return false;}T.className=YAHOO.lang.trim([T.className,Q].join(" "));return true;};return B.Dom.batch(R,S,B.Dom,true);},removeClass:function(S,R){var Q=P(R);var T=function(U){if(!this.hasClass(U,R)){return false;}var V=U.className;U.className=V.replace(Q," ");if(this.hasC!
 lass(U,R)){this.removeClass(U,R);}U.className=YAHOO.lang.trim(!
 U.classN
ame);return true;};return B.Dom.batch(S,T,B.Dom,true);},replaceClass:function(T,R,Q){if(!Q||R===Q){return false;}var S=P(R);var U=function(V){if(!this.hasClass(V,R)){this.addClass(V,Q);return true;}V.className=V.className.replace(S," "+Q+" ");if(this.hasClass(V,R)){this.replaceClass(V,R,Q);}V.className=YAHOO.lang.trim(V.className);return true;};return B.Dom.batch(T,U,B.Dom,true);},generateId:function(Q,S){S=S||"yui-gen";var R=function(T){if(T&&T.id){return T.id;}var U=S+H++;if(T){T.id=U;}return U;};return B.Dom.batch(Q,R,B.Dom,true)||R.apply(B.Dom,arguments);},isAncestor:function(Q,R){Q=B.Dom.get(Q);R=B.Dom.get(R);if(!Q||!R){return false;}if(Q.contains&&R.nodeType&&!M){return Q.contains(R);}else{if(Q.compareDocumentPosition&&R.nodeType){return !!(Q.compareDocumentPosition(R)&16);}else{if(R.nodeType){return !!this.getAncestorBy(R,function(S){return S==Q;});}}}return false;},inDocument:function(Q){return this.isAncestor(N.documentElement,Q);},getElementsBy:function(X,R,S,U){R=!
 R||"*";S=(S)?B.Dom.get(S):null||N;if(!S){return[];}var T=[],W=S.getElementsByTagName(R);for(var V=0,Q=W.length;V<Q;++V){if(X(W[V])){T[T.length]=W[V];if(U){U(W[V]);}}}return T;},batch:function(U,X,W,S){U=(U&&(U.tagName||U.item))?U:B.Dom.get(U);if(!U||!X){return false;}var T=(S)?W:window;if(U.tagName||U.length===undefined){return X.call(T,U,W);}var V=[];for(var R=0,Q=U.length;R<Q;++R){V[V.length]=X.call(T,U[R],W);}return V;},getDocumentHeight:function(){var R=(N.compatMode!="CSS1Compat")?N.body.scrollHeight:N.documentElement.scrollHeight;var Q=Math.max(R,B.Dom.getViewportHeight());return Q;},getDocumentWidth:function(){var R=(N.compatMode!="CSS1Compat")?N.body.scrollWidth:N.documentElement.scrollWidth;var Q=Math.max(R,B.Dom.getViewportWidth());return Q;},getViewportHeight:function(){var Q=self.innerHeight;var R=N.compatMode;if((R||G)&&!C){Q=(R=="CSS1Compat")?N.documentElement.clientHeight:N.body.clientHeight;
-}return Q;},getViewportWidth:function(){var Q=self.innerWidth;var R=N.compatMode;if(R||G){Q=(R=="CSS1Compat")?N.documentElement.clientWidth:N.body.clientWidth;}return Q;},getAncestorBy:function(Q,R){while(Q=Q.parentNode){if(D(Q,R)){return Q;}}return null;},getAncestorByClassName:function(R,Q){R=B.Dom.get(R);if(!R){return null;}var S=function(T){return B.Dom.hasClass(T,Q);};return B.Dom.getAncestorBy(R,S);},getAncestorByTagName:function(R,Q){R=B.Dom.get(R);if(!R){return null;}var S=function(T){return T.tagName&&T.tagName.toUpperCase()==Q.toUpperCase();};return B.Dom.getAncestorBy(R,S);},getPreviousSiblingBy:function(Q,R){while(Q){Q=Q.previousSibling;if(D(Q,R)){return Q;}}return null;},getPreviousSibling:function(Q){Q=B.Dom.get(Q);if(!Q){return null;}return B.Dom.getPreviousSiblingBy(Q);},getNextSiblingBy:function(Q,R){while(Q){Q=Q.nextSibling;if(D(Q,R)){return Q;}}return null;},getNextSibling:function(Q){Q=B.Dom.get(Q);if(!Q){return null;}return B.Dom.getNextSiblingBy(Q);},g!
 etFirstChildBy:function(Q,S){var R=(D(Q.firstChild,S))?Q.firstChild:null;return R||B.Dom.getNextSiblingBy(Q.firstChild,S);},getFirstChild:function(Q,R){Q=B.Dom.get(Q);if(!Q){return null;}return B.Dom.getFirstChildBy(Q);},getLastChildBy:function(Q,S){if(!Q){return null;}var R=(D(Q.lastChild,S))?Q.lastChild:null;return R||B.Dom.getPreviousSiblingBy(Q.lastChild,S);},getLastChild:function(Q){Q=B.Dom.get(Q);return B.Dom.getLastChildBy(Q);},getChildrenBy:function(R,T){var S=B.Dom.getFirstChildBy(R,T);var Q=S?[S]:[];B.Dom.getNextSiblingBy(S,function(U){if(!T||T(U)){Q[Q.length]=U;}return false;});return Q;},getChildren:function(Q){Q=B.Dom.get(Q);if(!Q){}return B.Dom.getChildrenBy(Q);},getDocumentScrollLeft:function(Q){Q=Q||N;return Math.max(Q.documentElement.scrollLeft,Q.body.scrollLeft);},getDocumentScrollTop:function(Q){Q=Q||N;return Math.max(Q.documentElement.scrollTop,Q.body.scrollTop);},insertBefore:function(R,Q){R=B.Dom.get(R);Q=B.Dom.get(Q);if(!R||!Q||!Q.parentNode){return n!
 ull;}return Q.parentNode.insertBefore(R,Q);},insertAfter:funct!
 ion(R,Q)
{R=B.Dom.get(R);Q=B.Dom.get(Q);if(!R||!Q||!Q.parentNode){return null;}if(Q.nextSibling){return Q.parentNode.insertBefore(R,Q.nextSibling);}else{return Q.parentNode.appendChild(R);}},getClientRegion:function(){var S=B.Dom.getDocumentScrollTop(),R=B.Dom.getDocumentScrollLeft(),T=B.Dom.getViewportWidth()+R,Q=B.Dom.getViewportHeight()+S;return new B.Region(S,T,Q,R);}};var I=function(){if(N.documentElement.getBoundingClientRect){return function(R){var S=R.getBoundingClientRect();var Q=R.ownerDocument;return[S.left+B.Dom.getDocumentScrollLeft(Q),S.top+B.Dom.getDocumentScrollTop(Q)];};}else{return function(S){var T=[S.offsetLeft,S.offsetTop];var R=S.offsetParent;var Q=(M&&B.Dom.getStyle(S,"position")=="absolute"&&S.offsetParent==S.ownerDocument.body);if(R!=S){while(R){T[0]+=R.offsetLeft;T[1]+=R.offsetTop;if(!Q&&M&&B.Dom.getStyle(R,"position")=="absolute"){Q=true;}R=R.offsetParent;}}if(Q){T[0]-=S.ownerDocument.body.offsetLeft;T[1]-=S.ownerDocument.body.offsetTop;}R=S.parentNode;whil!
 e(R.tagName&&!E.ROOT_TAG.test(R.tagName)){if(B.Dom.getStyle(R,"display").search(/^inline|table-row.*$/i)){T[0]-=R.scrollLeft;T[1]-=R.scrollTop;}R=R.parentNode;}return T;};}}();})();YAHOO.util.Region=function(C,D,A,B){this.top=C;this[1]=C;this.right=D;this.bottom=A;this.left=B;this[0]=B;};YAHOO.util.Region.prototype.contains=function(A){return(A.left>=this.left&&A.right<=this.right&&A.top>=this.top&&A.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(E){var C=Math.max(this.top,E.top);var D=Math.min(this.right,E.right);var A=Math.min(this.bottom,E.bottom);var B=Math.max(this.left,E.left);if(A>=C&&D>=B){return new YAHOO.util.Region(C,D,A,B);}else{return null;}};YAHOO.util.Region.prototype.union=function(E){var C=Math.min(this.top,E.top);var D=Math.max(this.right,E.right);var A=Math.max(this.bottom,E.bottom);var B=Math.min(this.left,E.left);return new YAHOO!
 .util.Region(C,D,A,B);};YAHOO.util.Region.prototype.toString=f!
 unction(
){return("Region {top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+"}");};YAHOO.util.Region.getRegion=function(D){var F=YAHOO.util.Dom.getXY(D);var C=F[1];var E=F[0]+D.offsetWidth;var A=F[1]+D.offsetHeight;var B=F[0];return new YAHOO.util.Region(C,E,A,B);};YAHOO.util.Point=function(A,B){if(YAHOO.lang.isArray(A)){B=A[1];A=A[0];}this.x=this.right=this.left=this[0]=A;this.y=this.top=this.bottom=this[1]=B;};YAHOO.util.Point.prototype=new YAHOO.util.Region();YAHOO.register("dom",YAHOO.util.Dom,{version:"2.4.1",build:"742"});
\ No newline at end of file
+(function(){var B=YAHOO.util,K,I,J={},F={},M=window.document;YAHOO.env._id_counter=YAHOO.env._id_counter||0;var C=YAHOO.env.ua.opera,L=YAHOO.env.ua.webkit,A=YAHOO.env.ua.gecko,G=YAHOO.env.ua.ie;var E={HYPHEN:/(-[a-z])/i,ROOT_TAG:/^body|html$/i,OP_SCROLL:/^(?:inline|table-row)$/i};var N=function(P){if(!E.HYPHEN.test(P)){return P;}if(J[P]){return J[P];}var Q=P;while(E.HYPHEN.exec(Q)){Q=Q.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());}J[P]=Q;return Q;};var O=function(Q){var P=F[Q];if(!P){P=new RegExp("(?:^|\\s+)"+Q+"(?:\\s+|$)");F[Q]=P;}return P;};if(M.defaultView&&M.defaultView.getComputedStyle){K=function(P,S){var R=null;if(S=="float"){S="cssFloat";}var Q=P.ownerDocument.defaultView.getComputedStyle(P,"");if(Q){R=Q[N(S)];}return P.style[S]||R;};}else{if(M.documentElement.currentStyle&&G){K=function(P,R){switch(N(R)){case"opacity":var T=100;try{T=P.filters["DXImageTransform.Microsoft.Alpha"].opacity;}catch(S){try{T=P.filters("alpha").opacity;}catch(S){}}return T/100;ca!
 se"float":R="styleFloat";default:var Q=P.currentStyle?P.currentStyle[R]:null;return(P.style[R]||Q);}};}else{K=function(P,Q){return P.style[Q];};}}if(G){I=function(P,Q,R){switch(Q){case"opacity":if(YAHOO.lang.isString(P.style.filter)){P.style.filter="alpha(opacity="+R*100+")";if(!P.currentStyle||!P.currentStyle.hasLayout){P.style.zoom=1;}}break;case"float":Q="styleFloat";default:P.style[Q]=R;}};}else{I=function(P,Q,R){if(Q=="float"){Q="cssFloat";}P.style[Q]=R;};}var D=function(P,Q){return P&&P.nodeType==1&&(!Q||Q(P));};YAHOO.util.Dom={get:function(R){if(R&&(R.nodeType||R.item)){return R;}if(YAHOO.lang.isString(R)||!R){return M.getElementById(R);}if(R.length!==undefined){var S=[];for(var Q=0,P=R.length;Q<P;++Q){S[S.length]=B.Dom.get(R[Q]);}return S;}return R;},getStyle:function(P,R){R=N(R);var Q=function(S){return K(S,R);};return B.Dom.batch(P,Q,B.Dom,true);},setStyle:function(P,R,S){R=N(R);var Q=function(T){I(T,R,S);};B.Dom.batch(P,Q,B.Dom,true);},getXY:function(P){var Q=fun!
 ction(R){if((R.parentNode===null||R.offsetParent===null||this.!
 getStyle
(R,"display")=="none")&&R!=R.ownerDocument.body){return false;}return H(R);};return B.Dom.batch(P,Q,B.Dom,true);},getX:function(P){var Q=function(R){return B.Dom.getXY(R)[0];};return B.Dom.batch(P,Q,B.Dom,true);},getY:function(P){var Q=function(R){return B.Dom.getXY(R)[1];};return B.Dom.batch(P,Q,B.Dom,true);},setXY:function(P,S,R){var Q=function(V){var U=this.getStyle(V,"position");if(U=="static"){this.setStyle(V,"position","relative");U="relative";}var X=this.getXY(V);if(X===false){return false;}var W=[parseInt(this.getStyle(V,"left"),10),parseInt(this.getStyle(V,"top"),10)];if(isNaN(W[0])){W[0]=(U=="relative")?0:V.offsetLeft;}if(isNaN(W[1])){W[1]=(U=="relative")?0:V.offsetTop;}if(S[0]!==null){V.style.left=S[0]-X[0]+W[0]+"px";}if(S[1]!==null){V.style.top=S[1]-X[1]+W[1]+"px";}if(!R){var T=this.getXY(V);if((S[0]!==null&&T[0]!=S[0])||(S[1]!==null&&T[1]!=S[1])){this.setXY(V,S,true);}}};B.Dom.batch(P,Q,B.Dom,true);},setX:function(Q,P){B.Dom.setXY(Q,[P,null]);},setY:function(P,Q!
 ){B.Dom.setXY(P,[null,Q]);},getRegion:function(P){var Q=function(R){if((R.parentNode===null||R.offsetParent===null||this.getStyle(R,"display")=="none")&&R!=R.ownerDocument.body){return false;}var S=B.Region.getRegion(R);return S;};return B.Dom.batch(P,Q,B.Dom,true);},getClientWidth:function(){return B.Dom.getViewportWidth();},getClientHeight:function(){return B.Dom.getViewportHeight();},getElementsByClassName:function(T,X,U,V){X=X||"*";U=(U)?B.Dom.get(U):null||M;if(!U){return[];}var Q=[],P=U.getElementsByTagName(X),W=O(T);for(var R=0,S=P.length;R<S;++R){if(W.test(P[R].className)){Q[Q.length]=P[R];if(V){V.call(P[R],P[R]);}}}return Q;},hasClass:function(R,Q){var P=O(Q);var S=function(T){return P.test(T.className);};return B.Dom.batch(R,S,B.Dom,true);},addClass:function(Q,P){var R=function(S){if(this.hasClass(S,P)){return false;}S.className=YAHOO.lang.trim([S.className,P].join(" "));return true;};return B.Dom.batch(Q,R,B.Dom,true);},removeClass:function(R,Q){var P=O(Q);var S=f!
 unction(T){if(!Q||!this.hasClass(T,Q)){return false;}var U=T.c!
 lassName
;T.className=U.replace(P," ");if(this.hasClass(T,Q)){this.removeClass(T,Q);}T.className=YAHOO.lang.trim(T.className);return true;};return B.Dom.batch(R,S,B.Dom,true);},replaceClass:function(S,Q,P){if(!P||Q===P){return false;}var R=O(Q);var T=function(U){if(!this.hasClass(U,Q)){this.addClass(U,P);return true;}U.className=U.className.replace(R," "+P+" ");if(this.hasClass(U,Q)){this.replaceClass(U,Q,P);}U.className=YAHOO.lang.trim(U.className);return true;};return B.Dom.batch(S,T,B.Dom,true);},generateId:function(P,R){R=R||"yui-gen";var Q=function(S){if(S&&S.id){return S.id;}var T=R+YAHOO.env._id_counter++;if(S){S.id=T;}return T;};return B.Dom.batch(P,Q,B.Dom,true)||Q.apply(B.Dom,arguments);},isAncestor:function(P,Q){P=B.Dom.get(P);Q=B.Dom.get(Q);if(!P||!Q){return false;}if(P.contains&&Q.nodeType&&!L){return P.contains(Q);}else{if(P.compareDocumentPosition&&Q.nodeType){return !!(P.compareDocumentPosition(Q)&16);}else{if(Q.nodeType){return !!this.getAncestorBy(Q,function(R){retu!
 rn R==P;});}}}return false;},inDocument:function(P){return this.isAncestor(M.documentElement,P);},getElementsBy:function(W,Q,R,T){Q=Q||"*";R=(R)?B.Dom.get(R):null||M;if(!R){return[];}var S=[],V=R.getElementsByTagName(Q);for(var U=0,P=V.length;U<P;++U){if(W(V[U])){S[S.length]=V[U];if(T){T(V[U]);}}}return S;},batch:function(T,W,V,R){T=(T&&(T.tagName||T.item))?T:B.Dom.get(T);if(!T||!W){return false;}var S=(R)?V:window;if(T.tagName||T.length===undefined){return W.call(S,T,V);}var U=[];for(var Q=0,P=T.length;Q<P;++Q){U[U.length]=W.call(S,T[Q],V);}return U;},getDocumentHeight:function(){var Q=(M.compatMode!="CSS1Compat")?M.body.scrollHeight:M.documentElement.scrollHeight;var P=Math.max(Q,B.Dom.getViewportHeight());return P;},getDocumentWidth:function(){var Q=(M.compatMode!="CSS1Compat")?M.body.scrollWidth:M.documentElement.scrollWidth;var P=Math.max(Q,B.Dom.getViewportWidth());return P;},getViewportHeight:function(){var P=self.innerHeight;
+var Q=M.compatMode;if((Q||G)&&!C){P=(Q=="CSS1Compat")?M.documentElement.clientHeight:M.body.clientHeight;}return P;},getViewportWidth:function(){var P=self.innerWidth;var Q=M.compatMode;if(Q||G){P=(Q=="CSS1Compat")?M.documentElement.clientWidth:M.body.clientWidth;}return P;},getAncestorBy:function(P,Q){while(P=P.parentNode){if(D(P,Q)){return P;}}return null;},getAncestorByClassName:function(Q,P){Q=B.Dom.get(Q);if(!Q){return null;}var R=function(S){return B.Dom.hasClass(S,P);};return B.Dom.getAncestorBy(Q,R);},getAncestorByTagName:function(Q,P){Q=B.Dom.get(Q);if(!Q){return null;}var R=function(S){return S.tagName&&S.tagName.toUpperCase()==P.toUpperCase();};return B.Dom.getAncestorBy(Q,R);},getPreviousSiblingBy:function(P,Q){while(P){P=P.previousSibling;if(D(P,Q)){return P;}}return null;},getPreviousSibling:function(P){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getPreviousSiblingBy(P);},getNextSiblingBy:function(P,Q){while(P){P=P.nextSibling;if(D(P,Q)){return P;}}return !
 null;},getNextSibling:function(P){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getNextSiblingBy(P);},getFirstChildBy:function(P,R){var Q=(D(P.firstChild,R))?P.firstChild:null;return Q||B.Dom.getNextSiblingBy(P.firstChild,R);},getFirstChild:function(P,Q){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getFirstChildBy(P);},getLastChildBy:function(P,R){if(!P){return null;}var Q=(D(P.lastChild,R))?P.lastChild:null;return Q||B.Dom.getPreviousSiblingBy(P.lastChild,R);},getLastChild:function(P){P=B.Dom.get(P);return B.Dom.getLastChildBy(P);},getChildrenBy:function(Q,S){var R=B.Dom.getFirstChildBy(Q,S);var P=R?[R]:[];B.Dom.getNextSiblingBy(R,function(T){if(!S||S(T)){P[P.length]=T;}return false;});return P;},getChildren:function(P){P=B.Dom.get(P);if(!P){}return B.Dom.getChildrenBy(P);},getDocumentScrollLeft:function(P){P=P||M;return Math.max(P.documentElement.scrollLeft,P.body.scrollLeft);},getDocumentScrollTop:function(P){P=P||M;return Math.max(P.documentElement.scrollTop,P.body!
 .scrollTop);},insertBefore:function(Q,P){Q=B.Dom.get(Q);P=B.Do!
 m.get(P)
;if(!Q||!P||!P.parentNode){return null;}return P.parentNode.insertBefore(Q,P);},insertAfter:function(Q,P){Q=B.Dom.get(Q);P=B.Dom.get(P);if(!Q||!P||!P.parentNode){return null;}if(P.nextSibling){return P.parentNode.insertBefore(Q,P.nextSibling);}else{return P.parentNode.appendChild(Q);}},getClientRegion:function(){var R=B.Dom.getDocumentScrollTop(),Q=B.Dom.getDocumentScrollLeft(),S=B.Dom.getViewportWidth()+Q,P=B.Dom.getViewportHeight()+R;return new B.Region(R,S,P,Q);}};var H=function(){if(M.documentElement.getBoundingClientRect){return function(Q){var R=Q.getBoundingClientRect();var P=Q.ownerDocument;return[R.left+B.Dom.getDocumentScrollLeft(P),R.top+B.Dom.getDocumentScrollTop(P)];};}else{return function(R){var S=[R.offsetLeft,R.offsetTop];var Q=R.offsetParent;var P=(L&&B.Dom.getStyle(R,"position")=="absolute"&&R.offsetParent==R.ownerDocument.body);if(Q!=R){while(Q){S[0]+=Q.offsetLeft;S[1]+=Q.offsetTop;if(!P&&L&&B.Dom.getStyle(Q,"position")=="absolute"){P=true;}Q=Q.offsetParen!
 t;}}if(P){S[0]-=R.ownerDocument.body.offsetLeft;S[1]-=R.ownerDocument.body.offsetTop;}Q=R.parentNode;while(Q.tagName&&!E.ROOT_TAG.test(Q.tagName)){if(Q.scrollTop||Q.scrollLeft){if(!E.OP_SCROLL.test(B.Dom.getStyle(Q,"display"))){if(!C||B.Dom.getStyle(Q,"overflow")!=="visible"){S[0]-=Q.scrollLeft;S[1]-=Q.scrollTop;}}}Q=Q.parentNode;}return S;};}}();})();YAHOO.util.Region=function(C,D,A,B){this.top=C;this[1]=C;this.right=D;this.bottom=A;this.left=B;this[0]=B;};YAHOO.util.Region.prototype.contains=function(A){return(A.left>=this.left&&A.right<=this.right&&A.top>=this.top&&A.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(E){var C=Math.max(this.top,E.top);var D=Math.min(this.right,E.right);var A=Math.min(this.bottom,E.bottom);var B=Math.max(this.left,E.left);if(A>=C&&D>=B){return new YAHOO.util.Region(C,D,A,B);}else{return null;}};YAHOO.util.Region.prototy!
 pe.union=function(E){var C=Math.min(this.top,E.top);var D=Math!
 .max(thi
s.right,E.right);var A=Math.max(this.bottom,E.bottom);var B=Math.min(this.left,E.left);return new YAHOO.util.Region(C,D,A,B);};YAHOO.util.Region.prototype.toString=function(){return("Region {"+"top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+"}");};YAHOO.util.Region.getRegion=function(D){var F=YAHOO.util.Dom.getXY(D);var C=F[1];var E=F[0]+D.offsetWidth;var A=F[1]+D.offsetHeight;var B=F[0];return new YAHOO.util.Region(C,E,A,B);};YAHOO.util.Point=function(A,B){if(YAHOO.lang.isArray(A)){B=A[1];A=A[0];}this.x=this.right=this.left=this[0]=A;this.y=this.top=this.bottom=this[1]=B;};YAHOO.util.Point.prototype=new YAHOO.util.Region();YAHOO.register("dom",YAHOO.util.Dom,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/dom/dom.js
===================================================================
--- trunk/root/static/yui/dom/dom.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/dom/dom.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The dom module provides helper methods for manipulating Dom elements.
@@ -14,11 +14,12 @@
     var Y = YAHOO.util,     // internal shorthand
         getStyle,           // for load time browser branching
         setStyle,           // ditto
-        id_counter = 0,     // for use with generateId
         propertyCache = {}, // for faster hyphen converts
         reClassNameCache = {},          // cache regexes for className
         document = window.document;     // cache for faster lookups
     
+    YAHOO.env._id_counter = YAHOO.env._id_counter || 0;     // for use with generateId (global to save state if Dom is overwritten)
+
     // brower detection
     var isOpera = YAHOO.env.ua.opera,
         isSafari = YAHOO.env.ua.webkit, 
@@ -28,7 +29,8 @@
     // regex cache
     var patterns = {
         HYPHEN: /(-[a-z])/i, // to normalize get/setStyle
-        ROOT_TAG: /^body|html$/i // body for quirks mode, html for standards
+        ROOT_TAG: /^body|html$/i, // body for quirks mode, html for standards,
+        OP_SCROLL:/^(?:inline|table-row)$/i
     };
 
     var toCamel = function(property) {
@@ -70,7 +72,7 @@
                 property = 'cssFloat';
             }
 
-            var computed = document.defaultView.getComputedStyle(el, '');
+            var computed = el.ownerDocument.defaultView.getComputedStyle(el, '');
             if (computed) { // test computed before touching for safari
                 value = computed[toCamel(property)];
             }
@@ -148,11 +150,11 @@
          * @return {HTMLElement | Array} A DOM reference to an HTML element or an array of HTMLElements.
          */
         get: function(el) {
-            if (el && (el.tagName || el.item)) { // HTMLElement, or HTMLCollection
+            if (el && (el.nodeType || el.item)) { // Node, or NodeList
                 return el;
             }
 
-            if (YAHOO.lang.isString(el) || !el) { // HTMLElement or null
+            if (YAHOO.lang.isString(el) || !el) { // id or null
                 return document.getElementById(el);
             }
             
@@ -334,7 +336,7 @@
         getRegion: function(el) {
             var f = function(el) {
                 if ( (el.parentNode === null || el.offsetParent === null ||
-                        this.getStyle(el, 'display') == 'none') && el != document.body) {
+                        this.getStyle(el, 'display') == 'none') && el != el.ownerDocument.body) {
                     return false;
                 }
 
@@ -447,7 +449,7 @@
             var re = getClassRegEx(className);
             
             var f = function(el) {
-                if (!this.hasClass(el, className)) {
+                if (!className || !this.hasClass(el, className)) {
                     return false; // not present
                 }                 
 
@@ -516,7 +518,7 @@
                     return el.id;
                 } 
 
-                var id = prefix + id_counter++;
+                var id = prefix + YAHOO.env._id_counter++;
 
                 if (el) {
                     el.id = id;
@@ -1022,10 +1024,14 @@
                 // account for any scrolled ancestors
                 while ( parentNode.tagName && !patterns.ROOT_TAG.test(parentNode.tagName) ) 
                 {
-                   // work around opera inline/table scrollLeft/Top bug
-                   if (Y.Dom.getStyle(parentNode, 'display').search(/^inline|table-row.*$/i)) { 
-                        pos[0] -= parentNode.scrollLeft;
-                        pos[1] -= parentNode.scrollTop;
+                    if (parentNode.scrollTop || parentNode.scrollLeft) {
+                        // work around opera inline/table scrollLeft/Top bug (false reports offset as scroll)
+                        if (!patterns.OP_SCROLL.test(Y.Dom.getStyle(parentNode, 'display'))) { 
+                            if (!isOpera || Y.Dom.getStyle(parentNode, 'overflow') !== 'visible') { // opera inline-block misreports when visible
+                                pos[0] -= parentNode.scrollLeft;
+                                pos[1] -= parentNode.scrollTop;
+                            }
+                        }
                     }
                     
                     parentNode = parentNode.parentNode; 
@@ -1221,4 +1227,4 @@
 
 YAHOO.util.Point.prototype = new YAHOO.util.Region();
 
-YAHOO.register("dom", YAHOO.util.Dom, {version: "2.4.1", build: "742"});
+YAHOO.register("dom", YAHOO.util.Dom, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/dragdrop/README
===================================================================
--- trunk/root/static/yui/dragdrop/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/dragdrop/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,14 @@
 Drag and Drop Release Notes
 
-2.4.1
-No change
+2.5.1
+    * No change
 
+2.5.0
+    * Added CustomEvents in addition to method overrides
+        (See API Docs for more information)
+    * Added an IFRAME element to the proxy div (only in IE) to keep select
+        elements and other object from bleeding through
+
 2.4.0
   * Added configuration option called "dragOnly". If dragOnly is set to true,
     all event in the fireEvents method will not fire. These events are:

Modified: trunk/root/static/yui/dragdrop/dragdrop-debug.js
===================================================================
--- trunk/root/static/yui/dragdrop/dragdrop-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/dragdrop/dragdrop-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The drag and drop utility provides a framework for building drag and drop
@@ -33,7 +33,6 @@
     var Event = YAHOO.util.Event;
 
     return {
-
         /**
          * Two dimensional Array of registered DragDrop objects.  The first 
          * dimension is the DragDrop item group, the second the DragDrop 
@@ -576,11 +575,13 @@
             YAHOO.log("firing drag start events", "info", "DragDropMgr");
             clearTimeout(this.clickTimeout);
             var dc = this.dragCurrent;
-            if (dc) {
+            if (dc && dc.events.b4StartDrag) {
                 dc.b4StartDrag(x, y);
+                dc.fireEvent('b4StartDragEvent', { x: x, y: y });
             }
-            if (dc) {
+            if (dc && dc.events.startDrag) {
                 dc.startDrag(x, y);
+                dc.fireEvent('startDragEvent', { x: x, y: y });
             }
             this.dragThreshMet = true;
         },
@@ -600,7 +601,7 @@
                 if (this.dragThreshMet) {
                     YAHOO.log("mouseup detected - completing drag", "info", "DragDropMgr");
                     if (this.fromTimeout) {
-                        YAHOO.log('fromTimeout is true (mouse didn\'t move), call handleMouseDown so we can get the dragOver event', 'info', 'DragDropMgr');
+                        YAHOO.log('fromTimeout is true (mouse didn\'t move), call handleMouseMove so we can get the dragOver event', 'info', 'DragDropMgr');
                         this.handleMouseMove(e);
                     }
                     this.fromTimeout = false;
@@ -651,17 +652,25 @@
          */
         stopDrag: function(e, silent) {
             // YAHOO.log("mouseup - removing event handlers");
-
+            var dc = this.dragCurrent;
             // Fire the drag end event for the item that was dragged
-            if (this.dragCurrent && !silent) {
+            if (dc && !silent) {
                 if (this.dragThreshMet) {
                     YAHOO.log("firing endDrag events", "info", "DragDropMgr");
-                    this.dragCurrent.b4EndDrag(e);
-                    this.dragCurrent.endDrag(e);
+                    if (dc.events.b4EndDrag) {
+                        dc.b4EndDrag(e);
+                        dc.fireEvent('b4EndDragEvent', { e: e });
+                    }
+                    if (dc.events.endDrag) {
+                        dc.endDrag(e);
+                        dc.fireEvent('endDragEvent', { e: e });
+                    }
                 }
-
-                YAHOO.log("firing dragdrop onMouseUp event", "info", "DragDropMgr");
-                this.dragCurrent.onMouseUp(e);
+                if (dc.events.mouseUp) {
+                    YAHOO.log("firing dragdrop onMouseUp event", "info", "DragDropMgr");
+                    dc.onMouseUp(e);
+                    dc.fireEvent('mouseUpEvent', { e: e });
+                }
             }
 
             this.dragCurrent = null;
@@ -697,6 +706,14 @@
                     YAHOO.log("button failure", "info", "DragDropMgr");
                     this.stopEvent(e);
                     return this.handleMouseUp(e);
+                } else {
+                    if (e.clientX < 0 || e.clientY < 0) {
+                        //This will stop the element from leaving the viewport in FF, Opera & Safari
+                        //Not turned on yet
+                        //YAHOO.log("Either clientX or clientY is negative, stop the event.", "info", "DragDropMgr");
+                        //this.stopEvent(e);
+                        //return false;
+                    }
                 }
 
                 if (!this.dragThreshMet) {
@@ -711,9 +728,13 @@
                 }
 
                 if (this.dragThreshMet) {
-                    dc.b4Drag(e);
-                    if (dc) {
+                    if (dc && dc.events.b4Drag) {
+                        dc.b4Drag(e);
+                        dc.fireEvent('b4DragEvent', { e: e});
+                    }
+                    if (dc && dc.events.drag) {
                         dc.onDrag(e);
+                        dc.fireEvent('dragEvent', { e: e});
                     }
                     if (dc) {
                         this.fireEvents(e, false);
@@ -748,18 +769,21 @@
                 pt = new YAHOO.util.Point(x,y),
                 pos = dc.getTargetCoord(pt.x, pt.y),
                 el = dc.getDragEl(),
+                events = ['out', 'over', 'drop', 'enter'],
                 curRegion = new YAHOO.util.Region( pos.y, 
                                                pos.x + el.offsetWidth,
                                                pos.y + el.offsetHeight, 
                                                pos.x ),
             
                 oldOvers = [], // cache the previous dragOver array
-                outEvts   = [],
-                overEvts  = [],
-                dropEvts  = [],
-                enterEvts = [],
                 inGroupsObj  = {},
-                inGroups  = [];
+                inGroups  = [],
+                data = {
+                    outEvts: [],
+                    overEvts: [],
+                    dropEvts: [],
+                    enterEvts: []
+                };
 
 
             // Check to see if the object(s) we were hovering over is no longer 
@@ -772,7 +796,7 @@
                     continue;
                 }
                 if (! this.isOverTarget(pt, ddo, this.mode, curRegion)) {
-                    outEvts.push( ddo );
+                    data.outEvts.push( ddo );
                 }
 
                 oldOvers[i] = true;
@@ -797,16 +821,16 @@
                             inGroupsObj[sGroup] = true;
                             // look for drop interactions
                             if (isDrop) {
-                                dropEvts.push( oDD );
+                                data.dropEvts.push( oDD );
                             // look for drag enter and drag over interactions
                             } else {
 
                                 // initial drag over: dragEnter fires
                                 if (!oldOvers[oDD.id]) {
-                                    enterEvts.push( oDD );
+                                    data.enterEvts.push( oDD );
                                 // subsequent drag overs: dragOver fires
                                 } else {
-                                    overEvts.push( oDD );
+                                    data.overEvts.push( oDD );
                                 }
 
                                 this.dragOvers[oDD.id] = oDD;
@@ -817,10 +841,10 @@
             }
 
             this.interactionInfo = {
-                out:       outEvts,
-                enter:     enterEvts,
-                over:      overEvts,
-                drop:      dropEvts,
+                out:       data.outEvts,
+                enter:     data.enterEvts,
+                over:      data.overEvts,
+                drop:      data.dropEvts,
                 point:     pt,
                 draggedRegion:    curRegion,
                 sourceRegion: this.locationCache[dc.id],
@@ -833,95 +857,51 @@
             }
 
             // notify about a drop that did not find a target
-            if (isDrop && !dropEvts.length) {
+            if (isDrop && !data.dropEvts.length) {
                 YAHOO.log(dc.id + " dropped, but not on a target", "info", "DragDropMgr");
                 this.interactionInfo.validDrop = false;
-                dc.onInvalidDrop(e);
+                if (dc.events.invalidDrop) {
+                    dc.onInvalidDrop(e);
+                    dc.fireEvent('invalidDropEvent', { e: e });
+                }
             }
 
-
-            if (this.mode) {
-                if (outEvts.length) {
-                    YAHOO.log(dc.id+" onDragOut: " + outEvts, "info", "DragDropMgr");
-                    dc.b4DragOut(e, outEvts);
-                    if (dc) {
-                        dc.onDragOut(e, outEvts);
-                    }
+            for (i = 0; i < events.length; i++) {
+                var tmp = null;
+                if (data[events[i] + 'Evts']) {
+                    tmp = data[events[i] + 'Evts'];
                 }
-
-                if (enterEvts.length) {
-                    YAHOO.log(dc.id+" onDragEnter: " + enterEvts + " (group: " + inGroups + ")", "info", "DragDropMgr");
-                    if (dc) {
-                        dc.onDragEnter(e, enterEvts, inGroups);
+                if (tmp && tmp.length) {
+                    var type = events[i].charAt(0).toUpperCase() + events[i].substr(1),
+                        ev = 'onDrag' + type,
+                        b4 = 'b4Drag' + type,
+                        cev = 'drag' + type + 'Event',
+                        check = 'drag' + type;
+                    
+                    if (this.mode) {
+                        YAHOO.log(dc.id + ' ' + ev + ': ' + tmp, "info", "DragDropMgr");
+                        if (dc.events[b4]) {
+                            dc[b4](e, tmp, inGroups);
+                            dc.fireEvent(b4 + 'Event', { event: e, info: tmp, group: inGroups });
+                        }
+                        if (dc.events[check]) {
+                            dc[ev](e, tmp, inGroups);
+                            dc.fireEvent(cev, { event: e, info: tmp, group: inGroups });
+                        }
+                    } else {
+                        for (var b = 0, len = tmp.length; b < len; ++b) {
+                            YAHOO.log(dc.id + ' ' + ev + ': ' + tmp[b].id, "info", "DragDropMgr");
+                            if (dc.events[b4]) {
+                                dc[b4](e, tmp[b].id, inGroups[0]);
+                                dc.fireEvent(b4 + 'Event', { event: e, info: tmp[b].id, group: inGroups[0] });
+                            }
+                            if (dc.events[check]) {
+                                dc[ev](e, tmp[b].id, inGroups[0]);
+                                dc.fireEvent(cev, { event: e, info: tmp[b].id, group: inGroups[0] });
+                            }
+                        }
                     }
                 }
-
-                if (overEvts.length) {
-                    YAHOO.log(dc.id+" onDragOver: " + overEvts + " (group: " + inGroups + ")", "info", "DragDropMgr");
-                    if (dc) {
-                        dc.b4DragOver(e, overEvts, inGroups);
-                    }
-
-                    if (dc) {
-                        dc.onDragOver(e, overEvts, inGroups);
-                    }
-                }
-
-                if (dropEvts.length) {
-                    YAHOO.log(dc.id+" onDragDrop: " + dropEvts + " (group: " + inGroups + ")", "info", "DragDropMgr");
-                    if (dc) {
-                        dc.b4DragDrop(e, dropEvts, inGroups);
-                    }
-                    if (dc) {
-                        dc.onDragDrop(e, dropEvts, inGroups);
-                    }
-                }
-
-            } else {
-                // fire dragout events
-                var len = 0;
-                for (i=0, len=outEvts.length; i<len; ++i) {
-                    YAHOO.log(dc.id+" onDragOut: " + outEvts[i].id, "info", "DragDropMgr");
-                    if (dc) {
-                        dc.b4DragOut(e, outEvts[i].id, inGroups[0]);
-                    }
-                    if (dc) {
-                        dc.onDragOut(e, outEvts[i].id, inGroups[0]);
-                    }
-                }
-                 
-                // fire enter events
-                for (i=0,len=enterEvts.length; i<len; ++i) {
-                    YAHOO.log(dc.id + " onDragEnter " + enterEvts[i].id + " (group: " + inGroups + ")", "info", "DragDropMgr");
-                    // dc.b4DragEnter(e, oDD.id);
-
-                    if (dc) {
-                        dc.onDragEnter(e, enterEvts[i].id, inGroups[0]);
-                    }
-                }
-         
-                // fire over events
-                for (i=0,len=overEvts.length; i<len; ++i) {
-                    YAHOO.log(dc.id + " onDragOver " + overEvts[i].id + " (group: " + inGroups + ")", "info", "DragDropMgr");
-                    if (dc) {
-                        dc.b4DragOver(e, overEvts[i].id, inGroups[0]);
-                    }
-                    if (dc) {
-                        dc.onDragOver(e, overEvts[i].id, inGroups[0]);
-                    }
-                }
-
-                // fire drop events
-                for (i=0, len=dropEvts.length; i<len; ++i) {
-                    YAHOO.log(dc.id + " dropped on " + dropEvts[i].id + " (group: " + inGroups + ")", "info", "DragDropMgr");
-                    if (dc) {
-                        dc.b4DragDrop(e, dropEvts[i].id, inGroups[0]);
-                    }
-                    if (dc) {
-                        dc.onDragDrop(e, dropEvts[i].id, inGroups[0]);
-                    }
-                }
-
             }
         },
 
@@ -1531,8 +1511,21 @@
 };
 
 YAHOO.util.DragDrop.prototype = {
-
     /**
+     * An Object Literal containing the events that we will be using: mouseDown, b4MouseDown, mouseUp, b4StartDrag, startDrag, b4EndDrag, endDrag, mouseUp, drag, b4Drag, invalidDrop, b4DragOut, dragOut, dragEnter, b4DragOver, dragOver, b4DragDrop, dragDrop
+     * By setting any of these to false, then event will not be fired.
+     * @property events
+     * @type object
+     */
+    events: null,
+    /**
+    * @method on
+    * @description Shortcut for EventProvider.subscribe, see <a href="YAHOO.util.EventProvider.html#subscribe">YAHOO.util.EventProvider.subscribe</a>
+    */
+    on: function() {
+        this.subscribe.apply(this, arguments);
+    },
+    /**
      * The id of the element associated with this object.  This is what we 
      * refer to as the "linked element" because the size and position of 
      * this element is used to determine when the drag and drop objects have 
@@ -2008,7 +2001,12 @@
         this.initTarget(id, sGroup, config);
         Event.on(this._domRef || this.id, "mousedown", 
                         this.handleMouseDown, this, true);
+
         // Event.on(this.id, "selectstart", Event.preventDefault);
+        for (var i in this.events) {
+            this.createEvent(i + 'Event');
+        }
+        
     },
 
     /**
@@ -2024,6 +2022,8 @@
         // configuration attributes 
         this.config = config || {};
 
+        this.events = {};
+
         // create a local reference to the drag and drop manager
         this.DDM = YAHOO.util.DDM;
 
@@ -2075,7 +2075,35 @@
      * @method applyConfig
      */
     applyConfig: function() {
+        this.events = {
+            mouseDown: true,
+            b4MouseDown: true,
+            mouseUp: true,
+            b4StartDrag: true,
+            startDrag: true,
+            b4EndDrag: true,
+            endDrag: true,
+            drag: true,
+            b4Drag: true,
+            invalidDrop: true,
+            b4DragOut: true,
+            dragOut: true,
+            dragEnter: true,
+            b4DragOver: true,
+            dragOver: true,
+            b4DragDrop: true,
+            dragDrop: true
+        };
+        
+        if (this.config.events) {
+            for (var i in this.config.events) {
+                if (this.config.events[i] === false) {
+                    this.events[i] = false;
+                }
+            }
+        }
 
+
         // configurable properties: 
         //    padding, isTarget, maintainOffset, primaryButtonOnly
         this.padding           = this.config.padding || [0, 0, 0, 0];
@@ -2131,7 +2159,11 @@
         var el = this.getEl();
 
         if (!this.DDM.verifyEl(el)) {
-            this.logger.log(this.id + " element is broken");
+            if (el && el.style && (el.style.display == 'none')) {
+                this.logger.log(this.id + " can not get initial position, element style is display: none");
+            } else {
+                this.logger.log(this.id + " element is broken");
+            }
             return;
         }
 
@@ -2295,7 +2327,13 @@
 
         // firing the mousedown events prior to calculating positions
         var b4Return = this.b4MouseDown(e);
+        if (this.events.b4MouseDown) {
+            b4Return = this.fireEvent('b4MouseDownEvent', e);
+        }
         var mDownReturn = this.onMouseDown(e);
+        if (this.events.mouseDown) {
+            mDownReturn = this.fireEvent('mouseDownEvent', e);
+        }
 
         if ((b4Return === false) || (mDownReturn === false)) {
             this.logger.log('b4MouseDown or onMouseDown returned false, exiting drag');
@@ -2342,10 +2380,9 @@
      * @description Method validates that the clicked element
      * was indeed the handle or a valid child of the handle
      * @param {Event} e 
-     * @private
      */
     clickValidator: function(e) {
-        var target = Event.getTarget(e);
+        var target = YAHOO.util.Event.getTarget(e);
         return ( this.isValidHandleChild(target) &&
                     (this.id == this.handleElId || 
                         this.DDM.handleWasClicked(target, this.id)) );
@@ -2711,7 +2748,100 @@
     }
 
 };
+YAHOO.augment(YAHOO.util.DragDrop, YAHOO.util.EventProvider);
 
+/**
+* @event mouseDownEvent
+* @description Provides access to the mousedown event. The mousedown does not always result in a drag operation.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4MouseDownEvent
+* @description Provides access to the mousedown event, before the mouseDownEvent gets fired. Returning false will cancel the drag.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event mouseUpEvent
+* @description Fired from inside DragDropMgr when the drag operation is finished.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4StartDragEvent
+* @description Fires before the startDragEvent, returning false will cancel the startDrag Event.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event startDragEvent
+* @description Occurs after a mouse down and the drag threshold has been met. The drag threshold default is either 3 pixels of mouse movement or 1 full second of holding the mousedown. 
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4EndDragEvent
+* @description Fires before the endDragEvent. Returning false will cancel.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event endDragEvent
+* @description Fires on the mouseup event after a drag has been initiated (startDrag fired).
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event dragEvent
+* @description Occurs every mousemove event while dragging.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragEvent
+* @description Fires before the dragEvent.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event invalidDropEvent
+* @description Fires when the dragged objects is dropped in a location that contains no drop targets.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragOutEvent
+* @description Fires before the dragOutEvent
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragOutEvent
+* @description Fires when a dragged object is no longer over an object that had the onDragEnter fire. 
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragEnterEvent
+* @description Occurs when the dragged object first interacts with another targettable drag and drop object.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragOverEvent
+* @description Fires before the dragOverEvent.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragOverEvent
+* @description Fires every mousemove event while over a drag and drop object.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragDropEvent 
+* @description Fires before the dragDropEvent
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragDropEvent
+* @description Fires when the dragged objects is dropped on another.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
 })();
 /**
  * A DragDrop implementation where the linked element follows the 
@@ -2811,12 +2941,9 @@
         } else {
             YAHOO.util.Dom.setStyle(el, "left", (oCoord.x + this.deltaSetXY[0]) + "px");
             YAHOO.util.Dom.setStyle(el, "top",  (oCoord.y + this.deltaSetXY[1]) + "px");
-            //el.style.left = (oCoord.x + this.deltaSetXY[0]) + "px";
-            //el.style.top = (oCoord.y + this.deltaSetXY[1]) + "px";
         }
         
         this.cachePosition(oCoord.x, oCoord.y);
-        //DAV
         var self = this;
         setTimeout(function() {
             self.autoScroll.call(self, oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
@@ -2991,6 +3118,98 @@
 
     */
 
+/**
+* @event mouseDownEvent
+* @description Provides access to the mousedown event. The mousedown does not always result in a drag operation.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4MouseDownEvent
+* @description Provides access to the mousedown event, before the mouseDownEvent gets fired. Returning false will cancel the drag.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event mouseUpEvent
+* @description Fired from inside DragDropMgr when the drag operation is finished.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4StartDragEvent
+* @description Fires before the startDragEvent, returning false will cancel the startDrag Event.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event startDragEvent
+* @description Occurs after a mouse down and the drag threshold has been met. The drag threshold default is either 3 pixels of mouse movement or 1 full second of holding the mousedown. 
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4EndDragEvent
+* @description Fires before the endDragEvent. Returning false will cancel.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event endDragEvent
+* @description Fires on the mouseup event after a drag has been initiated (startDrag fired).
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event dragEvent
+* @description Occurs every mousemove event while dragging.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragEvent
+* @description Fires before the dragEvent.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event invalidDropEvent
+* @description Fires when the dragged objects is dropped in a location that contains no drop targets.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragOutEvent
+* @description Fires before the dragOutEvent
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragOutEvent
+* @description Fires when a dragged object is no longer over an object that had the onDragEnter fire. 
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragEnterEvent
+* @description Occurs when the dragged object first interacts with another targettable drag and drop object.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragOverEvent
+* @description Fires before the dragOverEvent.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragOverEvent
+* @description Fires every mousemove event while over a drag and drop object.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragDropEvent 
+* @description Fires before the dragDropEvent
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragDropEvent
+* @description Fires when the dragged objects is dropped on another.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
 });
 /**
  * A DragDrop implementation that inserts an empty, bordered div into
@@ -3087,6 +3306,27 @@
             Dom.setStyle(_data, 'opacity', '0');
             div.appendChild(_data);
 
+            /**
+            * It seems that IE will fire the mouseup event if you pass a proxy element over a select box
+            * Placing the IFRAME element inside seems to stop this issue
+            */
+            if (YAHOO.env.ua.ie) {
+                //Only needed for Internet Explorer
+                var ifr = document.createElement('iframe');
+                ifr.setAttribute('src', 'about:blank');
+                ifr.setAttribute('scrolling', 'no');
+                ifr.setAttribute('frameborder', '0');
+                div.insertBefore(ifr, div.firstChild);
+                Dom.setStyle(ifr, 'height', '100%');
+                Dom.setStyle(ifr, 'width', '100%');
+                Dom.setStyle(ifr, 'position', 'absolute');
+                Dom.setStyle(ifr, 'top', '0');
+                Dom.setStyle(ifr, 'left', '0');
+                Dom.setStyle(ifr, 'opacity', '0');
+                Dom.setStyle(ifr, 'zIndex', '-1');
+                Dom.setStyle(ifr.nextSibling, 'zIndex', '2');
+            }
+
             // appendChild can blow up IE if invoked prior to the window load event
             // while rendering a table.  It is possible there are other scenarios 
             // that would cause this to happen as well.
@@ -3223,7 +3463,99 @@
     toString: function() {
         return ("DDProxy " + this.id);
     }
+/**
+* @event mouseDownEvent
+* @description Provides access to the mousedown event. The mousedown does not always result in a drag operation.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
 
+/**
+* @event b4MouseDownEvent
+* @description Provides access to the mousedown event, before the mouseDownEvent gets fired. Returning false will cancel the drag.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event mouseUpEvent
+* @description Fired from inside DragDropMgr when the drag operation is finished.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4StartDragEvent
+* @description Fires before the startDragEvent, returning false will cancel the startDrag Event.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event startDragEvent
+* @description Occurs after a mouse down and the drag threshold has been met. The drag threshold default is either 3 pixels of mouse movement or 1 full second of holding the mousedown. 
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4EndDragEvent
+* @description Fires before the endDragEvent. Returning false will cancel.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event endDragEvent
+* @description Fires on the mouseup event after a drag has been initiated (startDrag fired).
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event dragEvent
+* @description Occurs every mousemove event while dragging.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragEvent
+* @description Fires before the dragEvent.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event invalidDropEvent
+* @description Fires when the dragged objects is dropped in a location that contains no drop targets.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragOutEvent
+* @description Fires before the dragOutEvent
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragOutEvent
+* @description Fires when a dragged object is no longer over an object that had the onDragEnter fire. 
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragEnterEvent
+* @description Occurs when the dragged object first interacts with another targettable drag and drop object.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragOverEvent
+* @description Fires before the dragOverEvent.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragOverEvent
+* @description Fires every mousemove event while over a drag and drop object.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragDropEvent 
+* @description Fires before the dragDropEvent
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragDropEvent
+* @description Fires when the dragged objects is dropped on another.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
 });
 /**
  * A DragDrop implementation that does not move, but can be a drop 
@@ -3252,4 +3584,4 @@
         return ("DDTarget " + this.id);
     }
 });
-YAHOO.register("dragdrop", YAHOO.util.DragDropMgr, {version: "2.4.1", build: "742"});
+YAHOO.register("dragdrop", YAHOO.util.DragDropMgr, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/dragdrop/dragdrop-min.js
===================================================================
--- trunk/root/static/yui/dragdrop/dragdrop-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/dragdrop/dragdrop-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,10 +1,10 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-if(!YAHOO.util.DragDropMgr){YAHOO.util.DragDropMgr=function(){var A=YAHOO.util.Event;return{ids:{},handleIds:{},dragCurrent:null,dragOvers:{},deltaX:0,deltaY:0,preventDefault:true,stopPropagation:true,initialized:false,locked:false,interactionInfo:null,init:function(){this.initialized=true;},POINT:0,INTERSECT:1,STRICT_INTERSECT:2,mode:0,_execOnAll:function(D,C){for(var E in this.ids){for(var B in this.ids[E]){var F=this.ids[E][B];if(!this.isTypeOfDD(F)){continue;}F[D].apply(F,C);}}},_onLoad:function(){this.init();A.on(document,"mouseup",this.handleMouseUp,this,true);A.on(document,"mousemove",this.handleMouseMove,this,true);A.on(window,"unload",this._onUnload,this,true);A.on(window,"resize",this._onResize,this,true);},_onResize:function(B){this._execOnAll("resetConstraints",[]);},lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isLocked:function(){return this.locked;},locationCache:{},useCache:true,clickPixelThresh:3,clickTimeThresh:1000,dragThreshMet!
 :false,clickTimeout:null,startX:0,startY:0,fromTimeout:false,regDragDrop:function(C,B){if(!this.initialized){this.init();}if(!this.ids[B]){this.ids[B]={};}this.ids[B][C.id]=C;},removeDDFromGroup:function(D,B){if(!this.ids[B]){this.ids[B]={};}var C=this.ids[B];if(C&&C[D.id]){delete C[D.id];}},_remove:function(C){for(var B in C.groups){if(B&&this.ids[B][C.id]){delete this.ids[B][C.id];}}delete this.handleIds[C.id];},regHandle:function(C,B){if(!this.handleIds[C]){this.handleIds[C]={};}this.handleIds[C][B]=B;},isDragDrop:function(B){return(this.getDDById(B))?true:false;},getRelated:function(G,C){var F=[];for(var E in G.groups){for(var D in this.ids[E]){var B=this.ids[E][D];if(!this.isTypeOfDD(B)){continue;}if(!C||B.isTarget){F[F.length]=B;}}}return F;},isLegalTarget:function(F,E){var C=this.getRelated(F,true);for(var D=0,B=C.length;D<B;++D){if(C[D].id==E.id){return true;}}return false;},isTypeOfDD:function(B){return(B&&B.__ygDragDrop);},isHandle:function(C,B){return(this.handle!
 Ids[C]&&this.handleIds[C][B]);},getDDById:function(C){for(var !
 B in thi
s.ids){if(this.ids[B][C]){return this.ids[B][C];}}return null;},handleMouseDown:function(D,C){this.currentTarget=YAHOO.util.Event.getTarget(D);this.dragCurrent=C;var B=C.getEl();this.startX=YAHOO.util.Event.getPageX(D);this.startY=YAHOO.util.Event.getPageY(D);this.deltaX=this.startX-B.offsetLeft;this.deltaY=this.startY-B.offsetTop;this.dragThreshMet=false;this.clickTimeout=setTimeout(function(){var E=YAHOO.util.DDM;E.startDrag(E.startX,E.startY);E.fromTimeout=true;},this.clickTimeThresh);},startDrag:function(B,D){clearTimeout(this.clickTimeout);var C=this.dragCurrent;if(C){C.b4StartDrag(B,D);}if(C){C.startDrag(B,D);}this.dragThreshMet=true;},handleMouseUp:function(B){if(this.dragCurrent){clearTimeout(this.clickTimeout);if(this.dragThreshMet){if(this.fromTimeout){this.handleMouseMove(B);}this.fromTimeout=false;this.fireEvents(B,true);}else{}this.stopDrag(B);this.stopEvent(B);}},stopEvent:function(B){if(this.stopPropagation){YAHOO.util.Event.stopPropagation(B);}if(this.prevent!
 Default){YAHOO.util.Event.preventDefault(B);}},stopDrag:function(C,B){if(this.dragCurrent&&!B){if(this.dragThreshMet){this.dragCurrent.b4EndDrag(C);this.dragCurrent.endDrag(C);}this.dragCurrent.onMouseUp(C);}this.dragCurrent=null;this.dragOvers={};},handleMouseMove:function(E){var B=this.dragCurrent;if(B){if(YAHOO.util.Event.isIE&&!E.button){this.stopEvent(E);return this.handleMouseUp(E);}if(!this.dragThreshMet){var D=Math.abs(this.startX-YAHOO.util.Event.getPageX(E));var C=Math.abs(this.startY-YAHOO.util.Event.getPageY(E));if(D>this.clickPixelThresh||C>this.clickPixelThresh){this.startDrag(this.startX,this.startY);}}if(this.dragThreshMet){B.b4Drag(E);if(B){B.onDrag(E);}if(B){this.fireEvents(E,false);}}this.stopEvent(E);}},fireEvents:function(T,J){var V=this.dragCurrent;if(!V||V.isLocked()||V.dragOnly){return ;}var L=YAHOO.util.Event.getPageX(T),K=YAHOO.util.Event.getPageY(T),M=new YAHOO.util.Point(L,K),H=V.getTargetCoord(M.x,M.y),E=V.getDragEl(),S=new YAHOO.util.Region(H.y!
 ,H.x+E.offsetWidth,H.y+E.offsetHeight,H.x),G=[],I=[],D=[],U=[]!
 ,R=[],C=
{},N=[];for(var P in this.dragOvers){var W=this.dragOvers[P];if(!this.isTypeOfDD(W)){continue;}if(!this.isOverTarget(M,W,this.mode,S)){I.push(W);}G[P]=true;delete this.dragOvers[P];}for(var O in V.groups){if("string"!=typeof O){continue;}for(P in this.ids[O]){var F=this.ids[O][P];if(!this.isTypeOfDD(F)){continue;}if(F.isTarget&&!F.isLocked()&&F!=V){if(this.isOverTarget(M,F,this.mode,S)){C[O]=true;if(J){U.push(F);}else{if(!G[F.id]){R.push(F);}else{D.push(F);}this.dragOvers[F.id]=F;}}}}}this.interactionInfo={out:I,enter:R,over:D,drop:U,point:M,draggedRegion:S,sourceRegion:this.locationCache[V.id],validDrop:J};for(var B in C){N.push(B);}if(J&&!U.length){this.interactionInfo.validDrop=false;V.onInvalidDrop(T);}if(this.mode){if(I.length){V.b4DragOut(T,I);if(V){V.onDragOut(T,I);}}if(R.length){if(V){V.onDragEnter(T,R,N);}}if(D.length){if(V){V.b4DragOver(T,D,N);}if(V){V.onDragOver(T,D,N);}}if(U.length){if(V){V.b4DragDrop(T,U,N);}if(V){V.onDragDrop(T,U,N);}}}else{var Q=0;for(P=0,Q=I.!
 length;P<Q;++P){if(V){V.b4DragOut(T,I[P].id,N[0]);}if(V){V.onDragOut(T,I[P].id,N[0]);}}for(P=0,Q=R.length;P<Q;++P){if(V){V.onDragEnter(T,R[P].id,N[0]);}}for(P=0,Q=D.length;P<Q;++P){if(V){V.b4DragOver(T,D[P].id,N[0]);}if(V){V.onDragOver(T,D[P].id,N[0]);}}for(P=0,Q=U.length;P<Q;++P){if(V){V.b4DragDrop(T,U[P].id,N[0]);}if(V){V.onDragDrop(T,U[P].id,N[0]);}}}},getBestMatch:function(D){var F=null;var C=D.length;if(C==1){F=D[0];}else{for(var E=0;E<C;++E){var B=D[E];if(this.mode==this.INTERSECT&&B.cursorIsOver){F=B;break;}else{if(!F||!F.overlap||(B.overlap&&F.overlap.getArea()<B.overlap.getArea())){F=B;}}}}return F;},refreshCache:function(C){var E=C||this.ids;for(var B in E){if("string"!=typeof B){continue;}for(var D in this.ids[B]){var F=this.ids[B][D];if(this.isTypeOfDD(F)){var G=this.getLocation(F);if(G){this.locationCache[F.id]=G;}else{delete this.locationCache[F.id];}}}}},verifyEl:function(C){try{if(C){var B=C.offsetParent;
-if(B){return true;}}}catch(D){}return false;},getLocation:function(G){if(!this.isTypeOfDD(G)){return null;}var E=G.getEl(),J,D,C,L,K,M,B,I,F;try{J=YAHOO.util.Dom.getXY(E);}catch(H){}if(!J){return null;}D=J[0];C=D+E.offsetWidth;L=J[1];K=L+E.offsetHeight;M=L-G.padding[0];B=C+G.padding[1];I=K+G.padding[2];F=D-G.padding[3];return new YAHOO.util.Region(M,B,I,F);},isOverTarget:function(J,B,D,E){var F=this.locationCache[B.id];if(!F||!this.useCache){F=this.getLocation(B);this.locationCache[B.id]=F;}if(!F){return false;}B.cursorIsOver=F.contains(J);var I=this.dragCurrent;if(!I||(!D&&!I.constrainX&&!I.constrainY)){return B.cursorIsOver;}B.overlap=null;if(!E){var G=I.getTargetCoord(J.x,J.y);var C=I.getDragEl();E=new YAHOO.util.Region(G.y,G.x+C.offsetWidth,G.y+C.offsetHeight,G.x);}var H=E.intersect(F);if(H){B.overlap=H;return(D)?true:B.cursorIsOver;}else{return false;}},_onUnload:function(C,B){this.unregAll();},unregAll:function(){if(this.dragCurrent){this.stopDrag();this.dragCurrent=n!
 ull;}this._execOnAll("unreg",[]);this.ids={};},elementCache:{},getElWrapper:function(C){var B=this.elementCache[C];if(!B||!B.el){B=this.elementCache[C]=new this.ElementWrapper(YAHOO.util.Dom.get(C));}return B;},getElement:function(B){return YAHOO.util.Dom.get(B);},getCss:function(C){var B=YAHOO.util.Dom.get(C);return(B)?B.style:null;},ElementWrapper:function(B){this.el=B||null;this.id=this.el&&B.id;this.css=this.el&&B.style;},getPosX:function(B){return YAHOO.util.Dom.getX(B);},getPosY:function(B){return YAHOO.util.Dom.getY(B);},swapNode:function(D,B){if(D.swapNode){D.swapNode(B);}else{var E=B.parentNode;var C=B.nextSibling;if(C==D){E.insertBefore(D,B);}else{if(B==D.nextSibling){E.insertBefore(B,D);}else{D.parentNode.replaceChild(B,D);E.insertBefore(D,C);}}}},getScroll:function(){var D,B,E=document.documentElement,C=document.body;if(E&&(E.scrollTop||E.scrollLeft)){D=E.scrollTop;B=E.scrollLeft;}else{if(C){D=C.scrollTop;B=C.scrollLeft;}else{}}return{top:D,left:B};},getStyle:fu!
 nction(C,B){return YAHOO.util.Dom.getStyle(C,B);},getScrollTop!
 :functio
n(){return this.getScroll().top;},getScrollLeft:function(){return this.getScroll().left;},moveToEl:function(B,D){var C=YAHOO.util.Dom.getXY(D);YAHOO.util.Dom.setXY(B,C);},getClientHeight:function(){return YAHOO.util.Dom.getViewportHeight();},getClientWidth:function(){return YAHOO.util.Dom.getViewportWidth();},numericSort:function(C,B){return(C-B);},_timeoutCount:0,_addListeners:function(){var B=YAHOO.util.DDM;if(YAHOO.util.Event&&document){B._onLoad();}else{if(B._timeoutCount>2000){}else{setTimeout(B._addListeners,10);if(document&&document.body){B._timeoutCount+=1;}}}},handleWasClicked:function(B,D){if(this.isHandle(D,B.id)){return true;}else{var C=B.parentNode;while(C){if(this.isHandle(D,C.id)){return true;}else{C=C.parentNode;}}}return false;}};}();YAHOO.util.DDM=YAHOO.util.DragDropMgr;YAHOO.util.DDM._addListeners();}(function(){var A=YAHOO.util.Event;var B=YAHOO.util.Dom;YAHOO.util.DragDrop=function(E,C,D){if(E){this.init(E,C,D);}};YAHOO.util.DragDrop.prototype={id:null,c!
 onfig:null,dragElId:null,handleElId:null,invalidHandleTypes:null,invalidHandleIds:null,invalidHandleClasses:null,startPageX:0,startPageY:0,groups:null,locked:false,lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isTarget:true,padding:null,dragOnly:false,_domRef:null,__ygDragDrop:true,constrainX:false,constrainY:false,minX:0,maxX:0,minY:0,maxY:0,deltaX:0,deltaY:0,maintainOffset:false,xTicks:null,yTicks:null,primaryButtonOnly:true,available:false,hasOuterHandles:false,cursorIsOver:false,overlap:null,b4StartDrag:function(C,D){},startDrag:function(C,D){},b4Drag:function(C){},onDrag:function(C){},onDragEnter:function(C,D){},b4DragOver:function(C){},onDragOver:function(C,D){},b4DragOut:function(C){},onDragOut:function(C,D){},b4DragDrop:function(C){},onDragDrop:function(C,D){},onInvalidDrop:function(C){},b4EndDrag:function(C){},endDrag:function(C){},b4MouseDown:function(C){},onMouseDown:function(C){},onMouseUp:function(C){},onAvailable:function(){},getEl:f!
 unction(){if(!this._domRef){this._domRef=B.get(this.id);}retur!
 n this._
domRef;},getDragEl:function(){return B.get(this.dragElId);},init:function(E,C,D){this.initTarget(E,C,D);A.on(this._domRef||this.id,"mousedown",this.handleMouseDown,this,true);},initTarget:function(E,C,D){this.config=D||{};this.DDM=YAHOO.util.DDM;this.groups={};if(typeof E!=="string"){this._domRef=E;E=B.generateId(E);}this.id=E;this.addToGroup((C)?C:"default");this.handleElId=E;A.onAvailable(E,this.handleOnAvailable,this,true);this.setDragElId(E);this.invalidHandleTypes={A:"A"};this.invalidHandleIds={};this.invalidHandleClasses=[];this.applyConfig();},applyConfig:function(){this.padding=this.config.padding||[0,0,0,0];this.isTarget=(this.config.isTarget!==false);this.maintainOffset=(this.config.maintainOffset);this.primaryButtonOnly=(this.config.primaryButtonOnly!==false);this.dragOnly=((this.config.dragOnly===true)?true:false);},handleOnAvailable:function(){this.available=true;this.resetConstraints();this.onAvailable();},setPadding:function(E,C,F,D){if(!C&&0!==C){this.padding!
 =[E,E,E,E];}else{if(!F&&0!==F){this.padding=[E,C,E,C];}else{this.padding=[E,C,F,D];}}},setInitPosition:function(F,E){var G=this.getEl();if(!this.DDM.verifyEl(G)){return ;}var D=F||0;var C=E||0;var H=B.getXY(G);this.initPageX=H[0]-D;this.initPageY=H[1]-C;this.lastPageX=H[0];this.lastPageY=H[1];this.setStartPosition(H);},setStartPosition:function(D){var C=D||B.getXY(this.getEl());this.deltaSetXY=null;this.startPageX=C[0];this.startPageY=C[1];},addToGroup:function(C){this.groups[C]=true;this.DDM.regDragDrop(this,C);},removeFromGroup:function(C){if(this.groups[C]){delete this.groups[C];}this.DDM.removeDDFromGroup(this,C);},setDragElId:function(C){this.dragElId=C;},setHandleElId:function(C){if(typeof C!=="string"){C=B.generateId(C);}this.handleElId=C;this.DDM.regHandle(this.id,C);},setOuterHandleElId:function(C){if(typeof C!=="string"){C=B.generateId(C);}A.on(C,"mousedown",this.handleMouseDown,this,true);this.setHandleElId(C);
-this.hasOuterHandles=true;},unreg:function(){A.removeListener(this.id,"mousedown",this.handleMouseDown);this._domRef=null;this.DDM._remove(this);},isLocked:function(){return(this.DDM.isLocked()||this.locked);},handleMouseDown:function(H,G){var D=H.which||H.button;if(this.primaryButtonOnly&&D>1){return ;}if(this.isLocked()){return ;}var C=this.b4MouseDown(H);var E=this.onMouseDown(H);if((C===false)||(E===false)){return ;}this.DDM.refreshCache(this.groups);var F=new YAHOO.util.Point(A.getPageX(H),A.getPageY(H));if(!this.hasOuterHandles&&!this.DDM.isOverTarget(F,this)){}else{if(this.clickValidator(H)){this.setStartPosition();this.DDM.handleMouseDown(H,this);this.DDM.stopEvent(H);}else{}}},clickValidator:function(D){var C=A.getTarget(D);return(this.isValidHandleChild(C)&&(this.id==this.handleElId||this.DDM.handleWasClicked(C,this.id)));},getTargetCoord:function(E,D){var C=E-this.deltaX;var F=D-this.deltaY;if(this.constrainX){if(C<this.minX){C=this.minX;}if(C>this.maxX){C=this.m!
 axX;}}if(this.constrainY){if(F<this.minY){F=this.minY;}if(F>this.maxY){F=this.maxY;}}C=this.getTick(C,this.xTicks);F=this.getTick(F,this.yTicks);return{x:C,y:F};},addInvalidHandleType:function(C){var D=C.toUpperCase();this.invalidHandleTypes[D]=D;},addInvalidHandleId:function(C){if(typeof C!=="string"){C=B.generateId(C);}this.invalidHandleIds[C]=C;},addInvalidHandleClass:function(C){this.invalidHandleClasses.push(C);},removeInvalidHandleType:function(C){var D=C.toUpperCase();delete this.invalidHandleTypes[D];},removeInvalidHandleId:function(C){if(typeof C!=="string"){C=B.generateId(C);}delete this.invalidHandleIds[C];},removeInvalidHandleClass:function(D){for(var E=0,C=this.invalidHandleClasses.length;E<C;++E){if(this.invalidHandleClasses[E]==D){delete this.invalidHandleClasses[E];}}},isValidHandleChild:function(F){var E=true;var H;try{H=F.nodeName.toUpperCase();}catch(G){H=F.nodeName;}E=E&&!this.invalidHandleTypes[H];E=E&&!this.invalidHandleIds[F.id];for(var D=0,C=this.inv!
 alidHandleClasses.length;E&&D<C;++D){E=!B.hasClass(F,this.inva!
 lidHandl
eClasses[D]);}return E;},setXTicks:function(F,C){this.xTicks=[];this.xTickSize=C;var E={};for(var D=this.initPageX;D>=this.minX;D=D-C){if(!E[D]){this.xTicks[this.xTicks.length]=D;E[D]=true;}}for(D=this.initPageX;D<=this.maxX;D=D+C){if(!E[D]){this.xTicks[this.xTicks.length]=D;E[D]=true;}}this.xTicks.sort(this.DDM.numericSort);},setYTicks:function(F,C){this.yTicks=[];this.yTickSize=C;var E={};for(var D=this.initPageY;D>=this.minY;D=D-C){if(!E[D]){this.yTicks[this.yTicks.length]=D;E[D]=true;}}for(D=this.initPageY;D<=this.maxY;D=D+C){if(!E[D]){this.yTicks[this.yTicks.length]=D;E[D]=true;}}this.yTicks.sort(this.DDM.numericSort);},setXConstraint:function(E,D,C){this.leftConstraint=parseInt(E,10);this.rightConstraint=parseInt(D,10);this.minX=this.initPageX-this.leftConstraint;this.maxX=this.initPageX+this.rightConstraint;if(C){this.setXTicks(this.initPageX,C);}this.constrainX=true;},clearConstraints:function(){this.constrainX=false;this.constrainY=false;this.clearTicks();},clearTic!
 ks:function(){this.xTicks=null;this.yTicks=null;this.xTickSize=0;this.yTickSize=0;},setYConstraint:function(C,E,D){this.topConstraint=parseInt(C,10);this.bottomConstraint=parseInt(E,10);this.minY=this.initPageY-this.topConstraint;this.maxY=this.initPageY+this.bottomConstraint;if(D){this.setYTicks(this.initPageY,D);}this.constrainY=true;},resetConstraints:function(){if(this.initPageX||this.initPageX===0){var D=(this.maintainOffset)?this.lastPageX-this.initPageX:0;var C=(this.maintainOffset)?this.lastPageY-this.initPageY:0;this.setInitPosition(D,C);}else{this.setInitPosition();}if(this.constrainX){this.setXConstraint(this.leftConstraint,this.rightConstraint,this.xTickSize);}if(this.constrainY){this.setYConstraint(this.topConstraint,this.bottomConstraint,this.yTickSize);}},getTick:function(I,F){if(!F){return I;}else{if(F[0]>=I){return F[0];}else{for(var D=0,C=F.length;D<C;++D){var E=D+1;if(F[E]&&F[E]>=I){var H=I-F[D];var G=F[E]-I;return(G>H)?F[D]:F[E];}}return F[F.length-1];}}!
 },toString:function(){return("DragDrop "+this.id);}};})();YAHO!
 O.util.D
D=function(C,A,B){if(C){this.init(C,A,B);}};YAHOO.extend(YAHOO.util.DD,YAHOO.util.DragDrop,{scroll:true,autoOffset:function(C,B){var A=C-this.startPageX;var D=B-this.startPageY;this.setDelta(A,D);},setDelta:function(B,A){this.deltaX=B;this.deltaY=A;},setDragElPos:function(C,B){var A=this.getDragEl();this.alignElWithMouse(A,C,B);},alignElWithMouse:function(C,G,F){var E=this.getTargetCoord(G,F);if(!this.deltaSetXY){var H=[E.x,E.y];YAHOO.util.Dom.setXY(C,H);var D=parseInt(YAHOO.util.Dom.getStyle(C,"left"),10);var B=parseInt(YAHOO.util.Dom.getStyle(C,"top"),10);this.deltaSetXY=[D-E.x,B-E.y];}else{YAHOO.util.Dom.setStyle(C,"left",(E.x+this.deltaSetXY[0])+"px");YAHOO.util.Dom.setStyle(C,"top",(E.y+this.deltaSetXY[1])+"px");}this.cachePosition(E.x,E.y);var A=this;setTimeout(function(){A.autoScroll.call(A,E.x,E.y,C.offsetHeight,C.offsetWidth);},0);},cachePosition:function(B,A){if(B){this.lastPageX=B;this.lastPageY=A;}else{var C=YAHOO.util.Dom.getXY(this.getEl());this.lastPageX=C[0];!
 this.lastPageY=C[1];}},autoScroll:function(J,I,E,K){if(this.scroll){var L=this.DDM.getClientHeight();var B=this.DDM.getClientWidth();var N=this.DDM.getScrollTop();var D=this.DDM.getScrollLeft();var H=E+I;var M=K+J;var G=(L+N-I-this.deltaY);var F=(B+D-J-this.deltaX);var C=40;var A=(document.all)?80:30;if(H>L&&G<C){window.scrollTo(D,N+A);}if(I<N&&N>0&&I-N<C){window.scrollTo(D,N-A);}if(M>B&&F<C){window.scrollTo(D+A,N);}if(J<D&&D>0&&J-D<C){window.scrollTo(D-A,N);}}},applyConfig:function(){YAHOO.util.DD.superclass.applyConfig.call(this);this.scroll=(this.config.scroll!==false);},b4MouseDown:function(A){this.setStartPosition();this.autoOffset(YAHOO.util.Event.getPageX(A),YAHOO.util.Event.getPageY(A));},b4Drag:function(A){this.setDragElPos(YAHOO.util.Event.getPageX(A),YAHOO.util.Event.getPageY(A));},toString:function(){return("DD "+this.id);}});YAHOO.util.DDProxy=function(C,A,B){if(C){this.init(C,A,B);this.initFrame();
-}};YAHOO.util.DDProxy.dragElId="ygddfdiv";YAHOO.extend(YAHOO.util.DDProxy,YAHOO.util.DD,{resizeFrame:true,centerFrame:false,createFrame:function(){var B=this,A=document.body;if(!A||!A.firstChild){setTimeout(function(){B.createFrame();},50);return ;}var F=this.getDragEl(),E=YAHOO.util.Dom;if(!F){F=document.createElement("div");F.id=this.dragElId;var D=F.style;D.position="absolute";D.visibility="hidden";D.cursor="move";D.border="2px solid #aaa";D.zIndex=999;D.height="25px";D.width="25px";var C=document.createElement("div");E.setStyle(C,"height","100%");E.setStyle(C,"width","100%");E.setStyle(C,"background-color","#ccc");E.setStyle(C,"opacity","0");F.appendChild(C);A.insertBefore(F,A.firstChild);}},initFrame:function(){this.createFrame();},applyConfig:function(){YAHOO.util.DDProxy.superclass.applyConfig.call(this);this.resizeFrame=(this.config.resizeFrame!==false);this.centerFrame=(this.config.centerFrame);this.setDragElId(this.config.dragElId||YAHOO.util.DDProxy.dragElId);},s!
 howFrame:function(E,D){var C=this.getEl();var A=this.getDragEl();var B=A.style;this._resizeProxy();if(this.centerFrame){this.setDelta(Math.round(parseInt(B.width,10)/2),Math.round(parseInt(B.height,10)/2));}this.setDragElPos(E,D);YAHOO.util.Dom.setStyle(A,"visibility","visible");},_resizeProxy:function(){if(this.resizeFrame){var H=YAHOO.util.Dom;var B=this.getEl();var C=this.getDragEl();var G=parseInt(H.getStyle(C,"borderTopWidth"),10);var I=parseInt(H.getStyle(C,"borderRightWidth"),10);var F=parseInt(H.getStyle(C,"borderBottomWidth"),10);var D=parseInt(H.getStyle(C,"borderLeftWidth"),10);if(isNaN(G)){G=0;}if(isNaN(I)){I=0;}if(isNaN(F)){F=0;}if(isNaN(D)){D=0;}var E=Math.max(0,B.offsetWidth-I-D);var A=Math.max(0,B.offsetHeight-G-F);H.setStyle(C,"width",E+"px");H.setStyle(C,"height",A+"px");}},b4MouseDown:function(B){this.setStartPosition();var A=YAHOO.util.Event.getPageX(B);var C=YAHOO.util.Event.getPageY(B);this.autoOffset(A,C);},b4StartDrag:function(A,B){this.showFrame(A,B!
 );},b4EndDrag:function(A){YAHOO.util.Dom.setStyle(this.getDrag!
 El(),"vi
sibility","hidden");},endDrag:function(D){var C=YAHOO.util.Dom;var B=this.getEl();var A=this.getDragEl();C.setStyle(A,"visibility","");C.setStyle(B,"visibility","hidden");YAHOO.util.DDM.moveToEl(B,A);C.setStyle(A,"visibility","hidden");C.setStyle(B,"visibility","");},toString:function(){return("DDProxy "+this.id);}});YAHOO.util.DDTarget=function(C,A,B){if(C){this.initTarget(C,A,B);}};YAHOO.extend(YAHOO.util.DDTarget,YAHOO.util.DragDrop,{toString:function(){return("DDTarget "+this.id);}});YAHOO.register("dragdrop",YAHOO.util.DragDropMgr,{version:"2.4.1",build:"742"});
\ No newline at end of file
+if(!YAHOO.util.DragDropMgr){YAHOO.util.DragDropMgr=function(){var A=YAHOO.util.Event;return{ids:{},handleIds:{},dragCurrent:null,dragOvers:{},deltaX:0,deltaY:0,preventDefault:true,stopPropagation:true,initialized:false,locked:false,interactionInfo:null,init:function(){this.initialized=true;},POINT:0,INTERSECT:1,STRICT_INTERSECT:2,mode:0,_execOnAll:function(D,C){for(var E in this.ids){for(var B in this.ids[E]){var F=this.ids[E][B];if(!this.isTypeOfDD(F)){continue;}F[D].apply(F,C);}}},_onLoad:function(){this.init();A.on(document,"mouseup",this.handleMouseUp,this,true);A.on(document,"mousemove",this.handleMouseMove,this,true);A.on(window,"unload",this._onUnload,this,true);A.on(window,"resize",this._onResize,this,true);},_onResize:function(B){this._execOnAll("resetConstraints",[]);},lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isLocked:function(){return this.locked;},locationCache:{},useCache:true,clickPixelThresh:3,clickTimeThresh:1000,dragThreshMet!
 :false,clickTimeout:null,startX:0,startY:0,fromTimeout:false,regDragDrop:function(C,B){if(!this.initialized){this.init();}if(!this.ids[B]){this.ids[B]={};}this.ids[B][C.id]=C;},removeDDFromGroup:function(D,B){if(!this.ids[B]){this.ids[B]={};}var C=this.ids[B];if(C&&C[D.id]){delete C[D.id];}},_remove:function(C){for(var B in C.groups){if(B&&this.ids[B][C.id]){delete this.ids[B][C.id];}}delete this.handleIds[C.id];},regHandle:function(C,B){if(!this.handleIds[C]){this.handleIds[C]={};}this.handleIds[C][B]=B;},isDragDrop:function(B){return(this.getDDById(B))?true:false;},getRelated:function(G,C){var F=[];for(var E in G.groups){for(var D in this.ids[E]){var B=this.ids[E][D];if(!this.isTypeOfDD(B)){continue;}if(!C||B.isTarget){F[F.length]=B;}}}return F;},isLegalTarget:function(F,E){var C=this.getRelated(F,true);for(var D=0,B=C.length;D<B;++D){if(C[D].id==E.id){return true;}}return false;},isTypeOfDD:function(B){return(B&&B.__ygDragDrop);},isHandle:function(C,B){return(this.handle!
 Ids[C]&&this.handleIds[C][B]);},getDDById:function(C){for(var !
 B in thi
s.ids){if(this.ids[B][C]){return this.ids[B][C];}}return null;},handleMouseDown:function(D,C){this.currentTarget=YAHOO.util.Event.getTarget(D);this.dragCurrent=C;var B=C.getEl();this.startX=YAHOO.util.Event.getPageX(D);this.startY=YAHOO.util.Event.getPageY(D);this.deltaX=this.startX-B.offsetLeft;this.deltaY=this.startY-B.offsetTop;this.dragThreshMet=false;this.clickTimeout=setTimeout(function(){var E=YAHOO.util.DDM;E.startDrag(E.startX,E.startY);E.fromTimeout=true;},this.clickTimeThresh);},startDrag:function(B,D){clearTimeout(this.clickTimeout);var C=this.dragCurrent;if(C&&C.events.b4StartDrag){C.b4StartDrag(B,D);C.fireEvent("b4StartDragEvent",{x:B,y:D});}if(C&&C.events.startDrag){C.startDrag(B,D);C.fireEvent("startDragEvent",{x:B,y:D});}this.dragThreshMet=true;},handleMouseUp:function(B){if(this.dragCurrent){clearTimeout(this.clickTimeout);if(this.dragThreshMet){if(this.fromTimeout){this.handleMouseMove(B);}this.fromTimeout=false;this.fireEvents(B,true);}else{}this.stopDrag!
 (B);this.stopEvent(B);}},stopEvent:function(B){if(this.stopPropagation){YAHOO.util.Event.stopPropagation(B);}if(this.preventDefault){YAHOO.util.Event.preventDefault(B);}},stopDrag:function(D,C){var B=this.dragCurrent;if(B&&!C){if(this.dragThreshMet){if(B.events.b4EndDrag){B.b4EndDrag(D);B.fireEvent("b4EndDragEvent",{e:D});}if(B.events.endDrag){B.endDrag(D);B.fireEvent("endDragEvent",{e:D});}}if(B.events.mouseUp){B.onMouseUp(D);B.fireEvent("mouseUpEvent",{e:D});}}this.dragCurrent=null;this.dragOvers={};},handleMouseMove:function(E){var B=this.dragCurrent;if(B){if(YAHOO.util.Event.isIE&&!E.button){this.stopEvent(E);return this.handleMouseUp(E);}else{if(E.clientX<0||E.clientY<0){}}if(!this.dragThreshMet){var D=Math.abs(this.startX-YAHOO.util.Event.getPageX(E));var C=Math.abs(this.startY-YAHOO.util.Event.getPageY(E));if(D>this.clickPixelThresh||C>this.clickPixelThresh){this.startDrag(this.startX,this.startY);}}if(this.dragThreshMet){if(B&&B.events.b4Drag){B.b4Drag(E);B.fireEven!
 t("b4DragEvent",{e:E});}if(B&&B.events.drag){B.onDrag(E);B.fir!
 eEvent("
dragEvent",{e:E});}if(B){this.fireEvents(E,false);}}this.stopEvent(E);}},fireEvents:function(U,K){var Z=this.dragCurrent;if(!Z||Z.isLocked()||Z.dragOnly){return ;}var M=YAHOO.util.Event.getPageX(U),L=YAHOO.util.Event.getPageY(U),O=new YAHOO.util.Point(M,L),J=Z.getTargetCoord(O.x,O.y),E=Z.getDragEl(),D=["out","over","drop","enter"],T=new YAHOO.util.Region(J.y,J.x+E.offsetWidth,J.y+E.offsetHeight,J.x),H=[],C={},P=[],a={outEvts:[],overEvts:[],dropEvts:[],enterEvts:[]};for(var R in this.dragOvers){var c=this.dragOvers[R];if(!this.isTypeOfDD(c)){continue;}if(!this.isOverTarget(O,c,this.mode,T)){a.outEvts.push(c);}H[R]=true;delete this.dragOvers[R];}for(var Q in Z.groups){if("string"!=typeof Q){continue;}for(R in this.ids[Q]){var F=this.ids[Q][R];if(!this.isTypeOfDD(F)){continue;}if(F.isTarget&&!F.isLocked()&&F!=Z){if(this.isOverTarget(O,F,this.mode,T)){C[Q]=true;if(K){a.dropEvts.push(F);}else{if(!H[F.id]){a.enterEvts.push(F);}else{a.overEvts.push(F);}this.dragOvers[F.id]=F;}}}}}t!
 his.interactionInfo={out:a.outEvts,enter:a.enterEvts,over:a.overEvts,drop:a.dropEvts,point:O,draggedRegion:T,sourceRegion:this.locationCache[Z.id],validDrop:K};for(var B in C){P.push(B);}if(K&&!a.dropEvts.length){this.interactionInfo.validDrop=false;if(Z.events.invalidDrop){Z.onInvalidDrop(U);Z.fireEvent("invalidDropEvent",{e:U});}}for(R=0;R<D.length;R++){var X=null;if(a[D[R]+"Evts"]){X=a[D[R]+"Evts"];}if(X&&X.length){var G=D[R].charAt(0).toUpperCase()+D[R].substr(1),W="onDrag"+G,I="b4Drag"+G,N="drag"+G+"Event",V="drag"+G;if(this.mode){if(Z.events[I]){Z[I](U,X,P);Z.fireEvent(I+"Event",{event:U,info:X,group:P});}if(Z.events[V]){Z[W](U,X,P);Z.fireEvent(N,{event:U,info:X,group:P});}}else{for(var Y=0,S=X.length;Y<S;++Y){if(Z.events[I]){Z[I](U,X[Y].id,P[0]);Z.fireEvent(I+"Event",{event:U,info:X[Y].id,group:P[0]});}if(Z.events[V]){Z[W](U,X[Y].id,P[0]);Z.fireEvent(N,{event:U,info:X[Y].id,group:P[0]});}}}}}},getBestMatch:function(D){var F=null;
+var C=D.length;if(C==1){F=D[0];}else{for(var E=0;E<C;++E){var B=D[E];if(this.mode==this.INTERSECT&&B.cursorIsOver){F=B;break;}else{if(!F||!F.overlap||(B.overlap&&F.overlap.getArea()<B.overlap.getArea())){F=B;}}}}return F;},refreshCache:function(C){var E=C||this.ids;for(var B in E){if("string"!=typeof B){continue;}for(var D in this.ids[B]){var F=this.ids[B][D];if(this.isTypeOfDD(F)){var G=this.getLocation(F);if(G){this.locationCache[F.id]=G;}else{delete this.locationCache[F.id];}}}}},verifyEl:function(C){try{if(C){var B=C.offsetParent;if(B){return true;}}}catch(D){}return false;},getLocation:function(G){if(!this.isTypeOfDD(G)){return null;}var E=G.getEl(),J,D,C,L,K,M,B,I,F;try{J=YAHOO.util.Dom.getXY(E);}catch(H){}if(!J){return null;}D=J[0];C=D+E.offsetWidth;L=J[1];K=L+E.offsetHeight;M=L-G.padding[0];B=C+G.padding[1];I=K+G.padding[2];F=D-G.padding[3];return new YAHOO.util.Region(M,B,I,F);},isOverTarget:function(J,B,D,E){var F=this.locationCache[B.id];if(!F||!this.useCache){F=!
 this.getLocation(B);this.locationCache[B.id]=F;}if(!F){return false;}B.cursorIsOver=F.contains(J);var I=this.dragCurrent;if(!I||(!D&&!I.constrainX&&!I.constrainY)){return B.cursorIsOver;}B.overlap=null;if(!E){var G=I.getTargetCoord(J.x,J.y);var C=I.getDragEl();E=new YAHOO.util.Region(G.y,G.x+C.offsetWidth,G.y+C.offsetHeight,G.x);}var H=E.intersect(F);if(H){B.overlap=H;return(D)?true:B.cursorIsOver;}else{return false;}},_onUnload:function(C,B){this.unregAll();},unregAll:function(){if(this.dragCurrent){this.stopDrag();this.dragCurrent=null;}this._execOnAll("unreg",[]);this.ids={};},elementCache:{},getElWrapper:function(C){var B=this.elementCache[C];if(!B||!B.el){B=this.elementCache[C]=new this.ElementWrapper(YAHOO.util.Dom.get(C));}return B;},getElement:function(B){return YAHOO.util.Dom.get(B);},getCss:function(C){var B=YAHOO.util.Dom.get(C);return(B)?B.style:null;},ElementWrapper:function(B){this.el=B||null;this.id=this.el&&B.id;this.css=this.el&&B.style;},getPosX:function(B!
 ){return YAHOO.util.Dom.getX(B);},getPosY:function(B){return Y!
 AHOO.uti
l.Dom.getY(B);},swapNode:function(D,B){if(D.swapNode){D.swapNode(B);}else{var E=B.parentNode;var C=B.nextSibling;if(C==D){E.insertBefore(D,B);}else{if(B==D.nextSibling){E.insertBefore(B,D);}else{D.parentNode.replaceChild(B,D);E.insertBefore(D,C);}}}},getScroll:function(){var D,B,E=document.documentElement,C=document.body;if(E&&(E.scrollTop||E.scrollLeft)){D=E.scrollTop;B=E.scrollLeft;}else{if(C){D=C.scrollTop;B=C.scrollLeft;}else{}}return{top:D,left:B};},getStyle:function(C,B){return YAHOO.util.Dom.getStyle(C,B);},getScrollTop:function(){return this.getScroll().top;},getScrollLeft:function(){return this.getScroll().left;},moveToEl:function(B,D){var C=YAHOO.util.Dom.getXY(D);YAHOO.util.Dom.setXY(B,C);},getClientHeight:function(){return YAHOO.util.Dom.getViewportHeight();},getClientWidth:function(){return YAHOO.util.Dom.getViewportWidth();},numericSort:function(C,B){return(C-B);},_timeoutCount:0,_addListeners:function(){var B=YAHOO.util.DDM;if(YAHOO.util.Event&&document){B._on!
 Load();}else{if(B._timeoutCount>2000){}else{setTimeout(B._addListeners,10);if(document&&document.body){B._timeoutCount+=1;}}}},handleWasClicked:function(B,D){if(this.isHandle(D,B.id)){return true;}else{var C=B.parentNode;while(C){if(this.isHandle(D,C.id)){return true;}else{C=C.parentNode;}}}return false;}};}();YAHOO.util.DDM=YAHOO.util.DragDropMgr;YAHOO.util.DDM._addListeners();}(function(){var A=YAHOO.util.Event;var B=YAHOO.util.Dom;YAHOO.util.DragDrop=function(E,C,D){if(E){this.init(E,C,D);}};YAHOO.util.DragDrop.prototype={events:null,on:function(){this.subscribe.apply(this,arguments);},id:null,config:null,dragElId:null,handleElId:null,invalidHandleTypes:null,invalidHandleIds:null,invalidHandleClasses:null,startPageX:0,startPageY:0,groups:null,locked:false,lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isTarget:true,padding:null,dragOnly:false,_domRef:null,__ygDragDrop:true,constrainX:false,constrainY:false,minX:0,maxX:0,minY:0,maxY:0,deltaX:0,de!
 ltaY:0,maintainOffset:false,xTicks:null,yTicks:null,primaryBut!
 tonOnly:
true,available:false,hasOuterHandles:false,cursorIsOver:false,overlap:null,b4StartDrag:function(C,D){},startDrag:function(C,D){},b4Drag:function(C){},onDrag:function(C){},onDragEnter:function(C,D){},b4DragOver:function(C){},onDragOver:function(C,D){},b4DragOut:function(C){},onDragOut:function(C,D){},b4DragDrop:function(C){},onDragDrop:function(C,D){},onInvalidDrop:function(C){},b4EndDrag:function(C){},endDrag:function(C){},b4MouseDown:function(C){},onMouseDown:function(C){},onMouseUp:function(C){},onAvailable:function(){},getEl:function(){if(!this._domRef){this._domRef=B.get(this.id);}return this._domRef;},getDragEl:function(){return B.get(this.dragElId);},init:function(F,C,D){this.initTarget(F,C,D);A.on(this._domRef||this.id,"mousedown",this.handleMouseDown,this,true);for(var E in this.events){this.createEvent(E+"Event");}},initTarget:function(E,C,D){this.config=D||{};this.events={};this.DDM=YAHOO.util.DDM;this.groups={};if(typeof E!=="string"){this._domRef=E;E=B.generateId!
 (E);}this.id=E;this.addToGroup((C)?C:"default");this.handleElId=E;A.onAvailable(E,this.handleOnAvailable,this,true);this.setDragElId(E);this.invalidHandleTypes={A:"A"};this.invalidHandleIds={};this.invalidHandleClasses=[];this.applyConfig();},applyConfig:function(){this.events={mouseDown:true,b4MouseDown:true,mouseUp:true,b4StartDrag:true,startDrag:true,b4EndDrag:true,endDrag:true,drag:true,b4Drag:true,invalidDrop:true,b4DragOut:true,dragOut:true,dragEnter:true,b4DragOver:true,dragOver:true,b4DragDrop:true,dragDrop:true};if(this.config.events){for(var C in this.config.events){if(this.config.events[C]===false){this.events[C]=false;}}}this.padding=this.config.padding||[0,0,0,0];this.isTarget=(this.config.isTarget!==false);this.maintainOffset=(this.config.maintainOffset);this.primaryButtonOnly=(this.config.primaryButtonOnly!==false);this.dragOnly=((this.config.dragOnly===true)?true:false);},handleOnAvailable:function(){this.available=true;
+this.resetConstraints();this.onAvailable();},setPadding:function(E,C,F,D){if(!C&&0!==C){this.padding=[E,E,E,E];}else{if(!F&&0!==F){this.padding=[E,C,E,C];}else{this.padding=[E,C,F,D];}}},setInitPosition:function(F,E){var G=this.getEl();if(!this.DDM.verifyEl(G)){if(G&&G.style&&(G.style.display=="none")){}else{}return ;}var D=F||0;var C=E||0;var H=B.getXY(G);this.initPageX=H[0]-D;this.initPageY=H[1]-C;this.lastPageX=H[0];this.lastPageY=H[1];this.setStartPosition(H);},setStartPosition:function(D){var C=D||B.getXY(this.getEl());this.deltaSetXY=null;this.startPageX=C[0];this.startPageY=C[1];},addToGroup:function(C){this.groups[C]=true;this.DDM.regDragDrop(this,C);},removeFromGroup:function(C){if(this.groups[C]){delete this.groups[C];}this.DDM.removeDDFromGroup(this,C);},setDragElId:function(C){this.dragElId=C;},setHandleElId:function(C){if(typeof C!=="string"){C=B.generateId(C);}this.handleElId=C;this.DDM.regHandle(this.id,C);},setOuterHandleElId:function(C){if(typeof C!=="strin!
 g"){C=B.generateId(C);}A.on(C,"mousedown",this.handleMouseDown,this,true);this.setHandleElId(C);this.hasOuterHandles=true;},unreg:function(){A.removeListener(this.id,"mousedown",this.handleMouseDown);this._domRef=null;this.DDM._remove(this);},isLocked:function(){return(this.DDM.isLocked()||this.locked);},handleMouseDown:function(H,G){var D=H.which||H.button;if(this.primaryButtonOnly&&D>1){return ;}if(this.isLocked()){return ;}var C=this.b4MouseDown(H);if(this.events.b4MouseDown){C=this.fireEvent("b4MouseDownEvent",H);}var E=this.onMouseDown(H);if(this.events.mouseDown){E=this.fireEvent("mouseDownEvent",H);}if((C===false)||(E===false)){return ;}this.DDM.refreshCache(this.groups);var F=new YAHOO.util.Point(A.getPageX(H),A.getPageY(H));if(!this.hasOuterHandles&&!this.DDM.isOverTarget(F,this)){}else{if(this.clickValidator(H)){this.setStartPosition();this.DDM.handleMouseDown(H,this);this.DDM.stopEvent(H);}else{}}},clickValidator:function(D){var C=YAHOO.util.Event.getTarget(D);re!
 turn(this.isValidHandleChild(C)&&(this.id==this.handleElId||th!
 is.DDM.h
andleWasClicked(C,this.id)));},getTargetCoord:function(E,D){var C=E-this.deltaX;var F=D-this.deltaY;if(this.constrainX){if(C<this.minX){C=this.minX;}if(C>this.maxX){C=this.maxX;}}if(this.constrainY){if(F<this.minY){F=this.minY;}if(F>this.maxY){F=this.maxY;}}C=this.getTick(C,this.xTicks);F=this.getTick(F,this.yTicks);return{x:C,y:F};},addInvalidHandleType:function(C){var D=C.toUpperCase();this.invalidHandleTypes[D]=D;},addInvalidHandleId:function(C){if(typeof C!=="string"){C=B.generateId(C);}this.invalidHandleIds[C]=C;},addInvalidHandleClass:function(C){this.invalidHandleClasses.push(C);},removeInvalidHandleType:function(C){var D=C.toUpperCase();delete this.invalidHandleTypes[D];},removeInvalidHandleId:function(C){if(typeof C!=="string"){C=B.generateId(C);}delete this.invalidHandleIds[C];},removeInvalidHandleClass:function(D){for(var E=0,C=this.invalidHandleClasses.length;E<C;++E){if(this.invalidHandleClasses[E]==D){delete this.invalidHandleClasses[E];}}},isValidHandleChild:f!
 unction(F){var E=true;var H;try{H=F.nodeName.toUpperCase();}catch(G){H=F.nodeName;}E=E&&!this.invalidHandleTypes[H];E=E&&!this.invalidHandleIds[F.id];for(var D=0,C=this.invalidHandleClasses.length;E&&D<C;++D){E=!B.hasClass(F,this.invalidHandleClasses[D]);}return E;},setXTicks:function(F,C){this.xTicks=[];this.xTickSize=C;var E={};for(var D=this.initPageX;D>=this.minX;D=D-C){if(!E[D]){this.xTicks[this.xTicks.length]=D;E[D]=true;}}for(D=this.initPageX;D<=this.maxX;D=D+C){if(!E[D]){this.xTicks[this.xTicks.length]=D;E[D]=true;}}this.xTicks.sort(this.DDM.numericSort);},setYTicks:function(F,C){this.yTicks=[];this.yTickSize=C;var E={};for(var D=this.initPageY;D>=this.minY;D=D-C){if(!E[D]){this.yTicks[this.yTicks.length]=D;E[D]=true;}}for(D=this.initPageY;D<=this.maxY;D=D+C){if(!E[D]){this.yTicks[this.yTicks.length]=D;E[D]=true;}}this.yTicks.sort(this.DDM.numericSort);},setXConstraint:function(E,D,C){this.leftConstraint=parseInt(E,10);this.rightConstraint=parseInt(D,10);this.minX=t!
 his.initPageX-this.leftConstraint;this.maxX=this.initPageX+thi!
 s.rightC
onstraint;if(C){this.setXTicks(this.initPageX,C);}this.constrainX=true;},clearConstraints:function(){this.constrainX=false;this.constrainY=false;this.clearTicks();},clearTicks:function(){this.xTicks=null;this.yTicks=null;this.xTickSize=0;this.yTickSize=0;},setYConstraint:function(C,E,D){this.topConstraint=parseInt(C,10);this.bottomConstraint=parseInt(E,10);this.minY=this.initPageY-this.topConstraint;this.maxY=this.initPageY+this.bottomConstraint;if(D){this.setYTicks(this.initPageY,D);}this.constrainY=true;},resetConstraints:function(){if(this.initPageX||this.initPageX===0){var D=(this.maintainOffset)?this.lastPageX-this.initPageX:0;var C=(this.maintainOffset)?this.lastPageY-this.initPageY:0;this.setInitPosition(D,C);}else{this.setInitPosition();}if(this.constrainX){this.setXConstraint(this.leftConstraint,this.rightConstraint,this.xTickSize);}if(this.constrainY){this.setYConstraint(this.topConstraint,this.bottomConstraint,this.yTickSize);}},getTick:function(I,F){if(!F){return!
  I;}else{if(F[0]>=I){return F[0];}else{for(var D=0,C=F.length;D<C;++D){var E=D+1;if(F[E]&&F[E]>=I){var H=I-F[D];var G=F[E]-I;return(G>H)?F[D]:F[E];}}return F[F.length-1];}}},toString:function(){return("DragDrop "+this.id);}};YAHOO.augment(YAHOO.util.DragDrop,YAHOO.util.EventProvider);})();YAHOO.util.DD=function(C,A,B){if(C){this.init(C,A,B);}};YAHOO.extend(YAHOO.util.DD,YAHOO.util.DragDrop,{scroll:true,autoOffset:function(C,B){var A=C-this.startPageX;var D=B-this.startPageY;this.setDelta(A,D);},setDelta:function(B,A){this.deltaX=B;this.deltaY=A;},setDragElPos:function(C,B){var A=this.getDragEl();this.alignElWithMouse(A,C,B);},alignElWithMouse:function(C,G,F){var E=this.getTargetCoord(G,F);if(!this.deltaSetXY){var H=[E.x,E.y];YAHOO.util.Dom.setXY(C,H);var D=parseInt(YAHOO.util.Dom.getStyle(C,"left"),10);var B=parseInt(YAHOO.util.Dom.getStyle(C,"top"),10);this.deltaSetXY=[D-E.x,B-E.y];}else{YAHOO.util.Dom.setStyle(C,"left",(E.x+this.deltaSetXY[0])+"px");
+YAHOO.util.Dom.setStyle(C,"top",(E.y+this.deltaSetXY[1])+"px");}this.cachePosition(E.x,E.y);var A=this;setTimeout(function(){A.autoScroll.call(A,E.x,E.y,C.offsetHeight,C.offsetWidth);},0);},cachePosition:function(B,A){if(B){this.lastPageX=B;this.lastPageY=A;}else{var C=YAHOO.util.Dom.getXY(this.getEl());this.lastPageX=C[0];this.lastPageY=C[1];}},autoScroll:function(J,I,E,K){if(this.scroll){var L=this.DDM.getClientHeight();var B=this.DDM.getClientWidth();var N=this.DDM.getScrollTop();var D=this.DDM.getScrollLeft();var H=E+I;var M=K+J;var G=(L+N-I-this.deltaY);var F=(B+D-J-this.deltaX);var C=40;var A=(document.all)?80:30;if(H>L&&G<C){window.scrollTo(D,N+A);}if(I<N&&N>0&&I-N<C){window.scrollTo(D,N-A);}if(M>B&&F<C){window.scrollTo(D+A,N);}if(J<D&&D>0&&J-D<C){window.scrollTo(D-A,N);}}},applyConfig:function(){YAHOO.util.DD.superclass.applyConfig.call(this);this.scroll=(this.config.scroll!==false);},b4MouseDown:function(A){this.setStartPosition();this.autoOffset(YAHOO.util.Event.g!
 etPageX(A),YAHOO.util.Event.getPageY(A));},b4Drag:function(A){this.setDragElPos(YAHOO.util.Event.getPageX(A),YAHOO.util.Event.getPageY(A));},toString:function(){return("DD "+this.id);}});YAHOO.util.DDProxy=function(C,A,B){if(C){this.init(C,A,B);this.initFrame();}};YAHOO.util.DDProxy.dragElId="ygddfdiv";YAHOO.extend(YAHOO.util.DDProxy,YAHOO.util.DD,{resizeFrame:true,centerFrame:false,createFrame:function(){var B=this,A=document.body;if(!A||!A.firstChild){setTimeout(function(){B.createFrame();},50);return ;}var G=this.getDragEl(),E=YAHOO.util.Dom;if(!G){G=document.createElement("div");G.id=this.dragElId;var D=G.style;D.position="absolute";D.visibility="hidden";D.cursor="move";D.border="2px solid #aaa";D.zIndex=999;D.height="25px";D.width="25px";var C=document.createElement("div");E.setStyle(C,"height","100%");E.setStyle(C,"width","100%");E.setStyle(C,"background-color","#ccc");E.setStyle(C,"opacity","0");G.appendChild(C);if(YAHOO.env.ua.ie){var F=document.createElement("ifram!
 e");F.setAttribute("src","about:blank");F.setAttribute("scroll!
 ing","no
");F.setAttribute("frameborder","0");G.insertBefore(F,G.firstChild);E.setStyle(F,"height","100%");E.setStyle(F,"width","100%");E.setStyle(F,"position","absolute");E.setStyle(F,"top","0");E.setStyle(F,"left","0");E.setStyle(F,"opacity","0");E.setStyle(F,"zIndex","-1");E.setStyle(F.nextSibling,"zIndex","2");}A.insertBefore(G,A.firstChild);}},initFrame:function(){this.createFrame();},applyConfig:function(){YAHOO.util.DDProxy.superclass.applyConfig.call(this);this.resizeFrame=(this.config.resizeFrame!==false);this.centerFrame=(this.config.centerFrame);this.setDragElId(this.config.dragElId||YAHOO.util.DDProxy.dragElId);},showFrame:function(E,D){var C=this.getEl();var A=this.getDragEl();var B=A.style;this._resizeProxy();if(this.centerFrame){this.setDelta(Math.round(parseInt(B.width,10)/2),Math.round(parseInt(B.height,10)/2));}this.setDragElPos(E,D);YAHOO.util.Dom.setStyle(A,"visibility","visible");},_resizeProxy:function(){if(this.resizeFrame){var H=YAHOO.util.Dom;var B=this.getEl!
 ();var C=this.getDragEl();var G=parseInt(H.getStyle(C,"borderTopWidth"),10);var I=parseInt(H.getStyle(C,"borderRightWidth"),10);var F=parseInt(H.getStyle(C,"borderBottomWidth"),10);var D=parseInt(H.getStyle(C,"borderLeftWidth"),10);if(isNaN(G)){G=0;}if(isNaN(I)){I=0;}if(isNaN(F)){F=0;}if(isNaN(D)){D=0;}var E=Math.max(0,B.offsetWidth-I-D);var A=Math.max(0,B.offsetHeight-G-F);H.setStyle(C,"width",E+"px");H.setStyle(C,"height",A+"px");}},b4MouseDown:function(B){this.setStartPosition();var A=YAHOO.util.Event.getPageX(B);var C=YAHOO.util.Event.getPageY(B);this.autoOffset(A,C);},b4StartDrag:function(A,B){this.showFrame(A,B);},b4EndDrag:function(A){YAHOO.util.Dom.setStyle(this.getDragEl(),"visibility","hidden");},endDrag:function(D){var C=YAHOO.util.Dom;var B=this.getEl();var A=this.getDragEl();C.setStyle(A,"visibility","");C.setStyle(B,"visibility","hidden");YAHOO.util.DDM.moveToEl(B,A);C.setStyle(A,"visibility","hidden");C.setStyle(B,"visibility","");},toString:function(){return!
 ("DDProxy "+this.id);}});YAHOO.util.DDTarget=function(C,A,B){i!
 f(C){thi
s.initTarget(C,A,B);}};YAHOO.extend(YAHOO.util.DDTarget,YAHOO.util.DragDrop,{toString:function(){return("DDTarget "+this.id);}});YAHOO.register("dragdrop",YAHOO.util.DragDropMgr,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/dragdrop/dragdrop.js
===================================================================
--- trunk/root/static/yui/dragdrop/dragdrop.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/dragdrop/dragdrop.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The drag and drop utility provides a framework for building drag and drop
@@ -33,7 +33,6 @@
     var Event = YAHOO.util.Event;
 
     return {
-
         /**
          * Two dimensional Array of registered DragDrop objects.  The first 
          * dimension is the DragDrop item group, the second the DragDrop 
@@ -572,11 +571,13 @@
         startDrag: function(x, y) {
             clearTimeout(this.clickTimeout);
             var dc = this.dragCurrent;
-            if (dc) {
+            if (dc && dc.events.b4StartDrag) {
                 dc.b4StartDrag(x, y);
+                dc.fireEvent('b4StartDragEvent', { x: x, y: y });
             }
-            if (dc) {
+            if (dc && dc.events.startDrag) {
                 dc.startDrag(x, y);
+                dc.fireEvent('startDragEvent', { x: x, y: y });
             }
             this.dragThreshMet = true;
         },
@@ -643,15 +644,23 @@
          * @static
          */
         stopDrag: function(e, silent) {
-
+            var dc = this.dragCurrent;
             // Fire the drag end event for the item that was dragged
-            if (this.dragCurrent && !silent) {
+            if (dc && !silent) {
                 if (this.dragThreshMet) {
-                    this.dragCurrent.b4EndDrag(e);
-                    this.dragCurrent.endDrag(e);
+                    if (dc.events.b4EndDrag) {
+                        dc.b4EndDrag(e);
+                        dc.fireEvent('b4EndDragEvent', { e: e });
+                    }
+                    if (dc.events.endDrag) {
+                        dc.endDrag(e);
+                        dc.fireEvent('endDragEvent', { e: e });
+                    }
                 }
-
-                this.dragCurrent.onMouseUp(e);
+                if (dc.events.mouseUp) {
+                    dc.onMouseUp(e);
+                    dc.fireEvent('mouseUpEvent', { e: e });
+                }
             }
 
             this.dragCurrent = null;
@@ -683,6 +692,13 @@
                 if (YAHOO.util.Event.isIE && !e.button) {
                     this.stopEvent(e);
                     return this.handleMouseUp(e);
+                } else {
+                    if (e.clientX < 0 || e.clientY < 0) {
+                        //This will stop the element from leaving the viewport in FF, Opera & Safari
+                        //Not turned on yet
+                        //this.stopEvent(e);
+                        //return false;
+                    }
                 }
 
                 if (!this.dragThreshMet) {
@@ -695,9 +711,13 @@
                 }
 
                 if (this.dragThreshMet) {
-                    dc.b4Drag(e);
-                    if (dc) {
+                    if (dc && dc.events.b4Drag) {
+                        dc.b4Drag(e);
+                        dc.fireEvent('b4DragEvent', { e: e});
+                    }
+                    if (dc && dc.events.drag) {
                         dc.onDrag(e);
+                        dc.fireEvent('dragEvent', { e: e});
                     }
                     if (dc) {
                         this.fireEvents(e, false);
@@ -732,18 +752,21 @@
                 pt = new YAHOO.util.Point(x,y),
                 pos = dc.getTargetCoord(pt.x, pt.y),
                 el = dc.getDragEl(),
+                events = ['out', 'over', 'drop', 'enter'],
                 curRegion = new YAHOO.util.Region( pos.y, 
                                                pos.x + el.offsetWidth,
                                                pos.y + el.offsetHeight, 
                                                pos.x ),
             
                 oldOvers = [], // cache the previous dragOver array
-                outEvts   = [],
-                overEvts  = [],
-                dropEvts  = [],
-                enterEvts = [],
                 inGroupsObj  = {},
-                inGroups  = [];
+                inGroups  = [],
+                data = {
+                    outEvts: [],
+                    overEvts: [],
+                    dropEvts: [],
+                    enterEvts: []
+                };
 
 
             // Check to see if the object(s) we were hovering over is no longer 
@@ -756,7 +779,7 @@
                     continue;
                 }
                 if (! this.isOverTarget(pt, ddo, this.mode, curRegion)) {
-                    outEvts.push( ddo );
+                    data.outEvts.push( ddo );
                 }
 
                 oldOvers[i] = true;
@@ -780,16 +803,16 @@
                             inGroupsObj[sGroup] = true;
                             // look for drop interactions
                             if (isDrop) {
-                                dropEvts.push( oDD );
+                                data.dropEvts.push( oDD );
                             // look for drag enter and drag over interactions
                             } else {
 
                                 // initial drag over: dragEnter fires
                                 if (!oldOvers[oDD.id]) {
-                                    enterEvts.push( oDD );
+                                    data.enterEvts.push( oDD );
                                 // subsequent drag overs: dragOver fires
                                 } else {
-                                    overEvts.push( oDD );
+                                    data.overEvts.push( oDD );
                                 }
 
                                 this.dragOvers[oDD.id] = oDD;
@@ -800,10 +823,10 @@
             }
 
             this.interactionInfo = {
-                out:       outEvts,
-                enter:     enterEvts,
-                over:      overEvts,
-                drop:      dropEvts,
+                out:       data.outEvts,
+                enter:     data.enterEvts,
+                over:      data.overEvts,
+                drop:      data.dropEvts,
                 point:     pt,
                 draggedRegion:    curRegion,
                 sourceRegion: this.locationCache[dc.id],
@@ -816,86 +839,48 @@
             }
 
             // notify about a drop that did not find a target
-            if (isDrop && !dropEvts.length) {
+            if (isDrop && !data.dropEvts.length) {
                 this.interactionInfo.validDrop = false;
-                dc.onInvalidDrop(e);
+                if (dc.events.invalidDrop) {
+                    dc.onInvalidDrop(e);
+                    dc.fireEvent('invalidDropEvent', { e: e });
+                }
             }
 
-
-            if (this.mode) {
-                if (outEvts.length) {
-                    dc.b4DragOut(e, outEvts);
-                    if (dc) {
-                        dc.onDragOut(e, outEvts);
-                    }
+            for (i = 0; i < events.length; i++) {
+                var tmp = null;
+                if (data[events[i] + 'Evts']) {
+                    tmp = data[events[i] + 'Evts'];
                 }
-
-                if (enterEvts.length) {
-                    if (dc) {
-                        dc.onDragEnter(e, enterEvts, inGroups);
+                if (tmp && tmp.length) {
+                    var type = events[i].charAt(0).toUpperCase() + events[i].substr(1),
+                        ev = 'onDrag' + type,
+                        b4 = 'b4Drag' + type,
+                        cev = 'drag' + type + 'Event',
+                        check = 'drag' + type;
+                    
+                    if (this.mode) {
+                        if (dc.events[b4]) {
+                            dc[b4](e, tmp, inGroups);
+                            dc.fireEvent(b4 + 'Event', { event: e, info: tmp, group: inGroups });
+                        }
+                        if (dc.events[check]) {
+                            dc[ev](e, tmp, inGroups);
+                            dc.fireEvent(cev, { event: e, info: tmp, group: inGroups });
+                        }
+                    } else {
+                        for (var b = 0, len = tmp.length; b < len; ++b) {
+                            if (dc.events[b4]) {
+                                dc[b4](e, tmp[b].id, inGroups[0]);
+                                dc.fireEvent(b4 + 'Event', { event: e, info: tmp[b].id, group: inGroups[0] });
+                            }
+                            if (dc.events[check]) {
+                                dc[ev](e, tmp[b].id, inGroups[0]);
+                                dc.fireEvent(cev, { event: e, info: tmp[b].id, group: inGroups[0] });
+                            }
+                        }
                     }
                 }
-
-                if (overEvts.length) {
-                    if (dc) {
-                        dc.b4DragOver(e, overEvts, inGroups);
-                    }
-
-                    if (dc) {
-                        dc.onDragOver(e, overEvts, inGroups);
-                    }
-                }
-
-                if (dropEvts.length) {
-                    if (dc) {
-                        dc.b4DragDrop(e, dropEvts, inGroups);
-                    }
-                    if (dc) {
-                        dc.onDragDrop(e, dropEvts, inGroups);
-                    }
-                }
-
-            } else {
-                // fire dragout events
-                var len = 0;
-                for (i=0, len=outEvts.length; i<len; ++i) {
-                    if (dc) {
-                        dc.b4DragOut(e, outEvts[i].id, inGroups[0]);
-                    }
-                    if (dc) {
-                        dc.onDragOut(e, outEvts[i].id, inGroups[0]);
-                    }
-                }
-                 
-                // fire enter events
-                for (i=0,len=enterEvts.length; i<len; ++i) {
-                    // dc.b4DragEnter(e, oDD.id);
-
-                    if (dc) {
-                        dc.onDragEnter(e, enterEvts[i].id, inGroups[0]);
-                    }
-                }
-         
-                // fire over events
-                for (i=0,len=overEvts.length; i<len; ++i) {
-                    if (dc) {
-                        dc.b4DragOver(e, overEvts[i].id, inGroups[0]);
-                    }
-                    if (dc) {
-                        dc.onDragOver(e, overEvts[i].id, inGroups[0]);
-                    }
-                }
-
-                // fire drop events
-                for (i=0, len=dropEvts.length; i<len; ++i) {
-                    if (dc) {
-                        dc.b4DragDrop(e, dropEvts[i].id, inGroups[0]);
-                    }
-                    if (dc) {
-                        dc.onDragDrop(e, dropEvts[i].id, inGroups[0]);
-                    }
-                }
-
             }
         },
 
@@ -1488,8 +1473,21 @@
 };
 
 YAHOO.util.DragDrop.prototype = {
-
     /**
+     * An Object Literal containing the events that we will be using: mouseDown, b4MouseDown, mouseUp, b4StartDrag, startDrag, b4EndDrag, endDrag, mouseUp, drag, b4Drag, invalidDrop, b4DragOut, dragOut, dragEnter, b4DragOver, dragOver, b4DragDrop, dragDrop
+     * By setting any of these to false, then event will not be fired.
+     * @property events
+     * @type object
+     */
+    events: null,
+    /**
+    * @method on
+    * @description Shortcut for EventProvider.subscribe, see <a href="YAHOO.util.EventProvider.html#subscribe">YAHOO.util.EventProvider.subscribe</a>
+    */
+    on: function() {
+        this.subscribe.apply(this, arguments);
+    },
+    /**
      * The id of the element associated with this object.  This is what we 
      * refer to as the "linked element" because the size and position of 
      * this element is used to determine when the drag and drop objects have 
@@ -1964,7 +1962,12 @@
         this.initTarget(id, sGroup, config);
         Event.on(this._domRef || this.id, "mousedown", 
                         this.handleMouseDown, this, true);
+
         // Event.on(this.id, "selectstart", Event.preventDefault);
+        for (var i in this.events) {
+            this.createEvent(i + 'Event');
+        }
+        
     },
 
     /**
@@ -1980,6 +1983,8 @@
         // configuration attributes 
         this.config = config || {};
 
+        this.events = {};
+
         // create a local reference to the drag and drop manager
         this.DDM = YAHOO.util.DDM;
 
@@ -2027,7 +2032,35 @@
      * @method applyConfig
      */
     applyConfig: function() {
+        this.events = {
+            mouseDown: true,
+            b4MouseDown: true,
+            mouseUp: true,
+            b4StartDrag: true,
+            startDrag: true,
+            b4EndDrag: true,
+            endDrag: true,
+            drag: true,
+            b4Drag: true,
+            invalidDrop: true,
+            b4DragOut: true,
+            dragOut: true,
+            dragEnter: true,
+            b4DragOver: true,
+            dragOver: true,
+            b4DragDrop: true,
+            dragDrop: true
+        };
+        
+        if (this.config.events) {
+            for (var i in this.config.events) {
+                if (this.config.events[i] === false) {
+                    this.events[i] = false;
+                }
+            }
+        }
 
+
         // configurable properties: 
         //    padding, isTarget, maintainOffset, primaryButtonOnly
         this.padding           = this.config.padding || [0, 0, 0, 0];
@@ -2082,6 +2115,9 @@
         var el = this.getEl();
 
         if (!this.DDM.verifyEl(el)) {
+            if (el && el.style && (el.style.display == 'none')) {
+            } else {
+            }
             return;
         }
 
@@ -2233,7 +2269,13 @@
 
         // firing the mousedown events prior to calculating positions
         var b4Return = this.b4MouseDown(e);
+        if (this.events.b4MouseDown) {
+            b4Return = this.fireEvent('b4MouseDownEvent', e);
+        }
         var mDownReturn = this.onMouseDown(e);
+        if (this.events.mouseDown) {
+            mDownReturn = this.fireEvent('mouseDownEvent', e);
+        }
 
         if ((b4Return === false) || (mDownReturn === false)) {
             return;
@@ -2276,10 +2318,9 @@
      * @description Method validates that the clicked element
      * was indeed the handle or a valid child of the handle
      * @param {Event} e 
-     * @private
      */
     clickValidator: function(e) {
-        var target = Event.getTarget(e);
+        var target = YAHOO.util.Event.getTarget(e);
         return ( this.isValidHandleChild(target) &&
                     (this.id == this.handleElId || 
                         this.DDM.handleWasClicked(target, this.id)) );
@@ -2621,7 +2662,100 @@
     }
 
 };
+YAHOO.augment(YAHOO.util.DragDrop, YAHOO.util.EventProvider);
 
+/**
+* @event mouseDownEvent
+* @description Provides access to the mousedown event. The mousedown does not always result in a drag operation.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4MouseDownEvent
+* @description Provides access to the mousedown event, before the mouseDownEvent gets fired. Returning false will cancel the drag.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event mouseUpEvent
+* @description Fired from inside DragDropMgr when the drag operation is finished.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4StartDragEvent
+* @description Fires before the startDragEvent, returning false will cancel the startDrag Event.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event startDragEvent
+* @description Occurs after a mouse down and the drag threshold has been met. The drag threshold default is either 3 pixels of mouse movement or 1 full second of holding the mousedown. 
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4EndDragEvent
+* @description Fires before the endDragEvent. Returning false will cancel.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event endDragEvent
+* @description Fires on the mouseup event after a drag has been initiated (startDrag fired).
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event dragEvent
+* @description Occurs every mousemove event while dragging.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragEvent
+* @description Fires before the dragEvent.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event invalidDropEvent
+* @description Fires when the dragged objects is dropped in a location that contains no drop targets.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragOutEvent
+* @description Fires before the dragOutEvent
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragOutEvent
+* @description Fires when a dragged object is no longer over an object that had the onDragEnter fire. 
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragEnterEvent
+* @description Occurs when the dragged object first interacts with another targettable drag and drop object.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragOverEvent
+* @description Fires before the dragOverEvent.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragOverEvent
+* @description Fires every mousemove event while over a drag and drop object.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragDropEvent 
+* @description Fires before the dragDropEvent
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragDropEvent
+* @description Fires when the dragged objects is dropped on another.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
 })();
 /**
  * A DragDrop implementation where the linked element follows the 
@@ -2718,12 +2852,9 @@
         } else {
             YAHOO.util.Dom.setStyle(el, "left", (oCoord.x + this.deltaSetXY[0]) + "px");
             YAHOO.util.Dom.setStyle(el, "top",  (oCoord.y + this.deltaSetXY[1]) + "px");
-            //el.style.left = (oCoord.x + this.deltaSetXY[0]) + "px";
-            //el.style.top = (oCoord.y + this.deltaSetXY[1]) + "px";
         }
         
         this.cachePosition(oCoord.x, oCoord.y);
-        //DAV
         var self = this;
         setTimeout(function() {
             self.autoScroll.call(self, oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
@@ -2887,6 +3018,98 @@
 
     */
 
+/**
+* @event mouseDownEvent
+* @description Provides access to the mousedown event. The mousedown does not always result in a drag operation.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4MouseDownEvent
+* @description Provides access to the mousedown event, before the mouseDownEvent gets fired. Returning false will cancel the drag.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event mouseUpEvent
+* @description Fired from inside DragDropMgr when the drag operation is finished.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4StartDragEvent
+* @description Fires before the startDragEvent, returning false will cancel the startDrag Event.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event startDragEvent
+* @description Occurs after a mouse down and the drag threshold has been met. The drag threshold default is either 3 pixels of mouse movement or 1 full second of holding the mousedown. 
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4EndDragEvent
+* @description Fires before the endDragEvent. Returning false will cancel.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event endDragEvent
+* @description Fires on the mouseup event after a drag has been initiated (startDrag fired).
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event dragEvent
+* @description Occurs every mousemove event while dragging.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragEvent
+* @description Fires before the dragEvent.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event invalidDropEvent
+* @description Fires when the dragged objects is dropped in a location that contains no drop targets.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragOutEvent
+* @description Fires before the dragOutEvent
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragOutEvent
+* @description Fires when a dragged object is no longer over an object that had the onDragEnter fire. 
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragEnterEvent
+* @description Occurs when the dragged object first interacts with another targettable drag and drop object.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragOverEvent
+* @description Fires before the dragOverEvent.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragOverEvent
+* @description Fires every mousemove event while over a drag and drop object.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragDropEvent 
+* @description Fires before the dragDropEvent
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragDropEvent
+* @description Fires when the dragged objects is dropped on another.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
 });
 /**
  * A DragDrop implementation that inserts an empty, bordered div into
@@ -2983,6 +3206,27 @@
             Dom.setStyle(_data, 'opacity', '0');
             div.appendChild(_data);
 
+            /**
+            * It seems that IE will fire the mouseup event if you pass a proxy element over a select box
+            * Placing the IFRAME element inside seems to stop this issue
+            */
+            if (YAHOO.env.ua.ie) {
+                //Only needed for Internet Explorer
+                var ifr = document.createElement('iframe');
+                ifr.setAttribute('src', 'about:blank');
+                ifr.setAttribute('scrolling', 'no');
+                ifr.setAttribute('frameborder', '0');
+                div.insertBefore(ifr, div.firstChild);
+                Dom.setStyle(ifr, 'height', '100%');
+                Dom.setStyle(ifr, 'width', '100%');
+                Dom.setStyle(ifr, 'position', 'absolute');
+                Dom.setStyle(ifr, 'top', '0');
+                Dom.setStyle(ifr, 'left', '0');
+                Dom.setStyle(ifr, 'opacity', '0');
+                Dom.setStyle(ifr, 'zIndex', '-1');
+                Dom.setStyle(ifr.nextSibling, 'zIndex', '2');
+            }
+
             // appendChild can blow up IE if invoked prior to the window load event
             // while rendering a table.  It is possible there are other scenarios 
             // that would cause this to happen as well.
@@ -3113,7 +3357,99 @@
     toString: function() {
         return ("DDProxy " + this.id);
     }
+/**
+* @event mouseDownEvent
+* @description Provides access to the mousedown event. The mousedown does not always result in a drag operation.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
 
+/**
+* @event b4MouseDownEvent
+* @description Provides access to the mousedown event, before the mouseDownEvent gets fired. Returning false will cancel the drag.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event mouseUpEvent
+* @description Fired from inside DragDropMgr when the drag operation is finished.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4StartDragEvent
+* @description Fires before the startDragEvent, returning false will cancel the startDrag Event.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event startDragEvent
+* @description Occurs after a mouse down and the drag threshold has been met. The drag threshold default is either 3 pixels of mouse movement or 1 full second of holding the mousedown. 
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event b4EndDragEvent
+* @description Fires before the endDragEvent. Returning false will cancel.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event endDragEvent
+* @description Fires on the mouseup event after a drag has been initiated (startDrag fired).
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
+/**
+* @event dragEvent
+* @description Occurs every mousemove event while dragging.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragEvent
+* @description Fires before the dragEvent.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event invalidDropEvent
+* @description Fires when the dragged objects is dropped in a location that contains no drop targets.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragOutEvent
+* @description Fires before the dragOutEvent
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragOutEvent
+* @description Fires when a dragged object is no longer over an object that had the onDragEnter fire. 
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragEnterEvent
+* @description Occurs when the dragged object first interacts with another targettable drag and drop object.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragOverEvent
+* @description Fires before the dragOverEvent.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragOverEvent
+* @description Fires every mousemove event while over a drag and drop object.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event b4DragDropEvent 
+* @description Fires before the dragDropEvent
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+/**
+* @event dragDropEvent
+* @description Fires when the dragged objects is dropped on another.
+* @type YAHOO.util.CustomEvent See <a href="YAHOO.util.Element.html#addListener">Element.addListener</a> for more information on listening for this event.
+*/
+
 });
 /**
  * A DragDrop implementation that does not move, but can be a drop 
@@ -3142,4 +3478,4 @@
         return ("DDTarget " + this.id);
     }
 });
-YAHOO.register("dragdrop", YAHOO.util.DragDropMgr, {version: "2.4.1", build: "742"});
+YAHOO.register("dragdrop", YAHOO.util.DragDropMgr, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/editor/README
===================================================================
--- trunk/root/static/yui/editor/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/editor/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,57 @@
+**** version 2.5.1 ***
 
-**** version 2.4.1 ***
+    * Adobe AIR Support
+        * 1763867 - Adobe AIR: iFrame document open
+        * 1763869 - Adobe AIR: Blank Image insertion fails
+        * 1763872 - Adobe AIR: Setting font-family fails
+        * 1763880 - Adobe AIR: Image Editor should show copy/paste note
 
-No change
+    * Internet Explorer
+        * 1556954 - [SF 1816784 ] tabbing troubles...
+        * 1776579 - [SF 1873881 ] IE Bulleting Behavior
 
+    * Safari
+        * 1775802 - [SF 1899803] Links in safari are treated as regular links...
+        * 1777918 - [SF 1898878 ] Safari uses <span> instead of <strong> tags...
+
+    * All
+        * 1776107 - ToolbarButton doesn't have a destroy method
+        * 1776117 - Editor Accessibility Enhancements
+        * 1776539 - [SF 1874009 ] Greedy Regex in RTE Eats embed and other tags
+        * 1777925 - [SF 1878976 ] Regex matches both <i> and <iframe>
+        * 1764038 - [SF 1898886 ] Problem with handleSubmit after move to 2.5.0
+        * 1693686 - [SF 1869619] Image Modification Dialog
+
+
+**** version 2.5.0 ***
+
+    *Examples:
+        1. [1687273] - [SF 1861119 ] Flickr Example code is incorrect
+
+    *Config
+        1. [1556954] - [SF 1816784 ] tabbing troubles...
+            Added a new config option called plainText. (See API docs for more information)
+        2. Removed the requirement for a textarea. If you pass the config as the first argument to the constructor
+            the Editor will create the textarea for you.
+
+    *Internet Explorer
+        1. [1515145] - [SF 1807057 ] RTE _setDesignMode reloads page content
+        2. [1687267] - [SF 1861514 ] editorContentLoaded fires early in IE6/7
+        3. [1687244] - [SF 1866217 ] Editor in frameset causes "unspecified error" in IE6
+        4. [1687278] - [SF 1859031 ] Change Font Color on IE
+        5. [1687283] - [SF 1857798 ] IE7 RTE HTTPS problem
+        6. [1687316] - [SF 1854657 ] IE bullet/number strange behaviour
+    
+    *All
+        1. [1687258] - [SF 1862824 ] Problem with <script> tags in editor content
+        2. [1687292] - [SF 1857235 ] cleanHTML function stripping closing tags
+        3. [1687322] - [SF 1849730 ] Multiple Editors' toolbars conflict
+        4. [1688270] - [SF 1867927] Editor dynamic height adjust
+        5. [1693656] - [SF 1870215] handleSubmit hijacks the value of the submit button
+        6. [1693686] - [SF 1869619] Image Modification Dialog
+        7. [1693719] - [SF 1850814] Editor produces faulty code
+
+
 **** version 2.4.0 ***
 
 * Performance enhancements and bug fixes.

Modified: trunk/root/static/yui/editor/assets/editor-core.css
===================================================================
--- trunk/root/static/yui/editor/assets/editor-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/editor/assets/editor-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,14 +1,21 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* Set the cursor to busy when we are doing something */
 .yui-busy {
     cursor: wait !important;
 }
-
+.yui-toolbar-container fieldset {
+    padding: 0;
+    margin: 0;
+    border: 0;
+}
+.yui-toolbar-container legend {
+    display: none;
+}
 /* Setup the container with some padding and zoom it for IE's hasLayout */
 .yui-toolbar-container .yui-toolbar-subcont {
     padding: .25em 0;
@@ -52,6 +59,11 @@
     margin: 0;
     padding: .2em;
 }
+.yui-toolbar-container .yui-toolbar-titlebar h2 a {
+    text-decoration: none;
+    color: #000;
+    cursor: default;
+}
 /* If the toolbar is grouped the draghandle needs to be bigger */
 .yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-draghandle {
     height: 40px;

Modified: trunk/root/static/yui/editor/assets/simpleeditor-core.css
===================================================================
--- trunk/root/static/yui/editor/assets/simpleeditor-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/editor/assets/simpleeditor-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,14 +1,21 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* Set the cursor to busy when we are doing something */
 .yui-busy {
     cursor: wait !important;
 }
-
+.yui-toolbar-container fieldset {
+    padding: 0;
+    margin: 0;
+    border: 0;
+}
+.yui-toolbar-container legend {
+    display: none;
+}
 /* Setup the container with some padding and zoom it for IE's hasLayout */
 .yui-toolbar-container .yui-toolbar-subcont {
     padding: .25em 0;
@@ -52,6 +59,11 @@
     margin: 0;
     padding: .2em;
 }
+.yui-toolbar-container .yui-toolbar-titlebar h2 a {
+    text-decoration: none;
+    color: #000;
+    cursor: default;
+}
 /* If the toolbar is grouped the draghandle needs to be bigger */
 .yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-draghandle {
     height: 40px;

Modified: trunk/root/static/yui/editor/assets/skins/sam/editor-skin.css
===================================================================
--- trunk/root/static/yui/editor/assets/skins/sam/editor-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/editor/assets/skins/sam/editor-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* Place the border around the editor */
 .yui-skin-sam .yui-editor-container {

Modified: trunk/root/static/yui/editor/assets/skins/sam/editor.css
===================================================================
--- trunk/root/static/yui/editor/assets/skins/sam/editor.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/editor/assets/skins/sam/editor.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-.yui-busy{cursor:wait !important;}.yui-toolbar-container .yui-toolbar-subcont{padding:.25em 0;zoom:1;}.yui-toolbar-container-collapsed .yui-toolbar-subcont{display:none;}.yui-toolbar-container .yui-toolbar-subcont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container span.yui-toolbar-draghandle{cursor:move;border-left:1px solid #999;border-right:1px solid #999;overflow:hidden;text-indent:77777px;width:2px;height:20px;display:block;clear:none;float:left;margin:0 0 0 .2em;}.yui-toolbar-container .yui-toolbar-titlebar.draggable{cursor:move;}.yui-toolbar-container .yui-toolbar-titlebar{position:relative;}.yui-toolbar-container .yui-toolbar-titlebar h2{font-weight:bold;letter-spacing:0;border:none;color:#000;margin:0;padding:.2em;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-draghandle{height:40px;}.yui-toolbar-container .yui-toolbar-group{float:left;zoom:1;}.yui-toolbar-container .yui-toolbar-group:after{display:block;clear!
 :both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container .yui-toolbar-group h3{font-size:75%;padding:0 0 0 .25em;margin:0;}.yui-toolbar-container span.yui-toolbar-separator{width:2px;height:18px;margin:.2em 0 .2em .1em;display:block;clear:none;float:left;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-separator{height:35px;}.yui-toolbar-container.yui-toolbar-grouped .yui-toolbar-group span.yui-toolbar-separator{height:18px;}.yui-toolbar-container ul li{margin:0;padding:0;list-style-type:none;}.yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-toolbar-container .yui-push-button,.yui-toolbar-container .yui-color-button,.yui-toolbar-container .yui-menu-button{position:relative;cursor:pointer;}.yui-toolbar-container .yui-button .first-child,.yui-toolbar-container .yui-button .first-child a{height:100%;width:100%;overflow:hidden;}.yui-toolbar-container .yui-button-disabled{cursor:default;}.yui-toolbar-container .yui-button-disabled .!
 yui-toolbar-icon{opacity:.5;filter:alpha(opacity=50);}.yui-too!
 lbar-con
tainer .yui-button-disabled .up,.yui-toolbar-container .yui-button-disabled .down{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button a{overflow:hidden;}.yui-toolbar-container .yui-toolbar-select .first-child a{cursor:pointer;}.yui-toolbar-fontname-arial{font-family:Arial;}.yui-toolbar-fontname-arial-black{font-family:Arial Black;}.yui-toolbar-fontname-comic-sans-ms{font-family:Comic Sans MS;}.yui-toolbar-fontname-courier-new{font-family:Courier New;}.yui-toolbar-fontname-times-new-roman{font-family:Times New Roman;}.yui-toolbar-fontname-verdana{font-family:Verdana;}.yui-toolbar-fontname-impact{font-family:Impact;}.yui-toolbar-fontname-lucida-console{font-family:Lucida Console;}.yui-toolbar-fontname-tahoma{font-family:Tahoma;}.yui-toolbar-fontname-trebuchet-ms{font-family:Trebuchet MS;}.yui-toolbar-container .yui-toolbar-spinbutton{position:relative;}.yui-toolbar-container .yui-toolbar-spinbutton .first-child a{z-index:0;opacity:1;}.yui-toolbar-container !
 .yui-toolbar-spinbutton a.up,.yui-toolbar-container .yui-toolbar-spinbutton a.down{position:absolute;display:block right:0;cursor:pointer;z-index:1;padding:0;margin:0;}.yui-toolbar-container .yui-overlay{position:absolute;}.yui-toolbar-container .yui-overlay ul li{margin:0;list-style-type:none;}.yui-toolbar-container{z-index:1;}.yui-editor-container .yui-editor-editable-container{position:relative;z-index:0;width:100%;}.yui-editor-container .yui-editor-masked{background-color:#CCC;}.yui-editor-container iframe{border:0px;padding:0;margin:0;zoom:1;display:block;}.yui-editor-container .yui-editor-editable{padding:0;margin:0;}.yui-editor-container .dompath{font-size:85%;}.yui-editor-panel .hd{text-align:left;position:relative;}.yui-editor-panel .hd h3{font-weight:bold;padding:0.25em 0pt 0.25em 0.25em;margin:0;}.yui-editor-panel .bd{width:100%;zoom:1;position:relative;}.yui-editor-panel .bd div.yui-editor-body-cont{padding:.25em .1em;zoom:1;}.yui-editor-panel .bd div.yui-editor!
 -body-cont:after{display:block;clear:both;visibility:hidden;co!
 ntent:'.
';height:0;}.yui-editor-panel .ft{text-align:right;width:99%;float:left;clear:both;}.yui-editor-panel .ft span.tip{display:block;position:relative;padding:.5em .5em .5em 23px;text-align:left;zoom:1;}.yui-editor-panel label{clear:both;float:left;padding:0;width:100%;text-align:left;zoom:1;}.yui-editor-panel .gecko label{overflow:auto;}.yui-editor-panel label strong{float:left;width:6em;}.yui-editor-panel .removeLink{width:80%;text-align:right;}.yui-editor-panel label input{margin-left:.25em;float:left;}.yui-editor-panel .yui-toolbar-group-padding{}.yui-editor-panel .yui-toolbar-group-border{}.yui-editor-panel .yui-toolbar-group-textflow{}.yui-editor-panel .height-width{float:left;}.yui-editor-panel .height-width h3{}.yui-editor-panel .height-width span{font-style:italic;display:block;float:left;overflow:auto;}.yui-editor-panel .height-width span.info{font-size:70%;}.yui-editor-panel .yui-toolbar-bordersize,.yui-editor-panel .yui-toolbar-bordertype{font-size:75%;}.yui-editor-p!
 anel .yui-toolbar-container span.yui-toolbar-separator{border:none;}.yui-editor-panel .yui-toolbar-bordersize span a span,.yui-editor-panel .yui-toolbar-bordertype span a span{display:block;height:8px;left:4px;position:absolute;top:3px;*top:-5px;width:24px;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-solid{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dotted{border-bottom:1px dotted black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dashed{border-bottom:1px dashed black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-0{*top:0px;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-1{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-2{border-bottom:2px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersiz!
 e-3{top:2px;*top:-5px;border-bottom:3px solid black;}.yui-edit!
 or-panel
 .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-4{top:1px;*top:-5px;border-bottom:4px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-5{top:1px;*top:-5px;border-bottom:5px solid black;}.yui-toolbar-container .yui-toolbar-bordersize-menu,.yui-toolbar-container .yui-toolbar-bordertype-menu{width:95px !important;}.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel,.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel:hover{margin:0px 3px 7px 17px;}.yui-toolbar-bordersize-menu .yuimenuitemlabel .checkedindicator,.yui-toolbar-bordertype-menu .yuimenuitemlabel .checkedindicator{position:absolute;left:-12px;*top:14px;*left:0px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-1 a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-2 a{border-bottom:2px solid black;height:14px;}.yui-toolbar-borders!
 ize-menu li.yui-toolbar-bordersize-3 a{border-bottom:3px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-4 a{border-bottom:4px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-5 a{border-bottom:5px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-solid a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dashed a{border-bottom:1px dashed black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dotted a{border-bottom:1px dotted black;height:14px;}h2.yui-editor-skipheader,h3.yui-editor-skipheader{height:0;margin:0;padding:0;border:none;width:0;overflow:hidden;position:absolute;}.yui-toolbar-colors{width:133px;zoom:1;display:none;z-index:100;overflow:hidden;}.yui-toolbar-colors:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors a{height:9px;width:9px;float:left;display:block;overflo!
 w:hidden;text-indent:999px;margin:0;cursor:pointer;border:1px !
 solid #F
6F7EE;}.yui-toolbar-colors a:hover{border:1px solid black;}.yui-color-button-menu{overflow:visible;background-color:transparent;}.yui-toolbar-colors span{position:relative;display:block;padding:3px;overflow:hidden;float:left;width:100%;zoom:1;}.yui-toolbar-colors span:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors span em{height:35px;width:30px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0.75px;border:1px solid black;}.yui-toolbar-colors span strong{font-weight:normal;padding-left:3px;display:block;font-size:85%;float:left;width:65%;}.yui-skin-sam .yui-editor-container{border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container{zoom:1;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -200px;position:relative;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar h2{color:#000000;font-weight:bold;margin:0;padding:0.3em 1em;font!
 -size:100%;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-group h3{color:#808080;font-size:75%;margin:1em 0 0;padding-bottom:0;padding-left:0.25em;text-align:left;}.yui-toolbar-container span.yui-toolbar-separator{border:none;text-indent:33px;overflow:hidden;margin:.25em;}.yui-skin-sam .yui-toolbar-container{background-color:#F2F2F2;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subcont{padding:0 1em 0.35em;border-bottom:1px solid #808080;}.yui-skin-sam .yui-toolbar-container-collapsed .yui-toolbar-titlebar{border-bottom:1px solid #808080;}.yui-skin-sam .yui-editor-container .visible .yui-menu-shadow,.yui-skin-sam .yui-editor-panel .visible .yui-menu-shadow{display:none;}.yui-skin-sam .yui-editor-container ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-container ul li{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-toolbar-group ul li.yui-toolbar-groupitem{float:left;}.yui-skin-sam .yui-editor-container .dompath{bac!
 kground-color:#F2F2F2;border-top:1px solid #808080;color:#999;!
 text-ali
gn:left;padding:0.25em;}.yui-skin-sam .yui-toolbar-container .collapse{background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -400px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar span.collapse{cursor:pointer;position:absolute;top:4px;right:2px;display:block;overflow:hidden;height:15px;width:15px;text-indent:9999px;}.yui-skin-sam .yui-toolbar-container .yui-push-button,.yui-skin-sam .yui-toolbar-container .yui-color-button,.yui-skin-sam .yui-toolbar-container .yui-menu-button{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;position:relative;display:block;height:22px;width:30px;margin:0;border-color:#808080;border-style:solid;border-width:1px 0;}.yui-skin-sam .yui-toolbar-container .yui-push-button a,.yui-skin-sam .yui-toolbar-container .yui-color-button a,.yui-skin-sam .yui-toolbar-container .yui-menu-button a{padding-left:35px;height:20px;text-decoration:none;font-size:93%;line-height:2;display:block;color:#000000;overflow:hidd!
 en;}.yui-skin-sam .yui-toolbar-container .yui-push-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button .first-child{border-color:#808080;border-style:solid;border-width:0 1px;margin:0 -1px;display:block;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled{border-color:#ccc;}.yui-skin-s!
 am .yui-toolbar-container .yui-button .first-child{*left:0px;}!
 .yui-ski
n-sam .yui-toolbar-container .yui-toolbar-fontname{width:135px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-heading{width:92px;}.yui-skin-sam .yui-toolbar-container .yui-button-hover{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1300px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-button-selected{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1700px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels .yui-toolbar-group{margin-top:.75em;}.yui-skin-sam .yui-toolbar-container .yui-push-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-color-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-menu-button span.yui-toolbar-icon{display:block;position:absolute;top:2px;height:18px;width:18px;overflow:hidden;background:url(editor-sprite.gif) no-repeat 30px 30px;}.yu!
 i-skin-sam .yui-toolbar-container .yui-button-selected span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-button-hover span.yui-toolbar-icon{background-image:url(editor-sprite-active.gif);}.yui-skin-sam .yui-toolbar-container .visible .yuimenuitemlabel{cursor:pointer;color:#000;*position:relative;}.yui-skin-sam .yui-toolbar-container .yui-button-menu{background-color:#fff;}.yui-skin-sam div.yuimenu li.selected{background-color:#B3D4FF;}.yui-skin-sam div.yuimenu li.selected a.selected{color:#000;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bold span.yui-toolbar-icon{background-position:0 0;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-italic span.yui-toolbar-icon{background-position:0 -36px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-underline span.yui-toolbar-icon{background-position:0 -72px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subscript span.yui-toolbar-icon{background-position:0 -180px;left:5px;}.yui-!
 skin-sam .yui-toolbar-container .yui-toolbar-superscript span.!
 yui-tool
bar-icon{background-position:0 -144px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-forecolor span.yui-toolbar-icon{background-position:0 -216px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-backcolor span.yui-toolbar-icon{background-position:0 -288px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyleft span.yui-toolbar-icon{background-position:0 -324px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifycenter span.yui-toolbar-icon{background-position:0 -360px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyright span.yui-toolbar-icon{background-position:0 -396px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyfull span.yui-toolbar-icon{background-position:0 -432px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-indent span.yui-toolbar-icon{background-position:0 -720px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-outdent span.yui-toolbar-icon{backgr!
 ound-position:0 -684px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-createlink span.yui-toolbar-icon{background-position:0 -792px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertimage span.yui-toolbar-icon{background-position:1px -756px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-left span.yui-toolbar-icon{background-position:0 -972px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-right span.yui-toolbar-icon{background-position:0 -936px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-inline span.yui-toolbar-icon{background-position:0 -900px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-block span.yui-toolbar-icon{background-position:0 -864px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bordercolor span.yui-toolbar-icon{background-position:0 -252px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-removeformat span.yui-toolbar-icon{background-position:0 -1080px;le!
 ft:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-hidd!
 enelemen
ts span.yui-toolbar-icon{background-position:0 -1044px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertunorderedlist span.yui-toolbar-icon{background-position:0 -468px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertorderedlist span.yui-toolbar-icon{background-position:0 -504px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child{width:35px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child a{padding-left:2px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton span.yui-toolbar-icon{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{right:2px;background:url(editor-sprite.gif) no-repeat 0 -1222px;overflow:hidden;height:6px;width:7px;min-height:0;padding:0;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-s!
 pinbutton a.up{top:2px;background-position:0 -1222px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{bottom:2px;background-position:0 -1187px;}.yui-skin-sam .yui-toolbar-container select{height:22px;border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select .first-child a{padding-left:5px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select span.yui-toolbar-icon{background:url( editor-sprite.gif ) no-repeat 0 -1144px;overflow:hidden;right:-2px;top:0px;height:20px;}.yui-skin-sam .yui-editor-panel .yui-color-button-menu .bd{background-color:transparent;border:none;width:135px;}.yui-skin-sam .yui-color-button-menu .yui-toolbar-colors{border:1px solid #808080;}.yui-skin-sam .yui-editor-panel{padding:0;margin:0;border:none;background-color:transparent;overflow:visible;}.yui-skin-sam .yui-editor-panel .hd{margin:10px 0 0;padding:0;border:none;}.yui-skin-sam .yui-editor-panel .hd h3{color:#000;border:1px solid #8080!
 80;background:url(../../../../assets/skins/sam/sprite.png) rep!
 eat-x 0 
-200px;width:99%;position:relative;margin:0;padding:3px 0 0 0;font-size:93%;text-indent:5px;height:20px;}.yui-skin-sam .yui-editor-panel .bd{background-color:#F2F2F2;border-left:1px solid #808080;border-right:1px solid #808080;width:99%;margin:0;padding:0;overflow:visible;}.yui-skin-sam .yui-editor-panel ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-panel ul li{margin:0;padding:0;}.yui-skin-sam .yui-editor-panel .yuimenu{}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .yui-toolbar-subcont{padding:0;border:none;margin-top:0.35em;}.yui-skin-sam .yui-editor-panel .yui-toolbar-bordersize,.yui-skin-sam .yui-editor-panel .yui-toolbar-bordertype{width:50px;}.yui-skin-sam .yui-editor-panel label{display:block;float:none;padding:4px 0;margin-bottom:7px;}.yui-skin-sam .yui-editor-panel label strong{font-weight:normal;font-size:93%;text-align:right;padding-top:2px;}.yui-skin-sam .yui-editor-panel label input{width:75%;}.yui-skin-sam .yui-editor-panel #cr!
 eatelink_target,.yui-skin-sam .yui-editor-panel #insertimage_target{width:auto;margin-right:5px;}.yui-skin-sam .yui-editor-panel .removeLink{width:98%;}.yui-skin-sam .yui-editor-panel label input.warning{background-color:#FFEE69;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group h3{color:#000;float:left;font-weight:normal;font-size:93%;margin:5px 0 0 0;padding:0 3px 0 0;text-align:right;}.yui-skin-sam .yui-editor-panel .height-width h3{margin:3px 0 0 10px;}.yui-skin-sam .yui-editor-panel .height-width{margin:3px 0 0 35px;*margin-left:14px;width:42%;*width:44%;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-border{width:190px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-border{width:210px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding{width:203px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-padding{width:172px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding h3{margin-left:25px;*margin-left:12px;}.yui-skin-sam !
 .yui-editor-panel .yui-toolbar-group-textflow{width:182px;}.yu!
 i-skin-s
am .yui-editor-panel .hd{background:none;}.yui-skin-sam .yui-editor-panel .ft{background-color:#F2F2F2;border:1px solid #808080;border-top:none;padding:0;margin:0 0 2px 0;}.yui-skin-sam .yui-editor-panel .hd span.close{background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -300px;cursor:pointer;display:block;height:16px;overflow:hidden;position:absolute;right:5px;text-indent:500px;top:2px;width:26px;}.yui-skin-sam .yui-editor-panel .ft span.tip{background-color:#EDF5FF;border-top:1px solid #808080;font-size:85%;}.yui-skin-sam .yui-editor-panel .ft span.tip strong{display:block;float:left;margin:0 2px 8px 0;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon{background:url( editor-sprite.gif ) no-repeat 0 -1260px;display:block;height:20px;left:2px;position:absolute;top:8px;width:20px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-info{background-position:2px -1260px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-warn{background-position:2px !
 -1296px;}.yui-skin-sam .yui-editor-panel .hd span.knob{position:absolute;height:10px;width:28px;top:-10px;left:25px;text-indent:9999px;overflow:hidden;background:url( editor-knob.gif ) no-repeat 0 0;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container{float:left;width:100%;background-image:none;border:none;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .bd{background-color:#ffffff;}.yui-editor-blankimage{background-image:url( blankimage.png );}
+.yui-busy{cursor:wait !important;}.yui-toolbar-container fieldset{padding:0;margin:0;border:0;}.yui-toolbar-container legend{display:none;}.yui-toolbar-container .yui-toolbar-subcont{padding:.25em 0;zoom:1;}.yui-toolbar-container-collapsed .yui-toolbar-subcont{display:none;}.yui-toolbar-container .yui-toolbar-subcont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container span.yui-toolbar-draghandle{cursor:move;border-left:1px solid #999;border-right:1px solid #999;overflow:hidden;text-indent:77777px;width:2px;height:20px;display:block;clear:none;float:left;margin:0 0 0 .2em;}.yui-toolbar-container .yui-toolbar-titlebar.draggable{cursor:move;}.yui-toolbar-container .yui-toolbar-titlebar{position:relative;}.yui-toolbar-container .yui-toolbar-titlebar h2{font-weight:bold;letter-spacing:0;border:none;color:#000;margin:0;padding:.2em;}.yui-toolbar-container .yui-toolbar-titlebar h2 a{text-decoration:none;color:#000;cursor:default;}.yui-tool!
 bar-container.yui-toolbar-grouped span.yui-toolbar-draghandle{height:40px;}.yui-toolbar-container .yui-toolbar-group{float:left;zoom:1;}.yui-toolbar-container .yui-toolbar-group:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container .yui-toolbar-group h3{font-size:75%;padding:0 0 0 .25em;margin:0;}.yui-toolbar-container span.yui-toolbar-separator{width:2px;height:18px;margin:.2em 0 .2em .1em;display:block;clear:none;float:left;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-separator{height:35px;}.yui-toolbar-container.yui-toolbar-grouped .yui-toolbar-group span.yui-toolbar-separator{height:18px;}.yui-toolbar-container ul li{margin:0;padding:0;list-style-type:none;}.yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-toolbar-container .yui-push-button,.yui-toolbar-container .yui-color-button,.yui-toolbar-container .yui-menu-button{position:relative;cursor:pointer;}.yui-toolbar-container .yui-button .firs!
 t-child,.yui-toolbar-container .yui-button .first-child a{heig!
 ht:100%;
width:100%;overflow:hidden;}.yui-toolbar-container .yui-button-disabled{cursor:default;}.yui-toolbar-container .yui-button-disabled .yui-toolbar-icon{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button-disabled .up,.yui-toolbar-container .yui-button-disabled .down{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button a{overflow:hidden;}.yui-toolbar-container .yui-toolbar-select .first-child a{cursor:pointer;}.yui-toolbar-fontname-arial{font-family:Arial;}.yui-toolbar-fontname-arial-black{font-family:Arial Black;}.yui-toolbar-fontname-comic-sans-ms{font-family:Comic Sans MS;}.yui-toolbar-fontname-courier-new{font-family:Courier New;}.yui-toolbar-fontname-times-new-roman{font-family:Times New Roman;}.yui-toolbar-fontname-verdana{font-family:Verdana;}.yui-toolbar-fontname-impact{font-family:Impact;}.yui-toolbar-fontname-lucida-console{font-family:Lucida Console;}.yui-toolbar-fontname-tahoma{font-family:Tahoma;}.yui-toolbar-fontname-trebuche!
 t-ms{font-family:Trebuchet MS;}.yui-toolbar-container .yui-toolbar-spinbutton{position:relative;}.yui-toolbar-container .yui-toolbar-spinbutton .first-child a{z-index:0;opacity:1;}.yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-toolbar-container .yui-toolbar-spinbutton a.down{position:absolute;display:block right:0;cursor:pointer;z-index:1;padding:0;margin:0;}.yui-toolbar-container .yui-overlay{position:absolute;}.yui-toolbar-container .yui-overlay ul li{margin:0;list-style-type:none;}.yui-toolbar-container{z-index:1;}.yui-editor-container .yui-editor-editable-container{position:relative;z-index:0;width:100%;}.yui-editor-container .yui-editor-masked{background-color:#CCC;}.yui-editor-container iframe{border:0px;padding:0;margin:0;zoom:1;display:block;}.yui-editor-container .yui-editor-editable{padding:0;margin:0;}.yui-editor-container .dompath{font-size:85%;}.yui-editor-panel .hd{text-align:left;position:relative;}.yui-editor-panel .hd h3{font-weight:bold;padding:0!
 .25em 0pt 0.25em 0.25em;margin:0;}.yui-editor-panel .bd{width:!
 100%;zoo
m:1;position:relative;}.yui-editor-panel .bd div.yui-editor-body-cont{padding:.25em .1em;zoom:1;}.yui-editor-panel .bd div.yui-editor-body-cont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-editor-panel .ft{text-align:right;width:99%;float:left;clear:both;}.yui-editor-panel .ft span.tip{display:block;position:relative;padding:.5em .5em .5em 23px;text-align:left;zoom:1;}.yui-editor-panel label{clear:both;float:left;padding:0;width:100%;text-align:left;zoom:1;}.yui-editor-panel .gecko label{overflow:auto;}.yui-editor-panel label strong{float:left;width:6em;}.yui-editor-panel .removeLink{width:80%;text-align:right;}.yui-editor-panel label input{margin-left:.25em;float:left;}.yui-editor-panel .yui-toolbar-group-padding{}.yui-editor-panel .yui-toolbar-group-border{}.yui-editor-panel .yui-toolbar-group-textflow{}.yui-editor-panel .height-width{float:left;}.yui-editor-panel .height-width h3{}.yui-editor-panel .height-width span{font-style:italic;displa!
 y:block;float:left;overflow:auto;}.yui-editor-panel .height-width span.info{font-size:70%;}.yui-editor-panel .yui-toolbar-bordersize,.yui-editor-panel .yui-toolbar-bordertype{font-size:75%;}.yui-editor-panel .yui-toolbar-container span.yui-toolbar-separator{border:none;}.yui-editor-panel .yui-toolbar-bordersize span a span,.yui-editor-panel .yui-toolbar-bordertype span a span{display:block;height:8px;left:4px;position:absolute;top:3px;*top:-5px;width:24px;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-solid{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dotted{border-bottom:1px dotted black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dashed{border-bottom:1px dashed black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-0{*top:0px;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-1{border-bottom!
 :1px solid black;}.yui-editor-panel .yui-toolbar-bordersize sp!
 an a spa
n.yui-toolbar-bordersize-2{border-bottom:2px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-3{top:2px;*top:-5px;border-bottom:3px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-4{top:1px;*top:-5px;border-bottom:4px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-5{top:1px;*top:-5px;border-bottom:5px solid black;}.yui-toolbar-container .yui-toolbar-bordersize-menu,.yui-toolbar-container .yui-toolbar-bordertype-menu{width:95px !important;}.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel,.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel:hover{margin:0px 3px 7px 17px;}.yui-toolbar-bordersize-menu .yuimenuitemlabel .checkedindicator,.yui-toolbar-bordertype-menu .yuimenuitemlabel .checkedindicator{position:absolute;left:-12px;*top:14px;*left:0px;}.yui-toolbar-bordersi!
 ze-menu li.yui-toolbar-bordersize-1 a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-2 a{border-bottom:2px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-3 a{border-bottom:3px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-4 a{border-bottom:4px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-5 a{border-bottom:5px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-solid a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dashed a{border-bottom:1px dashed black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dotted a{border-bottom:1px dotted black;height:14px;}h2.yui-editor-skipheader,h3.yui-editor-skipheader{height:0;margin:0;padding:0;border:none;width:0;overflow:hidden;position:absolute;}.yui-toolbar-colors{width:133px;zoom:1;displ!
 ay:none;z-index:100;overflow:hidden;}.yui-toolbar-colors:after!
 {display
:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors a{height:9px;width:9px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0;cursor:pointer;border:1px solid #F6F7EE;}.yui-toolbar-colors a:hover{border:1px solid black;}.yui-color-button-menu{overflow:visible;background-color:transparent;}.yui-toolbar-colors span{position:relative;display:block;padding:3px;overflow:hidden;float:left;width:100%;zoom:1;}.yui-toolbar-colors span:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors span em{height:35px;width:30px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0.75px;border:1px solid black;}.yui-toolbar-colors span strong{font-weight:normal;padding-left:3px;display:block;font-size:85%;float:left;width:65%;}.yui-skin-sam .yui-editor-container{border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container{zoom:1;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar{background:url!
 (../../../../assets/skins/sam/sprite.png) repeat-x 0 -200px;position:relative;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar h2{color:#000000;font-weight:bold;margin:0;padding:0.3em 1em;font-size:100%;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-group h3{color:#808080;font-size:75%;margin:1em 0 0;padding-bottom:0;padding-left:0.25em;text-align:left;}.yui-toolbar-container span.yui-toolbar-separator{border:none;text-indent:33px;overflow:hidden;margin:.25em;}.yui-skin-sam .yui-toolbar-container{background-color:#F2F2F2;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subcont{padding:0 1em 0.35em;border-bottom:1px solid #808080;}.yui-skin-sam .yui-toolbar-container-collapsed .yui-toolbar-titlebar{border-bottom:1px solid #808080;}.yui-skin-sam .yui-editor-container .visible .yui-menu-shadow,.yui-skin-sam .yui-editor-panel .visible .yui-menu-shadow{display:none;}.yui-skin-sam .yui-editor-container ul{list-style-type:none;margin:0;padding:0;}.!
 yui-skin-sam .yui-editor-container ul li{list-style-type:none;!
 margin:0
;padding:0;}.yui-skin-sam .yui-toolbar-group ul li.yui-toolbar-groupitem{float:left;}.yui-skin-sam .yui-editor-container .dompath{background-color:#F2F2F2;border-top:1px solid #808080;color:#999;text-align:left;padding:0.25em;}.yui-skin-sam .yui-toolbar-container .collapse{background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -400px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar span.collapse{cursor:pointer;position:absolute;top:4px;right:2px;display:block;overflow:hidden;height:15px;width:15px;text-indent:9999px;}.yui-skin-sam .yui-toolbar-container .yui-push-button,.yui-skin-sam .yui-toolbar-container .yui-color-button,.yui-skin-sam .yui-toolbar-container .yui-menu-button{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;position:relative;display:block;height:22px;width:30px;margin:0;border-color:#808080;border-style:solid;border-width:1px 0;}.yui-skin-sam .yui-toolbar-container .yui-push-button a,.yui-skin-sam .yui-toolbar-con!
 tainer .yui-color-button a,.yui-skin-sam .yui-toolbar-container .yui-menu-button a{padding-left:35px;height:20px;text-decoration:none;font-size:93%;line-height:2;display:block;color:#000000;overflow:hidden;}.yui-skin-sam .yui-toolbar-container .yui-push-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button .first-child{border-color:#808080;border-style:solid;border-width:0 1px;margin:0 -1px;display:block;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yu!
 i-toolbar-container .yui-push-button-disabled,.yui-skin-sam .y!
 ui-toolb
ar-container .yui-color-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-button .first-child{*left:0px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-fontname{width:135px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-heading{width:92px;}.yui-skin-sam .yui-toolbar-container .yui-button-hover{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1300px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-button-selected{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1700px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels .yui-toolbar-group{margin-top:.75em;}.yui-skin-sam .yui-toolbar-container .yui-push-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-color-button span.yui-toolbar-icon,.yui-skin-!
 sam .yui-toolbar-container .yui-menu-button span.yui-toolbar-icon{display:block;position:absolute;top:2px;height:18px;width:18px;overflow:hidden;background:url(editor-sprite.gif) no-repeat 30px 30px;}.yui-skin-sam .yui-toolbar-container .yui-button-selected span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-button-hover span.yui-toolbar-icon{background-image:url(editor-sprite-active.gif);}.yui-skin-sam .yui-toolbar-container .visible .yuimenuitemlabel{cursor:pointer;color:#000;*position:relative;}.yui-skin-sam .yui-toolbar-container .yui-button-menu{background-color:#fff;}.yui-skin-sam div.yuimenu li.selected{background-color:#B3D4FF;}.yui-skin-sam div.yuimenu li.selected a.selected{color:#000;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bold span.yui-toolbar-icon{background-position:0 0;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-italic span.yui-toolbar-icon{background-position:0 -36px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-t!
 oolbar-underline span.yui-toolbar-icon{background-position:0 -!
 72px;lef
t:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subscript span.yui-toolbar-icon{background-position:0 -180px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-superscript span.yui-toolbar-icon{background-position:0 -144px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-forecolor span.yui-toolbar-icon{background-position:0 -216px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-backcolor span.yui-toolbar-icon{background-position:0 -288px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyleft span.yui-toolbar-icon{background-position:0 -324px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifycenter span.yui-toolbar-icon{background-position:0 -360px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyright span.yui-toolbar-icon{background-position:0 -396px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyfull span.yui-toolbar-icon{background-position:0 -432px;left:5px;}.!
 yui-skin-sam .yui-toolbar-container .yui-toolbar-indent span.yui-toolbar-icon{background-position:0 -720px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-outdent span.yui-toolbar-icon{background-position:0 -684px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-createlink span.yui-toolbar-icon{background-position:0 -792px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertimage span.yui-toolbar-icon{background-position:1px -756px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-left span.yui-toolbar-icon{background-position:0 -972px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-right span.yui-toolbar-icon{background-position:0 -936px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-inline span.yui-toolbar-icon{background-position:0 -900px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-block span.yui-toolbar-icon{background-position:0 -864px;left:5px;}.yui-skin-sam .yui-toolbar-container !
 .yui-toolbar-bordercolor span.yui-toolbar-icon{background-posi!
 tion:0 -
252px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-removeformat span.yui-toolbar-icon{background-position:0 -1080px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-hiddenelements span.yui-toolbar-icon{background-position:0 -1044px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertunorderedlist span.yui-toolbar-icon{background-position:0 -468px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertorderedlist span.yui-toolbar-icon{background-position:0 -504px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child{width:35px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child a{padding-left:2px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton span.yui-toolbar-icon{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-skin-sam .yui-toolbar-container .yui!
 -toolbar-spinbutton a.down{right:2px;background:url(editor-sprite.gif) no-repeat 0 -1222px;overflow:hidden;height:6px;width:7px;min-height:0;padding:0;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up{top:2px;background-position:0 -1222px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{bottom:2px;background-position:0 -1187px;}.yui-skin-sam .yui-toolbar-container select{height:22px;border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select .first-child a{padding-left:5px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select span.yui-toolbar-icon{background:url( editor-sprite.gif ) no-repeat 0 -1144px;overflow:hidden;right:-2px;top:0px;height:20px;}.yui-skin-sam .yui-editor-panel .yui-color-button-menu .bd{background-color:transparent;border:none;width:135px;}.yui-skin-sam .yui-color-button-menu .yui-toolbar-colors{border:1px solid #808080;}.yui-skin-sam .yui-editor-panel{padding:0;margin:0;bor!
 der:none;background-color:transparent;overflow:visible;}.yui-s!
 kin-sam 
.yui-editor-panel .hd{margin:10px 0 0;padding:0;border:none;}.yui-skin-sam .yui-editor-panel .hd h3{color:#000;border:1px solid #808080;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -200px;width:99%;position:relative;margin:0;padding:3px 0 0 0;font-size:93%;text-indent:5px;height:20px;}.yui-skin-sam .yui-editor-panel .bd{background-color:#F2F2F2;border-left:1px solid #808080;border-right:1px solid #808080;width:99%;margin:0;padding:0;overflow:visible;}.yui-skin-sam .yui-editor-panel ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-panel ul li{margin:0;padding:0;}.yui-skin-sam .yui-editor-panel .yuimenu{}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .yui-toolbar-subcont{padding:0;border:none;margin-top:0.35em;}.yui-skin-sam .yui-editor-panel .yui-toolbar-bordersize,.yui-skin-sam .yui-editor-panel .yui-toolbar-bordertype{width:50px;}.yui-skin-sam .yui-editor-panel label{display:block;float:none;padding:4px 0;margin-bottom:7px;!
 }.yui-skin-sam .yui-editor-panel label strong{font-weight:normal;font-size:93%;text-align:right;padding-top:2px;}.yui-skin-sam .yui-editor-panel label input{width:75%;}.yui-skin-sam .yui-editor-panel #createlink_target,.yui-skin-sam .yui-editor-panel #insertimage_target{width:auto;margin-right:5px;}.yui-skin-sam .yui-editor-panel .removeLink{width:98%;}.yui-skin-sam .yui-editor-panel label input.warning{background-color:#FFEE69;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group h3{color:#000;float:left;font-weight:normal;font-size:93%;margin:5px 0 0 0;padding:0 3px 0 0;text-align:right;}.yui-skin-sam .yui-editor-panel .height-width h3{margin:3px 0 0 10px;}.yui-skin-sam .yui-editor-panel .height-width{margin:3px 0 0 35px;*margin-left:14px;width:42%;*width:44%;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-border{width:190px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-border{width:210px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding{width!
 :203px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolba!
 r-group-
padding{width:172px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding h3{margin-left:25px;*margin-left:12px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-textflow{width:182px;}.yui-skin-sam .yui-editor-panel .hd{background:none;}.yui-skin-sam .yui-editor-panel .ft{background-color:#F2F2F2;border:1px solid #808080;border-top:none;padding:0;margin:0 0 2px 0;}.yui-skin-sam .yui-editor-panel .hd span.close{background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -300px;cursor:pointer;display:block;height:16px;overflow:hidden;position:absolute;right:5px;text-indent:500px;top:2px;width:26px;}.yui-skin-sam .yui-editor-panel .ft span.tip{background-color:#EDF5FF;border-top:1px solid #808080;font-size:85%;}.yui-skin-sam .yui-editor-panel .ft span.tip strong{display:block;float:left;margin:0 2px 8px 0;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon{background:url( editor-sprite.gif ) no-repeat 0 -1260px;display:block;height:20px;left:2px;position:abs!
 olute;top:8px;width:20px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-info{background-position:2px -1260px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-warn{background-position:2px -1296px;}.yui-skin-sam .yui-editor-panel .hd span.knob{position:absolute;height:10px;width:28px;top:-10px;left:25px;text-indent:9999px;overflow:hidden;background:url( editor-knob.gif ) no-repeat 0 0;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container{float:left;width:100%;background-image:none;border:none;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .bd{background-color:#ffffff;}.yui-editor-blankimage{background-image:url( blankimage.png );}

Modified: trunk/root/static/yui/editor/assets/skins/sam/simpleeditor-skin.css
===================================================================
--- trunk/root/static/yui/editor/assets/skins/sam/simpleeditor-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/editor/assets/skins/sam/simpleeditor-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* Place the border around the editor */
 .yui-skin-sam .yui-editor-container {

Modified: trunk/root/static/yui/editor/assets/skins/sam/simpleeditor.css
===================================================================
--- trunk/root/static/yui/editor/assets/skins/sam/simpleeditor.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/editor/assets/skins/sam/simpleeditor.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-.yui-busy{cursor:wait !important;}.yui-toolbar-container .yui-toolbar-subcont{padding:.25em 0;zoom:1;}.yui-toolbar-container-collapsed .yui-toolbar-subcont{display:none;}.yui-toolbar-container .yui-toolbar-subcont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container span.yui-toolbar-draghandle{cursor:move;border-left:1px solid #999;border-right:1px solid #999;overflow:hidden;text-indent:77777px;width:2px;height:20px;display:block;clear:none;float:left;margin:0 0 0 .2em;}.yui-toolbar-container .yui-toolbar-titlebar.draggable{cursor:move;}.yui-toolbar-container .yui-toolbar-titlebar{position:relative;}.yui-toolbar-container .yui-toolbar-titlebar h2{font-weight:bold;letter-spacing:0;border:none;color:#000;margin:0;padding:.2em;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-draghandle{height:40px;}.yui-toolbar-container .yui-toolbar-group{float:left;zoom:1;}.yui-toolbar-container .yui-toolbar-group:after{display:block;clear!
 :both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container .yui-toolbar-group h3{font-size:75%;padding:0 0 0 .25em;margin:0;}.yui-toolbar-container span.yui-toolbar-separator{width:2px;height:18px;margin:.2em 0 .2em .1em;display:block;clear:none;float:left;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-separator{height:35px;}.yui-toolbar-container.yui-toolbar-grouped .yui-toolbar-group span.yui-toolbar-separator{height:18px;}.yui-toolbar-container ul li{margin:0;padding:0;list-style-type:none;}.yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-toolbar-container .yui-push-button,.yui-toolbar-container .yui-color-button,.yui-toolbar-container .yui-menu-button{position:relative;cursor:pointer;}.yui-toolbar-container .yui-button .first-child,.yui-toolbar-container .yui-button .first-child a{height:100%;width:100%;overflow:hidden;}.yui-toolbar-container .yui-button-disabled{cursor:default;}.yui-toolbar-container .yui-button-disabled .!
 yui-toolbar-icon{opacity:.5;filter:alpha(opacity=50);}.yui-too!
 lbar-con
tainer .yui-button-disabled .up,.yui-toolbar-container .yui-button-disabled .down{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button a{overflow:hidden;}.yui-toolbar-container .yui-toolbar-select .first-child a{cursor:pointer;}.yui-toolbar-fontname-arial{font-family:Arial;}.yui-toolbar-fontname-arial-black{font-family:Arial Black;}.yui-toolbar-fontname-comic-sans-ms{font-family:Comic Sans MS;}.yui-toolbar-fontname-courier-new{font-family:Courier New;}.yui-toolbar-fontname-times-new-roman{font-family:Times New Roman;}.yui-toolbar-fontname-verdana{font-family:Verdana;}.yui-toolbar-fontname-impact{font-family:Impact;}.yui-toolbar-fontname-lucida-console{font-family:Lucida Console;}.yui-toolbar-fontname-tahoma{font-family:Tahoma;}.yui-toolbar-fontname-trebuchet-ms{font-family:Trebuchet MS;}.yui-toolbar-container .yui-toolbar-spinbutton{position:relative;}.yui-toolbar-container .yui-toolbar-spinbutton .first-child a{z-index:0;opacity:1;}.yui-toolbar-container !
 .yui-toolbar-spinbutton a.up,.yui-toolbar-container .yui-toolbar-spinbutton a.down{position:absolute;display:block right:0;cursor:pointer;z-index:1;padding:0;margin:0;}.yui-toolbar-container .yui-overlay{position:absolute;}.yui-toolbar-container .yui-overlay ul li{margin:0;list-style-type:none;}.yui-toolbar-container{z-index:1;}.yui-editor-container .yui-editor-editable-container{position:relative;z-index:0;width:100%;}.yui-editor-container .yui-editor-masked{background-color:#CCC;}.yui-editor-container iframe{border:0px;padding:0;margin:0;zoom:1;display:block;}.yui-editor-container .yui-editor-editable{padding:0;margin:0;}.yui-editor-container .dompath{font-size:85%;}.yui-editor-panel .hd{text-align:left;position:relative;}.yui-editor-panel .hd h3{font-weight:bold;padding:0.25em 0pt 0.25em 0.25em;margin:0;}.yui-editor-panel .bd{width:100%;zoom:1;position:relative;}.yui-editor-panel .bd div.yui-editor-body-cont{padding:.25em .1em;zoom:1;}.yui-editor-panel .bd div.yui-editor!
 -body-cont:after{display:block;clear:both;visibility:hidden;co!
 ntent:'.
';height:0;}.yui-editor-panel .ft{text-align:right;width:99%;float:left;clear:both;}.yui-editor-panel .ft span.tip{display:block;position:relative;padding:.5em .5em .5em 23px;text-align:left;zoom:1;}.yui-editor-panel label{clear:both;float:left;padding:0;width:100%;text-align:left;zoom:1;}.yui-editor-panel .gecko label{overflow:auto;}.yui-editor-panel label strong{float:left;width:6em;}.yui-editor-panel .removeLink{width:80%;text-align:right;}.yui-editor-panel label input{margin-left:.25em;float:left;}.yui-editor-panel .yui-toolbar-group-padding{}.yui-editor-panel .yui-toolbar-group-border{}.yui-editor-panel .yui-toolbar-group-textflow{}.yui-editor-panel .height-width{float:left;}.yui-editor-panel .height-width h3{}.yui-editor-panel .height-width span{font-style:italic;display:block;float:left;overflow:auto;}.yui-editor-panel .height-width span.info{font-size:70%;}.yui-editor-panel .yui-toolbar-bordersize,.yui-editor-panel .yui-toolbar-bordertype{font-size:75%;}.yui-editor-p!
 anel .yui-toolbar-container span.yui-toolbar-separator{border:none;}.yui-editor-panel .yui-toolbar-bordersize span a span,.yui-editor-panel .yui-toolbar-bordertype span a span{display:block;height:8px;left:4px;position:absolute;top:3px;*top:-5px;width:24px;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-solid{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dotted{border-bottom:1px dotted black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dashed{border-bottom:1px dashed black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-0{*top:0px;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-1{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-2{border-bottom:2px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersiz!
 e-3{top:2px;*top:-5px;border-bottom:3px solid black;}.yui-edit!
 or-panel
 .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-4{top:1px;*top:-5px;border-bottom:4px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-5{top:1px;*top:-5px;border-bottom:5px solid black;}.yui-toolbar-container .yui-toolbar-bordersize-menu,.yui-toolbar-container .yui-toolbar-bordertype-menu{width:95px !important;}.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel,.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel:hover{margin:0px 3px 7px 17px;}.yui-toolbar-bordersize-menu .yuimenuitemlabel .checkedindicator,.yui-toolbar-bordertype-menu .yuimenuitemlabel .checkedindicator{position:absolute;left:-12px;*top:14px;*left:0px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-1 a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-2 a{border-bottom:2px solid black;height:14px;}.yui-toolbar-borders!
 ize-menu li.yui-toolbar-bordersize-3 a{border-bottom:3px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-4 a{border-bottom:4px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-5 a{border-bottom:5px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-solid a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dashed a{border-bottom:1px dashed black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dotted a{border-bottom:1px dotted black;height:14px;}h2.yui-editor-skipheader,h3.yui-editor-skipheader{height:0;margin:0;padding:0;border:none;width:0;overflow:hidden;position:absolute;}.yui-toolbar-colors{width:133px;zoom:1;display:none;z-index:100;overflow:hidden;}.yui-toolbar-colors:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors a{height:9px;width:9px;float:left;display:block;overflo!
 w:hidden;text-indent:999px;margin:0;cursor:pointer;border:1px !
 solid #F
6F7EE;}.yui-toolbar-colors a:hover{border:1px solid black;}.yui-color-button-menu{overflow:visible;background-color:transparent;}.yui-toolbar-colors span{position:relative;display:block;padding:3px;overflow:hidden;float:left;width:100%;zoom:1;}.yui-toolbar-colors span:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors span em{height:35px;width:30px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0.75px;border:1px solid black;}.yui-toolbar-colors span strong{font-weight:normal;padding-left:3px;display:block;font-size:85%;float:left;width:65%;}.yui-skin-sam .yui-editor-container{border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container{zoom:1;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -200px;position:relative;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar h2{color:#000000;font-weight:bold;margin:0;padding:0.3em 1em;font!
 -size:100%;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-group h3{color:#808080;font-size:75%;margin:1em 0 0;padding-bottom:0;padding-left:0.25em;text-align:left;}.yui-toolbar-container span.yui-toolbar-separator{border:none;text-indent:33px;overflow:hidden;margin:.25em;}.yui-skin-sam .yui-toolbar-container{background-color:#F2F2F2;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subcont{padding:0 1em 0.35em;border-bottom:1px solid #808080;}.yui-skin-sam .yui-toolbar-container-collapsed .yui-toolbar-titlebar{border-bottom:1px solid #808080;}.yui-skin-sam .yui-editor-container .visible .yui-menu-shadow,.yui-skin-sam .yui-editor-panel .visible .yui-menu-shadow{display:none;}.yui-skin-sam .yui-editor-container ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-container ul li{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-toolbar-group ul li.yui-toolbar-groupitem{float:left;}.yui-skin-sam .yui-editor-container .dompath{bac!
 kground-color:#F2F2F2;border-top:1px solid #808080;color:#999;!
 text-ali
gn:left;padding:0.25em;}.yui-skin-sam .yui-toolbar-container .collapse{background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -400px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar span.collapse{cursor:pointer;position:absolute;top:4px;right:2px;display:block;overflow:hidden;height:15px;width:15px;text-indent:9999px;}.yui-skin-sam .yui-toolbar-container .yui-push-button,.yui-skin-sam .yui-toolbar-container .yui-color-button,.yui-skin-sam .yui-toolbar-container .yui-menu-button{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;position:relative;display:block;height:22px;width:30px;margin:0;border-color:#808080;border-style:solid;border-width:1px 0;}.yui-skin-sam .yui-toolbar-container .yui-push-button a,.yui-skin-sam .yui-toolbar-container .yui-color-button a,.yui-skin-sam .yui-toolbar-container .yui-menu-button a{padding-left:35px;height:20px;text-decoration:none;font-size:93%;line-height:2;display:block;color:#000000;overflow:hidd!
 en;}.yui-skin-sam .yui-toolbar-container .yui-push-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button .first-child{border-color:#808080;border-style:solid;border-width:0 1px;margin:0 -1px;display:block;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled{border-color:#ccc;}.yui-skin-s!
 am .yui-toolbar-container .yui-button .first-child{*left:0px;}!
 .yui-ski
n-sam .yui-toolbar-container .yui-toolbar-fontname{width:135px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-heading{width:92px;}.yui-skin-sam .yui-toolbar-container .yui-button-hover{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1300px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-button-selected{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1700px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels .yui-toolbar-group{margin-top:.75em;}.yui-skin-sam .yui-toolbar-container .yui-push-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-color-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-menu-button span.yui-toolbar-icon{display:block;position:absolute;top:2px;height:18px;width:18px;overflow:hidden;background:url(editor-sprite.gif) no-repeat 30px 30px;}.yu!
 i-skin-sam .yui-toolbar-container .yui-button-selected span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-button-hover span.yui-toolbar-icon{background-image:url(editor-sprite-active.gif);}.yui-skin-sam .yui-toolbar-container .visible .yuimenuitemlabel{cursor:pointer;color:#000;*position:relative;}.yui-skin-sam .yui-toolbar-container .yui-button-menu{background-color:#fff;}.yui-skin-sam div.yuimenu li.selected{background-color:#B3D4FF;}.yui-skin-sam div.yuimenu li.selected a.selected{color:#000;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bold span.yui-toolbar-icon{background-position:0 0;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-italic span.yui-toolbar-icon{background-position:0 -36px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-underline span.yui-toolbar-icon{background-position:0 -72px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subscript span.yui-toolbar-icon{background-position:0 -180px;left:5px;}.yui-!
 skin-sam .yui-toolbar-container .yui-toolbar-superscript span.!
 yui-tool
bar-icon{background-position:0 -144px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-forecolor span.yui-toolbar-icon{background-position:0 -216px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-backcolor span.yui-toolbar-icon{background-position:0 -288px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyleft span.yui-toolbar-icon{background-position:0 -324px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifycenter span.yui-toolbar-icon{background-position:0 -360px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyright span.yui-toolbar-icon{background-position:0 -396px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyfull span.yui-toolbar-icon{background-position:0 -432px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-indent span.yui-toolbar-icon{background-position:0 -720px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-outdent span.yui-toolbar-icon{backgr!
 ound-position:0 -684px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-createlink span.yui-toolbar-icon{background-position:0 -792px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertimage span.yui-toolbar-icon{background-position:1px -756px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-left span.yui-toolbar-icon{background-position:0 -972px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-right span.yui-toolbar-icon{background-position:0 -936px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-inline span.yui-toolbar-icon{background-position:0 -900px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-block span.yui-toolbar-icon{background-position:0 -864px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bordercolor span.yui-toolbar-icon{background-position:0 -252px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-removeformat span.yui-toolbar-icon{background-position:0 -1080px;le!
 ft:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-hidd!
 enelemen
ts span.yui-toolbar-icon{background-position:0 -1044px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertunorderedlist span.yui-toolbar-icon{background-position:0 -468px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertorderedlist span.yui-toolbar-icon{background-position:0 -504px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child{width:35px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child a{padding-left:2px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton span.yui-toolbar-icon{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{right:2px;background:url(editor-sprite.gif) no-repeat 0 -1222px;overflow:hidden;height:6px;width:7px;min-height:0;padding:0;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-s!
 pinbutton a.up{top:2px;background-position:0 -1222px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{bottom:2px;background-position:0 -1187px;}.yui-skin-sam .yui-toolbar-container select{height:22px;border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select .first-child a{padding-left:5px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select span.yui-toolbar-icon{background:url( editor-sprite.gif ) no-repeat 0 -1144px;overflow:hidden;right:-2px;top:0px;height:20px;}.yui-skin-sam .yui-editor-panel .yui-color-button-menu .bd{background-color:transparent;border:none;width:135px;}.yui-skin-sam .yui-color-button-menu .yui-toolbar-colors{border:1px solid #808080;}.yui-skin-sam .yui-editor-panel{padding:0;margin:0;border:none;background-color:transparent;overflow:visible;}.yui-skin-sam .yui-editor-panel .hd{margin:10px 0 0;padding:0;border:none;}.yui-skin-sam .yui-editor-panel .hd h3{color:#000;border:1px solid #8080!
 80;background:url(../../../../assets/skins/sam/sprite.png) rep!
 eat-x 0 
-200px;width:99%;position:relative;margin:0;padding:3px 0 0 0;font-size:93%;text-indent:5px;height:20px;}.yui-skin-sam .yui-editor-panel .bd{background-color:#F2F2F2;border-left:1px solid #808080;border-right:1px solid #808080;width:99%;margin:0;padding:0;overflow:visible;}.yui-skin-sam .yui-editor-panel ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-panel ul li{margin:0;padding:0;}.yui-skin-sam .yui-editor-panel .yuimenu{}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .yui-toolbar-subcont{padding:0;border:none;margin-top:0.35em;}.yui-skin-sam .yui-editor-panel .yui-toolbar-bordersize,.yui-skin-sam .yui-editor-panel .yui-toolbar-bordertype{width:50px;}.yui-skin-sam .yui-editor-panel label{display:block;float:none;padding:4px 0;margin-bottom:7px;}.yui-skin-sam .yui-editor-panel label strong{font-weight:normal;font-size:93%;text-align:right;padding-top:2px;}.yui-skin-sam .yui-editor-panel label input{width:75%;}.yui-skin-sam .yui-editor-panel #cr!
 eatelink_target,.yui-skin-sam .yui-editor-panel #insertimage_target{width:auto;margin-right:5px;}.yui-skin-sam .yui-editor-panel .removeLink{width:98%;}.yui-skin-sam .yui-editor-panel label input.warning{background-color:#FFEE69;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group h3{color:#000;float:left;font-weight:normal;font-size:93%;margin:5px 0 0 0;padding:0 3px 0 0;text-align:right;}.yui-skin-sam .yui-editor-panel .height-width h3{margin:3px 0 0 10px;}.yui-skin-sam .yui-editor-panel .height-width{margin:3px 0 0 35px;*margin-left:14px;width:42%;*width:44%;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-border{width:190px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-border{width:210px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding{width:203px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-padding{width:172px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding h3{margin-left:25px;*margin-left:12px;}.yui-skin-sam !
 .yui-editor-panel .yui-toolbar-group-textflow{width:182px;}.yu!
 i-skin-s
am .yui-editor-panel .hd{background:none;}.yui-skin-sam .yui-editor-panel .ft{background-color:#F2F2F2;border:1px solid #808080;border-top:none;padding:0;margin:0 0 2px 0;}.yui-skin-sam .yui-editor-panel .hd span.close{background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -300px;cursor:pointer;display:block;height:16px;overflow:hidden;position:absolute;right:5px;text-indent:500px;top:2px;width:26px;}.yui-skin-sam .yui-editor-panel .ft span.tip{background-color:#EDF5FF;border-top:1px solid #808080;font-size:85%;}.yui-skin-sam .yui-editor-panel .ft span.tip strong{display:block;float:left;margin:0 2px 8px 0;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon{background:url( editor-sprite.gif ) no-repeat 0 -1260px;display:block;height:20px;left:2px;position:absolute;top:8px;width:20px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-info{background-position:2px -1260px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-warn{background-position:2px !
 -1296px;}.yui-skin-sam .yui-editor-panel .hd span.knob{position:absolute;height:10px;width:28px;top:-10px;left:25px;text-indent:9999px;overflow:hidden;background:url( editor-knob.gif ) no-repeat 0 0;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container{float:left;width:100%;background-image:none;border:none;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .bd{background-color:#ffffff;}.yui-editor-blankimage{background-image:url( blankimage.png );}
+.yui-busy{cursor:wait !important;}.yui-toolbar-container fieldset{padding:0;margin:0;border:0;}.yui-toolbar-container legend{display:none;}.yui-toolbar-container .yui-toolbar-subcont{padding:.25em 0;zoom:1;}.yui-toolbar-container-collapsed .yui-toolbar-subcont{display:none;}.yui-toolbar-container .yui-toolbar-subcont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container span.yui-toolbar-draghandle{cursor:move;border-left:1px solid #999;border-right:1px solid #999;overflow:hidden;text-indent:77777px;width:2px;height:20px;display:block;clear:none;float:left;margin:0 0 0 .2em;}.yui-toolbar-container .yui-toolbar-titlebar.draggable{cursor:move;}.yui-toolbar-container .yui-toolbar-titlebar{position:relative;}.yui-toolbar-container .yui-toolbar-titlebar h2{font-weight:bold;letter-spacing:0;border:none;color:#000;margin:0;padding:.2em;}.yui-toolbar-container .yui-toolbar-titlebar h2 a{text-decoration:none;color:#000;cursor:default;}.yui-tool!
 bar-container.yui-toolbar-grouped span.yui-toolbar-draghandle{height:40px;}.yui-toolbar-container .yui-toolbar-group{float:left;zoom:1;}.yui-toolbar-container .yui-toolbar-group:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-container .yui-toolbar-group h3{font-size:75%;padding:0 0 0 .25em;margin:0;}.yui-toolbar-container span.yui-toolbar-separator{width:2px;height:18px;margin:.2em 0 .2em .1em;display:block;clear:none;float:left;}.yui-toolbar-container.yui-toolbar-grouped span.yui-toolbar-separator{height:35px;}.yui-toolbar-container.yui-toolbar-grouped .yui-toolbar-group span.yui-toolbar-separator{height:18px;}.yui-toolbar-container ul li{margin:0;padding:0;list-style-type:none;}.yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-toolbar-container .yui-push-button,.yui-toolbar-container .yui-color-button,.yui-toolbar-container .yui-menu-button{position:relative;cursor:pointer;}.yui-toolbar-container .yui-button .firs!
 t-child,.yui-toolbar-container .yui-button .first-child a{heig!
 ht:100%;
width:100%;overflow:hidden;}.yui-toolbar-container .yui-button-disabled{cursor:default;}.yui-toolbar-container .yui-button-disabled .yui-toolbar-icon{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button-disabled .up,.yui-toolbar-container .yui-button-disabled .down{opacity:.5;filter:alpha(opacity=50);}.yui-toolbar-container .yui-button a{overflow:hidden;}.yui-toolbar-container .yui-toolbar-select .first-child a{cursor:pointer;}.yui-toolbar-fontname-arial{font-family:Arial;}.yui-toolbar-fontname-arial-black{font-family:Arial Black;}.yui-toolbar-fontname-comic-sans-ms{font-family:Comic Sans MS;}.yui-toolbar-fontname-courier-new{font-family:Courier New;}.yui-toolbar-fontname-times-new-roman{font-family:Times New Roman;}.yui-toolbar-fontname-verdana{font-family:Verdana;}.yui-toolbar-fontname-impact{font-family:Impact;}.yui-toolbar-fontname-lucida-console{font-family:Lucida Console;}.yui-toolbar-fontname-tahoma{font-family:Tahoma;}.yui-toolbar-fontname-trebuche!
 t-ms{font-family:Trebuchet MS;}.yui-toolbar-container .yui-toolbar-spinbutton{position:relative;}.yui-toolbar-container .yui-toolbar-spinbutton .first-child a{z-index:0;opacity:1;}.yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-toolbar-container .yui-toolbar-spinbutton a.down{position:absolute;display:block right:0;cursor:pointer;z-index:1;padding:0;margin:0;}.yui-toolbar-container .yui-overlay{position:absolute;}.yui-toolbar-container .yui-overlay ul li{margin:0;list-style-type:none;}.yui-toolbar-container{z-index:1;}.yui-editor-container .yui-editor-editable-container{position:relative;z-index:0;width:100%;}.yui-editor-container .yui-editor-masked{background-color:#CCC;}.yui-editor-container iframe{border:0px;padding:0;margin:0;zoom:1;display:block;}.yui-editor-container .yui-editor-editable{padding:0;margin:0;}.yui-editor-container .dompath{font-size:85%;}.yui-editor-panel .hd{text-align:left;position:relative;}.yui-editor-panel .hd h3{font-weight:bold;padding:0!
 .25em 0pt 0.25em 0.25em;margin:0;}.yui-editor-panel .bd{width:!
 100%;zoo
m:1;position:relative;}.yui-editor-panel .bd div.yui-editor-body-cont{padding:.25em .1em;zoom:1;}.yui-editor-panel .bd div.yui-editor-body-cont:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-editor-panel .ft{text-align:right;width:99%;float:left;clear:both;}.yui-editor-panel .ft span.tip{display:block;position:relative;padding:.5em .5em .5em 23px;text-align:left;zoom:1;}.yui-editor-panel label{clear:both;float:left;padding:0;width:100%;text-align:left;zoom:1;}.yui-editor-panel .gecko label{overflow:auto;}.yui-editor-panel label strong{float:left;width:6em;}.yui-editor-panel .removeLink{width:80%;text-align:right;}.yui-editor-panel label input{margin-left:.25em;float:left;}.yui-editor-panel .yui-toolbar-group-padding{}.yui-editor-panel .yui-toolbar-group-border{}.yui-editor-panel .yui-toolbar-group-textflow{}.yui-editor-panel .height-width{float:left;}.yui-editor-panel .height-width h3{}.yui-editor-panel .height-width span{font-style:italic;displa!
 y:block;float:left;overflow:auto;}.yui-editor-panel .height-width span.info{font-size:70%;}.yui-editor-panel .yui-toolbar-bordersize,.yui-editor-panel .yui-toolbar-bordertype{font-size:75%;}.yui-editor-panel .yui-toolbar-container span.yui-toolbar-separator{border:none;}.yui-editor-panel .yui-toolbar-bordersize span a span,.yui-editor-panel .yui-toolbar-bordertype span a span{display:block;height:8px;left:4px;position:absolute;top:3px;*top:-5px;width:24px;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-solid{border-bottom:1px solid black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dotted{border-bottom:1px dotted black;}.yui-editor-panel .yui-toolbar-bordertype span a span.yui-toolbar-bordertype-dashed{border-bottom:1px dashed black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-0{*top:0px;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-1{border-bottom!
 :1px solid black;}.yui-editor-panel .yui-toolbar-bordersize sp!
 an a spa
n.yui-toolbar-bordersize-2{border-bottom:2px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-3{top:2px;*top:-5px;border-bottom:3px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-4{top:1px;*top:-5px;border-bottom:4px solid black;}.yui-editor-panel .yui-toolbar-bordersize span a span.yui-toolbar-bordersize-5{top:1px;*top:-5px;border-bottom:5px solid black;}.yui-toolbar-container .yui-toolbar-bordersize-menu,.yui-toolbar-container .yui-toolbar-bordertype-menu{width:95px !important;}.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel,.yui-toolbar-bordersize-menu .yuimenuitemlabel,.yui-toolbar-bordertype-menu .yuimenuitemlabel:hover{margin:0px 3px 7px 17px;}.yui-toolbar-bordersize-menu .yuimenuitemlabel .checkedindicator,.yui-toolbar-bordertype-menu .yuimenuitemlabel .checkedindicator{position:absolute;left:-12px;*top:14px;*left:0px;}.yui-toolbar-bordersi!
 ze-menu li.yui-toolbar-bordersize-1 a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-2 a{border-bottom:2px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-3 a{border-bottom:3px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-4 a{border-bottom:4px solid black;height:14px;}.yui-toolbar-bordersize-menu li.yui-toolbar-bordersize-5 a{border-bottom:5px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-solid a{border-bottom:1px solid black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dashed a{border-bottom:1px dashed black;height:14px;}.yui-toolbar-bordertype-menu li.yui-toolbar-bordertype-dotted a{border-bottom:1px dotted black;height:14px;}h2.yui-editor-skipheader,h3.yui-editor-skipheader{height:0;margin:0;padding:0;border:none;width:0;overflow:hidden;position:absolute;}.yui-toolbar-colors{width:133px;zoom:1;displ!
 ay:none;z-index:100;overflow:hidden;}.yui-toolbar-colors:after!
 {display
:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors a{height:9px;width:9px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0;cursor:pointer;border:1px solid #F6F7EE;}.yui-toolbar-colors a:hover{border:1px solid black;}.yui-color-button-menu{overflow:visible;background-color:transparent;}.yui-toolbar-colors span{position:relative;display:block;padding:3px;overflow:hidden;float:left;width:100%;zoom:1;}.yui-toolbar-colors span:after{display:block;clear:both;visibility:hidden;content:'.';height:0;}.yui-toolbar-colors span em{height:35px;width:30px;float:left;display:block;overflow:hidden;text-indent:999px;margin:0.75px;border:1px solid black;}.yui-toolbar-colors span strong{font-weight:normal;padding-left:3px;display:block;font-size:85%;float:left;width:65%;}.yui-skin-sam .yui-editor-container{border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container{zoom:1;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar{background:url!
 (../../../../assets/skins/sam/sprite.png) repeat-x 0 -200px;position:relative;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar h2{color:#000000;font-weight:bold;margin:0;padding:0.3em 1em;font-size:100%;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-group h3{color:#808080;font-size:75%;margin:1em 0 0;padding-bottom:0;padding-left:0.25em;text-align:left;}.yui-toolbar-container span.yui-toolbar-separator{border:none;text-indent:33px;overflow:hidden;margin:.25em;}.yui-skin-sam .yui-toolbar-container{background-color:#F2F2F2;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subcont{padding:0 1em 0.35em;border-bottom:1px solid #808080;}.yui-skin-sam .yui-toolbar-container-collapsed .yui-toolbar-titlebar{border-bottom:1px solid #808080;}.yui-skin-sam .yui-editor-container .visible .yui-menu-shadow,.yui-skin-sam .yui-editor-panel .visible .yui-menu-shadow{display:none;}.yui-skin-sam .yui-editor-container ul{list-style-type:none;margin:0;padding:0;}.!
 yui-skin-sam .yui-editor-container ul li{list-style-type:none;!
 margin:0
;padding:0;}.yui-skin-sam .yui-toolbar-group ul li.yui-toolbar-groupitem{float:left;}.yui-skin-sam .yui-editor-container .dompath{background-color:#F2F2F2;border-top:1px solid #808080;color:#999;text-align:left;padding:0.25em;}.yui-skin-sam .yui-toolbar-container .collapse{background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -400px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-titlebar span.collapse{cursor:pointer;position:absolute;top:4px;right:2px;display:block;overflow:hidden;height:15px;width:15px;text-indent:9999px;}.yui-skin-sam .yui-toolbar-container .yui-push-button,.yui-skin-sam .yui-toolbar-container .yui-color-button,.yui-skin-sam .yui-toolbar-container .yui-menu-button{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;position:relative;display:block;height:22px;width:30px;margin:0;border-color:#808080;border-style:solid;border-width:1px 0;}.yui-skin-sam .yui-toolbar-container .yui-push-button a,.yui-skin-sam .yui-toolbar-con!
 tainer .yui-color-button a,.yui-skin-sam .yui-toolbar-container .yui-menu-button a{padding-left:35px;height:20px;text-decoration:none;font-size:93%;line-height:2;display:block;color:#000000;overflow:hidden;}.yui-skin-sam .yui-toolbar-container .yui-push-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button .first-child{border-color:#808080;border-style:solid;border-width:0 1px;margin:0 -1px;display:block;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled .first-child,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled .first-child{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-push-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-color-button-disabled a,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled a{color:#A6A6A6;cursor:default;}.yui-skin-sam .yu!
 i-toolbar-container .yui-push-button-disabled,.yui-skin-sam .y!
 ui-toolb
ar-container .yui-color-button-disabled,.yui-skin-sam .yui-toolbar-container .yui-menu-button-disabled{border-color:#ccc;}.yui-skin-sam .yui-toolbar-container .yui-button .first-child{*left:0px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-fontname{width:135px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-heading{width:92px;}.yui-skin-sam .yui-toolbar-container .yui-button-hover{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1300px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-button-selected{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1700px;border-color:#808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels h3{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-nogrouplabels .yui-toolbar-group{margin-top:.75em;}.yui-skin-sam .yui-toolbar-container .yui-push-button span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-color-button span.yui-toolbar-icon,.yui-skin-!
 sam .yui-toolbar-container .yui-menu-button span.yui-toolbar-icon{display:block;position:absolute;top:2px;height:18px;width:18px;overflow:hidden;background:url(editor-sprite.gif) no-repeat 30px 30px;}.yui-skin-sam .yui-toolbar-container .yui-button-selected span.yui-toolbar-icon,.yui-skin-sam .yui-toolbar-container .yui-button-hover span.yui-toolbar-icon{background-image:url(editor-sprite-active.gif);}.yui-skin-sam .yui-toolbar-container .visible .yuimenuitemlabel{cursor:pointer;color:#000;*position:relative;}.yui-skin-sam .yui-toolbar-container .yui-button-menu{background-color:#fff;}.yui-skin-sam div.yuimenu li.selected{background-color:#B3D4FF;}.yui-skin-sam div.yuimenu li.selected a.selected{color:#000;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-bold span.yui-toolbar-icon{background-position:0 0;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-italic span.yui-toolbar-icon{background-position:0 -36px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-t!
 oolbar-underline span.yui-toolbar-icon{background-position:0 -!
 72px;lef
t:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-subscript span.yui-toolbar-icon{background-position:0 -180px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-superscript span.yui-toolbar-icon{background-position:0 -144px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-forecolor span.yui-toolbar-icon{background-position:0 -216px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-backcolor span.yui-toolbar-icon{background-position:0 -288px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyleft span.yui-toolbar-icon{background-position:0 -324px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifycenter span.yui-toolbar-icon{background-position:0 -360px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyright span.yui-toolbar-icon{background-position:0 -396px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-justifyfull span.yui-toolbar-icon{background-position:0 -432px;left:5px;}.!
 yui-skin-sam .yui-toolbar-container .yui-toolbar-indent span.yui-toolbar-icon{background-position:0 -720px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-outdent span.yui-toolbar-icon{background-position:0 -684px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-createlink span.yui-toolbar-icon{background-position:0 -792px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertimage span.yui-toolbar-icon{background-position:1px -756px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-left span.yui-toolbar-icon{background-position:0 -972px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-right span.yui-toolbar-icon{background-position:0 -936px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-inline span.yui-toolbar-icon{background-position:0 -900px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-block span.yui-toolbar-icon{background-position:0 -864px;left:5px;}.yui-skin-sam .yui-toolbar-container !
 .yui-toolbar-bordercolor span.yui-toolbar-icon{background-posi!
 tion:0 -
252px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-removeformat span.yui-toolbar-icon{background-position:0 -1080px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-hiddenelements span.yui-toolbar-icon{background-position:0 -1044px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertunorderedlist span.yui-toolbar-icon{background-position:0 -468px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-insertorderedlist span.yui-toolbar-icon{background-position:0 -504px;left:5px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton,.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child{width:35px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton .first-child a{padding-left:2px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton span.yui-toolbar-icon{display:none;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up,.yui-skin-sam .yui-toolbar-container .yui!
 -toolbar-spinbutton a.down{right:2px;background:url(editor-sprite.gif) no-repeat 0 -1222px;overflow:hidden;height:6px;width:7px;min-height:0;padding:0;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.up{top:2px;background-position:0 -1222px;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-spinbutton a.down{bottom:2px;background-position:0 -1187px;}.yui-skin-sam .yui-toolbar-container select{height:22px;border:1px solid #808080;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select .first-child a{padding-left:5px;text-align:left;}.yui-skin-sam .yui-toolbar-container .yui-toolbar-select span.yui-toolbar-icon{background:url( editor-sprite.gif ) no-repeat 0 -1144px;overflow:hidden;right:-2px;top:0px;height:20px;}.yui-skin-sam .yui-editor-panel .yui-color-button-menu .bd{background-color:transparent;border:none;width:135px;}.yui-skin-sam .yui-color-button-menu .yui-toolbar-colors{border:1px solid #808080;}.yui-skin-sam .yui-editor-panel{padding:0;margin:0;bor!
 der:none;background-color:transparent;overflow:visible;}.yui-s!
 kin-sam 
.yui-editor-panel .hd{margin:10px 0 0;padding:0;border:none;}.yui-skin-sam .yui-editor-panel .hd h3{color:#000;border:1px solid #808080;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -200px;width:99%;position:relative;margin:0;padding:3px 0 0 0;font-size:93%;text-indent:5px;height:20px;}.yui-skin-sam .yui-editor-panel .bd{background-color:#F2F2F2;border-left:1px solid #808080;border-right:1px solid #808080;width:99%;margin:0;padding:0;overflow:visible;}.yui-skin-sam .yui-editor-panel ul{list-style-type:none;margin:0;padding:0;}.yui-skin-sam .yui-editor-panel ul li{margin:0;padding:0;}.yui-skin-sam .yui-editor-panel .yuimenu{}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .yui-toolbar-subcont{padding:0;border:none;margin-top:0.35em;}.yui-skin-sam .yui-editor-panel .yui-toolbar-bordersize,.yui-skin-sam .yui-editor-panel .yui-toolbar-bordertype{width:50px;}.yui-skin-sam .yui-editor-panel label{display:block;float:none;padding:4px 0;margin-bottom:7px;!
 }.yui-skin-sam .yui-editor-panel label strong{font-weight:normal;font-size:93%;text-align:right;padding-top:2px;}.yui-skin-sam .yui-editor-panel label input{width:75%;}.yui-skin-sam .yui-editor-panel #createlink_target,.yui-skin-sam .yui-editor-panel #insertimage_target{width:auto;margin-right:5px;}.yui-skin-sam .yui-editor-panel .removeLink{width:98%;}.yui-skin-sam .yui-editor-panel label input.warning{background-color:#FFEE69;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group h3{color:#000;float:left;font-weight:normal;font-size:93%;margin:5px 0 0 0;padding:0 3px 0 0;text-align:right;}.yui-skin-sam .yui-editor-panel .height-width h3{margin:3px 0 0 10px;}.yui-skin-sam .yui-editor-panel .height-width{margin:3px 0 0 35px;*margin-left:14px;width:42%;*width:44%;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-border{width:190px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolbar-group-border{width:210px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding{width!
 :203px;}.yui-skin-sam .yui-editor-panel .no-button .yui-toolba!
 r-group-
padding{width:172px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-padding h3{margin-left:25px;*margin-left:12px;}.yui-skin-sam .yui-editor-panel .yui-toolbar-group-textflow{width:182px;}.yui-skin-sam .yui-editor-panel .hd{background:none;}.yui-skin-sam .yui-editor-panel .ft{background-color:#F2F2F2;border:1px solid #808080;border-top:none;padding:0;margin:0 0 2px 0;}.yui-skin-sam .yui-editor-panel .hd span.close{background:url(../../../../assets/skins/sam/sprite.png) no-repeat 0 -300px;cursor:pointer;display:block;height:16px;overflow:hidden;position:absolute;right:5px;text-indent:500px;top:2px;width:26px;}.yui-skin-sam .yui-editor-panel .ft span.tip{background-color:#EDF5FF;border-top:1px solid #808080;font-size:85%;}.yui-skin-sam .yui-editor-panel .ft span.tip strong{display:block;float:left;margin:0 2px 8px 0;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon{background:url( editor-sprite.gif ) no-repeat 0 -1260px;display:block;height:20px;left:2px;position:abs!
 olute;top:8px;width:20px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-info{background-position:2px -1260px;}.yui-skin-sam .yui-editor-panel .ft span.tip span.icon-warn{background-position:2px -1296px;}.yui-skin-sam .yui-editor-panel .hd span.knob{position:absolute;height:10px;width:28px;top:-10px;left:25px;text-indent:9999px;overflow:hidden;background:url( editor-knob.gif ) no-repeat 0 0;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container{float:left;width:100%;background-image:none;border:none;}.yui-skin-sam .yui-editor-panel .yui-toolbar-container .bd{background-color:#ffffff;}.yui-editor-blankimage{background-image:url( blankimage.png );}

Modified: trunk/root/static/yui/editor/editor-beta-debug.js
===================================================================
--- trunk/root/static/yui/editor/editor-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/editor/editor-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 (function() {
     /**
@@ -90,6 +90,7 @@
         oConfig.element.setAttribute('unselectable', 'on');
         oConfig.element.className = 'yui-button yui-' + oConfig.attributes.type + '-button';
         oConfig.element.innerHTML = '<span class="first-child"><a href="#">LABEL</a></span>';
+        oConfig.element.firstChild.firstChild.tabIndex = '-1';
         oConfig.attributes.id = Dom.generateId();
 
         YAHOO.widget.ToolbarButton.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
@@ -287,6 +288,20 @@
             return this.get('menu');
         },
         /** 
+        * @method destroy
+        * @description Destroy the button
+        */        
+        destroy: function() {
+            Event.purgeElement(this.get('element'), true);
+            this.get('element').parentNode.removeChild(this.get('element'));
+            //Brutal Object Destroy
+            for (var i in this) {
+                if (Lang.hasOwnProperty(this, i)) {
+                    this[i] = null;
+                }
+            }       
+        },
+        /** 
         * @method fireEvent
         * @description Overridden fireEvent method to prevent DOM events from firing if the button is disabled.
         */        
@@ -311,7 +326,6 @@
 })();
 /**
  * @description <p>Creates a rich Toolbar widget based on Button. Primarily used with the Rich Text Editor</p>
- * @class Toolbar
  * @namespace YAHOO.widget
  * @requires yahoo, dom, element, event, toolbarbutton
  * @optional container_core, dragdrop
@@ -324,10 +338,29 @@
 var Dom = YAHOO.util.Dom,
     Event = YAHOO.util.Event,
     Lang = YAHOO.lang;
+    
+    var getButton = function(id) {
+        var button = id;
+        if (Lang.isString(id)) {
+            button = this.getButtonById(id);
+        }
+        if (Lang.isNumber(id)) {
+            button = this.getButtonByIndex(id);
+        }
+        if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
+            button = this.getButtonByValue(id);
+        }
+        if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            return button;
+        }
+        return false;
+    };
 
     /**
      * Provides a rich toolbar widget based on the button and menu widgets
      * @constructor
+     * @class Toolbar
+     * @extends YAHOO.util.Element
      * @param {String/HTMLElement} el The element to turn into a toolbar.
      * @param {Object} attrs Object liternal containing configuration parameters.
     */
@@ -371,10 +404,19 @@
         }
         YAHOO.log('Initing toolbar with id: ' + oConfig.element.id, 'info', 'Toolbar');
         
+        var fs = document.createElement('fieldset');
+        var lg = document.createElement('legend');
+        lg.innerHTML = 'Toolbar';
+        fs.appendChild(lg);
+        
         var cont = document.createElement('DIV');
         oConfig.attributes.cont = cont;
         Dom.addClass(cont, 'yui-toolbar-subcont');
-        oConfig.element.appendChild(cont);
+        fs.appendChild(cont);
+        oConfig.element.appendChild(fs);
+
+        oConfig.element.tabIndex = -1;
+
         
         oConfig.attributes.element = oConfig.element;
         oConfig.attributes.id = oConfig.element.id;
@@ -695,6 +737,7 @@
         */
         init: function(p_oElement, p_oAttributes) {
             YAHOO.widget.Toolbar.superclass.init.call(this, p_oElement, p_oAttributes);
+
         },
         /**
         * @method initAttributes
@@ -821,7 +864,7 @@
             * @type Boolean
             */
             this.setAttributeConfig('grouplabels', {
-                value: attr.grouplabels || true,
+                value: ((attr.grouplabels === false) ? false : true),
                 method: function(grouplabels) {
                     if (grouplabels) {
                         Dom.removeClass(this.get('cont'), (this.CLASS_PREFIX + '-nogrouplabels'));
@@ -845,12 +888,22 @@
                             this._titlebar.parentNode.removeChild(this._titlebar);
                         }
                         this._titlebar = document.createElement('DIV');
+                        this._titlebar.tabIndex = '-1';
+                        Event.on(this._titlebar, 'focus', function() {
+                            this._handleFocus();
+                        }, this, true);
                         Dom.addClass(this._titlebar, this.CLASS_PREFIX + '-titlebar');
                         if (Lang.isString(titlebar)) {
                             var h2 = document.createElement('h2');
                             h2.tabIndex = '-1';
-                            h2.innerHTML = titlebar;
+                            h2.innerHTML = '<a href="#" tabIndex="0">' + titlebar + '</a>';
                             this._titlebar.appendChild(h2);
+                            Event.on(h2.firstChild, 'click', function(ev) {
+                                Event.stopEvent(ev);
+                            });
+                            Event.on([h2, h2.firstChild], 'focus', function() {
+                                this._handleFocus();
+                            }, this, true);
                         }
                         if (this.get('firstChild')) {
                             this.insertBefore(this._titlebar, this.get('firstChild'));
@@ -879,34 +932,36 @@
             this.setAttributeConfig('collapse', {
                 value: false,
                 method: function(collapse) {
-                    var collapseEl = null;
-                    var el = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
-                    if (collapse) {
-                        if (el.length > 0) {
-                            //There is already a collapse button
-                            return true;
-                        }
-                        collapseEl = document.createElement('SPAN');
-                        collapseEl.innerHTML = 'X';
-                        collapseEl.title = this.STR_COLLAPSE;
+                    if (this._titlebar) {
+                        var collapseEl = null;
+                        var el = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
+                        if (collapse) {
+                            if (el.length > 0) {
+                                //There is already a collapse button
+                                return true;
+                            }
+                            collapseEl = document.createElement('SPAN');
+                            collapseEl.innerHTML = 'X';
+                            collapseEl.title = this.STR_COLLAPSE;
 
-                        Dom.addClass(collapseEl, 'collapse');
-                        this._titlebar.appendChild(collapseEl);
-                        Event.addListener(collapseEl, 'click', function() {
-                            if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
-                                this.collapse(false); //Expand Toolbar
-                            } else {
-                                this.collapse(); //Collapse Toolbar
+                            Dom.addClass(collapseEl, 'collapse');
+                            this._titlebar.appendChild(collapseEl);
+                            Event.addListener(collapseEl, 'click', function() {
+                                if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
+                                    this.collapse(false); //Expand Toolbar
+                                } else {
+                                    this.collapse(); //Collapse Toolbar
+                                }
+                            }, this, true);
+                        } else {
+                            collapseEl = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
+                            if (collapseEl[0]) {
+                                if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
+                                    //We are closed, reopen the titlebar..
+                                    this.collapse(false); //Expand Toolbar
+                                }
+                                collapseEl[0].parentNode.removeChild(collapseEl[0]);
                             }
-                        }, this, true);
-                    } else {
-                        collapseEl = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
-                        if (collapseEl[0]) {
-                            if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
-                                //We are closed, reopen the titlebar..
-                                this.collapse(false); //Expand Toolbar
-                            }
-                            collapseEl[0].parentNode.removeChild(collapseEl[0]);
                         }
                     }
                 }
@@ -979,7 +1034,7 @@
         /**
         * @method addButtonGroup
         * @description Add a new button group to the toolbar. (uses addButton)
-        * @param {Object} oGroup Object literal reference to the Groups Config (contains an array of button configs)
+        * @param {Object} oGroup Object literal reference to the Groups Config (contains an array of button configs as well as the group label)
         */
         addButtonGroup: function(oGroup) {
             if (!this.get('element')) {
@@ -993,7 +1048,6 @@
             var div = document.createElement('DIV');
             Dom.addClass(div, this.CLASS_PREFIX + '-group');
             Dom.addClass(div, this.CLASS_PREFIX + '-group-' + oGroup.group);
-            //if (oGroup.label && this.get('grouplabels')) {
             if (oGroup.label) {
                 var label = document.createElement('h3');
                 label.innerHTML = oGroup.label;
@@ -1073,9 +1127,6 @@
                                         oButton.menucmd = oButton.value;
                                     }
                                     oButton.value = ((oMenu.value) ? oMenu.value : oMenu._oText.nodeValue);
-                                    //This line made Opera fire the click event and the mousedown,
-                                    //  so events for menus where firing twice.
-                                    //this._buttonClick('click', oButton);
                                 },
                                 scope: this
                             };
@@ -1126,8 +1177,11 @@
             } else {
                 //Add to .get('buttons') manually
                 this._configs.buttons.value[this._configs.buttons.value.length] = oButton;
-
+                
                 var tmp = new this.buttonType(_oButton);
+                tmp.get('element').tabIndex = '-1';
+                tmp.get('element').setAttribute('role', 'button');
+                tmp._selected = true;
                 if (!tmp.buttonType) {
                     tmp.buttonType = 'rich';
                     tmp.checkValue = function(value) {
@@ -1177,6 +1231,7 @@
                     var a = document.createElement('a');
                     a.innerHTML = tmp._button.innerHTML;
                     a.href = '#';
+                    a.tabIndex = '-1';
                     Event.on(a, 'click', function(ev) {
                         Event.stopEvent(ev);
                     });
@@ -1210,7 +1265,9 @@
                                 exec = false;
                             }
                             if (exec) {
-                                this._colorPicker._button = oButton.value;
+                                if (this._colorPicker) {
+                                    this._colorPicker._button = oButton.value;
+                                }
                                 var menuEL = tmp.getMenu().element;
                                 if (Dom.getStyle(menuEL, 'visibility') == 'hidden') {
                                     tmp.getMenu().show();
@@ -1230,7 +1287,7 @@
                             this._buttonClick(ev, oButton);
                         }, oButton, this);
                         tmp.on('click', function(ev) {
-                            YAHOO.util.Event.stopEvent(ev);
+                            //YAHOO.util.Event.stopEvent(ev);
                         });
                     } else {
                         //Stop the mousedown event so we can trap the selection in the editor!
@@ -1247,6 +1304,7 @@
                             oButton.value = ev.value;
                             this._buttonClick(ev, oButton);
                         }, this, true);
+
                         var self = this;
                         //Hijack the mousedown event in the menu and make it fire a button click..
                         if (tmp.getMenu().mouseDownEvent) {
@@ -1284,6 +1342,7 @@
                     });
                 }
                 if (this.browser.ie) {
+                    /*
                     //Add a couple of new events for IE
                     tmp.DOM_EVENTS.focusin = true;
                     tmp.DOM_EVENTS.focusout = true;
@@ -1299,6 +1358,7 @@
                     tmp.on('click', function(ev) {
                         YAHOO.util.Event.stopEvent(ev);
                     }, oButton, this);
+                    */
                 }
                 if (this.browser.webkit) {
                     //This will keep the document from gaining focus and the editor from loosing it..
@@ -1400,11 +1460,14 @@
                 }
             }
             html += '<span><em>X</em><strong></strong></span>';
-            picker.innerHTML = html;
-            var em = picker.getElementsByTagName('em')[0];
-            var strong = picker.getElementsByTagName('strong')[0];
+            window.setTimeout(function() {
+                picker.innerHTML = html;
+            }, 0);
 
             Event.on(picker, 'mouseover', function(ev) {
+                var picker = this._colorPicker;
+                var em = picker.getElementsByTagName('em')[0];
+                var strong = picker.getElementsByTagName('strong')[0];
                 var tar = Event.getTarget(ev);
                 if (tar.tagName.toLowerCase() == 'a') {
                     em.style.backgroundColor = tar.style.backgroundColor;
@@ -1421,7 +1484,16 @@
                 Event.stopEvent(ev);
                 var tar = Event.getTarget(ev);
                 if (tar.tagName.toLowerCase() == 'a') {
-                    this.fireEvent('colorPickerClicked', { type: 'colorPickerClicked', target: this, button: this._colorPicker._button, color: tar.innerHTML, colorName: this._colorData['#' + tar.innerHTML] } );
+                    var retVal = this.fireEvent('colorPickerClicked', { type: 'colorPickerClicked', target: this, button: this._colorPicker._button, color: tar.innerHTML, colorName: this._colorData['#' + tar.innerHTML] } );
+                    if (retVal !== false) {
+                        var info = {
+                            color: tar.innerHTML,
+                            colorName: this._colorData['#' + tar.innerHTML],
+                            value: this._colorPicker._button 
+                        };
+                    
+                        this.fireEvent('buttonClick', { type: 'buttonClick', target: this.get('element'), button: info });
+                    }
                     this.getButtonByValue(this._colorPicker._button).getMenu().hide();
                 }
             }, this, true);
@@ -1484,6 +1556,8 @@
                 _b2 = document.createElement('a');
                 _b1.href = '#';
                 _b2.href = '#';
+                _b1.tabIndex = '-1';
+                _b2.tabIndex = '-1';
             
             //Setup the up and down arrows
             _b1.className = 'up';
@@ -1637,12 +1711,75 @@
                         }
                     }
                 }
+                if (ev) {
+                    Event.stopEvent(ev);
+                }
             }
-            if (ev) {
-                Event.stopEvent(ev);
+        },
+        /**
+        * @private
+        * @property _keyNav
+        * @description Flag to determine if the arrow nav listeners have been attached
+        * @type Boolean
+        */
+        _keyNav: null,
+        /**
+        * @private
+        * @property _navCounter
+        * @description Internal counter for walking the buttons in the toolbar with the arrow keys
+        * @type Number
+        */
+        _navCounter: null,
+        /**
+        * @private
+        * @method _navigateButtons
+        * @description Handles the navigation/focus of toolbar buttons with the Arrow Keys
+        * @param {Event} ev The Key Event
+        */
+        _navigateButtons: function(ev) {
+            switch (ev.keyCode) {
+                case 37:
+                case 39:
+                    if (ev.keyCode == 37) {
+                        this._navCounter--;
+                    } else {
+                        this._navCounter++;
+                    }
+                    if (this._navCounter > (this._buttonList.length - 1)) {
+                        this._navCounter = 0;
+                    }
+                    if (this._navCounter < 0) {
+                        this._navCounter = (this._buttonList.length - 1);
+                    }
+                    var el = this._buttonList[this._navCounter].get('element');
+                    if (this.browser.ie) {
+                        el = this._buttonList[this._navCounter].get('element').getElementsByTagName('a')[0];
+                    }
+                    if (this._buttonList[this._navCounter].get('disabled')) {
+                        this._navigateButtons(ev);
+                    } else {
+                        el.focus();
+                    }
+                    break;
             }
         },
         /**
+        * @private
+        * @method _handleFocus
+        * @description Sets up the listeners for the arrow key navigation
+        */
+        _handleFocus: function() {
+            if (!this._keyNav) {
+                var ev = 'keypress';
+                if (this.browser.ie) {
+                    ev = 'keydown';
+                }
+                Event.on(this.get('element'), ev, this._navigateButtons, this, true);
+                this._keyNav = true;
+                this._navCounter = -1;
+            }
+        },
+        /**
         * @method getButtonById
         * @description Gets a button instance from the toolbar by is Dom id.
         * @param {String} id The Dom id to query for.
@@ -1723,17 +1860,8 @@
         * @return {Boolean}
         */
         disableButton: function(id) {
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 button.set('disabled', true);
             } else {
                 return false;
@@ -1749,17 +1877,8 @@
             if (this.get('disabled')) {
                 return false;
             }
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 if (button.get('disabled')) {
                     button.set('disabled', false);
                 }
@@ -1768,42 +1887,46 @@
             }
         },
         /**
+        * @method isSelected
+        * @description Tells if a button is selected or not.
+        * @param {String/Number} id A button by it's id, index or value.
+        * @return {Boolean}
+        */
+        isSelected: function(id) {
+            var button = getButton.call(this, id);
+            if (button) {
+                return button._selected;
+            }
+            return false;
+        },
+        /**
         * @method selectButton
         * @description Selects a button in the toolbar.
         * @param {String/Number} id Select a button by it's id, index or value.
+        * @param {String} value If this is a Menu Button, check this item in the menu
         * @return {Boolean}
         */
         selectButton: function(id, value) {
-            var button = id;
-            if (id) {
-                if (Lang.isString(id)) {
-                    button = this.getButtonById(id);
-                }
-                if (Lang.isNumber(id)) {
-                    button = this.getButtonByIndex(id);
-                }
-                if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                    button = this.getButtonByValue(id);
-                }
-                if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
-                    button.addClass('yui-button-selected');
-                    button.addClass('yui-button-' + button.get('value') + '-selected');
-                    if (value) {
-                        if (button.buttonType == 'rich') {
-                            var _items = button.getMenu().getItems();
-                            for (var m = 0; m < _items.length; m++) {
-                                if (_items[m].value == value) {
-                                    _items[m].cfg.setProperty('checked', true);
-                                    button.set('label', '<span class="yui-toolbar-' + button.get('value') + '-' + (value).replace(/ /g, '-').toLowerCase() + '">' + _items[m]._oText.nodeValue + '</span>');
-                                } else {
-                                    _items[m].cfg.setProperty('checked', false);
-                                }
+            var button = getButton.call(this, id);
+            if (button) {
+                button.addClass('yui-button-selected');
+                button.addClass('yui-button-' + button.get('value') + '-selected');
+                button._selected = true;
+                if (value) {
+                    if (button.buttonType == 'rich') {
+                        var _items = button.getMenu().getItems();
+                        for (var m = 0; m < _items.length; m++) {
+                            if (_items[m].value == value) {
+                                _items[m].cfg.setProperty('checked', true);
+                                button.set('label', '<span class="yui-toolbar-' + button.get('value') + '-' + (value).replace(/ /g, '-').toLowerCase() + '">' + _items[m]._oText.nodeValue + '</span>');
+                            } else {
+                                _items[m].cfg.setProperty('checked', false);
                             }
                         }
                     }
-                } else {
-                    return false;
                 }
+            } else {
+                return false;
             }
         },
         /**
@@ -1813,20 +1936,12 @@
         * @return {Boolean}
         */
         deselectButton: function(id) {
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 button.removeClass('yui-button-selected');
                 button.removeClass('yui-button-' + button.get('value') + '-selected');
                 button.removeClass('yui-button-hover');
+                button._selected = false;
             } else {
                 return false;
             }
@@ -1907,17 +2022,8 @@
         * @return {Boolean}
         */
         destroyButton: function(id) {
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 var thisID = button.get('id');
                 button.destroy();
 
@@ -1930,7 +2036,6 @@
             } else {
                 return false;
             }
-
         },
         /**
         * @method destroy
@@ -2035,16 +2140,35 @@
     
     YAHOO.widget.SimpleEditor = function(el, attrs) {
         YAHOO.log('SimpleEditor Initalizing', 'info', 'SimpleEditor');
+        
+        var o = {};
+        if (Lang.isObject(el) && (!el.tagName) && !attrs) {
+            Lang.augmentObject(o, el); //Break the config reference
+            el = document.createElement('textarea');
+            this.DOMReady = true;
+            if (o.container) {
+                var c = Dom.get(o.container);
+                c.appendChild(el);
+            } else {
+                document.body.appendChild(el);
+            }
+        } else {
+            Lang.augmentObject(o, attrs); //Break the config reference
+        }
 
         var oConfig = {
             element: null,
-            attributes: (attrs || {})
+            attributes: o
         }, id = null;
 
         if (Lang.isString(el)) {
             id = el;
         } else {
-            id = el.id;
+            if (oConfig.attributes.id) {
+                id = oConfig.attributes.id;
+            } else {
+                id = Dom.generateId(el);
+            }
         }
         oConfig.element = el;
 
@@ -2073,7 +2197,7 @@
     * @method _cleanClassName
     * @description Makes a useable classname from dynamic data, by dropping it to lowercase and replacing spaces with -'s.
     * @param {String} str The classname to clean up
-    * @returns {String}
+    * @return {String}
     */
     function _cleanClassName(str) {
         return str.replace(/ /g, '-').toLowerCase();
@@ -2092,70 +2216,20 @@
         * @description This flag will be set when certain things in the Editor happen. It is to be used by the developer to check to see if content has changed.
         * @type Boolean
         */
-        editorDirty: false,
+        editorDirty: null,
         /**
         * @property _defaultCSS
         * @description The default CSS used in the config for 'css'. This way you can add to the config like this: { css: YAHOO.widget.SimpleEditor.prototype._defaultCSS + 'ADD MYY CSS HERE' }
         * @type String
         */
-        _defaultCSS: 'html { height: 95%; } body { height: 100%; padding: 7px; background-color: #fff; font:13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a { color: blue; text-decoration: underline; cursor: pointer; } .warning-localfile { border-bottom: 1px dashed red !important; } .yui-busy { cursor: wait !important; } img.selected { border: 2px dotted #808080; } img { cursor: pointer !important; border: none; }',
+        _defaultCSS: 'html { height: 95%; } body { padding: 7px; background-color: #fff; font:13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a { color: blue; text-decoration: underline; cursor: text; } .warning-localfile { border-bottom: 1px dashed red !important; } .yui-busy { cursor: wait !important; } img.selected { border: 2px dotted #808080; } img { cursor: pointer !important; border: none; }',
         /**
         * @property _defaultToolbar
         * @private
         * @description Default toolbar config.
         * @type Object
         */
-        _defaultToolbar: {
-            collapse: true,
-            titlebar: 'Text Editing Tools',
-            draggable: false,
-            buttons: [
-                { group: 'fontstyle', label: 'Font Name and Size',
-                    buttons: [
-                        { type: 'select', label: 'Arial', value: 'fontname', disabled: true,
-                            menu: [
-                                { text: 'Arial', checked: true },
-                                { text: 'Arial Black' },
-                                { text: 'Comic Sans MS' },
-                                { text: 'Courier New' },
-                                { text: 'Lucida Console' },
-                                { text: 'Tahoma' },
-                                { text: 'Times New Roman' },
-                                { text: 'Trebuchet MS' },
-                                { text: 'Verdana' }
-                            ]
-                        },
-                        { type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'textstyle', label: 'Font Style',
-                    buttons: [
-                        { type: 'push', label: 'Bold CTRL + SHIFT + B', value: 'bold' },
-                        { type: 'push', label: 'Italic CTRL + SHIFT + I', value: 'italic' },
-                        { type: 'push', label: 'Underline CTRL + SHIFT + U', value: 'underline' },
-                        { type: 'separator' },
-                        { type: 'color', label: 'Font Color', value: 'forecolor', disabled: true },
-                        { type: 'color', label: 'Background Color', value: 'backcolor', disabled: true }
-                        
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'indentlist', label: 'Lists',
-                    buttons: [
-                        { type: 'push', label: 'Create an Unordered List', value: 'insertunorderedlist' },
-                        { type: 'push', label: 'Create an Ordered List', value: 'insertorderedlist' }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'insertitem', label: 'Insert Item',
-                    buttons: [
-                        { type: 'push', label: 'HTML Link CTRL + SHIFT + L', value: 'createlink', disabled: true },
-                        { type: 'push', label: 'Insert Image', value: 'insertimage' }
-                    ]
-                }
-            ]
-        },
+        _defaultToolbar: null,
         /**
         * @property _lastButton
         * @private
@@ -2188,9 +2262,9 @@
         * @property _blankImageLoaded
         * @private
         * @description Don't load the blank image more than once..
-        * @type Date
+        * @type Boolean
         */
-        _blankImageLoaded: false,
+        _blankImageLoaded: null,
         /**
         * @property _fixNodesTimer
         * @private
@@ -2225,7 +2299,7 @@
         * @description Flag to determine if editor has been rendered or not
         * @type Boolean
         */
-        _rendered: false,
+        _rendered: null,
         /**
         * @property DOMReady
         * @private
@@ -2284,7 +2358,7 @@
         * @description A reference to the current working element in the editor
         * @type Array
         */
-        currentElement: [],
+        currentElement: null,
         /**
         * @property dompath
         * @description A reference to the dompath container for writing the current working dom path to.
@@ -2316,6 +2390,7 @@
             link: true,
             html: true,
             body: true,
+            iframe: true,
             script: true,
             style: true,
             textarea: true
@@ -2391,7 +2466,7 @@
         * @private _createIframe
         * @description Creates the DOM and YUI Element for the iFrame editor area.
         * @param {String} id The string ID to prefix the iframe with
-        * @returns {Object} iFrame object
+        * @return {Object} iFrame object
         */
         _createIframe: function() {
             var ifrmDom = document.createElement('iframe');
@@ -2406,6 +2481,9 @@
                 allowTransparency: 'true',
                 width: '100%'
             };
+            if (this.get('autoHeight')) {
+                config.scrolling = 'no';
+            }
             for (var i in config) {
                 if (Lang.hasOwnProperty(config, i)) {
                     ifrmDom.setAttribute(i, config[i]);
@@ -2413,9 +2491,7 @@
             }
             var isrc = 'javascript:;';
             if (this.browser.ie) {
-                if (window.location.href.toLowerCase().indexOf("https") !== 0) {
-                    isrc = 'about:blank';
-                }
+                isrc = 'about:blank';
             }
             ifrmDom.setAttribute('src', isrc);
             var ifrm = new YAHOO.util.Element(ifrmDom);
@@ -2427,7 +2503,7 @@
         * @description Checks to see if an Element reference is a valid one and has a certain tag type
         * @param {HTMLElement} el The element to check
         * @param {String} tag The tag that the element needs to be
-        * @returns {Boolean}
+        * @return {Boolean}
         */
         _isElement: function(el, tag) {
             if (el && el.tagName && (el.tagName.toLowerCase() == tag)) {
@@ -2443,7 +2519,7 @@
         * @description Checks to see if an Element reference or one of it's parents is a valid one and has a certain tag type
         * @param {HTMLElement} el The element to check
         * @param {String} tag The tag that the element needs to be
-        * @returns HTMLElement
+        * @return HTMLElement
         */
         _hasParent: function(el, tag) {
             if (!el || !el.parentNode) {
@@ -2535,13 +2611,17 @@
         * @private
         * @method _hasSelection
         * @description Determines if there is a selection in the editor document.
-        * @returns {Boolean}
+        * @return {Boolean}
         */
         _hasSelection: function() {
             var sel = this._getSelection();
             var range = this._getRange();
             var hasSel = false;
 
+            if (!sel || !range) {
+                return hasSel;
+            }
+
             //Internet Explorer
             if (this.browser.ie || this.browser.opera) {
                 if (range.text) {
@@ -2567,7 +2647,7 @@
         * @private
         * @method _getSelection
         * @description Handles the different selection objects across the A-Grade list.
-        * @returns {Object} Selection Object
+        * @return {Object} Selection Object
         */
         _getSelection: function() {
             var _sel = null;
@@ -2638,7 +2718,7 @@
         * @private
         * @method _getRange
         * @description Handles the different range objects across the A-Grade list.
-        * @returns {Object} Range Object
+        * @return {Object} Range Object
         */
         _getRange: function() {
             var sel = this._getSelection();
@@ -2659,7 +2739,11 @@
             }
 
             if (this.browser.ie || this.browser.opera) {
-                return sel.createRange();
+                try {
+                    return sel.createRange();
+                } catch (e) {
+                    return null;
+                }
             }
 
             if (sel.rangeCount > 0) {
@@ -2675,14 +2759,21 @@
         */
         _setDesignMode: function(state) {
             try {
-                this._getDoc().designMode = state;
+                var set = true;
+                //SourceForge Bug #1807057
+                if (this.browser.ie && (state.toLowerCase() == 'off')) {
+                    set = false;
+                }
+                if (set) {
+                    this._getDoc().designMode = state;
+                }
             } catch(e) { }
         },
         /**
         * @private
         * @method _toggleDesignMode
         * @description Toggles the designMode of the iFrame document on and off.
-        * @returns {String} The state that it was set to.
+        * @return {String} The state that it was set to.
         */
         _toggleDesignMode: function() {
             var _dMode = this._getDoc().designMode.toLowerCase(),
@@ -2699,14 +2790,23 @@
         * @description This method is fired from _checkLoaded when the document is ready. It turns on designMode and set's up the listeners.
         */
         _initEditor: function() {
-            YAHOO.log('editorLoaded', 'info', 'SimpleEditor');
             if (this.browser.ie) {
                 this._getDoc().body.style.margin = '0';
             }
             if (!this.get('disabled')) {
-                this._setDesignMode('on');
+                if (this._getDoc().designMode.toLowerCase() != 'on') {
+                    this._setDesignMode('on');
+                    this._contentTimerCounter = 0;
+                }
             }
+            if (!this._getDoc().body) {
+                YAHOO.log('Body is null, check again', 'error', 'SimpleEditor');
+                this._contentTimerCounter = 0;
+                this._checkLoaded();
+                return false;
+            }
             
+            YAHOO.log('editorLoaded', 'info', 'SimpleEditor');
             this.toolbar.on('buttonClick', this._handleToolbarClick, this, true);
             //Setup Listeners on iFrame
             Event.on(this._getDoc(), 'mouseup', this._handleMouseUp, this, true);
@@ -2740,14 +2840,22 @@
             if (this._contentTimer) {
                 clearTimeout(this._contentTimer);
             }
-            if (this._contentTimerCounter > 250) {
+            if (this._contentTimerCounter > 500) {
                 YAHOO.log('ERROR: Body Did Not load', 'error', 'SimpleEditor');
                 return false;
             }
             var init = false;
             try {
-                if (this._getDoc() && this._getDoc().body && (this._getDoc().body._rteLoaded === true)) {
-                    init = true;
+                if (this._getDoc() && this._getDoc().body) {
+                    if (this.browser.ie) {
+                        if (this._getDoc().body.readyState == 'complete') {
+                            init = true;
+                        }
+                    } else {
+                        if (this._getDoc().body._rteLoaded === true) {
+                            init = true;
+                        }
+                    }
                 }
             } catch (e) {
                 init = false;
@@ -2789,9 +2897,23 @@
             if (this.browser.ie || this.browser.webkit || this.browser.opera || (navigator.userAgent.indexOf('Firefox/1.5') != -1)) {
                 //Firefox 1.5 doesn't like setting designMode on an document created with a data url
                 try {
-                    this._getDoc().open();
-                    this._getDoc().write(html);
-                    this._getDoc().close();
+                    //Adobe AIR Code
+                    if (this.browser.air) {
+                        var doc = this._getDoc().implementation.createHTMLDocument();
+                        var origDoc = this._getDoc();
+                        origDoc.open();
+                        origDoc.close();
+                        doc.open();
+                        doc.write(html);
+                        doc.close();
+                        var node = origDoc.importNode(doc.getElementsByTagName("html")[0], true);
+                        origDoc.replaceChild(node, origDoc.getElementsByTagName("html")[0]);
+                        origDoc.body._rteLoaded = true;
+                    } else {               
+                        this._getDoc().open();
+                        this._getDoc().write(html);
+                        this._getDoc().close();
+                    }
                 } catch (e) {
                     YAHOO.log('Setting doc failed.. (_setInitialContent)', 'error', 'SimpleEditor');
                     //Safari will only be here if we are hidden
@@ -2843,7 +2965,7 @@
         * @private
         * @method _getSelectedElement
         * @description This method will attempt to locate the element that was last interacted with, either via selection, location or event.
-        * @returns {HTMLElement} The currently selected element.
+        * @return {HTMLElement} The currently selected element.
         */
         _getSelectedElement: function() {
             var doc = this._getDoc(),
@@ -2911,7 +3033,7 @@
                 } catch (e) {
                     YAHOO.log('Firefox 1.5 errors here: ' + e, 'error', 'SimpleEditor');
                 }
-            } else if (this.currentElement && this.currentElement[0]) {
+            } else if ((this.currentElement && this.currentElement[0]) && (!this.browser.ie)) {
                 elm = this.currentElement[0];
             }
             if (this.browser.opera || this.browser.webkit) {
@@ -2943,7 +3065,7 @@
         * @method _getDomPath
         * @description This method will attempt to build the DOM path from the currently selected element.
         * @param HTMLElement el The element to start with, if not provided _getSelectedElement is used
-        * @returns {Array} An array of node references that will create the DOM Path.
+        * @return {Array} An array of node references that will create the DOM Path.
         */
         _getDomPath: function(el) {
             if (!el) {
@@ -3082,7 +3204,7 @@
         * @description Method is called at the beginning of all event handlers to check if this element or a parent element has the class yui-noedit (this.CLASS_NOEDIT) applied.
         * If it does, then this method will stop the event and return true. The event handlers will then return false and stop the nodeChange from occuring. This method will also
         * disable and enable the Editor's toolbar based on the noedit state.
-        * @returns Boolean
+        * @return Boolean
         */
         _isNonEditable: function(ev) {
             if (this.get('allowNoEdit')) {
@@ -3497,7 +3619,10 @@
             switch (ev.keyCode) {
                 case 84: //Focus Toolbar Header -- Ctrl + Shift + T
                     if (ev.shiftKey && ev.ctrlKey) {
-                        this.toolbar._titlebar.firstChild.focus();
+                        var h = this.toolbar.getElementsByTagName('h2')[0];
+                        if (h) {
+                            h.focus();
+                        }
                         Event.stopEvent(ev);
                         doExec = false;
                     }
@@ -3787,6 +3912,13 @@
         * @description Creates the accessibility h2 header and places it after the iframe in the Dom for navigation.
         */
         _setupAfterElement: function() {
+            if (!this.beforeElement) {
+                this.beforeElement = document.createElement('h2');
+                this.beforeElement.className = 'yui-editor-skipheader';
+                this.beforeElement.tabIndex = '-1';
+                this.beforeElement.innerHTML = this.STR_BEFORE_EDITOR;
+                this.get('element_cont').get('firstChild').insertBefore(this.beforeElement, this.toolbar.get('nextSibling'));
+            }
             if (!this.afterElement) {
                 this.afterElement = document.createElement('h2');
                 this.afterElement.className = 'yui-editor-skipheader';
@@ -3804,7 +3936,9 @@
         _disableEditor: function(disabled) {
             if (disabled) {
                 if (!this._mask) {
-                    this._setDesignMode('off');
+                    if (!!this.browser.ie) {
+                        this._setDesignMode('off');
+                    }
                     if (this.toolbar) {
                         this.toolbar.set('disabled', true);
                     }
@@ -3933,7 +4067,7 @@
         browser: function() {
             var br = YAHOO.env.ua;
             //Check for webkit3
-            if (br.webkit > 420) {
+            if (br.webkit >= 420) {
                 br.webkit3 = br.webkit;
             } else {
                 br.webkit3 = 0;
@@ -3946,9 +4080,66 @@
         */
         init: function(p_oElement, p_oAttributes) {
             YAHOO.log('init', 'info', 'SimpleEditor');
+
+            if (!this._defaultToolbar) {
+                this._defaultToolbar = {
+                    collapse: true,
+                    titlebar: 'Text Editing Tools',
+                    draggable: false,
+                    buttons: [
+                        { group: 'fontstyle', label: 'Font Name and Size',
+                            buttons: [
+                                { type: 'select', label: 'Arial', value: 'fontname', disabled: true,
+                                    menu: [
+                                        { text: 'Arial', checked: true },
+                                        { text: 'Arial Black' },
+                                        { text: 'Comic Sans MS' },
+                                        { text: 'Courier New' },
+                                        { text: 'Lucida Console' },
+                                        { text: 'Tahoma' },
+                                        { text: 'Times New Roman' },
+                                        { text: 'Trebuchet MS' },
+                                        { text: 'Verdana' }
+                                    ]
+                                },
+                                { type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true }
+                            ]
+                        },
+                        { type: 'separator' },
+                        { group: 'textstyle', label: 'Font Style',
+                            buttons: [
+                                { type: 'push', label: 'Bold CTRL + SHIFT + B', value: 'bold' },
+                                { type: 'push', label: 'Italic CTRL + SHIFT + I', value: 'italic' },
+                                { type: 'push', label: 'Underline CTRL + SHIFT + U', value: 'underline' },
+                                { type: 'separator' },
+                                { type: 'color', label: 'Font Color', value: 'forecolor', disabled: true },
+                                { type: 'color', label: 'Background Color', value: 'backcolor', disabled: true }
+                                
+                            ]
+                        },
+                        { type: 'separator' },
+                        { group: 'indentlist', label: 'Lists',
+                            buttons: [
+                                { type: 'push', label: 'Create an Unordered List', value: 'insertunorderedlist' },
+                                { type: 'push', label: 'Create an Ordered List', value: 'insertorderedlist' }
+                            ]
+                        },
+                        { type: 'separator' },
+                        { group: 'insertitem', label: 'Insert Item',
+                            buttons: [
+                                { type: 'push', label: 'HTML Link CTRL + SHIFT + L', value: 'createlink', disabled: true },
+                                { type: 'push', label: 'Insert Image', value: 'insertimage' }
+                            ]
+                        }
+                    ]
+                };
+            }
+
             YAHOO.widget.SimpleEditor.superclass.init.call(this, p_oElement, p_oAttributes);
             YAHOO.widget.EditorInfo._instances[this.get('id')] = this;
 
+
+            this.currentElement = [];
             this.on('contentReady', function() {
                 this.DOMReady = true;
                 this.fireQueue();
@@ -3967,6 +4158,27 @@
             var self = this;
 
             /**
+            * @config container
+            * @description Used when dynamically creating the Editor from Javascript with no default textarea.
+            * We will create one and place it in this container. If no container is passed we will append to document.body.
+            * @default false
+            * @type HTMLElement
+            */
+            this.setAttributeConfig('container', {
+                writeOnce: true,
+                value: attr.container || false
+            });
+            /**
+            * @config plainText
+            * @description Process the inital textarea data as if it was plain text. Accounting for spaces, tabs and line feeds.
+            * @default false
+            * @type Boolean
+            */
+            this.setAttributeConfig('plainText', {
+                writeOnce: true,
+                value: attr.plainText || false
+            });
+            /**
             * @private
             * @config iframe
             * @description Internal config for holding the iframe element.
@@ -3989,6 +4201,17 @@
                 writeOnce: true
             });
             /**
+            * @private
+            * @config container
+            * @description Internal config for holding a reference to the container to append a dynamic editor to.
+            * @default null
+            * @type HTMLElement
+            */
+            this.setAttributeConfig('container', {
+                readOnly: true,
+                value: null
+            });
+            /**
             * @config nodeChangeThreshold
             * @description The number of seconds that need to be in between nodeChange processing
             * @default 3
@@ -4064,6 +4287,32 @@
                 }
             });
             /**
+            * @config autoHeight
+            * @description Remove the scrollbars from the edit area and resize it to fit the content. It will not go any lower than the current config height.
+            * @default false
+            * @type Boolean || Number
+            */
+            this.setAttributeConfig('autoHeight', {
+                value: attr.autoHeight || false,
+                method: function(a) {
+                    if (a) {
+                        if (this.get('iframe')) {
+                            this.get('iframe').get('element').setAttribute('scrolling', 'no');
+                        }
+                        this.on('afterNodeChange', this._handleAutoHeight, this, true);
+                        this.on('editorKeyDown', this._handleAutoHeight, this, true);
+                        this.on('editorKeyPress', this._handleAutoHeight, this, true);
+                    } else {
+                        if (this.get('iframe')) {
+                            this.get('iframe').get('element').setAttribute('scrolling', 'auto');
+                        }
+                        this.unsubscribe('afterNodeChange', this._handleAutoHeight);
+                        this.unsubscribe('editorKeyDown', this._handleAutoHeight);
+                        this.unsubscribe('editorKeyPress', this._handleAutoHeight);
+                    }
+                }
+            });
+            /**
             * @attribute width
             * @description The width of the editor container.
             * @default Best guessed size of the textarea, for best results use CSS to style the width of the textarea or pass it in as an argument
@@ -4174,7 +4423,7 @@
             * @type String
             */            
             this.setAttributeConfig('extracss', {
-                value: attr.css || '',
+                value: attr.extracss || '',
                 writeOnce: true
             });
 
@@ -4187,22 +4436,28 @@
             * @type Boolean
             */            
             this.setAttributeConfig('handleSubmit', {
-                value: false,
-                writeOnce: true,
+                value: attr.handleSubmit || false,
                 method: function(exec) {
-                    if (exec) {
-                        var ta = this.get('element');
-                        if (ta.form) {
-                            var submitForm = function(ev) {
-                                Event.stopEvent(ev);
-                                this.saveHTML();
-                                window.setTimeout(function() {
-                                    YAHOO.util.Event.removeListener(ta.form, 'submit', submitForm);
-                                    ta.form.submit();
-                                }, 200);
-                            };
-                            Event.on(ta.form, 'submit', submitForm, this, true);
+                    if (this.get('element').form) {
+                        if (!this._formButtons) {
+                            this._formButtons = [];
                         }
+                        if (exec) {
+                            Event.on(this.get('element').form, 'submit', this._handleFormSubmit, this, true);
+                            var i = this.get('element').form.getElementsByTagName('input');
+                            for (var s = 0; s < i.length; s++) {
+                                var type = i[s].getAttribute('type');
+                                if (type && (type.toLowerCase() == 'submit')) {
+                                    Event.on(i[s], 'click', this._handleFormButtonClick, this, true);
+                                    this._formButtons[this._formButtons.length] = i[s];
+                                }
+                            }
+                        } else {
+                            Event.unsubscribe(this.get('element').form, 'submit', this._handleFormSubmit);
+                            if (this._formButtons) {
+                                Event.unsubscribe(this._formButtons, 'click', this._handleFormButtonClick);
+                            }
+                        }
                     }
                 }
             });
@@ -4261,7 +4516,7 @@
                         ret = false;
                     }
                     return ret;
-                }               
+                }
             });
             /**
             * @config panel
@@ -4320,7 +4575,6 @@
                         this.dompath.parentNode.removeChild(this.dompath);
                         this.dompath = null;
                     }
-                    this._setupAfterElement();
                 }
             });
             /**
@@ -4362,7 +4616,7 @@
         * @private
         * @method _getBlankImage
         * @description Retrieves the full url of the image to use as the blank image.
-        * @returns {String} The URL to the blank image
+        * @return {String} The URL to the blank image
         */
         _getBlankImage: function() {
             if (!this.DOMReady) {
@@ -4371,16 +4625,24 @@
             }
             var img = '';
             if (!this._blankImageLoaded) {
-                var div = document.createElement('div');
-                div.style.position = 'absolute';
-                div.style.top = '-9999px';
-                div.style.left = '-9999px';
-                div.className = this.CLASS_PREFIX + '-blankimage';
-                document.body.appendChild(div);
-                img = YAHOO.util.Dom.getStyle(div, 'background-image');
-                img = img.replace('url(', '').replace(')', '').replace(/"/g, '');
-                this.set('blankimage', img);
-                this._blankImageLoaded = true;
+                if (YAHOO.widget.EditorInfo.blankImage) {
+                    this.set('blankimage', YAHOO.widget.EditorInfo.blankImage);
+                    this._blankImageLoaded = true;
+                } else {
+                    var div = document.createElement('div');
+                    div.style.position = 'absolute';
+                    div.style.top = '-9999px';
+                    div.style.left = '-9999px';
+                    div.className = this.CLASS_PREFIX + '-blankimage';
+                    document.body.appendChild(div);
+                    img = YAHOO.util.Dom.getStyle(div, 'background-image');
+                    img = img.replace('url(', '').replace(')', '').replace(/"/g, '');
+                    //Adobe AIR Code
+                    img = img.replace('app:/', '');                    
+                    this.set('blankimage', img);
+                    this._blankImageLoaded = true;
+                    YAHOO.widget.EditorInfo.blankImage = img;
+                }
             } else {
                 img = this.get('blankimage');
             }
@@ -4388,6 +4650,82 @@
         },
         /**
         * @private
+        * @method _handleAutoHeight
+        * @description Handles resizing the editor's height based on the content
+        */
+        _handleAutoHeight: function() {
+            var doc = this._getDoc(),
+                body = doc.body,
+                docEl = doc.documentElement;
+
+            var height = parseInt(Dom.getStyle(this.get('editor_wrapper'), 'height'), 10);
+            var newHeight = body.scrollHeight;
+            if (this.browser.webkit) {
+                newHeight = docEl.scrollHeight;
+            }
+            if (newHeight < parseInt(this.get('height'), 10)) {
+                newHeight = parseInt(this.get('height'), 10);
+            }
+            if ((height != newHeight) && (newHeight >= parseInt(this.get('height'), 10))) {   
+                Dom.setStyle(this.get('editor_wrapper'), 'height', newHeight + 'px');
+                if (this.browser.ie) {
+                    //Internet Explorer needs this
+                    this.get('iframe').setStyle('height', '99%');
+                    this.get('iframe').setStyle('zoom', '1');
+                    var self = this;
+                    window.setTimeout(function() {
+                        self.get('iframe').setStyle('height', '100%');
+                    }, 1);
+                }
+            }
+        },
+        _formButtons: null,
+        _formButtonClicked: null,
+        _handleFormButtonClick: function(ev) {
+            var tar = Event.getTarget(ev);
+            this._formButtonClicked = tar;
+        },
+        /**
+        * @private
+        * @method _handleFormSubmit
+        * @description Handles the form submission.
+        * @param {Object} ev The Form Submit Event
+        */
+        _handleFormSubmit: function(ev) {
+            Event.stopEvent(ev);
+            YAHOO.log('Button: ' + this._formButtonClicked.id, 'info', 'SimpleEditor');
+            
+            this.saveHTML();
+            var form = this.get('element').form;
+            var tar = this._formButtonClicked || false;
+            var self = this;
+
+            window.setTimeout(function() {
+                YAHOO.util.Event.removeListener(form, 'submit', self._handleFormSubmit);
+                if (YAHOO.env.ua.ie) {
+                    form.fireEvent("onsubmit");
+                    if (tar && !tar.disabled) {
+                        tar.click();
+                    }
+                } else {  // Gecko, Opera, and Safari
+                    if (tar && !tar.disabled) {
+                        tar.click();
+                    } else {
+                        var oEvent = document.createEvent("HTMLEvents");
+                        oEvent.initEvent("submit", true, true);
+                        form.dispatchEvent(oEvent);
+                        if (YAHOO.env.ua.webkit) {
+                            if (YAHOO.lang.isFunction(form.submit)) {
+                                form.submit();
+                            }
+                        }
+                    }
+                }
+            }, 200);
+            
+        },
+        /**
+        * @private
         * @method _handleFontSize
         * @description Handles the font size button in the toolbar.
         * @param {Object} o Object returned from Toolbar's buttonClick Event
@@ -4456,6 +4794,8 @@
                 family = elm.getAttribute('face');
                 if (Dom.getStyle(elm, 'font-family')) {
                     family = Dom.getStyle(elm, 'font-family');
+                    //Adobe AIR Code
+                    family = family.replace(/'/g, '');                    
                 }
 
                 if (tag.substring(0, 1) == 'h') {
@@ -4511,7 +4851,6 @@
                 this.toolbar.disableButton('indent');
                 this.toolbar.enableButton('outdent');
             }
-            //if (this._isElement(elm, 'ol') || this._isElement(elm, 'ul') || this._isElement(elm, 'li')) {
             if (this._hasParent(elm, 'ol') || this._hasParent(elm, 'ul')) {
                 this.toolbar.disableButton('indent');
             }
@@ -4519,6 +4858,7 @@
             
         },
         _setBusy: function(off) {
+            /*
             if (off) {
                 Dom.removeClass(document.body, 'yui-busy');
                 Dom.removeClass(this._getDoc().body, 'yui-busy');
@@ -4526,6 +4866,7 @@
                 Dom.addClass(document.body, 'yui-busy');
                 Dom.addClass(this._getDoc().body, 'yui-busy');
             }
+            */
         },
         /**
         * @private
@@ -4558,9 +4899,10 @@
                 var str = prompt(this.STR_LINK_URL + ': ', src);
                 if ((str !== '') && (str !== null)) {
                     el.setAttribute('src', str);
-                } else if (str !== null) {
+                } else if (str === null) {
                     el.parentNode.removeChild(el);
                     this.currentElement = [];
+                    this.nodeChange();
                 }
                 this.closeWindow();
                 this.toolbar.set('disabled', false);
@@ -4645,7 +4987,7 @@
         },
         /**
         * @method render
-        * @description Causes the toolbar and the editor to render and replace the textarea.
+        * @description Calls the private method _render in a setTimeout to allow for other things on the page to continue to load.
         */
         render: function() {
             if (this._rendered) {
@@ -4656,10 +4998,20 @@
                 this._queue[this._queue.length] = ['render', arguments];
                 return false;
             }
-            this._setBusy();
             this._rendered = true;
             var self = this;
-
+            window.setTimeout(function() {
+                self._render.call(self);
+            }, 4);
+        },
+        /**
+        * @private
+        * @method _render
+        * @description Causes the toolbar and the editor to render and replace the textarea.
+        */
+        _render: function() {
+            this._setBusy();
+            var self = this;
             this.set('textarea', this.get('element'));
 
             this.get('element_cont').setStyle('display', 'none');
@@ -4708,6 +5060,7 @@
             
             this.toolbar.on('colorPickerClicked', function(o) {
                 this._handleColorPicker(o);
+                return false; //Stop the buttonClick event
             }, this, true);
 
             this.toolbar.on('alignClick', function(o) {
@@ -4731,18 +5084,9 @@
             
 
             //Replace Textarea with editable area
-            
             this.get('parentNode').replaceChild(this.get('element_cont').get('element'), this.get('element'));
 
             
-            if (!this.beforeElement) {
-                this.beforeElement = document.createElement('h2');
-                this.beforeElement.className = 'yui-editor-skipheader';
-                this.beforeElement.tabIndex = '-1';
-                this.beforeElement.innerHTML = this.STR_BEFORE_EDITOR;
-                this.get('element_cont').get('firstChild').insertBefore(this.beforeElement, this.toolbar.get('nextSibling'));
-            }
-
             this.setStyle('visibility', 'hidden');
             this.setStyle('position', 'absolute');
             this.setStyle('top', '-9999px');
@@ -4761,9 +5105,9 @@
             this.get('iframe').setStyle('width', '100%'); //WIDTH
             this.get('iframe').setStyle('height', '100%');
 
-            if (this.browser.ie == 7) {
-            }
-
+            window.setTimeout(function() {
+                self._setupAfterElement.call(self);
+            }, 0);
             this.fireEvent('afterRender', { type: 'afterRender', target: this });
         },
         /**
@@ -5058,9 +5402,13 @@
                 exec = false;
             } else {
                 el = this._getSelectedElement();
-                if (this._isElement(el, 'li') && this._isElement(el.parentNode, tag) || (this.browser.ie && this._isElement(this._getRange().parentElement, 'li'))) { //we are in a list..
+                YAHOO.log(el.tagName);
+                if (this._isElement(el, 'li') && this._isElement(el.parentNode, tag) || (this.browser.ie && this._isElement(this._getRange().parentElement, 'li')) || (this.browser.ie && this._isElement(el, 'ul')) || (this.browser.ie && this._isElement(el, 'ol'))) { //we are in a list..
                     YAHOO.log('We already have a list, undo it', 'info', 'SimpleEditor');
                     if (this.browser.ie) {
+                        if ((this.browser.ie && this._isElement(el, 'ul')) || (this.browser.ie && this._isElement(el, 'ol'))) {
+                            el = el.getElementsByTagName('li')[0];
+                        }
                         YAHOO.log('Undo IE', 'info', 'SimpleEditor');
                         str = '';
                         var lis2 = el.parentNode.getElementsByTagName('li');
@@ -5093,7 +5441,15 @@
                     if (this._getRange().html) {
                         html = '<li>' + this._getRange().html+ '</li>';
                     } else {
-                        html = '<li>' + this._getRange().text + '</li>';
+                        var t = this._getRange().text.split('\n');
+                        if (t.length > 1) {
+                            html = '';
+                            for (var ie = 0; ie < t.length; ie++) {
+                                html += '<li>' + t[ie] + '</li>';
+                            }
+                        } else {
+                            html = '<li>' + this._getRange().text + '</li>';
+                        }
                     }
 
                     this._getRange().pasteHTML('<' + tag + '>' + html + '</' + tag + '>');
@@ -5140,7 +5496,7 @@
         * @description This is an execCommand override method. It is called from execCommand when the execCommand('fontsize') is used.
         */
         cmd_fontsize: function(value) {
-            if ((this.currentElement.length > 0) && (!this._hasSelection())) {
+            if (this.currentElement && (this.currentElement.length > 0) && (!this._hasSelection())) {
                 YAHOO.util.Dom.setStyle(this.currentElement, 'fontSize', value);
             } else if (!this._isElement(this._getSelectedElement(), 'body')) {
                 var el = this._getSelectedElement();
@@ -5357,6 +5713,7 @@
         /**
         * @method saveHTML
         * @description Cleans the HTML with the cleanHTML method then places that string back into the textarea.
+        * @return String
         */
         saveHTML: function() {
             var html = this.cleanHTML();
@@ -5378,6 +5735,11 @@
         * @description Gets the unprocessed/unfiltered HTML from the editor
         */
         getEditorHTML: function() {
+            var b = this._getDoc().body;
+            if (b === null) {
+                YAHOO.log('Body is null, returning null.', 'error', 'SimpleEditor');
+                return null;
+            }
             return this._getDoc().body.innerHTML;
         },
         /**
@@ -5429,20 +5791,46 @@
         * @method _cleanIncomingHTML
         * @param {String} html The unfiltered HTML
         * @description Process the HTML with a few regexes to clean it up and stabilize the input
-        * @returns {String} The filtered HTML
+        * @return {String} The filtered HTML
         */
         _cleanIncomingHTML: function(html) {
             html = html.replace(/<strong([^>]*)>/gi, '<b$1>');
             html = html.replace(/<\/strong>/gi, '</b>');   
+
+            //replace embed before em check
+            html = html.replace(/<embed([^>]*)>/gi, '<YUI_EMBED$1>');
+            html = html.replace(/<\/embed>/gi, '</YUI_EMBED>');
+
             html = html.replace(/<em([^>]*)>/gi, '<i$1>');
             html = html.replace(/<\/em>/gi, '</i>');
+            
+            //Put embed tags back in..
+            html = html.replace(/<YUI_EMBED([^>]*)>/gi, '<embed$1>');
+            html = html.replace(/<\/YUI_EMBED>/gi, '</embed>');
+            if (this.get('plainText')) {
+                YAHOO.log('Filtering as plain text', 'info', 'SimpleEditor');
+                html = html.replace(/\n/g, '<br>').replace(/\r/g, '<br>');
+                html = html.replace(/  /gi, '  '); //Replace all double spaces
+                html = html.replace(/\t/gi, '    '); //Replace all tabs
+            }
+            //Removing Script Tags from the Editor
+            html = html.replace(/<script([^>]*)>/gi, '<bad>');
+            html = html.replace(/<\/script([^>]*)>/gi, '</bad>');
+            html = html.replace(/<script([^>]*)>/gi, '<bad>');
+            html = html.replace(/<\/script([^>]*)>/gi, '</bad>');
+            //Replace the line feeds
+            html = html.replace(/\n/g, '<YUI_LF>').replace(/\r/g, '<YUI_LF>');
+            //Remove Bad HTML elements (used to be script nodes)
+            html = html.replace(new RegExp('<bad([^>]*)>(.*?)<\/bad>', 'gi'), '');
+            //Replace the lines feeds
+            html = html.replace(/<YUI_LF>/g, '\n');
             return html;
         },
         /**
         * @method cleanHTML
         * @param {String} html The unfiltered HTML
         * @description Process the HTML with a few regexes to clean it up and stabilize the output
-        * @returns {String} The filtered HTML
+        * @return {String} The filtered HTML
         */
         cleanHTML: function(html) {
             //Start Filtering Output
@@ -5465,9 +5853,12 @@
 		    html = html.replace(/<blockquote([^>]*)>/gi, '<YUI_BQ$1>');
 		    html = html.replace(/<\/blockquote>/gi, '<\/YUI_BQ>');
 
+		    html = html.replace(/<embed([^>]*)>/gi, '<YUI_EMBED$1>');
+		    html = html.replace(/<\/embed>/gi, '<\/YUI_EMBED>');
+
             //Convert b and i tags to strong and em tags
             if ((markup == 'semantic') || (markup == 'xhtml')) {
-                html = html.replace(/<i([^>]*)>/gi, '<em$1>');
+                html = html.replace(/<i(\s+[^>]*)?>/gi, '<em$1>');
                 html = html.replace(/<\/i>/gi, '</em>');
                 html = html.replace(/<b([^>]*)>/gi, '<strong$1>');
                 html = html.replace(/<\/b>/gi, '</strong>');
@@ -5481,6 +5872,10 @@
             if ((markup == 'semantic') || (markup == 'xhtml') || (markup == 'css')) {
                 html = html.replace(new RegExp('<font([^>]*)face="([^>]*)">(.*?)<\/font>', 'gi'), '<span $1 style="font-family: $2;">$3</span>');
                 html = html.replace(/<u/gi, '<span style="text-decoration: underline;"');
+                if (this.browser.webkit) {
+                    html = html.replace(new RegExp('<span class="Apple-style-span" style="font-weight: bold;">([^>]*)<\/span>', 'gi'), '<strong>$1</strong>');
+                    html = html.replace(new RegExp('<span class="Apple-style-span" style="font-style: italic;">([^>]*)<\/span>', 'gi'), '<em>$1</em>');
+                }
                 html = html.replace(/\/u>/gi, '/span>');
                 if (markup == 'css') {
                     html = html.replace(/<em([^>]*)>/gi, '<i$1>');
@@ -5511,8 +5906,8 @@
             html = this.post_filter_linebreaks(html, markup);
 
             if (markup == 'xhtml') {
-		        html = html.replace(/<YUI_IMG([^>]*)>/g, '<img $1/>');
-		        html = html.replace(/<YUI_INPUT([^>]*)>/g, '<input $1/>');
+		        html = html.replace(/<YUI_IMG([^>]*)>/g, '<img $1 />');
+		        html = html.replace(/<YUI_INPUT([^>]*)>/g, '<input $1 />');
             } else {
 		        html = html.replace(/<YUI_IMG([^>]*)>/g, '<img $1>');
 		        html = html.replace(/<YUI_INPUT([^>]*)>/g, '<input $1>');
@@ -5525,6 +5920,9 @@
 		    html = html.replace(/<YUI_BQ([^>]*)>/g, '<blockquote$1>');
 		    html = html.replace(/<\/YUI_BQ>/g, '<\/blockquote>');
 
+		    html = html.replace(/<YUI_EMBED([^>]*)>/g, '<embed$1>');
+		    html = html.replace(/<\/YUI_EMBED>/g, '<\/embed>');
+
             //Trim the output, removing whitespace from the beginning and end
             html = YAHOO.lang.trim(html);
 
@@ -5536,13 +5934,12 @@
             //First empty span
             if (html.substring(0, 6).toLowerCase() == '<span>')  {
                 html = html.substring(6);
+                //Last empty span
+                if (html.substring(html.length - 7, html.length).toLowerCase() == '</span>')  {
+                    html = html.substring(0, html.length - 7);
+                }
             }
-            //Last empty span
-            if (html.substring(html.length - 7, html.length).toLowerCase() == '</span>')  {
-                html = html.substring(0, html.length - 7);
-            }
 
-
             for (var v in this.invalidHTML) {
                 if (YAHOO.lang.hasOwnProperty(this.invalidHTML, v)) {
                     if (Lang.isObject(v) && v.keepContents) {
@@ -5561,7 +5958,6 @@
         * @method filter_invalid_lists
         * @param String html The HTML string to filter
         * @description Filters invalid ol and ul list markup, converts this: <li></li><ol>..</ol> to this: <li></li><li><ol>..</ol></li>
-        * @returns String
         */
         filter_invalid_lists: function(html) {
             html = html.replace(/<\/li>\n/gi, '</li>');
@@ -5584,10 +5980,12 @@
         * @method filter_safari
         * @param String html The HTML string to filter
         * @description Filters strings specific to Safari
-        * @returns String
+        * @return String
         */
         filter_safari: function(html) {
             if (this.browser.webkit) {
+                //<span class="Apple-tab-span" style="white-space:pre">	</span>
+                html = html.replace(/<span class="Apple-tab-span" style="white-space:pre">([^>])<\/span>/gi, '    ');
                 html = html.replace(/Apple-style-span/gi, '');
                 html = html.replace(/style="line-height: normal;"/gi, '');
                 //Remove bogus LI's
@@ -5604,7 +6002,7 @@
         * @method filter_internals
         * @param String html The HTML string to filter
         * @description Filters internal RTE strings and bogus attrs we don't want
-        * @returns String
+        * @return String
         */
         filter_internals: function(html) {
 		    html = html.replace(/\r/g, '');
@@ -5638,7 +6036,7 @@
         * @method filter_all_rgb
         * @param String str The HTML string to filter
         * @description Converts all RGB color strings found in passed string to a hex color, example: style="color: rgb(0, 255, 0)" converts to style="color: #00ff00"
-        * @returns String
+        * @return String
         */
         filter_all_rgb: function(str) {
             var exp = new RegExp("rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)", "gi");
@@ -5656,7 +6054,7 @@
         * @method filter_rgb
         * @param String css The CSS string containing rgb(#,#,#);
         * @description Converts an RGB color string to a hex color, example: rgb(0, 255, 0) converts to #00ff00
-        * @returns String
+        * @return String
         */
         filter_rgb: function(css) {
             if (css.toLowerCase().indexOf('rgb') != -1) {
@@ -5682,7 +6080,7 @@
         * @param String html The HTML to filter
         * @param String markup The markup type to filter to
         * @description HTML Pre Filter
-        * @returns String
+        * @return String
         */
         pre_filter_linebreaks: function(html, markup) {
             if (this.browser.webkit) {
@@ -5708,11 +6106,11 @@
         * @param String html The HTML to filter
         * @param String markup The markup type to filter to
         * @description HTML Pre Filter
-        * @returns String
+        * @return String
         */
         post_filter_linebreaks: function(html, markup) {
             if (markup == 'xhtml') {
-		        html = html.replace(/<YUI_BR>/g, '<br/>');
+		        html = html.replace(/<YUI_BR>/g, '<br />');
             } else {
 		        html = html.replace(/<YUI_BR>/g, '<br>');
             }
@@ -5775,6 +6173,7 @@
             var textArea = this.get('element');
             this.get('element_cont').get('parentNode').replaceChild(textArea, this.get('element_cont').get('element'));
             this.get('element_cont').get('element').innerHTML = '';
+            this.set('handleSubmit', false); //Remove the submit handler
             //Brutal Object Destroy
             for (var i in this) {
                 if (Lang.hasOwnProperty(this, i)) {
@@ -5889,6 +6288,13 @@
         _instances: {},
         /**
         * @private
+        * @property blankImage
+        * @description A reference to the blankImage url
+        * @type String 
+        */
+        blankImage: '',
+        /**
+        * @private
         * @property window
         * @description A reference to the currently open window object in any editor on the page.
         * @type Object <a href="YAHOO.widget.EditorWindow.html">YAHOO.widget.EditorWindow</a>
@@ -5905,7 +6311,7 @@
         * @method getEditorById
         * @description Returns a reference to the Editor object associated with the given textarea
         * @param {String/HTMLElement} id The id or reference of the textarea to return the Editor instance of
-        * @returns Object <a href="YAHOO.widget.Editor.html">YAHOO.widget.Editor</a>
+        * @return Object <a href="YAHOO.widget.Editor.html">YAHOO.widget.Editor</a>
         */
         getEditorById: function(id) {
             if (!YAHOO.lang.isString(id)) {
@@ -5961,19 +6367,7 @@
     
     YAHOO.widget.Editor = function(el, attrs) {
         YAHOO.log('Editor Initalizing', 'info', 'Editor');
-        
-        var oConfig = {
-            element: null,
-            attributes: (attrs || {})
-        }, id = null;
-
-        if (Lang.isString(el)) {
-            id = el;
-        } else {
-            id = el.id;
-        }
-        oConfig.element = el;
-        YAHOO.widget.Editor.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
+        YAHOO.widget.Editor.superclass.constructor.call(this, el, attrs);
     };
 
     /**
@@ -5981,7 +6375,7 @@
     * @method _cleanClassName
     * @description Makes a useable classname from dynamic data, by dropping it to lowercase and replacing spaces with -'s.
     * @param {String} str The classname to clean up
-    * @returns {String}
+    * @return {String}
     */
     function _cleanClassName(str) {
         return str.replace(/ /g, '-').toLowerCase();
@@ -6111,7 +6505,94 @@
         */
         init: function(p_oElement, p_oAttributes) {
             YAHOO.log('init', 'info', 'Editor');
+
+            this._defaultToolbar = {
+                collapse: true,
+                titlebar: 'Text Editing Tools',
+                draggable: false,
+                buttonType: 'advanced',
+                buttons: [
+                    { group: 'fontstyle', label: 'Font Name and Size',
+                        buttons: [
+                            { type: 'select', label: 'Arial', value: 'fontname', disabled: true,
+                                menu: [
+                                    { text: 'Arial', checked: true },
+                                    { text: 'Arial Black' },
+                                    { text: 'Comic Sans MS' },
+                                    { text: 'Courier New' },
+                                    { text: 'Lucida Console' },
+                                    { text: 'Tahoma' },
+                                    { text: 'Times New Roman' },
+                                    { text: 'Trebuchet MS' },
+                                    { text: 'Verdana' }
+                                ]
+                            },
+                            { type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true }
+                        ]
+                    },
+                    { type: 'separator' },
+                    { group: 'textstyle', label: 'Font Style',
+                        buttons: [
+                            { type: 'push', label: 'Bold CTRL + SHIFT + B', value: 'bold' },
+                            { type: 'push', label: 'Italic CTRL + SHIFT + I', value: 'italic' },
+                            { type: 'push', label: 'Underline CTRL + SHIFT + U', value: 'underline' },
+                            { type: 'separator' },
+                            { type: 'push', label: 'Subscript', value: 'subscript', disabled: true },
+                            { type: 'push', label: 'Superscript', value: 'superscript', disabled: true },
+                            { type: 'separator' },
+                            { type: 'color', label: 'Font Color', value: 'forecolor', disabled: true },
+                            { type: 'color', label: 'Background Color', value: 'backcolor', disabled: true },
+                            { type: 'separator' },
+                            { type: 'push', label: 'Remove Formatting', value: 'removeformat', disabled: true },
+                            { type: 'push', label: 'Show/Hide Hidden Elements', value: 'hiddenelements' }
+                        ]
+                    },
+                    { type: 'separator' },
+                    { group: 'alignment', label: 'Alignment',
+                        buttons: [
+                            { type: 'push', label: 'Align Left CTRL + SHIFT + [', value: 'justifyleft' },
+                            { type: 'push', label: 'Align Center CTRL + SHIFT + |', value: 'justifycenter' },
+                            { type: 'push', label: 'Align Right CTRL + SHIFT + ]', value: 'justifyright' },
+                            { type: 'push', label: 'Justify', value: 'justifyfull' }
+                        ]
+                    },
+                    { type: 'separator' },
+                    { group: 'parastyle', label: 'Paragraph Style',
+                        buttons: [
+                        { type: 'select', label: 'Normal', value: 'heading', disabled: true,
+                            menu: [
+                                { text: 'Normal', value: 'none', checked: true },
+                                { text: 'Header 1', value: 'h1' },
+                                { text: 'Header 2', value: 'h2' },
+                                { text: 'Header 3', value: 'h3' },
+                                { text: 'Header 4', value: 'h4' },
+                                { text: 'Header 5', value: 'h5' },
+                                { text: 'Header 6', value: 'h6' }
+                            ]
+                        }
+                        ]
+                    },
+                    { type: 'separator' },
+                    { group: 'indentlist', label: 'Indenting and Lists',
+                        buttons: [
+                            { type: 'push', label: 'Indent', value: 'indent', disabled: true },
+                            { type: 'push', label: 'Outdent', value: 'outdent', disabled: true },
+                            { type: 'push', label: 'Create an Unordered List', value: 'insertunorderedlist' },
+                            { type: 'push', label: 'Create an Ordered List', value: 'insertorderedlist' }
+                        ]
+                    },
+                    { type: 'separator' },
+                    { group: 'insertitem', label: 'Insert Item',
+                        buttons: [
+                            { type: 'push', label: 'HTML Link CTRL + SHIFT + L', value: 'createlink', disabled: true },
+                            { type: 'push', label: 'Insert Image', value: 'insertimage' }
+                        ]
+                    }
+                ]
+            };
+
             YAHOO.widget.Editor.superclass.init.call(this, p_oElement, p_oAttributes);
+
         },
         /**
         * @method initAttributes
@@ -6208,97 +6689,7 @@
         */
         _alwaysEnabled: { hiddenelements: true },
         /**
-        * @property _defaultToolbar
         * @private
-        * @description Default toolbar config.
-        * @type Object
-        */
-        _defaultToolbar: {
-            collapse: true,
-            titlebar: 'Text Editing Tools',
-            draggable: false,
-            buttonType: 'advanced',
-            buttons: [
-                { group: 'fontstyle', label: 'Font Name and Size',
-                    buttons: [
-                        { type: 'select', label: 'Arial', value: 'fontname', disabled: true,
-                            menu: [
-                                { text: 'Arial', checked: true },
-                                { text: 'Arial Black' },
-                                { text: 'Comic Sans MS' },
-                                { text: 'Courier New' },
-                                { text: 'Lucida Console' },
-                                { text: 'Tahoma' },
-                                { text: 'Times New Roman' },
-                                { text: 'Trebuchet MS' },
-                                { text: 'Verdana' }
-                            ]
-                        },
-                        { type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'textstyle', label: 'Font Style',
-                    buttons: [
-                        { type: 'push', label: 'Bold CTRL + SHIFT + B', value: 'bold' },
-                        { type: 'push', label: 'Italic CTRL + SHIFT + I', value: 'italic' },
-                        { type: 'push', label: 'Underline CTRL + SHIFT + U', value: 'underline' },
-                        { type: 'separator' },
-                        { type: 'push', label: 'Subscript', value: 'subscript', disabled: true },
-                        { type: 'push', label: 'Superscript', value: 'superscript', disabled: true },
-                        { type: 'separator' },
-                        { type: 'color', label: 'Font Color', value: 'forecolor', disabled: true },
-                        { type: 'color', label: 'Background Color', value: 'backcolor', disabled: true },
-                        { type: 'separator' },
-                        { type: 'push', label: 'Remove Formatting', value: 'removeformat', disabled: true },
-                        { type: 'push', label: 'Show/Hide Hidden Elements', value: 'hiddenelements' }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'alignment', label: 'Alignment',
-                    buttons: [
-                        { type: 'push', label: 'Align Left CTRL + SHIFT + [', value: 'justifyleft' },
-                        { type: 'push', label: 'Align Center CTRL + SHIFT + |', value: 'justifycenter' },
-                        { type: 'push', label: 'Align Right CTRL + SHIFT + ]', value: 'justifyright' },
-                        { type: 'push', label: 'Justify', value: 'justifyfull' }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'parastyle', label: 'Paragraph Style',
-                    buttons: [
-                    { type: 'select', label: 'Normal', value: 'heading', disabled: true,
-                        menu: [
-                            { text: 'Normal', value: 'none', checked: true },
-                            { text: 'Header 1', value: 'h1' },
-                            { text: 'Header 2', value: 'h2' },
-                            { text: 'Header 3', value: 'h3' },
-                            { text: 'Header 4', value: 'h4' },
-                            { text: 'Header 5', value: 'h5' },
-                            { text: 'Header 6', value: 'h6' }
-                        ]
-                    }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'indentlist', label: 'Indenting and Lists',
-                    buttons: [
-                        { type: 'push', label: 'Indent', value: 'indent', disabled: true },
-                        { type: 'push', label: 'Outdent', value: 'outdent', disabled: true },
-                        { type: 'push', label: 'Create an Unordered List', value: 'insertunorderedlist' },
-                        { type: 'push', label: 'Create an Ordered List', value: 'insertorderedlist' }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'insertitem', label: 'Insert Item',
-                    buttons: [
-                        { type: 'push', label: 'HTML Link CTRL + SHIFT + L', value: 'createlink', disabled: true },
-                        { type: 'push', label: 'Insert Image', value: 'insertimage' }
-                    ]
-                }
-            ]
-        },
-        /**
-        * @private
         * @method _handleKeyDown
         * @param {Event} ev The event we are working on.
         * @description Override method that handles some new keydown events inside the iFrame document.
@@ -6629,7 +7020,7 @@
                 if ((height != oheight) || (width != owidth)) {
                     orgSize = '<span class="info">' + this.STR_IMAGE_ORIG_SIZE + '<br>'+ owidth +' x ' + oheight + '</span>';
                 }
-                hw.innerHTML += '<span><input type="text" size="3" value="'+width+'" id="insertimage_width"> x <input type="text" size="3" value="'+height+'" id="insertimage_height"></span>' + orgSize;
+                hw.innerHTML += '<span tabIndex="-1"><input type="text" size="3" value="'+width+'" id="insertimage_width"> x <input type="text" size="3" value="'+height+'" id="insertimage_height"></span>' + orgSize;
                 cont.insertBefore(hw, cont.firstChild);
 
                 Event.onAvailable('insertimage_width', function() {
@@ -6637,7 +7028,8 @@
                         var value = parseInt(Dom.get('insertimage_width').value, 10);
                         if (value > 5) {
                             el.style.width = value + 'px';
-                            this.moveWindow();
+                            //Removed moveWindow call so the window doesn't jump
+                            //this.moveWindow();
                         }
                     }, this, true);
                 }, this, true);
@@ -6646,7 +7038,8 @@
                         var value = parseInt(Dom.get('insertimage_height').value, 10);
                         if (value > 5) {
                             el.style.height = value + 'px';
-                            this.moveWindow();
+                            //Removed moveWindow call so the window doesn't jump
+                            //this.moveWindow();
                         }
                     }, this, true);
                 }, this, true);
@@ -6754,7 +7147,8 @@
 
                 win.setHeader(this.STR_IMAGE_PROP_TITLE);
                 win.setBody(body);
-                if ((this.browser.webkit && !this.browser.webkit3) || this.browser.opera) {
+                //Adobe AIR Code
+                if ((this.browser.webkit && !this.browser.webkit3 || this.browser.air) || this.browser.opera) {                
                     win.setFooter(this.STR_IMAGE_COPY);
                 }
                 this.openWindow(win);
@@ -6782,7 +7176,8 @@
                             } else {
                                 Dom.removeClass(url, 'warning');
                                 this.get('panel').setFooter(' ');
-                                if ((this.browser.webkit && !this.browser.webkit3) || this.browser.opera) {
+                                //Adobe AIR Code
+                                if ((this.browser.webkit && !this.browser.webkit3 || this.browser.air) || this.browser.opera) {                
                                     this.get('panel').setFooter(this.STR_IMAGE_COPY);
                                 }
                             }
@@ -6790,6 +7185,13 @@
 
                         Event.on('insertimage_url', 'blur', function() {
                             var url = Dom.get('insertimage_url');
+                            if (url.value && el) {
+                                if (url.value == el.getAttribute('src', 2)) {
+                                    YAHOO.log('Images are the same, bail on blur handler', 'info', 'Editor');
+                                    return false;
+                                }
+                            }
+                            YAHOO.log('Images are different, process blur handler', 'info', 'Editor');
                             if (this._isLocalFile(url.value)) {
                                 //Local File throw Warning
                                 Dom.addClass(url, 'warning');
@@ -6798,7 +7200,8 @@
                             } else if (this.currentElement[0]) {
                                 Dom.removeClass(url, 'warning');
                                 this.get('panel').setFooter(' ');
-                                if ((this.browser.webkit && !this.browser.webkit3) || this.browser.opera) {
+                                //Adobe AIR Code
+                                if ((this.browser.webkit && !this.browser.webkit3 || this.browser.air) || this.browser.opera) {                
                                     this.get('panel').setFooter(this.STR_IMAGE_COPY);
                                 }
                                 
@@ -6825,8 +7228,9 @@
                                                 self.currentElement[0]._width = img.width;
                                             }
                                         }
-                                        self.moveWindow();
-                                    }, 200);
+                                        //Removed moveWindow call so the window doesn't jump
+                                        //self.moveWindow();
+                                    }, 800); //Bumped the timeout up to account for larger images..
 
                                     if (url.value != this.STR_IMAGE_HERE) {
                                         img.src = url.value;
@@ -6899,7 +7303,7 @@
         * @private
         * @method _renderPanel
         * @description Renders the panel used for Editor Windows to the document so we can start using it..
-        * @returns {<a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>}
+        * @return {<a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>}
         */
         _renderPanel: function() {
             var panel = null;
@@ -7059,19 +7463,18 @@
                 newXY = [(xy[0] + elXY[0]), (xy[1] + elXY[1])],
                 wWidth = (parseInt(win.attrs.width, 10) / 2),
                 align = 'center',
-                orgXY = panel.cfg.getProperty('xy'),
+                orgXY = panel.cfg.getProperty('xy') || [0,0],
                 _knob = win._knob,
                 xDiff = 0,
                 yDiff = 0,
                 anim = false;
 
+
             newXY[0] = ((newXY[0] - wWidth) + 20);
             //Account for the Scroll bars in a scrolled editor window.
             newXY[0] = newXY[0] - Dom.getDocumentScrollLeft(this._getDoc());
             newXY[1] = newXY[1] - Dom.getDocumentScrollTop(this._getDoc());
             
-
-
             if (this._isElement(this.currentElement[0], 'img')) {
                 if (this.currentElement[0].src.indexOf(this.get('blankimage')) != -1) {
                     newXY[0] = (newXY[0] + (75 / 2)); //Placeholder size
@@ -7105,6 +7508,16 @@
                 xDiff = (newXY[0] - orgXY[0]);
                 yDiff = (newXY[1] - orgXY[1]);
             } catch (e) {}
+
+
+            var iTop = elXY[1] + parseInt(this.get('height'), 10);
+            var iLeft = elXY[0] + parseInt(this.get('width'), 10);
+            if (newXY[1] > iTop) {
+                newXY[1] = iTop;
+            }
+            if (newXY[0] > iLeft) {
+                newXY[0] = (iLeft / 2);
+            }
             
             //Convert negative numbers to positive so we can get the difference in distance
             xDiff = ((xDiff < 0) ? (xDiff * -1) : xDiff);
@@ -7121,13 +7534,13 @@
                 var leftOffset = xy[0] + elXY[0] + elW;
                 _knobLeft = leftOffset - newXY[0];
                 //Check to see if the knob will go off either side & reposition it
-                if (_knobLeft > (parseInt(win.attrs.width, 10) - 40)) {
-                    _knobLeft = parseInt(win.attrs.width, 10) - 40;
+                if (_knobLeft > (parseInt(win.attrs.width, 10) - 1)) {
+                    _knobLeft = ((parseInt(win.attrs.width, 10) - 30) - 1);
                 } else if (_knobLeft < 40) {
-                    _knobLeft = 40;
+                    _knobLeft = 1;
                 }
                 if (isNaN(_knobLeft)) {
-                    _knobLeft = 40;
+                    _knobLeft = 1;
                 }
                 if (force) {
                     if (_knob) {
@@ -7553,4 +7966,4 @@
 */
 
 })();
-YAHOO.register("editor", YAHOO.widget.Editor, {version: "2.4.1", build: "742"});
+YAHOO.register("editor", YAHOO.widget.Editor, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/editor/editor-beta-min.js
===================================================================
--- trunk/root/static/yui/editor/editor-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/editor/editor-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,25 +1,26 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-(function(){var B=YAHOO.util.Dom,A=YAHOO.util.Event,C=YAHOO.lang;if(YAHOO.widget.Button){YAHOO.widget.ToolbarButtonAdvanced=YAHOO.widget.Button;YAHOO.widget.ToolbarButtonAdvanced.prototype.buttonType="rich";YAHOO.widget.ToolbarButtonAdvanced.prototype.checkValue=function(F){var E=this.getMenu().getItems();if(E.length===0){this.getMenu()._onBeforeShow();E=this.getMenu().getItems();}for(var D=0;D<E.length;D++){E[D].cfg.setProperty("checked",false);if(E[D].value==F){E[D].cfg.setProperty("checked",true);}}};}else{YAHOO.widget.ToolbarButtonAdvanced=function(){};}YAHOO.widget.ToolbarButton=function(E,D){if(C.isObject(arguments[0])&&!B.get(E).nodeType){D=E;}var G=(D||{});var F={element:null,attributes:G};if(!F.attributes.type){F.attributes.type="push";}F.element=document.createElement("span");F.element.setAttribute("unselectable","on");F.element.className="yui-button yui-"+F.attributes.type+"-button";F.element.innerHTML="<span class=\"first-child\"><a href=\"#\">LABEL</a></span>";!
 F.attributes.id=B.generateId();YAHOO.widget.ToolbarButton.superclass.constructor.call(this,F.element,F.attributes);};YAHOO.extend(YAHOO.widget.ToolbarButton,YAHOO.util.Element,{buttonType:"normal",_handleMouseOver:function(){if(!this.get("disabled")){this.addClass("yui-button-hover");this.addClass("yui-"+this.get("type")+"-button-hover");}},_handleMouseOut:function(){this.removeClass("yui-button-hover");this.removeClass("yui-"+this.get("type")+"-button-hover");},checkValue:function(F){if(this.get("type")=="menu"){var E=this._button.options;for(var D=0;D<E.length;D++){if(E[D].value==F){E.selectedIndex=D;}}}},init:function(E,D){YAHOO.widget.ToolbarButton.superclass.init.call(this,E,D);this.on("mouseover",this._handleMouseOver,this,true);this.on("mouseout",this._handleMouseOut,this,true);},initAttributes:function(D){YAHOO.widget.ToolbarButton.superclass.initAttributes.call(this,D);this.setAttributeConfig("value",{value:D.value});this.setAttributeConfig("menu",{value:D.menu||fa!
 lse});this.setAttributeConfig("type",{value:D.type,writeOnce:t!
 rue,meth
od:function(H){var G,F;if(!this._button){this._button=this.get("element").getElementsByTagName("a")[0];}switch(H){case"select":case"menu":G=document.createElement("select");var I=this.get("menu");for(var E=0;E<I.length;E++){F=document.createElement("option");F.innerHTML=I[E].text;F.value=I[E].value;if(I[E].checked){F.selected=true;}G.appendChild(F);}this._button.parentNode.replaceChild(G,this._button);A.on(G,"change",this._handleSelect,this,true);this._button=G;break;}}});this.setAttributeConfig("disabled",{value:D.disabled||false,method:function(E){if(E){this.addClass("yui-button-disabled");this.addClass("yui-"+this.get("type")+"-button-disabled");}else{this.removeClass("yui-button-disabled");this.removeClass("yui-"+this.get("type")+"-button-disabled");}if(this.get("type")=="menu"){this._button.disabled=E;}}});this.setAttributeConfig("label",{value:D.label,method:function(E){if(!this._button){this._button=this.get("element").getElementsByTagName("a")[0];}if(this.get("type")!
 =="push"){this._button.innerHTML=E;}}});this.setAttributeConfig("title",{value:D.title});this.setAttributeConfig("container",{value:null,writeOnce:true,method:function(E){this.appendTo(E);}});},_handleSelect:function(E){var D=A.getTarget(E);var F=D.options[D.selectedIndex].value;this.fireEvent("change",{type:"change",value:F});},getMenu:function(){return this.get("menu");},fireEvent:function(E,D){if(this.DOM_EVENTS[E]&&this.get("disabled")){return ;}YAHOO.widget.ToolbarButton.superclass.fireEvent.call(this,E,D);},toString:function(){return"ToolbarButton ("+this.get("id")+")";}});})();(function(){var B=YAHOO.util.Dom,A=YAHOO.util.Event,D=YAHOO.lang;YAHOO.widget.Toolbar=function(G,F){if(D.isObject(arguments[0])&&!B.get(G).nodeType){F=G;}var I=(F||{});var H={element:null,attributes:I};if(D.isString(G)&&B.get(G)){H.element=B.get(G);}else{if(D.isObject(G)&&B.get(G)&&B.get(G).nodeType){H.element=B.get(G);}}if(!H.element){H.element=document.createElement("DIV");H.element.id=B.gene!
 rateId();if(I.container&&B.get(I.container)){B.get(I.container!
 ).append
Child(H.element);}}if(!H.element.id){H.element.id=((D.isString(G))?G:B.generateId());}var E=document.createElement("DIV");H.attributes.cont=E;B.addClass(E,"yui-toolbar-subcont");H.element.appendChild(E);H.attributes.element=H.element;H.attributes.id=H.element.id;YAHOO.widget.Toolbar.superclass.constructor.call(this,H.element,H.attributes);};function C(H,E,I){B.addClass(this.element,"yui-toolbar-"+I.get("value")+"-menu");if(B.hasClass(I._button.parentNode.parentNode,"yui-toolbar-select")){B.addClass(this.element,"yui-toolbar-select-menu");}var F=this.getItems();for(var G=0;G<F.length;G++){B.addClass(F[G].element,"yui-toolbar-"+I.get("value")+"-"+((F[G].value)?F[G].value.replace(/ /g,"-").toLowerCase():F[G]._oText.nodeValue.replace(/ /g,"-").toLowerCase()));B.addClass(F[G].element,"yui-toolbar-"+I.get("value")+"-"+((F[G].value)?F[G].value.replace(/ /g,"-"):F[G]._oText.nodeValue.replace(/ /g,"-")));}}YAHOO.extend(YAHOO.widget.Toolbar,YAHOO.util.Element,{buttonType:YAHOO.widget.!
 ToolbarButton,dd:null,_colorData:{"#111111":"Obsidian","#2D2D2D":"Dark Gray","#434343":"Shale","#5B5B5B":"Flint","#737373":"Gray","#8B8B8B":"Concrete","#A2A2A2":"Gray","#B9B9B9":"Titanium","#000000":"Black","#D0D0D0":"Light Gray","#E6E6E6":"Silver","#FFFFFF":"White","#BFBF00":"Pumpkin","#FFFF00":"Yellow","#FFFF40":"Banana","#FFFF80":"Pale Yellow","#FFFFBF":"Butter","#525330":"Raw Siena","#898A49":"Mildew","#AEA945":"Olive","#7F7F00":"Paprika","#C3BE71":"Earth","#E0DCAA":"Khaki","#FCFAE1":"Cream","#60BF00":"Cactus","#80FF00":"Chartreuse","#A0FF40":"Green","#C0FF80":"Pale Lime","#DFFFBF":"Light Mint","#3B5738":"Green","#668F5A":"Lime Gray","#7F9757":"Yellow","#407F00":"Clover","#8A9B55":"Pistachio","#B7C296":"Light Jade","#E6EBD5":"Breakwater","#00BF00":"Spring Frost","#00FF80":"Pastel Green","#40FFA0":"Light Emerald","#80FFC0":"Sea Foam","#BFFFDF":"Sea Mist","#033D21":"Dark Forrest","#438059":"Moss","#7FA37C":"Medium Green","#007F40":"Pine","#8DAE94":"Yellow Gray Green","#AC!
 C6B5":"Aqua Lung","#DDEBE2":"Sea Vapor","#00BFBF":"Fog","#00FF!
 FF":"Cya
n","#40FFFF":"Turquoise Blue","#80FFFF":"Light Aqua","#BFFFFF":"Pale Cyan","#033D3D":"Dark Teal","#347D7E":"Gray Turquoise","#609A9F":"Green Blue","#007F7F":"Seaweed","#96BDC4":"Green Gray","#B5D1D7":"Soapstone","#E2F1F4":"Light Turquoise","#0060BF":"Summer Sky","#0080FF":"Sky Blue","#40A0FF":"Electric Blue","#80C0FF":"Light Azure","#BFDFFF":"Ice Blue","#1B2C48":"Navy","#385376":"Biscay","#57708F":"Dusty Blue","#00407F":"Sea Blue","#7792AC":"Sky Blue Gray","#A8BED1":"Morning Sky","#DEEBF6":"Vapor","#0000BF":"Deep Blue","#0000FF":"Blue","#4040FF":"Cerulean Blue","#8080FF":"Evening Blue","#BFBFFF":"Light Blue","#212143":"Deep Indigo","#373E68":"Sea Blue","#444F75":"Night Blue","#00007F":"Indigo Blue","#585E82":"Dockside","#8687A4":"Blue Gray","#D2D1E1":"Light Blue Gray","#6000BF":"Neon Violet","#8000FF":"Blue Violet","#A040FF":"Violet Purple","#C080FF":"Violet Dusk","#DFBFFF":"Pale Lavender","#302449":"Cool Shale","#54466F":"Dark Indigo","#655A7F":"Dark Violet","#40007F":"Viol!
 et","#726284":"Smoky Violet","#9E8FA9":"Slate Gray","#DCD1DF":"Violet White","#BF00BF":"Royal Violet","#FF00FF":"Fuchsia","#FF40FF":"Magenta","#FF80FF":"Orchid","#FFBFFF":"Pale Magenta","#4A234A":"Dark Purple","#794A72":"Medium Purple","#936386":"Cool Granite","#7F007F":"Purple","#9D7292":"Purple Moon","#C0A0B6":"Pale Purple","#ECDAE5":"Pink Cloud","#BF005F":"Hot Pink","#FF007F":"Deep Pink","#FF409F":"Grape","#FF80BF":"Electric Pink","#FFBFDF":"Pink","#451528":"Purple Red","#823857":"Purple Dino","#A94A76":"Purple Gray","#7F003F":"Rose","#BC6F95":"Antique Mauve","#D8A5BB":"Cool Marble","#F7DDE9":"Pink Granite","#C00000":"Apple","#FF0000":"Fire Truck","#FF4040":"Pale Red","#FF8080":"Salmon","#FFC0C0":"Warm Pink","#441415":"Sepia","#82393C":"Rust","#AA4D4E":"Brick","#800000":"Brick Red","#BC6E6E":"Mauve","#D8A3A4":"Shrimp Pink","#F8DDDD":"Shell Pink","#BF5F00":"Dark Orange","#FF7F00":"Orange","#FF9F40":"Grapefruit","#FFBF80":"Canteloupe","#FFDFBF":"Wax","#482C1B":"Dark Brick"!
 ,"#855A40":"Dirt","#B27C51":"Tan","#7F3F00":"Nutmeg","#C49B71"!
 :"Mustar
d","#E1C4A8":"Pale Tan","#FDEEE0":"Marble"},_colorPicker:null,STR_COLLAPSE:"Collapse Toolbar",STR_SPIN_LABEL:"Spin Button with value {VALUE}. Use Control Shift Up Arrow and Control Shift Down arrow keys to increase or decrease the value.",STR_SPIN_UP:"Click to increase the value of this input",STR_SPIN_DOWN:"Click to decrease the value of this input",_titlebar:null,browser:YAHOO.env.ua,_buttonList:null,_buttonGroupList:null,_sep:null,_sepCount:null,_dragHandle:null,_toolbarConfigs:{renderer:true},CLASS_CONTAINER:"yui-toolbar-container",CLASS_DRAGHANDLE:"yui-toolbar-draghandle",CLASS_SEPARATOR:"yui-toolbar-separator",CLASS_DISABLED:"yui-toolbar-disabled",CLASS_PREFIX:"yui-toolbar",init:function(F,E){YAHOO.widget.Toolbar.superclass.init.call(this,F,E);
-},initAttributes:function(E){YAHOO.widget.Toolbar.superclass.initAttributes.call(this,E);this.addClass(this.CLASS_CONTAINER);this.setAttributeConfig("buttonType",{value:E.buttonType||"basic",writeOnce:true,validator:function(F){switch(F){case"advanced":case"basic":return true;}return false;},method:function(F){if(F=="advanced"){if(YAHOO.widget.Button){this.buttonType=YAHOO.widget.ToolbarButtonAdvanced;}else{this.buttonType=YAHOO.widget.ToolbarButton;}}else{this.buttonType=YAHOO.widget.ToolbarButton;}}});this.setAttributeConfig("buttons",{value:[],writeOnce:true,method:function(G){for(var F in G){if(D.hasOwnProperty(G,F)){if(G[F].type=="separator"){this.addSeparator();}else{if(G[F].group!==undefined){this.addButtonGroup(G[F]);}else{this.addButton(G[F]);}}}}}});this.setAttributeConfig("disabled",{value:false,method:function(F){if(this.get("disabled")===F){return false;}if(F){this.addClass(this.CLASS_DISABLED);this.set("draggable",false);this.disableAllButtons();}else{this.rem!
 oveClass(this.CLASS_DISABLED);if(this._configs.draggable._initialConfig.value){this.set("draggable",true);}this.resetAllButtons();}}});this.setAttributeConfig("cont",{value:E.cont,readOnly:true});this.setAttributeConfig("grouplabels",{value:E.grouplabels||true,method:function(F){if(F){B.removeClass(this.get("cont"),(this.CLASS_PREFIX+"-nogrouplabels"));}else{B.addClass(this.get("cont"),(this.CLASS_PREFIX+"-nogrouplabels"));}}});this.setAttributeConfig("titlebar",{value:false,method:function(G){if(G){if(this._titlebar&&this._titlebar.parentNode){this._titlebar.parentNode.removeChild(this._titlebar);}this._titlebar=document.createElement("DIV");B.addClass(this._titlebar,this.CLASS_PREFIX+"-titlebar");if(D.isString(G)){var F=document.createElement("h2");F.tabIndex="-1";F.innerHTML=G;this._titlebar.appendChild(F);}if(this.get("firstChild")){this.insertBefore(this._titlebar,this.get("firstChild"));}else{this.appendChild(this._titlebar);}if(this.get("collapse")){this.set("collaps!
 e",true);}}else{if(this._titlebar){if(this._titlebar&&this._ti!
 tlebar.p
arentNode){this._titlebar.parentNode.removeChild(this._titlebar);}}}}});this.setAttributeConfig("collapse",{value:false,method:function(H){var G=null;var F=B.getElementsByClassName("collapse","span",this._titlebar);if(H){if(F.length>0){return true;}G=document.createElement("SPAN");G.innerHTML="X";G.title=this.STR_COLLAPSE;B.addClass(G,"collapse");this._titlebar.appendChild(G);A.addListener(G,"click",function(){if(B.hasClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed")){this.collapse(false);}else{this.collapse();}},this,true);}else{G=B.getElementsByClassName("collapse","span",this._titlebar);if(G[0]){if(B.hasClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed")){this.collapse(false);}G[0].parentNode.removeChild(G[0]);}}}});this.setAttributeConfig("draggable",{value:(E.draggable||false),method:function(F){if(F&&!this.get("titlebar")){if(!this._dragHandle){this._dragHandle=document.createElement("SPAN");this._dragHandle.innerHTML="|";this._dragH!
 andle.setAttribute("title","Click to drag the toolbar");this._dragHandle.id=this.get("id")+"_draghandle";B.addClass(this._dragHandle,this.CLASS_DRAGHANDLE);if(this.get("cont").hasChildNodes()){this.get("cont").insertBefore(this._dragHandle,this.get("cont").firstChild);}else{this.get("cont").appendChild(this._dragHandle);}this.dd=new YAHOO.util.DD(this.get("id"));this.dd.setHandleElId(this._dragHandle.id);}}else{if(this._dragHandle){this._dragHandle.parentNode.removeChild(this._dragHandle);this._dragHandle=null;this.dd=null;}}if(this._titlebar){if(F){this.dd=new YAHOO.util.DD(this.get("id"));this.dd.setHandleElId(this._titlebar);B.addClass(this._titlebar,"draggable");}else{B.removeClass(this._titlebar,"draggable");if(this.dd){this.dd.unreg();this.dd=null;}}}},validator:function(G){var F=true;if(!YAHOO.util.DD){F=false;}return F;}});},addButtonGroup:function(I){if(!this.get("element")){this._queue[this._queue.length]=["addButtonGroup",arguments];return false;}if(!this.hasClas!
 s(this.CLASS_PREFIX+"-grouped")){this.addClass(this.CLASS_PREF!
 IX+"-gro
uped");}var J=document.createElement("DIV");B.addClass(J,this.CLASS_PREFIX+"-group");B.addClass(J,this.CLASS_PREFIX+"-group-"+I.group);if(I.label){var F=document.createElement("h3");F.innerHTML=I.label;J.appendChild(F);}if(!this.get("grouplabels")){B.addClass(this.get("cont"),this.CLASS_PREFIX,"-nogrouplabels");}this.get("cont").appendChild(J);var H=document.createElement("ul");J.appendChild(H);if(!this._buttonGroupList){this._buttonGroupList={};}this._buttonGroupList[I.group]=H;for(var G=0;G<I.buttons.length;G++){var E=document.createElement("li");E.className=this.CLASS_PREFIX+"-groupitem";H.appendChild(E);if((I.buttons[G].type!==undefined)&&I.buttons[G].type=="separator"){this.addSeparator(E);}else{I.buttons[G].container=E;this.addButton(I.buttons[G]);}}},addButtonToGroup:function(G,H,I){var F=this._buttonGroupList[H];var E=document.createElement("li");E.className=this.CLASS_PREFIX+"-groupitem";G.container=E;this.addButton(G,I);F.appendChild(E);},addButton:function(J,I){if!
 (!this.get("element")){this._queue[this._queue.length]=["addButton",arguments];return false;}if(!this._buttonList){this._buttonList=[];}if(!J.container){J.container=this.get("cont");}if((J.type=="menu")||(J.type=="split")||(J.type=="select")){if(D.isArray(J.menu)){for(var P in J.menu){if(D.hasOwnProperty(J.menu,P)){var V={fn:function(Y,W,X){if(!J.menucmd){J.menucmd=J.value;}J.value=((X.value)?X.value:X._oText.nodeValue);},scope:this};J.menu[P].onclick=V;}}}}var Q={},N=false;for(var L in J){if(D.hasOwnProperty(J,L)){if(!this._toolbarConfigs[L]){Q[L]=J[L];}}}if(J.type=="select"){Q.type="menu";}if(J.type=="spin"){Q.type="push";}if(Q.type=="color"){if(YAHOO.widget.Overlay){Q=this._makeColorButton(Q);}else{N=true;}}if(Q.menu){if((YAHOO.widget.Overlay)&&(J.menu instanceof YAHOO.widget.Overlay)){J.menu.showEvent.subscribe(function(){this._button=Q;});}else{for(var O=0;O<Q.menu.length;O++){if(!Q.menu[O].value){Q.menu[O].value=Q.menu[O].text;
-}}if(this.browser.webkit){Q.focusmenu=false;}}}if(N){J=false;}else{this._configs.buttons.value[this._configs.buttons.value.length]=J;var T=new this.buttonType(Q);if(!T.buttonType){T.buttonType="rich";T.checkValue=function(Y){var X=this.getMenu().getItems();if(X.length===0){this.getMenu()._onBeforeShow();X=this.getMenu().getItems();}for(var W=0;W<X.length;W++){X[W].cfg.setProperty("checked",false);if(X[W].value==Y){X[W].cfg.setProperty("checked",true);}}};}if(this.get("disabled")){T.set("disabled",true);}if(!J.id){J.id=T.get("id");}if(I){var F=T.get("element");var M=null;if(I.get){M=I.get("element").nextSibling;}else{if(I.nextSibling){M=I.nextSibling;}}if(M){M.parentNode.insertBefore(F,M);}}T.addClass(this.CLASS_PREFIX+"-"+T.get("value"));var S=document.createElement("span");S.className=this.CLASS_PREFIX+"-icon";T.get("element").insertBefore(S,T.get("firstChild"));if(T._button.tagName.toLowerCase()=="button"){T.get("element").setAttribute("unselectable","on");var U=document.!
 createElement("a");U.innerHTML=T._button.innerHTML;U.href="#";A.on(U,"click",function(W){A.stopEvent(W);});T._button.parentNode.replaceChild(U,T._button);T._button=U;}if(J.type=="select"){if(T._button.tagName.toLowerCase()=="select"){S.parentNode.removeChild(S);var G=T._button;var R=T.get("element");R.parentNode.replaceChild(G,R);}else{T.addClass(this.CLASS_PREFIX+"-select");}}if(J.type=="spin"){if(!D.isArray(J.range)){J.range=[10,100];}this._makeSpinButton(T,J);}T.get("element").setAttribute("title",T.get("label"));if(J.type!="spin"){if((YAHOO.widget.Overlay)&&(Q.menu instanceof YAHOO.widget.Overlay)){var H=function(Y){var W=true;if(Y.keyCode&&(Y.keyCode==9)){W=false;}if(W){this._colorPicker._button=J.value;var X=T.getMenu().element;if(B.getStyle(X,"visibility")=="hidden"){T.getMenu().show();}else{T.getMenu().hide();}}YAHOO.util.Event.stopEvent(Y);};T.on("mousedown",H,J,this);T.on("keydown",H,J,this);}else{if((J.type!="menu")&&(J.type!="select")){T.on("keypress",this._butt!
 onClick,J,this);T.on("mousedown",function(W){YAHOO.util.Event.!
 stopEven
t(W);this._buttonClick(W,J);},J,this);T.on("click",function(W){YAHOO.util.Event.stopEvent(W);});}else{T.on("mousedown",function(W){YAHOO.util.Event.stopEvent(W);});T.on("click",function(W){YAHOO.util.Event.stopEvent(W);});T.on("change",function(W){if(!J.menucmd){J.menucmd=J.value;}J.value=W.value;this._buttonClick(W,J);},this,true);var K=this;if(T.getMenu().mouseDownEvent){T.getMenu().mouseDownEvent.subscribe(function(Y,X){var W=X[1];YAHOO.util.Event.stopEvent(X[0]);T._onMenuClick(X[0],T);if(!J.menucmd){J.menucmd=J.value;}J.value=((W.value)?W.value:W._oText.nodeValue);K._buttonClick.call(K,X[1],J);T._hideMenu();return false;});T.getMenu().clickEvent.subscribe(function(X,W){YAHOO.util.Event.stopEvent(W[0]);});T.getMenu().mouseUpEvent.subscribe(function(X,W){YAHOO.util.Event.stopEvent(W[0]);});}}}}else{T.on("mousedown",function(W){YAHOO.util.Event.stopEvent(W);});T.on("click",function(W){YAHOO.util.Event.stopEvent(W);});}if(this.browser.ie){T.DOM_EVENTS.focusin=true;T.DOM_EVEN!
 TS.focusout=true;T.on("focusin",function(W){YAHOO.util.Event.stopEvent(W);},J,this);T.on("focusout",function(W){YAHOO.util.Event.stopEvent(W);},J,this);T.on("click",function(W){YAHOO.util.Event.stopEvent(W);},J,this);}if(this.browser.webkit){T.hasFocus=function(){return true;};}this._buttonList[this._buttonList.length]=T;if((J.type=="menu")||(J.type=="split")||(J.type=="select")){if(D.isArray(J.menu)){var E=T.getMenu();if(E.renderEvent){E.renderEvent.subscribe(C,T);if(J.renderer){E.renderEvent.subscribe(J.renderer,T);}}}}}return J;},addSeparator:function(E,H){if(!this.get("element")){this._queue[this._queue.length]=["addSeparator",arguments];return false;}var F=((E)?E:this.get("cont"));if(!this.get("element")){this._queue[this._queue.length]=["addSeparator",arguments];return false;}if(this._sepCount===null){this._sepCount=0;}if(!this._sep){this._sep=document.createElement("SPAN");B.addClass(this._sep,this.CLASS_SEPARATOR);this._sep.innerHTML="|";}var G=this._sep.cloneNode(t!
 rue);this._sepCount++;B.addClass(G,this.CLASS_SEPARATOR+"-"+th!
 is._sepC
ount);if(H){var I=null;if(H.get){I=H.get("element").nextSibling;}else{if(H.nextSibling){I=H.nextSibling;}else{I=H;}}if(I){if(I==H){I.parentNode.appendChild(G);}else{I.parentNode.insertBefore(G,I);}}}else{F.appendChild(G);}return G;},_createColorPicker:function(J){if(B.get(J+"_colors")){B.get(J+"_colors").parentNode.removeChild(B.get(J+"_colors"));}var F=document.createElement("div");F.className="yui-toolbar-colors";F.id=J+"_colors";F.style.display="none";A.on(window,"load",function(){document.body.appendChild(F);},this,true);this._colorPicker=F;var I="";for(var H in this._colorData){if(D.hasOwnProperty(this._colorData,H)){I+="<a style=\"background-color: "+H+"\" href=\"#\">"+H.replace("#","")+"</a>";}}I+="<span><em>X</em><strong></strong></span>";F.innerHTML=I;var G=F.getElementsByTagName("em")[0];var E=F.getElementsByTagName("strong")[0];A.on(F,"mouseover",function(L){var K=A.getTarget(L);if(K.tagName.toLowerCase()=="a"){G.style.backgroundColor=K.style.backgroundColor;E.inn!
 erHTML=this._colorData["#"+K.innerHTML]+"<br>"+K.innerHTML;}},this,true);A.on(F,"focus",function(K){A.stopEvent(K);});A.on(F,"click",function(K){A.stopEvent(K);});A.on(F,"mousedown",function(L){A.stopEvent(L);var K=A.getTarget(L);if(K.tagName.toLowerCase()=="a"){this.fireEvent("colorPickerClicked",{type:"colorPickerClicked",target:this,button:this._colorPicker._button,color:K.innerHTML,colorName:this._colorData["#"+K.innerHTML]});this.getButtonByValue(this._colorPicker._button).getMenu().hide();}},this,true);},_resetColorPicker:function(){var F=this._colorPicker.getElementsByTagName("em")[0];var E=this._colorPicker.getElementsByTagName("strong")[0];F.style.backgroundColor="transparent";E.innerHTML="";},_makeColorButton:function(E){if(!this._colorPicker){this._createColorPicker(this.get("id"));}E.type="color";E.menu=new YAHOO.widget.Overlay(this.get("id")+"_"+E.value+"_menu",{visible:false,position:"absolute",iframe:true});
-E.menu.setBody("");E.menu.render(this.get("cont"));B.addClass(E.menu.element,"yui-button-menu");B.addClass(E.menu.element,"yui-color-button-menu");E.menu.beforeShowEvent.subscribe(function(){E.menu.cfg.setProperty("zindex",5);E.menu.cfg.setProperty("context",[this.getButtonById(E.id).get("element"),"tl","bl"]);this._resetColorPicker();var F=this._colorPicker;if(F.parentNode){F.parentNode.removeChild(F);}E.menu.setBody("");E.menu.appendToBody(F);this._colorPicker.style.display="block";},this,true);return E;},_makeSpinButton:function(R,L){R.addClass(this.CLASS_PREFIX+"-spinbutton");var S=this,N=R._button.parentNode.parentNode,I=L.range,H=document.createElement("a"),G=document.createElement("a");H.href="#";G.href="#";H.className="up";H.title=this.STR_SPIN_UP;H.innerHTML=this.STR_SPIN_UP;G.className="down";G.title=this.STR_SPIN_DOWN;G.innerHTML=this.STR_SPIN_DOWN;N.appendChild(H);N.appendChild(G);var M=YAHOO.lang.substitute(this.STR_SPIN_LABEL,{VALUE:R.get("label")});R.set("tit!
 le",M);var Q=function(T){T=((T<I[0])?I[0]:T);T=((T>I[1])?I[1]:T);return T;};var P=this.browser;var F=false;var K=this.STR_SPIN_LABEL;if(this._titlebar&&this._titlebar.firstChild){F=this._titlebar.firstChild;}var E=function(U){YAHOO.util.Event.stopEvent(U);if(!R.get("disabled")&&(U.keyCode!=9)){var V=parseInt(R.get("label"),10);V++;V=Q(V);R.set("label",""+V);var T=YAHOO.lang.substitute(K,{VALUE:R.get("label")});R.set("title",T);if(!P.webkit&&F){}S._buttonClick(U,L);}};var O=function(U){YAHOO.util.Event.stopEvent(U);if(!R.get("disabled")&&(U.keyCode!=9)){var V=parseInt(R.get("label"),10);V--;V=Q(V);R.set("label",""+V);var T=YAHOO.lang.substitute(K,{VALUE:R.get("label")});R.set("title",T);if(!P.webkit&&F){}S._buttonClick(U,L);}};var J=function(T){if(T.keyCode==38){E(T);}else{if(T.keyCode==40){O(T);}else{if(T.keyCode==107&&T.shiftKey){E(T);}else{if(T.keyCode==109&&T.shiftKey){O(T);}}}}};R.on("keydown",J,this,true);A.on(H,"mousedown",function(T){A.stopEvent(T);},this,true);A.on(!
 G,"mousedown",function(T){A.stopEvent(T);},this,true);A.on(H,"!
 click",E
,this,true);A.on(G,"click",O,this,true);},_buttonClick:function(L,F){var E=true;if(L&&L.type=="keypress"){if(L.keyCode==9){E=false;}else{if((L.keyCode===13)||(L.keyCode===0)||(L.keyCode===32)){}else{E=false;}}}if(E){var N=true,H=false;if(F.value){H=this.fireEvent(F.value+"Click",{type:F.value+"Click",target:this.get("element"),button:F});if(H===false){N=false;}}if(F.menucmd&&N){H=this.fireEvent(F.menucmd+"Click",{type:F.menucmd+"Click",target:this.get("element"),button:F});if(H===false){N=false;}}if(N){this.fireEvent("buttonClick",{type:"buttonClick",target:this.get("element"),button:F});}if(F.type=="select"){var K=this.getButtonById(F.id);if(K.buttonType=="rich"){var J=F.value;for(var I=0;I<F.menu.length;I++){if(F.menu[I].value==F.value){J=F.menu[I].text;break;}}K.set("label","<span class=\"yui-toolbar-"+F.menucmd+"-"+(F.value).replace(/ /g,"-").toLowerCase()+"\">"+J+"</span>");var M=K.getMenu().getItems();for(var G=0;G<M.length;G++){if(M[G].value.toLowerCase()==F.value.toL!
 owerCase()){M[G].cfg.setProperty("checked",true);}else{M[G].cfg.setProperty("checked",false);}}}}}if(L){A.stopEvent(L);}},getButtonById:function(G){var E=this._buttonList.length;for(var F=0;F<E;F++){if(this._buttonList[F].get("id")==G){return this._buttonList[F];}}return false;},getButtonByValue:function(K){var H=this.get("buttons");var F=H.length;for(var I=0;I<F;I++){if(H[I].group!==undefined){for(var E=0;E<H[I].buttons.length;E++){if((H[I].buttons[E].value==K)||(H[I].buttons[E].menucmd==K)){return this.getButtonById(H[I].buttons[E].id);}if(H[I].buttons[E].menu){for(var J=0;J<H[I].buttons[E].menu.length;J++){if(H[I].buttons[E].menu[J].value==K){return this.getButtonById(H[I].buttons[E].id);}}}}}else{if((H[I].value==K)||(H[I].menucmd==K)){return this.getButtonById(H[I].id);}if(H[I].menu){for(var G=0;G<H[I].menu.length;G++){if(H[I].menu[G].value==K){return this.getButtonById(H[I].id);}}}}}return false;},getButtonByIndex:function(E){if(this._buttonList[E]){return this._button!
 List[E];}else{return false;}},getButtons:function(){return thi!
 s._butto
nList;},disableButton:function(F){var E=F;if(D.isString(F)){E=this.getButtonById(F);}if(D.isNumber(F)){E=this.getButtonByIndex(F);}if((!(E instanceof YAHOO.widget.ToolbarButton))&&(!(E instanceof YAHOO.widget.ToolbarButtonAdvanced))){E=this.getButtonByValue(F);}if((E instanceof YAHOO.widget.ToolbarButton)||(E instanceof YAHOO.widget.ToolbarButtonAdvanced)){E.set("disabled",true);}else{return false;}},enableButton:function(F){if(this.get("disabled")){return false;}var E=F;if(D.isString(F)){E=this.getButtonById(F);}if(D.isNumber(F)){E=this.getButtonByIndex(F);}if((!(E instanceof YAHOO.widget.ToolbarButton))&&(!(E instanceof YAHOO.widget.ToolbarButtonAdvanced))){E=this.getButtonByValue(F);}if((E instanceof YAHOO.widget.ToolbarButton)||(E instanceof YAHOO.widget.ToolbarButtonAdvanced)){if(E.get("disabled")){E.set("disabled",false);}}else{return false;}},selectButton:function(I,G){var F=I;if(I){if(D.isString(I)){F=this.getButtonById(I);}if(D.isNumber(I)){F=this.getButtonByIndex(I!
 );}if((!(F instanceof YAHOO.widget.ToolbarButton))&&(!(F instanceof YAHOO.widget.ToolbarButtonAdvanced))){F=this.getButtonByValue(I);}if((F instanceof YAHOO.widget.ToolbarButton)||(F instanceof YAHOO.widget.ToolbarButtonAdvanced)){F.addClass("yui-button-selected");F.addClass("yui-button-"+F.get("value")+"-selected");if(G){if(F.buttonType=="rich"){var H=F.getMenu().getItems();for(var E=0;E<H.length;E++){if(H[E].value==G){H[E].cfg.setProperty("checked",true);F.set("label","<span class=\"yui-toolbar-"+F.get("value")+"-"+(G).replace(/ /g,"-").toLowerCase()+"\">"+H[E]._oText.nodeValue+"</span>");}else{H[E].cfg.setProperty("checked",false);}}}}}else{return false;}}},deselectButton:function(F){var E=F;if(D.isString(F)){E=this.getButtonById(F);}if(D.isNumber(F)){E=this.getButtonByIndex(F);}if((!(E instanceof YAHOO.widget.ToolbarButton))&&(!(E instanceof YAHOO.widget.ToolbarButtonAdvanced))){E=this.getButtonByValue(F);
-}if((E instanceof YAHOO.widget.ToolbarButton)||(E instanceof YAHOO.widget.ToolbarButtonAdvanced)){E.removeClass("yui-button-selected");E.removeClass("yui-button-"+E.get("value")+"-selected");E.removeClass("yui-button-hover");}else{return false;}},deselectAllButtons:function(){var E=this._buttonList.length;for(var F=0;F<E;F++){this.deselectButton(this._buttonList[F]);}},disableAllButtons:function(){if(this.get("disabled")){return false;}var E=this._buttonList.length;for(var F=0;F<E;F++){this.disableButton(this._buttonList[F]);}},enableAllButtons:function(){if(this.get("disabled")){return false;}var E=this._buttonList.length;for(var F=0;F<E;F++){this.enableButton(this._buttonList[F]);}},resetAllButtons:function(I){if(!D.isObject(I)){I={};}if(this.get("disabled")){return false;}var E=this._buttonList.length;for(var F=0;F<E;F++){var H=this._buttonList[F];var G=H._configs.disabled._initialConfig.value;if(I[H.get("id")]){this.enableButton(H);this.selectButton(H);}else{if(G){this.!
 disableButton(H);}else{this.enableButton(H);}this.deselectButton(H);}}},destroyButton:function(I){var G=I;if(D.isString(I)){G=this.getButtonById(I);}if(D.isNumber(I)){G=this.getButtonByIndex(I);}if((!(G instanceof YAHOO.widget.ToolbarButton))&&(!(G instanceof YAHOO.widget.ToolbarButtonAdvanced))){G=this.getButtonByValue(I);}if((G instanceof YAHOO.widget.ToolbarButton)||(G instanceof YAHOO.widget.ToolbarButtonAdvanced)){var H=G.get("id");G.destroy();var E=this._buttonList.length;for(var F=0;F<E;F++){if(this._buttonList[F].get("id")==H){this._buttonList[F]=null;}}}else{return false;}},destroy:function(){this.get("element").innerHTML="";this.get("element").className="";for(var E in this){if(D.hasOwnProperty(this,E)){this[E]=null;}}return true;},collapse:function(F){var E=B.getElementsByClassName("collapse","span",this._titlebar);if(F===false){B.removeClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed");if(E[0]){B.removeClass(E[0],"collapsed");}this.fireEvent("t!
 oolbarExpanded",{type:"toolbarExpanded",target:this});}else{if!
 (E[0]){B
.addClass(E[0],"collapsed");}B.addClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed");this.fireEvent("toolbarCollapsed",{type:"toolbarCollapsed",target:this});}},toString:function(){return"Toolbar (#"+this.get("element").id+") with "+this._buttonList.length+" buttons.";}});})();(function(){var C=YAHOO.util.Dom,A=YAHOO.util.Event,D=YAHOO.lang,B=YAHOO.widget.Toolbar;YAHOO.widget.SimpleEditor=function(H,F){var J={element:null,attributes:(F||{})},L=null;if(D.isString(H)){L=H;}else{L=H.id;}J.element=H;var G=document.createElement("DIV");J.attributes.element_cont=new YAHOO.util.Element(G,{id:L+"_container"});var K=document.createElement("div");C.addClass(K,"first-child");J.attributes.element_cont.appendChild(K);if(!J.attributes.toolbar_cont){J.attributes.toolbar_cont=document.createElement("DIV");J.attributes.toolbar_cont.id=L+"_toolbar";K.appendChild(J.attributes.toolbar_cont);}var I=document.createElement("DIV");K.appendChild(I);J.attributes.editor_wrapper=I;YAH!
 OO.widget.SimpleEditor.superclass.constructor.call(this,J.element,J.attributes);};function E(F){return F.replace(/ /g,"-").toLowerCase();}YAHOO.extend(YAHOO.widget.SimpleEditor,YAHOO.util.Element,{_docType:"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">",editorDirty:false,_defaultCSS:"html { height: 95%; } body { height: 100%; padding: 7px; background-color: #fff; font:13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a { color: blue; text-decoration: underline; cursor: pointer; } .warning-localfile { border-bottom: 1px dashed red !important; } .yui-busy { cursor: wait !important; } img.selected { border: 2px dotted #808080; } img { cursor: pointer !important; border: none; }",_defaultToolbar:{collapse:true,titlebar:"Text Editing Tools",draggable:false,buttons:[{group:"fontstyle",label:"Font Name and Size",buttons:[{type:"select",label:"Arial",value:"fontname",disabled:true,menu:[{text:"Arial",checke!
 d:true},{text:"Arial Black"},{text:"Comic Sans MS"},{text:"Cou!
 rier New
"},{text:"Lucida Console"},{text:"Tahoma"},{text:"Times New Roman"},{text:"Trebuchet MS"},{text:"Verdana"}]},{type:"spin",label:"13",value:"fontsize",range:[9,75],disabled:true}]},{type:"separator"},{group:"textstyle",label:"Font Style",buttons:[{type:"push",label:"Bold CTRL + SHIFT + B",value:"bold"},{type:"push",label:"Italic CTRL + SHIFT + I",value:"italic"},{type:"push",label:"Underline CTRL + SHIFT + U",value:"underline"},{type:"separator"},{type:"color",label:"Font Color",value:"forecolor",disabled:true},{type:"color",label:"Background Color",value:"backcolor",disabled:true}]},{type:"separator"},{group:"indentlist",label:"Lists",buttons:[{type:"push",label:"Create an Unordered List",value:"insertunorderedlist"},{type:"push",label:"Create an Ordered List",value:"insertorderedlist"}]},{type:"separator"},{group:"insertitem",label:"Insert Item",buttons:[{type:"push",label:"HTML Link CTRL + SHIFT + L",value:"createlink",disabled:true},{type:"push",label:"Insert Image",value!
 :"insertimage"}]}]},_lastButton:null,_baseHREF:function(){var F=document.location.href;if(F.indexOf("?")!==-1){F=F.substring(0,F.indexOf("?"));}F=F.substring(0,F.lastIndexOf("/"))+"/";return F;}(),_lastImage:null,_blankImageLoaded:false,_fixNodesTimer:null,_nodeChangeTimer:null,_lastNodeChangeEvent:null,_lastNodeChange:0,_rendered:false,DOMReady:null,_selection:null,_mask:null,_showingHiddenElements:null,currentWindow:null,currentEvent:null,operaEvent:null,currentFont:null,currentElement:[],dompath:null,beforeElement:null,afterElement:null,invalidHTML:{form:true,input:true,button:true,select:true,link:true,html:true,body:true,script:true,style:true,textarea:true},toolbar:null,_contentTimer:null,_contentTimerCounter:0,_disabled:["createlink","fontname","fontsize","forecolor","backcolor"],_alwaysDisabled:{},_alwaysEnabled:{},_semantic:{"bold":true,"italic":true,"underline":true},_tag2cmd:{"b":"bold","strong":"bold","i":"italic","em":"italic","u":"underline","sup":"superscript!
 ","sub":"subscript","img":"insertimage","a":"createlink","ul":!
 "insertu
norderedlist","ol":"insertorderedlist"},_createIframe:function(){var J=document.createElement("iframe");
-J.id=this.get("id")+"_editor";var H={border:"0",frameBorder:"0",marginWidth:"0",marginHeight:"0",leftMargin:"0",topMargin:"0",allowTransparency:"true",width:"100%"};for(var I in H){if(D.hasOwnProperty(H,I)){J.setAttribute(I,H[I]);}}var G="javascript:;";if(this.browser.ie){if(window.location.href.toLowerCase().indexOf("https")!==0){G="about:blank";}}J.setAttribute("src",G);var F=new YAHOO.util.Element(J);return F;},_isElement:function(G,F){if(G&&G.tagName&&(G.tagName.toLowerCase()==F)){return true;}if(G&&G.getAttribute&&(G.getAttribute("tag")==F)){return true;}return false;},_hasParent:function(G,F){if(!G||!G.parentNode){return false;}while(G.parentNode){if(this._isElement(G,F)){return G;}if(G.parentNode){G=G.parentNode;}else{return false;}}return false;},_getDoc:function(){var F=false;if(this.get){if(this.get("iframe")){if(this.get("iframe").get){if(this.get("iframe").get("element")){try{if(this.get("iframe").get("element").contentWindow){if(this.get("iframe").get("element"!
 ).contentWindow.document){F=this.get("iframe").get("element").contentWindow.document;return F;}}}catch(G){}}}}}return false;},_getWindow:function(){return this.get("iframe").get("element").contentWindow;},_focusWindow:function(F){if(this.browser.webkit){if(F){this._getSelection().setBaseAndExtent(this._getDoc().body.firstChild,0,this._getDoc().body.firstChild,1);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(false);}}else{this._getSelection().setBaseAndExtent(this._getDoc().body,1,this._getDoc().body,1);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(false);}}this._getWindow().focus();}else{this._getWindow().focus();}},_hasSelection:function(){var H=this._getSelection();var F=this._getRange();var G=false;if(this.browser.ie||this.browser.opera){if(F.text){G=true;}if(F.html){G=true;}}else{if(this.browser.webkit){if(H+""!==""){G=true;}}else{if(H&&(H.toString()!=="")&&(H!==u!
 ndefined)){G=true;}}}return G;},_getSelection:function(){var F!
 =null;if
(this._getDoc()&&this._getWindow()){if(this._getDoc().selection){F=this._getDoc().selection;}else{F=this._getWindow().getSelection();}if(this.browser.webkit){if(F.baseNode){this._selection={};this._selection.baseNode=F.baseNode;this._selection.baseOffset=F.baseOffset;this._selection.extentNode=F.extentNode;this._selection.extentOffset=F.extentOffset;}else{if(this._selection!==null){F=this._getWindow().getSelection();F.setBaseAndExtent(this._selection.baseNode,this._selection.baseOffset,this._selection.extentNode,this._selection.extentOffset);this._selection=null;}}}}return F;},_selectNode:function(G){if(!G){return false;}var H=this._getSelection(),F=null;if(this.browser.ie){try{F=this._getDoc().body.createTextRange();F.moveToElementText(G);F.select();}catch(I){}}else{if(this.browser.webkit){H.setBaseAndExtent(G,0,G,G.innerText.length);}else{if(this.browser.opera){H=this._getWindow().getSelection();F=this._getDoc().createRange();F.selectNode(G);H.removeAllRanges();H.addRange(!
 F);}else{F=this._getDoc().createRange();F.selectNodeContents(G);H.removeAllRanges();H.addRange(F);}}}},_getRange:function(){var F=this._getSelection();if(F===null){return null;}if(this.browser.webkit&&!F.getRangeAt){var H=this._getDoc().createRange();try{H.setStart(F.anchorNode,F.anchorOffset);H.setEnd(F.focusNode,F.focusOffset);}catch(G){H=this._getWindow().getSelection()+"";}return H;}if(this.browser.ie||this.browser.opera){return F.createRange();}if(F.rangeCount>0){return F.getRangeAt(0);}return null;},_setDesignMode:function(F){try{this._getDoc().designMode=F;}catch(G){}},_toggleDesignMode:function(){var G=this._getDoc().designMode.toLowerCase(),F="on";if(G=="on"){F="off";}this._setDesignMode(F);return F;},_initEditor:function(){if(this.browser.ie){this._getDoc().body.style.margin="0";}if(!this.get("disabled")){this._setDesignMode("on");}this.toolbar.on("buttonClick",this._handleToolbarClick,this,true);A.on(this._getDoc(),"mouseup",this._handleMouseUp,this,true);A.on(th!
 is._getDoc(),"mousedown",this._handleMouseDown,this,true);A.on!
 (this._g
etDoc(),"click",this._handleClick,this,true);A.on(this._getDoc(),"dblclick",this._handleDoubleClick,this,true);A.on(this._getDoc(),"keypress",this._handleKeyPress,this,true);A.on(this._getDoc(),"keyup",this._handleKeyUp,this,true);A.on(this._getDoc(),"keydown",this._handleKeyDown,this,true);if(!this.get("disabled")){this.toolbar.set("disabled",false);}this.fireEvent("editorContentLoaded",{type:"editorLoaded",target:this});if(this.get("dompath")){var F=this;setTimeout(function(){F._writeDomPath.call(F);},150);}this.nodeChange(true);this._setBusy(true);},_checkLoaded:function(){this._contentTimerCounter++;if(this._contentTimer){clearTimeout(this._contentTimer);}if(this._contentTimerCounter>250){return false;}var H=false;try{if(this._getDoc()&&this._getDoc().body&&(this._getDoc().body._rteLoaded===true)){H=true;}}catch(G){H=false;}if(H===true){this._initEditor();}else{var F=this;this._contentTimer=setTimeout(function(){F._checkLoaded.call(F);},20);}},_setInitialContent:function!
 (){var G=D.substitute(this.get("html"),{TITLE:this.STR_TITLE,CONTENT:this._cleanIncomingHTML(this.get("element").value),CSS:this.get("css"),HIDDEN_CSS:((this.get("hiddencss"))?this.get("hiddencss"):"/* No Hidden CSS */"),EXTRA_CSS:((this.get("extracss"))?this.get("extracss"):"/* No Extra CSS */")}),F=true;if(document.compatMode!="BackCompat"){G=this._docType+"\n"+G;}else{}if(this.browser.ie||this.browser.webkit||this.browser.opera||(navigator.userAgent.indexOf("Firefox/1.5")!=-1)){try{this._getDoc().open();this._getDoc().write(G);this._getDoc().close();}catch(H){F=false;}}else{this.get("iframe").get("element").src="data:text/html;charset=utf-8,"+encodeURIComponent(G);}if(F){this._checkLoaded();}},_setMarkupType:function(F){switch(this.get("markup")){case"css":this._setEditorStyle(true);break;case"default":this._setEditorStyle(false);break;case"semantic":case"xhtml":if(this._semantic[F]){this._setEditorStyle(false);
-}else{this._setEditorStyle(true);}break;}},_setEditorStyle:function(G){try{this._getDoc().execCommand("useCSS",false,!G);}catch(F){}},_getSelectedElement:function(){var I=this._getDoc(),F=null,G=null,J=null;if(this.browser.ie){this.currentEvent=this._getWindow().event;F=this._getRange();if(F){J=F.item?F.item(0):F.parentElement();if(J==I.body){J=null;}}if((this.currentEvent!==null)&&(this.currentEvent.keyCode===0)){J=A.getTarget(this.currentEvent);}}else{G=this._getSelection();F=this._getRange();if(!G||!F){return null;}if(!this._hasSelection()){if(G.anchorNode&&(G.anchorNode.nodeType==3)){if(G.anchorNode.parentNode){J=G.anchorNode.parentNode;}if(G.anchorNode.nextSibling!=G.focusNode.nextSibling){J=G.anchorNode.nextSibling;}}if(this._isElement(J,"br")){J=null;}if(!J){J=F.commonAncestorContainer;if(!F.collapsed){if(F.startContainer==F.endContainer){if(F.startOffset-F.endOffset<2){if(F.startContainer.hasChildNodes()){J=F.startContainer.childNodes[F.startOffset];}}}}}}}if(this.c!
 urrentEvent!==null){try{switch(this.currentEvent.type){case"click":case"mousedown":case"mouseup":J=A.getTarget(this.currentEvent);break;default:break;}}catch(H){}}else{if(this.currentElement&&this.currentElement[0]){J=this.currentElement[0];}}if(this.browser.opera||this.browser.webkit){if(this.currentEvent&&!J){J=YAHOO.util.Event.getTarget(this.currentEvent);}}if(!J||!J.tagName){J=I.body;}if(this._isElement(J,"html")){J=I.body;}if(this._isElement(J,"body")){J=I.body;}if(J&&!J.parentNode){J=I.body;}if(J===undefined){J=null;}return J;},_getDomPath:function(F){if(!F){F=this._getSelectedElement();}var G=[];while(F!==null){if(F.ownerDocument!=this._getDoc()){F=null;break;}if(F.nodeName&&F.nodeType&&(F.nodeType==1)){G[G.length]=F;}if(this._isElement(F,"body")){break;}F=F.parentNode;}if(G.length===0){if(this._getDoc()&&this._getDoc().body){G[0]=this._getDoc().body;}}return G.reverse();},_writeDomPath:function(){var L=this._getDomPath(),J=[],H="",M="";for(var F=0;F<L.length;F++){va!
 r N=L[F].tagName.toLowerCase();if((N=="ol")&&(L[F].type)){N+="!
 :"+L[F].
type;}if(C.hasClass(L[F],"yui-tag")){N=L[F].getAttribute("tag");}if((this.get("markup")=="semantic")||(this.get("markup")=="xhtml")){switch(N){case"b":N="strong";break;case"i":N="em";break;}}if(!C.hasClass(L[F],"yui-non")){if(C.hasClass(L[F],"yui-tag")){M=N;}else{H=((L[F].className!=="")?"."+L[F].className.replace(/ /g,"."):"");if((H.indexOf("yui")!=-1)||(H.toLowerCase().indexOf("apple-style-span")!=-1)){H="";}M=N+((L[F].id)?"#"+L[F].id:"")+H;}switch(N){case"a":if(L[F].getAttribute("href",2)){M+=":"+L[F].getAttribute("href",2).replace("mailto:","").replace("http://","").replace("https://","");}break;case"img":var G=L[F].height;var K=L[F].width;if(L[F].style.height){G=parseInt(L[F].style.height,10);}if(L[F].style.width){K=parseInt(L[F].style.width,10);}M+="("+G+"x"+K+")";break;}if(M.length>10){M="<span title=\""+M+"\">"+M.substring(0,10)+"...</span>";}else{M="<span title=\""+M+"\">"+M+"</span>";}J[J.length]=M;}}var I=J.join(" "+this.SEP_DOMPATH+" ");if(this.dompath.innerHTML!!
 =I){this.dompath.innerHTML=I;}},_fixNodes:function(){var K=this._getDoc(),I=[];for(var F in this.invalidHTML){if(YAHOO.lang.hasOwnProperty(this.invalidHTML,F)){if(F.toLowerCase()!="span"){var G=K.body.getElementsByTagName(F);if(G.length){for(var H=0;H<G.length;H++){I.push(G[H]);}}}}}for(var J=0;J<I.length;J++){if(I[J].parentNode){if(D.isObject(this.invalidHTML[I[J].tagName.toLowerCase()])&&this.invalidHTML[I[J].tagName.toLowerCase()].keepContents){this._swapEl(I[J],"span",function(M){M.className="yui-non";});}else{I[J].parentNode.removeChild(I[J]);}}}var L=this._getDoc().getElementsByTagName("img");C.addClass(L,"yui-img");},_isNonEditable:function(H){if(this.get("allowNoEdit")){var G=A.getTarget(H);if(this._isElement(G,"html")){G=null;}var J=this._getDomPath(G);for(var F=(J.length-1);F>-1;F--){if(C.hasClass(J[F],this.CLASS_NOEDIT)){try{this._getDoc().execCommand("enableObjectResizing",false,"false");}catch(I){}this.nodeChange();A.stopEvent(H);return true;}}try{this._getDoc(!
 ).execCommand("enableObjectResizing",false,"true");}catch(I){}!
 }return 
false;},_setCurrentEvent:function(F){this.currentEvent=F;},_handleClick:function(G){if(this._isNonEditable(G)){return false;}this._setCurrentEvent(G);if(this.currentWindow){this.closeWindow();}if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}if(this.browser.webkit){var F=A.getTarget(G);if(this._isElement(F,"a")||this._isElement(F.parentNode,"a")){A.stopEvent(G);this.nodeChange();}}else{this.nodeChange();}},_handleMouseUp:function(G){if(this._isNonEditable(G)){return false;}var F=this;if(this.browser.opera){var H=A.getTarget(G);if(this._isElement(H,"img")){this.nodeChange();if(this.operaEvent){clearTimeout(this.operaEvent);this.operaEvent=null;this._handleDoubleClick(G);}else{this.operaEvent=window.setTimeout(function(){F.operaEvent=false;},700);}}}if(this.browser.webkit||this.browser.opera){if(this.browser.webkit){A.stopEvent(G);}}this.nodeChange();this.fi!
 reEvent("editorMouseUp",{type:"editorMouseUp",target:this,ev:G});},_handleMouseDown:function(F){if(this._isNonEditable(F)){return false;}this._setCurrentEvent(F);var G=A.getTarget(F);if(this.browser.webkit&&this._hasSelection()){var H=this._getSelection();if(!this.browser.webkit3){H.collapse(true);}else{H.collapseToStart();}}if(this.browser.webkit&&this._lastImage){C.removeClass(this._lastImage,"selected");this._lastImage=null;}if(this._isElement(G,"img")||this._isElement(G,"a")){if(this.browser.webkit){A.stopEvent(F);if(this._isElement(G,"img")){C.addClass(G,"selected");this._lastImage=G;}}this.nodeChange();}this.fireEvent("editorMouseDown",{type:"editorMouseDown",target:this,ev:F});},_handleDoubleClick:function(F){if(this._isNonEditable(F)){return false;}this._setCurrentEvent(F);var G=A.getTarget(F);if(this._isElement(G,"img")){this.currentElement[0]=G;this.toolbar.fireEvent("insertimageClick",{type:"insertimageClick",target:this.toolbar});
-this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});}else{if(this._hasParent(G,"a")){this.currentElement[0]=this._hasParent(G,"a");this.toolbar.fireEvent("createlinkClick",{type:"createlinkClick",target:this.toolbar});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});}}this.nodeChange();this.editorDirty=false;this.fireEvent("editorDoubleClick",{type:"editorDoubleClick",target:this,ev:F});},_handleKeyUp:function(G){if(this._isNonEditable(G)){return false;}this._setCurrentEvent(G);switch(G.keyCode){case 37:case 38:case 39:case 40:case 46:case 8:case 87:if((G.keyCode==87)&&this.currentWindow&&G.shiftKey&&G.ctrlKey){this.closeWindow();}else{if(!this.browser.ie){if(this._nodeChangeTimer){clearTimeout(this._nodeChangeTimer);}var F=this;this._nodeChangeTimer=setTimeout(function(){F._nodeChangeTimer=null;F.nodeChange.call(F);},100);}else{this.nodeChange();}this.editorDirty=true;}break;}this.fireEvent("editorKeyUp",{type:"editorKeyUp",targ!
 et:this,ev:G});},_handleKeyPress:function(F){if(this.get("allowNoEdit")){if(F&&F.keyCode&&((F.keyCode==46)||F.keyCode==63272)){A.stopEvent(F);}}if(this._isNonEditable(F)){return false;}this._setCurrentEvent(F);if(this.browser.webkit){if(!this.browser.webkit3){if(F.keyCode&&(F.keyCode==122)&&(F.metaKey)){if(this._hasParent(this._getSelectedElement(),"li")){A.stopEvent(F);}}}this._listFix(F);}this.fireEvent("editorKeyPress",{type:"editorKeyPress",target:this,ev:F});},_listFix:function(L){var O=null,J=null,F=false,H=null;if(this.browser.webkit){if(L.keyCode&&(L.keyCode==13)){if(this._hasParent(this._getSelectedElement(),"li")){var I=this._hasParent(this._getSelectedElement(),"li");var N=this._getDoc().createElement("li");N.innerHTML="<span class=\"yui-non\"> </span> ";if(I.nextSibling){I.parentNode.insertBefore(N,I.nextSibling);}else{I.parentNode.appendChild(N);}this.currentElement[0]=N;this._selectNode(N.firstChild);if(!this.browser.webkit3){I.parentNode.style.displ!
 ay="list-item";setTimeout(function(){I.parentNode.style.displa!
 y="block
";},1);}A.stopEvent(L);}}}if(L.keyCode&&((!this.browser.webkit3&&(L.keyCode==25))||((this.browser.webkit3||!this.browser.webkit)&&((L.keyCode==9)&&L.shiftKey)))){O=this._getSelectedElement();if(this._hasParent(O,"li")){O=this._hasParent(O,"li");if(this._hasParent(O,"ul")||this._hasParent(O,"ol")){J=this._hasParent(O,"ul");if(!J){J=this._hasParent(O,"ol");}if(this._isElement(J.previousSibling,"li")){J.removeChild(O);J.parentNode.insertBefore(O,J.nextSibling);if(this.browser.ie){H=this._getDoc().body.createTextRange();H.moveToElementText(O);H.collapse(false);H.select();}if(this.browser.webkit){if(!this.browser.webkit3){J.style.display="list-item";J.parentNode.style.display="list-item";setTimeout(function(){J.style.display="block";J.parentNode.style.display="block";},1);}}A.stopEvent(L);}}}}if(L.keyCode&&((L.keyCode==9)&&(!L.shiftKey))){var G=this._getSelectedElement();if(this._hasParent(G,"li")){F=this._hasParent(G,"li").innerHTML;}if(this.browser.webkit){this._getDoc().execCo!
 mmand("inserttext",false,"\t");}O=this._getSelectedElement();if(this._hasParent(O,"li")){J=this._hasParent(O,"li");var K=this._getDoc().createElement(J.parentNode.tagName.toLowerCase());if(this.browser.webkit){var M=C.getElementsByClassName("Apple-tab-span","span",J);if(M[0]){J.removeChild(M[0]);J.innerHTML=D.trim(J.innerHTML);if(F){J.innerHTML="<span class=\"yui-non\">"+F+"</span> ";}else{J.innerHTML="<span class=\"yui-non\"> </span> ";}}}else{if(F){J.innerHTML=F+" ";}else{J.innerHTML=" ";}}J.parentNode.replaceChild(K,J);K.appendChild(J);if(this.browser.webkit){this._getSelection().setBaseAndExtent(J.firstChild,1,J.firstChild,J.firstChild.innerText.length);if(!this.browser.webkit3){J.parentNode.parentNode.style.display="list-item";setTimeout(function(){J.parentNode.parentNode.style.display="block";},1);}}else{if(this.browser.ie){H=this._getDoc().body.createTextRange();H.moveToElementText(J);H.collapse(false);H.select();}else{this._selectNode(J);}}A!
 .stopEvent(L);}if(this.browser.webkit){A.stopEvent(L);}this.no!
 deChange
();}},_handleKeyDown:function(J){if(this._isNonEditable(J)){return false;}this._setCurrentEvent(J);if(this.currentWindow){this.closeWindow();}if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}var I=false,K=null,H=false;if(J.shiftKey&&J.ctrlKey){I=true;}switch(J.keyCode){case 84:if(J.shiftKey&&J.ctrlKey){this.toolbar._titlebar.firstChild.focus();A.stopEvent(J);I=false;}break;case 27:if(J.shiftKey){this.afterElement.focus();A.stopEvent(J);H=false;}break;case 76:if(this._hasSelection()){if(J.shiftKey&&J.ctrlKey){var G=true;if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("createlink")){G=false;}}if(G){this.execCommand("createlink","");this.toolbar.fireEvent("createlinkClick",{type:"createlinkClick",target:this.toolbar});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});I=false;}}}break;case 65:if(J.metaKey&&this.browser.we!
 bkit){A.stopEvent(J);this._getSelection().setBaseAndExtent(this._getDoc().body,1,this._getDoc().body,this._getDoc().body.innerHTML.length);}break;case 66:K="bold";break;case 73:K="italic";break;case 85:K="underline";break;case 13:if(this.browser.ie){var L=this._getRange();var F=this._getSelectedElement();if(!this._isElement(F,"li")){if(L){L.pasteHTML("<br>");L.collapse(false);L.select();}A.stopEvent(J);}}}if(this.browser.ie){this._listFix(J);}if(I&&K){this.execCommand(K,null);A.stopEvent(J);this.nodeChange();}this.fireEvent("editorKeyDown",{type:"editorKeyDown",target:this,ev:J});},nodeChange:function(G){var H=parseInt(this.get("nodeChangeThreshold"),10);var N=Math.round(new Date().getTime()/1000);if(G===true){this._lastNodeChange=0;}if((this._lastNodeChange+H)<N){var Q=this;if(this._fixNodesTimer===null){this._fixNodesTimer=window.setTimeout(function(){Q._fixNodes.call(Q);Q._fixNodesTimer=null;},0);}}this._lastNodeChange=N;
-if(this.currentEvent){this._lastNodeChangeEvent=this.currentEvent.type;}var Y=this.fireEvent("beforeNodeChange",{type:"beforeNodeChange",target:this});if(Y===false){return false;}if(this.get("dompath")){this._writeDomPath();}if(!this.get("disabled")){if(this.STOP_NODE_CHANGE){this.STOP_NODE_CHANGE=false;return false;}else{var S=this._getSelection(),P=this._getRange(),F=this._getSelectedElement(),L=this.toolbar.getButtonByValue("fontname"),K=this.toolbar.getButtonByValue("fontsize");if(G!==true){this.editorDirty=true;}var M={};if(this._lastButton){M[this._lastButton.id]=true;}if(!this._isElement(F,"body")){if(L){M[L.get("id")]=true;}if(K){M[K.get("id")]=true;}}this.toolbar.resetAllButtons(M);for(var Z=0;Z<this._disabled.length;Z++){var O=this.toolbar.getButtonByValue(this._disabled[Z]);if(O&&O.get){if(this._lastButton&&(O.get("id")===this._lastButton.id)){}else{if(!this._hasSelection()){switch(this._disabled[Z]){case"fontname":case"fontsize":break;default:this.toolbar.disabl!
 eButton(O);}}else{if(!this._alwaysDisabled[this._disabled[Z]]){this.toolbar.enableButton(O);}}if(!this._alwaysEnabled[this._disabled[Z]]){this.toolbar.deselectButton(O);}}}}var R=this._getDomPath();var a=null,V=null;for(var W=0;W<R.length;W++){a=R[W].tagName.toLowerCase();if(R[W].getAttribute("tag")){a=R[W].getAttribute("tag").toLowerCase();}V=this._tag2cmd[a];if(V===undefined){V=[];}if(!D.isArray(V)){V=[V];}if(R[W].style.fontWeight.toLowerCase()=="bold"){V[V.length]="bold";}if(R[W].style.fontStyle.toLowerCase()=="italic"){V[V.length]="italic";}if(R[W].style.textDecoration.toLowerCase()=="underline"){V[V.length]="underline";}if(V.length>0){for(var U=0;U<V.length;U++){this.toolbar.selectButton(V[U]);this.toolbar.enableButton(V[U]);}}switch(R[W].style.textAlign.toLowerCase()){case"left":case"right":case"center":case"justify":var T=R[W].style.textAlign.toLowerCase();if(R[W].style.textAlign.toLowerCase()=="justify"){T="full";}this.toolbar.selectButton("justify"+T);this.toolbar.!
 enableButton("justify"+T);break;}}if(L){var X=L._configs.label!
 ._initia
lConfig.value;L.set("label","<span class=\"yui-toolbar-fontname-"+E(X)+"\">"+X+"</span>");this._updateMenuChecked("fontname",X);}if(K){K.set("label",K._configs.label._initialConfig.value);}var J=this.toolbar.getButtonByValue("heading");if(J){J.set("label",J._configs.label._initialConfig.value);this._updateMenuChecked("heading","none");}var I=this.toolbar.getButtonByValue("insertimage");if(I&&this.currentWindow&&(this.currentWindow.name=="insertimage")){this.toolbar.disableButton(I);}}}this.fireEvent("afterNodeChange",{type:"afterNodeChange",target:this});},_updateMenuChecked:function(F,G,I){if(!I){I=this.toolbar;}var H=I.getButtonByValue(F);H.checkValue(G);},_handleToolbarClick:function(G){var I="";var J="";var H=G.button.value;if(G.button.menucmd){I=H;H=G.button.menucmd;}this._lastButton=G.button;if(this.STOP_EXEC_COMMAND){this.STOP_EXEC_COMMAND=false;return false;}else{this.execCommand(H,I);if(!this.browser.webkit){var F=this;setTimeout(function(){F._focusWindow.call(F);},!
 5);}}A.stopEvent(G);},_setupAfterElement:function(){if(!this.afterElement){this.afterElement=document.createElement("h2");this.afterElement.className="yui-editor-skipheader";this.afterElement.tabIndex="-1";this.afterElement.innerHTML=this.STR_LEAVE_EDITOR;this.get("element_cont").get("firstChild").appendChild(this.afterElement);}},_disableEditor:function(G){if(G){if(!this._mask){this._setDesignMode("off");if(this.toolbar){this.toolbar.set("disabled",true);}this._mask=document.createElement("DIV");C.setStyle(this._mask,"height","100%");C.setStyle(this._mask,"width","100%");C.setStyle(this._mask,"position","absolute");C.setStyle(this._mask,"top","0");C.setStyle(this._mask,"left","0");C.setStyle(this._mask,"opacity",".5");C.addClass(this._mask,"yui-editor-masked");this.get("iframe").get("parentNode").appendChild(this._mask);}}else{if(this._mask){this._mask.parentNode.removeChild(this._mask);this._mask=null;if(this.toolbar){this.toolbar.set("disabled",false);}this._setDesignMod!
 e("on");this._focusWindow();var F=this;window.setTimeout(funct!
 ion(){F.
nodeChange.call(F);},100);}}},EDITOR_PANEL_ID:"yui-editor-panel",SEP_DOMPATH:"<",STR_LEAVE_EDITOR:"You have left the Rich Text Editor.",STR_BEFORE_EDITOR:"This text field can contain stylized text and graphics. To cycle through all formatting options, use the keyboard shortcut Control + Shift + T to place focus on the toolbar and navigate between option heading names. <h4>Common formatting keyboard shortcuts:</h4><ul><li>Control Shift B sets text to bold</li> <li>Control Shift I sets text to italic</li> <li>Control Shift U underlines text</li> <li>Control Shift L adds an HTML link</li> <li>To exit this text editor use the keyboard shortcut Control + Shift + ESC.</li></ul>",STR_TITLE:"Rich Text Area.",STR_IMAGE_HERE:"Image Url Here",STR_LINK_URL:"Link URL",STOP_EXEC_COMMAND:false,STOP_NODE_CHANGE:false,CLASS_NOEDIT:"yui-noedit",CLASS_CONTAINER:"yui-editor-container",CLASS_EDITABLE:"yui-editor-editable",CLASS_EDITABLE_CONT:"yui-editor-editable-container",CLASS_PREFIX:"yui-edit!
 or",browser:function(){var F=YAHOO.env.ua;if(F.webkit>420){F.webkit3=F.webkit;}else{F.webkit3=0;}return F;}(),init:function(G,F){YAHOO.widget.SimpleEditor.superclass.init.call(this,G,F);YAHOO.widget.EditorInfo._instances[this.get("id")]=this;this.on("contentReady",function(){this.DOMReady=true;this.fireQueue();},this,true);},initAttributes:function(F){YAHOO.widget.SimpleEditor.superclass.initAttributes.call(this,F);var G=this;this.setAttributeConfig("iframe",{value:null});this.setAttributeConfig("textarea",{value:null,writeOnce:true});this.setAttributeConfig("nodeChangeThreshold",{value:F.nodeChangeThreshold||3,validator:YAHOO.lang.isNumber});this.setAttributeConfig("allowNoEdit",{value:F.allowNoEdit||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("limitCommands",{value:F.limitCommands||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("element_cont",{value:F.element_cont});this.setAttributeConfig("editor_wrapper",{value:F.editor_wrapper||null,w!
 riteOnce:true});
-this.setAttributeConfig("height",{value:F.height||C.getStyle(G.get("element"),"height"),method:function(H){if(this._rendered){if(this.get("animate")){var I=new YAHOO.util.Anim(this.get("iframe").get("parentNode"),{height:{to:parseInt(H,10)}},0.5);I.animate();}else{C.setStyle(this.get("iframe").get("parentNode"),"height",H);}}}});this.setAttributeConfig("width",{value:F.width||C.getStyle(this.get("element"),"width"),method:function(H){if(this._rendered){if(this.get("animate")){var I=new YAHOO.util.Anim(this.get("element_cont").get("element"),{width:{to:parseInt(H,10)}},0.5);I.animate();}else{this.get("element_cont").setStyle("width",H);}}}});this.setAttributeConfig("blankimage",{value:F.blankimage||this._getBlankImage()});this.setAttributeConfig("css",{value:F.css||this._defaultCSS,writeOnce:true});this.setAttributeConfig("html",{value:F.html||"<html><head><title>{TITLE}</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><base href=\""+this._base!
 HREF+"\"><style>{CSS}</style><style>{HIDDEN_CSS}</style><style>{EXTRA_CSS}</style></head><body onload=\"document.body._rteLoaded = true;\">{CONTENT}</body></html>",writeOnce:true});this.setAttributeConfig("extracss",{value:F.css||"",writeOnce:true});this.setAttributeConfig("handleSubmit",{value:false,writeOnce:true,method:function(H){if(H){var J=this.get("element");if(J.form){var I=function(K){A.stopEvent(K);this.saveHTML();window.setTimeout(function(){YAHOO.util.Event.removeListener(J.form,"submit",I);J.form.submit();},200);};A.on(J.form,"submit",I,this,true);}}}});this.setAttributeConfig("disabled",{value:false,method:function(H){if(this._rendered){this._disableEditor(H);}}});this.setAttributeConfig("toolbar_cont",{value:null,writeOnce:true});this.setAttributeConfig("toolbar",{value:F.toolbar||this._defaultToolbar,writeOnce:true,method:function(H){if(!H.buttonType){H.buttonType=this._defaultToolbar.buttonType;}this._defaultToolbar=H;}});this.setAttributeConfig("animate",{!
 value:((F.animate)?((YAHOO.util.Anim)?true:false):false),valid!
 ator:fun
ction(I){var H=true;if(!YAHOO.util.Anim){H=false;}return H;}});this.setAttributeConfig("panel",{value:null,writeOnce:true,validator:function(I){var H=true;if(!YAHOO.widget.Overlay){H=false;}return H;}});this.setAttributeConfig("focusAtStart",{value:F.focusAtStart||false,writeOnce:true,method:function(){this.on("editorContentLoaded",function(){var H=this;setTimeout(function(){H._focusWindow.call(H,true);H.editorDirty=false;},400);},this,true);}});this.setAttributeConfig("dompath",{value:F.dompath||false,method:function(H){if(H&&!this.dompath){this.dompath=document.createElement("DIV");this.dompath.id=this.get("id")+"_dompath";C.addClass(this.dompath,"dompath");this.get("element_cont").get("firstChild").appendChild(this.dompath);if(this.get("iframe")){this._writeDomPath();}}else{if(!H&&this.dompath){this.dompath.parentNode.removeChild(this.dompath);this.dompath=null;}}this._setupAfterElement();}});this.setAttributeConfig("markup",{value:F.markup||"semantic",validator:function(!
 H){switch(H.toLowerCase()){case"semantic":case"css":case"default":case"xhtml":return true;}return false;}});this.setAttributeConfig("removeLineBreaks",{value:F.removeLineBreaks||false,validator:YAHOO.lang.isBoolean});this.on("afterRender",function(){this._renderPanel();});},_getBlankImage:function(){if(!this.DOMReady){this._queue[this._queue.length]=["_getBlankImage",arguments];return"";}var F="";if(!this._blankImageLoaded){var G=document.createElement("div");G.style.position="absolute";G.style.top="-9999px";G.style.left="-9999px";G.className=this.CLASS_PREFIX+"-blankimage";document.body.appendChild(G);F=YAHOO.util.Dom.getStyle(G,"background-image");F=F.replace("url(","").replace(")","").replace(/"/g,"");this.set("blankimage",F);this._blankImageLoaded=true;}else{F=this.get("blankimage");}return F;},_handleFontSize:function(H){var F=this.toolbar.getButtonById(H.button.id);var G=F.get("label")+"px";this.execCommand("fontsize",G);this.STOP_EXEC_COMMAND=true;},_handleColorPicke!
 r:function(H){var G=H.button;var F="#"+H.color;if((G=="forecol!
 or")||(G
=="backcolor")){this.execCommand(G,F);}},_handleAlign:function(I){var H=null;for(var F=0;F<I.button.menu.length;F++){if(I.button.menu[F].value==I.button.value){H=I.button.menu[F].value;}}var G=this._getSelection();this.execCommand(H,G);this.STOP_EXEC_COMMAND=true;},_handleAfterNodeChange:function(){var R=this._getDomPath(),M=null,I=null,N=null,G=false;var K=this.toolbar.getButtonByValue("fontname");var L=this.toolbar.getButtonByValue("fontsize");var F=this.toolbar.getButtonByValue("heading");for(var H=0;H<R.length;H++){M=R[H];var Q=M.tagName.toLowerCase();if(M.getAttribute("tag")){Q=M.getAttribute("tag");}I=M.getAttribute("face");if(C.getStyle(M,"font-family")){I=C.getStyle(M,"font-family");}if(Q.substring(0,1)=="h"){if(F){for(var J=0;J<F._configs.menu.value.length;J++){if(F._configs.menu.value[J].value.toLowerCase()==Q){F.set("label",F._configs.menu.value[J].text);}}this._updateMenuChecked("heading",Q);}}}if(K){for(var P=0;P<K._configs.menu.value.length;P++){if(I&&K._config!
 s.menu.value[P].text.toLowerCase()==I.toLowerCase()){G=true;I=K._configs.menu.value[P].text;}}if(!G){I=K._configs.label._initialConfig.value;}var O="<span class=\"yui-toolbar-fontname-"+E(I)+"\">"+I+"</span>";if(K.get("label")!=O){K.set("label",O);this._updateMenuChecked("fontname",I);}}if(L){N=parseInt(C.getStyle(M,"fontSize"),10);if((N===null)||isNaN(N)){N=L._configs.label._initialConfig.value;}L.set("label",""+N);}if(!this._isElement(M,"body")&&!this._isElement(M,"img")){this.toolbar.enableButton(K);this.toolbar.enableButton(L);this.toolbar.enableButton("forecolor");this.toolbar.enableButton("backcolor");}if(this._isElement(M,"img")){if(YAHOO.widget.Overlay){this.toolbar.enableButton("createlink");}}if(this._isElement(M,"blockquote")){this.toolbar.selectButton("indent");this.toolbar.disableButton("indent");this.toolbar.enableButton("outdent");}if(this._hasParent(M,"ol")||this._hasParent(M,"ul")){this.toolbar.disableButton("indent");
-}this._lastButton=null;},_setBusy:function(F){if(F){C.removeClass(document.body,"yui-busy");C.removeClass(this._getDoc().body,"yui-busy");}else{C.addClass(document.body,"yui-busy");C.addClass(this._getDoc().body,"yui-busy");}},_handleInsertImageClick:function(){if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("insertimage")){return false;}}this.toolbar.set("disabled",true);this.on("afterExecCommand",function(){var F=this.currentElement[0],H="http://";if(!F){F=this._getSelectedElement();}if(F){if(F.getAttribute("src")){H=F.getAttribute("src",2);if(H.indexOf(this.get("blankimage"))!=-1){H=this.STR_IMAGE_HERE;}}}var G=prompt(this.STR_LINK_URL+": ",H);if((G!=="")&&(G!==null)){F.setAttribute("src",G);}else{if(G!==null){F.parentNode.removeChild(F);this.currentElement=[];}}this.closeWindow();this.toolbar.set("disabled",false);},this,true);},_handleInsertImageWindowClose:function(){this.nodeChange();},_isLocalFile:function(F){if((F!=="")&&((F.indexOf("file:/")!=-1)||!
 (F.indexOf(":\\")!=-1))){return true;}return false;},_handleCreateLinkClick:function(){if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("createlink")){return false;}}this.toolbar.set("disabled",true);this.on("afterExecCommand",function(){var H=this.currentElement[0],G="";if(H){if(H.getAttribute("href",2)!==null){G=H.getAttribute("href",2);}}var J=prompt(this.STR_LINK_URL+": ",G);if((J!=="")&&(J!==null)){var I=J;if((I.indexOf("://")==-1)&&(I.substring(0,1)!="/")&&(I.substring(0,6).toLowerCase()!="mailto")){if((I.indexOf("@")!=-1)&&(I.substring(0,6).toLowerCase()!="mailto")){I="mailto:"+I;}else{if(I.substring(0,1)!="#"){I="http://"+I;}}}H.setAttribute("href",I);}else{if(J!==null){var F=this._getDoc().createElement("span");F.innerHTML=H.innerHTML;C.addClass(F,"yui-non");H.parentNode.replaceChild(F,H);}}this.closeWindow();this.toolbar.set("disabled",false);});},_handleCreateLinkWindowClose:function(){this.nodeChange();this.currentElement=[];},render:function(){if!
 (this._rendered){return false;}if(!this.DOMReady){this._queue[!
 this._qu
eue.length]=["render",arguments];return false;}this._setBusy();this._rendered=true;var F=this;this.set("textarea",this.get("element"));this.get("element_cont").setStyle("display","none");this.get("element_cont").addClass(this.CLASS_CONTAINER);this.set("iframe",this._createIframe());window.setTimeout(function(){F._setInitialContent.call(F);},10);this.get("editor_wrapper").appendChild(this.get("iframe").get("element"));if(this.get("disabled")){this._disableEditor(true);}var G=this.get("toolbar");if(G instanceof B){this.toolbar=G;this.toolbar.set("disabled",true);}else{G.disabled=true;this.toolbar=new B(this.get("toolbar_cont"),G);}this.fireEvent("toolbarLoaded",{type:"toolbarLoaded",target:this.toolbar});this.toolbar.on("toolbarCollapsed",function(){if(this.currentWindow){this.moveWindow();}},this,true);this.toolbar.on("toolbarExpanded",function(){if(this.currentWindow){this.moveWindow();}},this,true);this.toolbar.on("fontsizeClick",function(H){this._handleFontSize(H);},this,t!
 rue);this.toolbar.on("colorPickerClicked",function(H){this._handleColorPicker(H);},this,true);this.toolbar.on("alignClick",function(H){this._handleAlign(H);},this,true);this.on("afterNodeChange",function(){this._handleAfterNodeChange();},this,true);this.toolbar.on("insertimageClick",function(){this._handleInsertImageClick();},this,true);this.on("windowinsertimageClose",function(){this._handleInsertImageWindowClose();},this,true);this.toolbar.on("createlinkClick",function(){this._handleCreateLinkClick();},this,true);this.on("windowcreatelinkClose",function(){this._handleCreateLinkWindowClose();},this,true);this.get("parentNode").replaceChild(this.get("element_cont").get("element"),this.get("element"));if(!this.beforeElement){this.beforeElement=document.createElement("h2");this.beforeElement.className="yui-editor-skipheader";this.beforeElement.tabIndex="-1";this.beforeElement.innerHTML=this.STR_BEFORE_EDITOR;this.get("element_cont").get("firstChild").insertBefore(this.beforeE!
 lement,this.toolbar.get("nextSibling"));}this.setStyle("visibi!
 lity","h
idden");this.setStyle("position","absolute");this.setStyle("top","-9999px");this.setStyle("left","-9999px");this.get("element_cont").appendChild(this.get("element"));this.get("element_cont").setStyle("display","block");C.addClass(this.get("iframe").get("parentNode"),this.CLASS_EDITABLE_CONT);this.get("iframe").addClass(this.CLASS_EDITABLE);this.get("element_cont").setStyle("width",this.get("width"));C.setStyle(this.get("iframe").get("parentNode"),"height",this.get("height"));this.get("iframe").setStyle("width","100%");this.get("iframe").setStyle("height","100%");if(this.browser.ie==7){}this.fireEvent("afterRender",{type:"afterRender",target:this});},execCommand:function(H,G){var K=this.fireEvent("beforeExecCommand",{type:"beforeExecCommand",target:this,args:arguments});if((K===false)||(this.STOP_EXEC_COMMAND)){this.STOP_EXEC_COMMAND=false;return false;}this._setMarkupType(H);if(this.browser.ie){this._getWindow().focus();}var F=true;if(this.get("limitCommands")){if(!this.tool!
 bar.getButtonByValue(H)){F=false;}}this.editorDirty=true;if((typeof this["cmd_"+H.toLowerCase()]=="function")&&F){var J=this["cmd_"+H.toLowerCase()](G);F=J[0];if(J[1]){H=J[1];}if(J[2]){G=J[2];}}if(F){try{this._getDoc().execCommand(H,false,G);}catch(I){}}else{}this.on("afterExecCommand",function(){this.unsubscribeAll("afterExecCommand");this.nodeChange();});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});},cmd_backcolor:function(I){var F=true,G=this._getSelectedElement(),H="backcolor";if(this.browser.gecko||this.browser.opera){this._setEditorStyle(true);H="hilitecolor";}if(!this._isElement(G,"body")){C.setStyle(G,"background-color",I);this._selectNode(G);F=false;}else{this._createCurrentElement("span",{backgroundColor:I});this._selectNode(this.currentElement[0]);F=false;}return[F,H];},cmd_forecolor:function(H){var F=true,G=this._getSelectedElement();if(!this._isElement(G,"body")){C.setStyle(G,"color",H);
-this._selectNode(G);F=false;}else{this._createCurrentElement("span",{color:H});this._selectNode(this.currentElement[0]);F=false;}return[F];},cmd_unlink:function(F){this._swapEl(this.currentElement[0],"span",function(G){G.className="yui-non";});return[false];},cmd_createlink:function(H){var G=this._getSelectedElement(),F=null;if(this._hasParent(G,"a")){this.currentElement[0]=this._hasParent(G,"a");}else{if(!this._isElement(G,"a")){this._createCurrentElement("a");F=this._swapEl(this.currentElement[0],"a");this.currentElement[0]=F;}else{this.currentElement[0]=G;}}return[false];},cmd_insertimage:function(K){var F=true,G=null,J="insertimage",I=this._getSelectedElement();if(K===""){K=this.get("blankimage");}if(this._isElement(I,"img")){this.currentElement[0]=I;F=false;}else{if(this._getDoc().queryCommandEnabled(J)){this._getDoc().execCommand("insertimage",false,K);var L=this._getDoc().getElementsByTagName("img");for(var H=0;H<L.length;H++){if(!YAHOO.util.Dom.hasClass(L[H],"yui-im!
 g")){YAHOO.util.Dom.addClass(L[H],"yui-img");this.currentElement[0]=L[H];}}F=false;}else{if(I==this._getDoc().body){G=this._getDoc().createElement("img");G.setAttribute("src",K);YAHOO.util.Dom.addClass(G,"yui-img");this._getDoc().body.appendChild(G);}else{this._createCurrentElement("img");G=this._getDoc().createElement("img");G.setAttribute("src",K);YAHOO.util.Dom.addClass(G,"yui-img");this.currentElement[0].parentNode.replaceChild(G,this.currentElement[0]);}this.currentElement[0]=G;F=false;}}return[F];},cmd_inserthtml:function(I){var F=true,H="inserthtml",G=null,J=null;if(this.browser.webkit&&!this._getDoc().queryCommandEnabled(H)){this._createCurrentElement("img");G=this._getDoc().createElement("span");G.innerHTML=I;this.currentElement[0].parentNode.replaceChild(G,this.currentElement[0]);F=false;}else{if(this.browser.ie){J=this._getRange();if(J.item){J.item(0).outerHTML=I;}else{J.pasteHTML(I);}F=false;}}return[F];},cmd_list:function(U){var H=true,O=null,R=0,F=null,P="",L=!
 this._getSelectedElement(),I="insertorderedlist";if(U=="ul"){I!
 ="insert
unorderedlist";}if((this.browser.webkit&&!this._getDoc().queryCommandEnabled(I))){if(this._isElement(L,"li")&&this._isElement(L.parentNode,U)){F=L.parentNode;O=this._getDoc().createElement("span");YAHOO.util.Dom.addClass(O,"yui-non");P="";var T=F.getElementsByTagName("li");for(R=0;R<T.length;R++){P+="<div>"+T[R].innerHTML+"</div>";}O.innerHTML=P;this.currentElement[0]=F;this.currentElement[0].parentNode.replaceChild(O,this.currentElement[0]);}else{this._createCurrentElement(U.toLowerCase());O=this._getDoc().createElement(U);for(R=0;R<this.currentElement.length;R++){var Q=this._getDoc().createElement("li");Q.innerHTML=this.currentElement[R].innerHTML+"<span class=\"yui-non\"> </span> ";O.appendChild(Q);if(R>0){this.currentElement[R].parentNode.removeChild(this.currentElement[R]);}}this.currentElement[0].parentNode.replaceChild(O,this.currentElement[0]);this.currentElement[0]=O;var K=this.currentElement[0].firstChild;K=C.getElementsByClassName("yui-non","span",K)[0];!
 this._getSelection().setBaseAndExtent(K,1,K,K.innerText.length);}H=false;}else{F=this._getSelectedElement();if(this._isElement(F,"li")&&this._isElement(F.parentNode,U)||(this.browser.ie&&this._isElement(this._getRange().parentElement,"li"))){if(this.browser.ie){P="";var N=F.parentNode.getElementsByTagName("li");for(var J=0;J<N.length;J++){P+=N[J].innerHTML+"<br>";}var G=this._getDoc().createElement("span");G.innerHTML=P;F.parentNode.parentNode.replaceChild(G,F.parentNode);}else{this.nodeChange();this._getDoc().execCommand(I,"",F.parentNode);this.nodeChange();}H=false;}if(this.browser.opera){var S=this;window.setTimeout(function(){var V=S._getDoc().getElementsByTagName("li");for(var W=0;W<V.length;W++){if(V[W].innerHTML.toLowerCase()=="<br>"){V[W].parentNode.parentNode.removeChild(V[W].parentNode);}}},30);}if(this.browser.ie&&H){var M="";if(this._getRange().html){M="<li>"+this._getRange().html+"</li>";}else{M="<li>"+this._getRange().text+"</li>";}this._getRange().pasteHTML("!
 <"+U+">"+M+"</"+U+">");H=false;}}return H;},cmd_insertorderedl!
 ist:func
tion(F){return[this.cmd_list("ol")];},cmd_insertunorderedlist:function(F){return[this.cmd_list("ul")];},cmd_fontname:function(H){var F=true,G=this._getSelectedElement();this.currentFont=H;if(G&&G.tagName&&!this._hasSelection()){YAHOO.util.Dom.setStyle(G,"font-family",H);F=false;}return[F];},cmd_fontsize:function(G){if((this.currentElement.length>0)&&(!this._hasSelection())){YAHOO.util.Dom.setStyle(this.currentElement,"fontSize",G);}else{if(!this._isElement(this._getSelectedElement(),"body")){var F=this._getSelectedElement();YAHOO.util.Dom.setStyle(F,"fontSize",G);this._selectNode(F);}else{this._createCurrentElement("span",{"fontSize":G});this._selectNode(this.currentElement[0]);}}return[false];},_swapEl:function(G,F,I){var H=this._getDoc().createElement(F);H.innerHTML=G.innerHTML;if(typeof I=="function"){I.call(this,H);}G.parentNode.replaceChild(H,G);return H;},_createCurrentElement:function(H,U){H=((H)?H:"a");var b=null,G=[],I=this._getDoc();if(this.currentFont){if(!U){U={}!
 ;}U.fontFamily=this.currentFont;this.currentFont=null;}this.currentElement=[];var X=function(){var f=null;switch(H){case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":f=I.createElement(H);break;default:f=I.createElement("span");YAHOO.util.Dom.addClass(f,"yui-tag-"+H);YAHOO.util.Dom.addClass(f,"yui-tag");f.setAttribute("tag",H);for(var e in U){if(YAHOO.util.Lang.hasOwnProperty(U,e)){f.style[e]=U[e];}}break;}return f;};if(!this._hasSelection()){if(this._getDoc().queryCommandEnabled("insertimage")){this._getDoc().execCommand("insertimage",false,"yui-tmp-img");var W=this._getDoc().getElementsByTagName("img");for(var Z=0;Z<W.length;Z++){if(W[Z].getAttribute("src",2)=="yui-tmp-img"){G=X();W[Z].parentNode.replaceChild(G,W[Z]);this.currentElement[this.currentElement.length]=G;}}}else{if(this.currentEvent){b=YAHOO.util.Event.getTarget(this.currentEvent);}else{b=this._getDoc().body;}}if(b){G=X();if(this._isElement(b,"body")||this._isElement(b,"html")){if(this._isElement(b,"html"))!
 {b=this._getDoc().body;
-}b.appendChild(G);}else{if(b.nextSibling){b.parentNode.insertBefore(G,b.nextSibling);}else{b.parentNode.appendChild(G);}}this.currentElement[this.currentElement.length]=G;this.currentEvent=null;if(this.browser.webkit){this._getSelection().setBaseAndExtent(G,0,G,0);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(true);}}}}else{this._setEditorStyle(true);this._getDoc().execCommand("fontname",false,"yui-tmp");var F=[];var R=this._getDoc().getElementsByTagName("font");var P=this._getDoc().getElementsByTagName(this._getSelectedElement().tagName);var M=this._getDoc().getElementsByTagName("span");var L=this._getDoc().getElementsByTagName("i");var K=this._getDoc().getElementsByTagName("b");var J=this._getDoc().getElementsByTagName(this._getSelectedElement().parentNode.tagName);for(var V=0;V<R.length;V++){F[F.length]=R[V];}for(var N=0;N<J.length;N++){F[F.length]=J[N];}for(var T=0;T<P.length;T++){F[F.length]=P[T];}for(var S=0;S<M.le!
 ngth;S++){F[F.length]=M[S];}for(var Q=0;Q<L.length;Q++){F[F.length]=L[Q];}for(var O=0;O<K.length;O++){F[F.length]=K[O];}for(var a=0;a<F.length;a++){if((YAHOO.util.Dom.getStyle(F[a],"font-family")=="yui-tmp")||(F[a].face&&(F[a].face=="yui-tmp"))){G=X();G.innerHTML=F[a].innerHTML;if(this._isElement(F[a],"ol")||(this._isElement(F[a],"ul"))){var Y=F[a].getElementsByTagName("li")[0];F[a].style.fontFamily="inherit";Y.style.fontFamily="inherit";G.innerHTML=Y.innerHTML;Y.innerHTML="";Y.appendChild(G);this.currentElement[this.currentElement.length]=G;}else{if(this._isElement(F[a],"li")){F[a].innerHTML="";F[a].appendChild(G);F[a].style.fontFamily="inherit";this.currentElement[this.currentElement.length]=G;}else{if(F[a].parentNode){F[a].parentNode.replaceChild(G,F[a]);this.currentElement[this.currentElement.length]=G;this.currentEvent=null;if(this.browser.webkit){this._getSelection().setBaseAndExtent(G,0,G,0);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._!
 getSelection().collapse(true);}}if(this.browser.ie&&U&&U.fontS!
 ize){thi
s._getSelection().empty();}if(this.browser.gecko){this._getSelection().collapseToStart();}}}}}}var c=this.currentElement.length;for(var d=0;d<c;d++){if((d+1)!=c){if(this.currentElement[d]&&this.currentElement[d].nextSibling){if(this._isElement(this.currentElement[d],"br")){this.currentElement[this.currentElement.length]=this.currentElement[d].nextSibling;}}}}}},saveHTML:function(){var F=this.cleanHTML();this.get("element").value=F;return F;},setEditorHTML:function(F){F=this._cleanIncomingHTML(F);this._getDoc().body.innerHTML=F;this.nodeChange();},getEditorHTML:function(){return this._getDoc().body.innerHTML;},show:function(){if(this.browser.gecko){this._setDesignMode("on");this._focusWindow();}if(this.browser.webkit){var F=this;window.setTimeout(function(){F._setInitialContent.call(F);},10);}if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}this.get("iframe!
 ").setStyle("position","static");this.get("iframe").setStyle("left","");},hide:function(){if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}if(this._fixNodesTimer){clearTimeout(this._fixNodesTimer);this._fixNodesTimer=null;}if(this._nodeChangeTimer){clearTimeout(this._nodeChangeTimer);this._nodeChangeTimer=null;}this._lastNodeChange=0;this.get("iframe").setStyle("position","absolute");this.get("iframe").setStyle("left","-9999px");},_cleanIncomingHTML:function(F){F=F.replace(/<strong([^>]*)>/gi,"<b$1>");F=F.replace(/<\/strong>/gi,"</b>");F=F.replace(/<em([^>]*)>/gi,"<i$1>");F=F.replace(/<\/em>/gi,"</i>");return F;},cleanHTML:function(H){if(!H){H=this.getEditorHTML();}var G=this.get("markup");H=this.pre_filter_linebreaks(H,G);H=H.replace(/<img([^>]*)\/>/gi,"<YUI_IMG$1>");H=H.replace(/<img([^>]*)>/gi,"<YUI_IMG$1>");H=H.replace(/<input([^>]*)\/>/gi,"<YUI_INPUT!
 $1>");H=H.replace(/<input([^>]*)>/gi,"<YUI_INPUT$1>");H=H.repl!
 ace(/<ul
([^>]*)>/gi,"<YUI_UL$1>");H=H.replace(/<\/ul>/gi,"</YUI_UL>");H=H.replace(/<blockquote([^>]*)>/gi,"<YUI_BQ$1>");H=H.replace(/<\/blockquote>/gi,"</YUI_BQ>");if((G=="semantic")||(G=="xhtml")){H=H.replace(/<i([^>]*)>/gi,"<em$1>");H=H.replace(/<\/i>/gi,"</em>");H=H.replace(/<b([^>]*)>/gi,"<strong$1>");H=H.replace(/<\/b>/gi,"</strong>");}H=H.replace(/<font/gi,"<font");H=H.replace(/<\/font>/gi,"</font>");H=H.replace(/<span/gi,"<span");H=H.replace(/<\/span>/gi,"</span>");if((G=="semantic")||(G=="xhtml")||(G=="css")){H=H.replace(new RegExp("<font([^>]*)face=\"([^>]*)\">(.*?)</font>","gi"),"<span $1 style=\"font-family: $2;\">$3</span>");H=H.replace(/<u/gi,"<span style=\"text-decoration: underline;\"");H=H.replace(/\/u>/gi,"/span>");if(G=="css"){H=H.replace(/<em([^>]*)>/gi,"<i$1>");H=H.replace(/<\/em>/gi,"</i>");H=H.replace(/<strong([^>]*)>/gi,"<b$1>");H=H.replace(/<\/strong>/gi,"</b>");H=H.replace(/<b/gi,"<span style=\"font-weight: bold;\"");H=H.replace(/\/b>/gi,"/span>");H=H.replac!
 e(/<i/gi,"<span style=\"font-style: italic;\"");H=H.replace(/\/i>/gi,"/span>");}H=H.replace(/  /gi," ");}else{H=H.replace(/<u/gi,"<u");H=H.replace(/\/u>/gi,"/u>");}H=H.replace(/<ol([^>]*)>/gi,"<ol$1>");H=H.replace(/\/ol>/gi,"/ol>");H=H.replace(/<li/gi,"<li");H=H.replace(/\/li>/gi,"/li>");H=this.filter_safari(H);H=this.filter_internals(H);H=this.filter_all_rgb(H);H=this.post_filter_linebreaks(H,G);if(G=="xhtml"){H=H.replace(/<YUI_IMG([^>]*)>/g,"<img $1/>");H=H.replace(/<YUI_INPUT([^>]*)>/g,"<input $1/>");}else{H=H.replace(/<YUI_IMG([^>]*)>/g,"<img $1>");H=H.replace(/<YUI_INPUT([^>]*)>/g,"<input $1>");}H=H.replace(/<YUI_UL([^>]*)>/g,"<ul$1>");H=H.replace(/<\/YUI_UL>/g,"</ul>");H=this.filter_invalid_lists(H);H=H.replace(/<YUI_BQ([^>]*)>/g,"<blockquote$1>");H=H.replace(/<\/YUI_BQ>/g,"</blockquote>");H=YAHOO.lang.trim(H);if(this.get("removeLineBreaks")){H=H.replace(/\n/g,"").replace(/\r/g,"");H=H.replace(/  /gi," ");
-}if(H.substring(0,6).toLowerCase()=="<span>"){H=H.substring(6);}if(H.substring(H.length-7,H.length).toLowerCase()=="</span>"){H=H.substring(0,H.length-7);}for(var F in this.invalidHTML){if(YAHOO.lang.hasOwnProperty(this.invalidHTML,F)){if(D.isObject(F)&&F.keepContents){H=H.replace(new RegExp("<"+F+"([^>]*)>(.*?)</"+F+">","gi"),"$1");}else{H=H.replace(new RegExp("<"+F+"([^>]*)>(.*?)</"+F+">","gi"),"");}}}this.fireEvent("cleanHTML",{type:"cleanHTML",target:this,html:H});return H;},filter_invalid_lists:function(F){F=F.replace(/<\/li>\n/gi,"</li>");F=F.replace(/<\/li><ol>/gi,"</li><li><ol>");F=F.replace(/<\/ol>/gi,"</ol></li>");F=F.replace(/<\/ol><\/li>\n/gi,"</ol>\n");F=F.replace(/<\/li><ul>/gi,"</li><li><ul>");F=F.replace(/<\/ul>/gi,"</ul></li>");F=F.replace(/<\/ul><\/li>\n/gi,"</ul>\n");F=F.replace(/<\/li>/gi,"</li>\n");F=F.replace(/<\/ol>/gi,"</ol>\n");F=F.replace(/<ol>/gi,"<ol>\n");F=F.replace(/<ul>/gi,"<ul>\n");return F;},filter_safari:function(F){if(this.browser.webkit){!
 F=F.replace(/Apple-style-span/gi,"");F=F.replace(/style="line-height: normal;"/gi,"");F=F.replace(/<li><\/li>/gi,"");F=F.replace(/<li> <\/li>/gi,"");F=F.replace(/<li>  <\/li>/gi,"");F=F.replace(/<div><\/div>/gi,"");F=F.replace(/<div> <\/div>/gi,"");}return F;},filter_internals:function(F){F=F.replace(/\r/g,"");F=F.replace(/<\/?(body|head|html)[^>]*>/gi,"");F=F.replace(/<YUI_BR><\/li>/gi,"</li>");F=F.replace(/yui-tag-span/gi,"");F=F.replace(/yui-tag/gi,"");F=F.replace(/yui-non/gi,"");F=F.replace(/yui-img/gi,"");F=F.replace(/ tag="span"/gi,"");F=F.replace(/ class=""/gi,"");F=F.replace(/ style=""/gi,"");F=F.replace(/ class=" "/gi,"");F=F.replace(/ class="  "/gi,"");F=F.replace(/ target=""/gi,"");F=F.replace(/ title=""/gi,"");if(this.browser.ie){F=F.replace(/ class= /gi,"");F=F.replace(/ class= >/gi,"");F=F.replace(/_height="([^>])"/gi,"");F=F.replace(/_width="([^>])"/gi,"");}return F;},filter_all_rgb:function(J){var I=new RegExp("rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\!
 s*?([0-9]+).*?\\)","gi");var F=J.match(I);if(D.isArray(F)){for!
 (var H=0
;H<F.length;H++){var G=this.filter_rgb(F[H]);J=J.replace(F[H].toString(),G);}}return J;},filter_rgb:function(H){if(H.toLowerCase().indexOf("rgb")!=-1){var K=new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)","gi");var G=H.replace(K,"$1,$2,$3,$4,$5").split(",");if(G.length==5){var J=parseInt(G[1],10).toString(16);var I=parseInt(G[2],10).toString(16);var F=parseInt(G[3],10).toString(16);J=J.length==1?"0"+J:J;I=I.length==1?"0"+I:I;F=F.length==1?"0"+F:F;H="#"+J+I+F;}}return H;},pre_filter_linebreaks:function(G,F){if(this.browser.webkit){G=G.replace(/<br class="khtml-block-placeholder">/gi,"<YUI_BR>");G=G.replace(/<br class="webkit-block-placeholder">/gi,"<YUI_BR>");}G=G.replace(/<br>/gi,"<YUI_BR>");G=G.replace(/<br (.*?)>/gi,"<YUI_BR>");G=G.replace(/<br\/>/gi,"<YUI_BR>");G=G.replace(/<br \/>/gi,"<YUI_BR>");G=G.replace(/<div><YUI_BR><\/div>/gi,"<YUI_BR>");G=G.replace(/<p>( | )<\/p>/g,"<YUI_BR>");G=G.replace(/<p><br> <\/p>/gi,"<Y!
 UI_BR>");G=G.replace(/<p> <\/p>/gi,"<YUI_BR>");G=G.replace(/<YUI_BR>$/,"");G=G.replace(/<YUI_BR><\/p>/g,"</p>");return G;},post_filter_linebreaks:function(G,F){if(F=="xhtml"){G=G.replace(/<YUI_BR>/g,"<br/>");}else{G=G.replace(/<YUI_BR>/g,"<br>");}return G;},clearEditorDoc:function(){this._getDoc().body.innerHTML=" ";},_renderPanel:function(){},openWindow:function(F){},moveWindow:function(){},_closeWindow:function(){},closeWindow:function(){this.unsubscribeAll("afterExecCommand");this.toolbar.resetAllButtons();this._focusWindow();},destroy:function(){this.saveHTML();this.toolbar.destroy();this.setStyle("visibility","hidden");this.setStyle("position","absolute");this.setStyle("top","-9999px");this.setStyle("left","-9999px");var G=this.get("element");this.get("element_cont").get("parentNode").replaceChild(G,this.get("element_cont").get("element"));this.get("element_cont").get("element").innerHTML="";for(var F in this){if(D.hasOwnProperty(this,F)){this[F]=null;}}retur!
 n true;},toString:function(){var F="SimpleEditor";if(this.get&!
 &this.ge
t("element_cont")){F="SimpleEditor (#"+this.get("element_cont").get("id")+")"+((this.get("disabled")?" Disabled":""));}return F;}});YAHOO.widget.EditorInfo={_instances:{},window:{},panel:null,getEditorById:function(F){if(!YAHOO.lang.isString(F)){F=F.id;}if(this._instances[F]){return this._instances[F];}return false;},toString:function(){var F=0;for(var G in this._instances){F++;}return"Editor Info ("+F+" registered intance"+((F>1)?"s":"")+")";}};})();(function(){var C=YAHOO.util.Dom,A=YAHOO.util.Event,D=YAHOO.lang,B=YAHOO.widget.Toolbar;YAHOO.widget.Editor=function(G,F){var H={element:null,attributes:(F||{})},I=null;if(D.isString(G)){I=G;}else{I=G.id;}H.element=G;YAHOO.widget.Editor.superclass.constructor.call(this,H.element,H.attributes);};function E(F){return F.replace(/ /g,"-").toLowerCase();}YAHOO.extend(YAHOO.widget.Editor,YAHOO.widget.SimpleEditor,{STR_BEFORE_EDITOR:"This text field can contain stylized text and graphics. To cycle through all formatting options, use th!
 e keyboard shortcut Control + Shift + T to place focus on the toolbar and navigate between option heading names. <h4>Common formatting keyboard shortcuts:</h4><ul><li>Control Shift B sets text to bold</li> <li>Control Shift I sets text to italic</li> <li>Control Shift U underlines text</li> <li>Control Shift [ aligns text left</li> <li>Control Shift | centers text</li> <li>Control Shift ] aligns text right</li> <li>Control Shift L adds an HTML link</li> <li>To exit this text editor use the keyboard shortcut Control + Shift + ESC.</li></ul>",STR_CLOSE_WINDOW:"Close Window",STR_CLOSE_WINDOW_NOTE:"To close this window use the Control + Shift + W key",STR_IMAGE_PROP_TITLE:"Image Options",STR_IMAGE_URL:"Image Url",STR_IMAGE_TITLE:"Description",STR_IMAGE_SIZE:"Size",STR_IMAGE_ORIG_SIZE:"Original Size",STR_IMAGE_COPY:"<span class=\"tip\"><span class=\"icon icon-info\"></span><strong>Note:</strong>To move this image just highlight it, cut, and paste where ever you'd like.</span>",S!
 TR_IMAGE_PADDING:"Padding",STR_IMAGE_BORDER:"Border",STR_IMAGE!
 _TEXTFLO
W:"Text Flow",STR_LOCAL_FILE_WARNING:"<span class=\"tip\"><span class=\"icon icon-warn\"></span><strong>Note:</strong>This image/link points to a file on your computer and will not be accessible to others on the internet.</span>",STR_LINK_PROP_TITLE:"Link Options",STR_LINK_PROP_REMOVE:"Remove link from text",STR_LINK_NEW_WINDOW:"Open in a new window.",STR_LINK_TITLE:"Description",CLASS_LOCAL_FILE:"warning-localfile",CLASS_HIDDEN:"yui-hidden",init:function(G,F){YAHOO.widget.Editor.superclass.init.call(this,G,F);
-},initAttributes:function(F){YAHOO.widget.Editor.superclass.initAttributes.call(this,F);this.setAttributeConfig("localFileWarning",{value:F.locaFileWarning||true});this.setAttributeConfig("hiddencss",{value:F.hiddencss||".yui-hidden font, .yui-hidden strong, .yui-hidden b, .yui-hidden em, .yui-hidden i, .yui-hidden u, .yui-hidden div,.yui-hidden p,.yui-hidden span,.yui-hidden img, .yui-hidden ul, .yui-hidden ol, .yui-hidden li, .yui-hidden table { border: 1px dotted #ccc; } .yui-hidden .yui-non { border: none; } .yui-hidden img { padding: 2px; }",writeOnce:true});},_fixNodes:function(){YAHOO.widget.Editor.superclass._fixNodes.call(this);var I="";var J=this._getDoc().getElementsByTagName("img");for(var G=0;G<J.length;G++){if(J[G].getAttribute("href",2)){I=J[G].getAttribute("src",2);if(this._isLocalFile(I)){C.addClass(J[G],this.CLASS_LOCAL_FILE);}else{C.removeClass(J[G],this.CLASS_LOCAL_FILE);}}}var H=this._getDoc().body.getElementsByTagName("a");for(var F=0;F<H.length;F++){i!
 f(H[F].getAttribute("href",2)){I=H[F].getAttribute("href",2);if(this._isLocalFile(I)){C.addClass(H[F],this.CLASS_LOCAL_FILE);}else{C.removeClass(H[F],this.CLASS_LOCAL_FILE);}}}},_disabled:["createlink","forecolor","backcolor","fontname","fontsize","superscript","subscript","removeformat","heading","indent"],_alwaysDisabled:{"outdent":true},_alwaysEnabled:{hiddenelements:true},_defaultToolbar:{collapse:true,titlebar:"Text Editing Tools",draggable:false,buttonType:"advanced",buttons:[{group:"fontstyle",label:"Font Name and Size",buttons:[{type:"select",label:"Arial",value:"fontname",disabled:true,menu:[{text:"Arial",checked:true},{text:"Arial Black"},{text:"Comic Sans MS"},{text:"Courier New"},{text:"Lucida Console"},{text:"Tahoma"},{text:"Times New Roman"},{text:"Trebuchet MS"},{text:"Verdana"}]},{type:"spin",label:"13",value:"fontsize",range:[9,75],disabled:true}]},{type:"separator"},{group:"textstyle",label:"Font Style",buttons:[{type:"push",label:"Bold CTRL + SHIFT + B",v!
 alue:"bold"},{type:"push",label:"Italic CTRL + SHIFT + I",valu!
 e:"itali
c"},{type:"push",label:"Underline CTRL + SHIFT + U",value:"underline"},{type:"separator"},{type:"push",label:"Subscript",value:"subscript",disabled:true},{type:"push",label:"Superscript",value:"superscript",disabled:true},{type:"separator"},{type:"color",label:"Font Color",value:"forecolor",disabled:true},{type:"color",label:"Background Color",value:"backcolor",disabled:true},{type:"separator"},{type:"push",label:"Remove Formatting",value:"removeformat",disabled:true},{type:"push",label:"Show/Hide Hidden Elements",value:"hiddenelements"}]},{type:"separator"},{group:"alignment",label:"Alignment",buttons:[{type:"push",label:"Align Left CTRL + SHIFT + [",value:"justifyleft"},{type:"push",label:"Align Center CTRL + SHIFT + |",value:"justifycenter"},{type:"push",label:"Align Right CTRL + SHIFT + ]",value:"justifyright"},{type:"push",label:"Justify",value:"justifyfull"}]},{type:"separator"},{group:"parastyle",label:"Paragraph Style",buttons:[{type:"select",label:"Normal",value:"he!
 ading",disabled:true,menu:[{text:"Normal",value:"none",checked:true},{text:"Header 1",value:"h1"},{text:"Header 2",value:"h2"},{text:"Header 3",value:"h3"},{text:"Header 4",value:"h4"},{text:"Header 5",value:"h5"},{text:"Header 6",value:"h6"}]}]},{type:"separator"},{group:"indentlist",label:"Indenting and Lists",buttons:[{type:"push",label:"Indent",value:"indent",disabled:true},{type:"push",label:"Outdent",value:"outdent",disabled:true},{type:"push",label:"Create an Unordered List",value:"insertunorderedlist"},{type:"push",label:"Create an Ordered List",value:"insertorderedlist"}]},{type:"separator"},{group:"insertitem",label:"Insert Item",buttons:[{type:"push",label:"HTML Link CTRL + SHIFT + L",value:"createlink",disabled:true},{type:"push",label:"Insert Image",value:"insertimage"}]}]},_handleKeyDown:function(H){YAHOO.widget.Editor.superclass._handleKeyDown.call(this,H);var G=false,I=null,F=false;if(H.shiftKey&&H.ctrlKey){G=true;}switch(H.keyCode){case 219:I="justifyleft";!
 break;case 220:I="justifycenter";break;case 221:I="justifyrigh!
 t";break
;}if(G&&I){this.execCommand(I,null);A.stopEvent(H);this.nodeChange();}},_handleCreateLinkClick:function(){var F=this._getSelectedElement();if(this._isElement(F,"img")){this.STOP_EXEC_COMMAND=true;this.currentElement[0]=F;this.toolbar.fireEvent("insertimageClick",{type:"insertimageClick",target:this.toolbar});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});return false;}if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("createlink")){return false;}}this.on("afterExecCommand",function(){var M=new YAHOO.widget.EditorWindow("createlink",{width:"350px"});var J=this.currentElement[0],I="",P="",N="",K=false;if(J){if(J.getAttribute("href",2)!==null){I=J.getAttribute("href",2);if(this._isLocalFile(I)){M.setFooter(this.STR_LOCAL_FILE_WARNING);K=true;}else{M.setFooter(" ");}}if(J.getAttribute("title")!==null){P=J.getAttribute("title");}if(J.getAttribute("target")!==null){N=J.getAttribute("target");}}var O="<label for=\"createlink_url\"><strong>"+t!
 his.STR_LINK_URL+":</strong> <input type=\"text\" name=\"createlink_url\" id=\"createlink_url\" value=\""+I+"\""+((K)?" class=\"warning\"":"")+"></label>";O+="<label for=\"createlink_target\"><strong> </strong><input type=\"checkbox\" name=\"createlink_target_\" id=\"createlink_target\" value=\"_blank\""+((N)?" checked":"")+"> "+this.STR_LINK_NEW_WINDOW+"</label>";O+="<label for=\"createlink_title\"><strong>"+this.STR_LINK_TITLE+":</strong> <input type=\"text\" name=\"createlink_title\" id=\"createlink_title\" value=\""+P+"\"></label>";var L=document.createElement("div");L.innerHTML=O;var H=document.createElement("div");H.className="removeLink";var G=document.createElement("a");G.href="#";G.innerHTML=this.STR_LINK_PROP_REMOVE;G.title=this.STR_LINK_PROP_REMOVE;A.on(G,"click",function(Q){A.stopEvent(Q);this.execCommand("unlink");this.closeWindow();},this,true);H.appendChild(G);L.appendChild(H);M.setHeader(this.STR_LINK_PROP_TITLE);
-M.setBody(L);A.onAvailable("createlink_url",function(){window.setTimeout(function(){try{YAHOO.util.Dom.get("createlink_url").focus();}catch(Q){}},50);A.on("createlink_url","blur",function(){var Q=C.get("createlink_url");if(this._isLocalFile(Q.value)){C.addClass(Q,"warning");this.get("panel").setFooter(this.STR_LOCAL_FILE_WARNING);}else{C.removeClass(Q,"warning");this.get("panel").setFooter(" ");}},this,true);},this,true);this.openWindow(M);});},_handleCreateLinkWindowClose:function(){var H=C.get("createlink_url"),J=C.get("createlink_target"),L=C.get("createlink_title"),I=this.currentElement[0],F=I;if(H&&H.value){var K=H.value;if((K.indexOf("://")==-1)&&(K.substring(0,1)!="/")&&(K.substring(0,6).toLowerCase()!="mailto")){if((K.indexOf("@")!=-1)&&(K.substring(0,6).toLowerCase()!="mailto")){K="mailto:"+K;}else{if(K.substring(0,1)!="#"){K="http://"+K;}}}I.setAttribute("href",K);if(J.checked){I.setAttribute("target",J.value);}else{I.setAttribute("target","");}I.setAttribute("tit!
 le",((L.value)?L.value:""));}else{var G=this._getDoc().createElement("span");G.innerHTML=I.innerHTML;C.addClass(G,"yui-non");I.parentNode.replaceChild(G,I);}this.nodeChange();this.currentElement=[];},_handleInsertImageClick:function(){if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("insertimage")){return false;}}this._setBusy();this.on("afterExecCommand",function(){var I=this.currentElement[0],S=null,P="",e="",f="",O="",b="",V=75,Y=75,U=0,Q=0,N=0,W=false,M=new YAHOO.widget.EditorWindow("insertimage",{width:"415px"});if(!I){I=this._getSelectedElement();}if(I){if(I.getAttribute("src")){O=I.getAttribute("src",2);if(O.indexOf(this.get("blankimage"))!=-1){O=this.STR_IMAGE_HERE;W=true;}}if(I.getAttribute("alt",2)){f=I.getAttribute("alt",2);}if(I.getAttribute("title",2)){f=I.getAttribute("title",2);}if(I.parentNode&&this._isElement(I.parentNode,"a")){P=I.parentNode.getAttribute("href",2);if(I.parentNode.getAttribute("target")!==null){e=I.parentNode.getAttribute("ta!
 rget");}}V=parseInt(I.height,10);Y=parseInt(I.width,10);if(I.s!
 tyle.hei
ght){V=parseInt(I.style.height,10);}if(I.style.width){Y=parseInt(I.style.width,10);}if(I.style.margin){U=parseInt(I.style.margin,10);}if(!I._height){I._height=V;}if(!I._width){I._width=Y;}Q=I._height;N=I._width;}var Z="<label for=\"insertimage_url\"><strong>"+this.STR_IMAGE_URL+":</strong> <input type=\"text\" id=\"insertimage_url\" value=\""+O+"\" size=\"40\"></label>";S=document.createElement("div");S.innerHTML=Z;var K=document.createElement("div");K.id="img_toolbar";S.appendChild(K);var F="<label for=\"insertimage_title\"><strong>"+this.STR_IMAGE_TITLE+":</strong> <input type=\"text\" id=\"insertimage_title\" value=\""+f+"\" size=\"40\"></label>";F+="<label for=\"insertimage_link\"><strong>"+this.STR_LINK_URL+":</strong> <input type=\"text\" name=\"insertimage_link\" id=\"insertimage_link\" value=\""+P+"\"></label>";F+="<label for=\"insertimage_target\"><strong> </strong><input type=\"checkbox\" name=\"insertimage_target_\" id=\"insertimage_target\" value=\"_blank\""!
 +((e)?" checked":"")+"> "+this.STR_LINK_NEW_WINDOW+"</label>";var T=document.createElement("div");T.innerHTML=F;S.appendChild(T);M.cache=S;var H=new YAHOO.widget.Toolbar(K,{buttonType:this._defaultToolbar.buttonType,buttons:[{group:"textflow",label:this.STR_IMAGE_TEXTFLOW+":",buttons:[{type:"push",label:"Left",value:"left"},{type:"push",label:"Inline",value:"inline"},{type:"push",label:"Block",value:"block"},{type:"push",label:"Right",value:"right"}]},{type:"separator"},{group:"padding",label:this.STR_IMAGE_PADDING+":",buttons:[{type:"spin",label:""+U,value:"padding",range:[0,50]}]},{type:"separator"},{group:"border",label:this.STR_IMAGE_BORDER+":",buttons:[{type:"select",label:"Border Size",value:"bordersize",menu:[{text:"none",value:"0",checked:true},{text:"1px",value:"1"},{text:"2px",value:"2"},{text:"3px",value:"3"},{text:"4px",value:"4"},{text:"5px",value:"5"}]},{type:"select",label:"Border Type",value:"bordertype",disabled:true,menu:[{text:"Solid",value:"solid",checke!
 d:true},{text:"Dashed",value:"dashed"},{text:"Dotted",value:"d!
 otted"}]
},{type:"color",label:"Border Color",value:"bordercolor",disabled:true}]}]});var G="0";var X="solid";if(I.style.borderLeftWidth){G=parseInt(I.style.borderLeftWidth,10);}if(I.style.borderLeftStyle){X=I.style.borderLeftStyle;}var d=H.getButtonByValue("bordersize");var a=((parseInt(G,10)>0)?"":"none");d.set("label","<span class=\"yui-toolbar-bordersize-"+G+"\">"+a+"</span>");this._updateMenuChecked("bordersize",G,H);var R=H.getButtonByValue("bordertype");R.set("label","<span class=\"yui-toolbar-bordertype-"+X+"\"></span>");this._updateMenuChecked("bordertype",X,H);if(parseInt(G,10)>0){H.enableButton(R);H.enableButton(d);}var J=H.get("cont");var c=document.createElement("div");c.className="yui-toolbar-group yui-toolbar-group-height-width height-width";c.innerHTML="<h3>"+this.STR_IMAGE_SIZE+":</h3>";var L="";if((V!=Q)||(Y!=N)){L="<span class=\"info\">"+this.STR_IMAGE_ORIG_SIZE+"<br>"+N+" x "+Q+"</span>";}c.innerHTML+="<span><input type=\"text\" size=\"3\" value=\""+Y+"\" id=\"ins!
 ertimage_width\"> x <input type=\"text\" size=\"3\" value=\""+V+"\" id=\"insertimage_height\"></span>"+L;J.insertBefore(c,J.firstChild);A.onAvailable("insertimage_width",function(){A.on("insertimage_width","blur",function(){var g=parseInt(C.get("insertimage_width").value,10);if(g>5){I.style.width=g+"px";this.moveWindow();}},this,true);},this,true);A.onAvailable("insertimage_height",function(){A.on("insertimage_height","blur",function(){var g=parseInt(C.get("insertimage_height").value,10);if(g>5){I.style.height=g+"px";this.moveWindow();}},this,true);},this,true);if((I.align=="right")||(I.align=="left")){H.selectButton(I.align);}else{if(I.style.display=="block"){H.selectButton("block");}else{H.selectButton("inline");}}if(parseInt(I.style.marginLeft,10)>0){H.getButtonByValue("padding").set("label",""+parseInt(I.style.marginLeft,10));}if(I.style.borderSize){H.selectButton("bordersize");H.selectButton(parseInt(I.style.borderSize,10));
-}H.on("colorPickerClicked",function(k){var h="1",j="solid",g="black";if(I.style.borderLeftWidth){h=parseInt(I.style.borderLeftWidth,10);}if(I.style.borderLeftStyle){j=I.style.borderLeftStyle;}if(I.style.borderLeftColor){g=I.style.borderLeftColor;}var i=h+"px "+j+" #"+k.color;I.style.border=i;},this.toolbar,true);H.on("buttonClick",function(m){var k=m.button.value,j="";if(m.button.menucmd){k=m.button.menucmd;}var h="1",i="solid",g="black";if(I.style.borderLeftWidth){h=parseInt(I.style.borderLeftWidth,10);}if(I.style.borderLeftStyle){i=I.style.borderLeftStyle;}if(I.style.borderLeftColor){g=I.style.borderLeftColor;}switch(k){case"bordersize":if(this.browser.webkit&&this._lastImage){C.removeClass(this._lastImage,"selected");this._lastImage=null;}j=parseInt(m.button.value,10)+"px "+i+" "+g;I.style.border=j;if(parseInt(m.button.value,10)>0){H.enableButton("bordertype");H.enableButton("bordercolor");}else{H.disableButton("bordertype");H.disableButton("bordercolor");}break;case"bor!
 dertype":if(this.browser.webkit&&this._lastImage){C.removeClass(this._lastImage,"selected");this._lastImage=null;}j=h+"px "+m.button.value+" "+g;I.style.border=j;break;case"right":case"left":H.deselectAllButtons();I.style.display="";I.align=m.button.value;break;case"inline":H.deselectAllButtons();I.style.display="";I.align="";break;case"block":H.deselectAllButtons();I.style.display="block";I.align="center";break;case"padding":var l=H.getButtonById(m.button.id);I.style.margin=l.get("label")+"px";break;}H.selectButton(m.button.value);this.moveWindow();},this,true);M.setHeader(this.STR_IMAGE_PROP_TITLE);M.setBody(S);if((this.browser.webkit&&!this.browser.webkit3)||this.browser.opera){M.setFooter(this.STR_IMAGE_COPY);}this.openWindow(M);A.onAvailable("insertimage_url",function(){this.toolbar.selectButton("insertimage");window.setTimeout(function(){YAHOO.util.Dom.get("insertimage_url").focus();if(W){YAHOO.util.Dom.get("insertimage_url").select();}},50);if(this.get("localFileWarn!
 ing")){A.on("insertimage_link","blur",function(){var g=C.get("!
 insertim
age_link");if(this._isLocalFile(g.value)){C.addClass(g,"warning");this.get("panel").setFooter(this.STR_LOCAL_FILE_WARNING);}else{C.removeClass(g,"warning");this.get("panel").setFooter(" ");if((this.browser.webkit&&!this.browser.webkit3)||this.browser.opera){this.get("panel").setFooter(this.STR_IMAGE_COPY);}}},this,true);A.on("insertimage_url","blur",function(){var i=C.get("insertimage_url");if(this._isLocalFile(i.value)){C.addClass(i,"warning");this.get("panel").setFooter(this.STR_LOCAL_FILE_WARNING);}else{if(this.currentElement[0]){C.removeClass(i,"warning");this.get("panel").setFooter(" ");if((this.browser.webkit&&!this.browser.webkit3)||this.browser.opera){this.get("panel").setFooter(this.STR_IMAGE_COPY);}if(i&&i.value&&(i.value!=this.STR_IMAGE_HERE)){this.currentElement[0].setAttribute("src",i.value);var h=this,g=new Image();g.onerror=function(){i.value=h.STR_IMAGE_HERE;g.setAttribute("src",h.get("blankimage"));h.currentElement[0].setAttribute("src",h.get("blankimage"));!
 YAHOO.util.Dom.get("insertimage_height").value=g.height;YAHOO.util.Dom.get("insertimage_width").value=g.width;};window.setTimeout(function(){YAHOO.util.Dom.get("insertimage_height").value=g.height;YAHOO.util.Dom.get("insertimage_width").value=g.width;if(h.currentElement&&h.currentElement[0]){if(!h.currentElement[0]._height){h.currentElement[0]._height=g.height;}if(!h.currentElement[0]._width){h.currentElement[0]._width=g.width;}}h.moveWindow();},200);if(i.value!=this.STR_IMAGE_HERE){g.src=i.value;}}}}},this,true);}},this,true);});},_handleInsertImageWindowClose:function(){var F=C.get("insertimage_url");var M=C.get("insertimage_title");var J=C.get("insertimage_link");var K=C.get("insertimage_target");var I=this.currentElement[0];if(F&&F.value&&(F.value!=this.STR_IMAGE_HERE)){I.setAttribute("src",F.value);I.setAttribute("title",M.value);I.setAttribute("alt",M.value);var H=I.parentNode;if(J.value){var L=J.value;if((L.indexOf("://")==-1)&&(L.substring(0,1)!="/")&&(L.substring(0!
 ,6).toLowerCase()!="mailto")){if((L.indexOf("@")!=-1)&&(L.subs!
 tring(0,
6).toLowerCase()!="mailto")){L="mailto:"+L;}else{L="http://"+L;}}if(H&&this._isElement(H,"a")){H.setAttribute("href",L);if(K.checked){H.setAttribute("target",K.value);}else{H.setAttribute("target","");}}else{var G=this._getDoc().createElement("a");G.setAttribute("href",L);if(K.checked){G.setAttribute("target",K.value);}else{G.setAttribute("target","");}I.parentNode.replaceChild(G,I);G.appendChild(I);}}else{if(H&&this._isElement(H,"a")){H.parentNode.replaceChild(I,H);}}}else{I.parentNode.removeChild(I);}this.currentElement=[];this.nodeChange();},_renderPanel:function(){var F=null;if(!YAHOO.widget.EditorInfo.panel){F=new YAHOO.widget.Overlay(this.EDITOR_PANEL_ID,{width:"300px",iframe:true,visible:false,underlay:"none",draggable:false,close:false});YAHOO.widget.EditorInfo.panel=F;}else{F=YAHOO.widget.EditorInfo.panel;}this.set("panel",F);this.get("panel").setBody("---");this.get("panel").setHeader(" ");this.get("panel").setFooter(" ");if(this.DOMReady){this.get("panel").render(!
 document.body);C.addClass(this.get("panel").element,"yui-editor-panel");}else{A.onDOMReady(function(){this.get("panel").render(document.body);C.addClass(this.get("panel").element,"yui-editor-panel");},this,true);}this.get("panel").showEvent.subscribe(function(){YAHOO.util.Dom.setStyle(this.element,"display","block");});return this.get("panel");},openWindow:function(K){this.toolbar.set("disabled",true);A.on(document,"keypress",this._closeWindow,this,true);if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}YAHOO.widget.EditorInfo.window.win=K;YAHOO.widget.EditorInfo.window.scope=this;var P=this,L=C.getXY(this.currentElement[0]),U=C.getXY(this.get("iframe").get("element")),N=this.get("panel"),T=[(L[0]+U[0]-20),(L[1]+U[1]+10)],O=(parseInt(K.attrs.width,10)/2),R="center",M=null;this.fireEvent("beforeOpenWindow",{type:"beforeOpenWindow",win:K,panel:N});
-M=document.createElement("div");M.className=this.CLASS_PREFIX+"-body-cont";for(var V in this.browser){if(this.browser[V]){C.addClass(M,V);break;}}C.addClass(M,((YAHOO.widget.Button&&(this._defaultToolbar.buttonType=="advanced"))?"good-button":"no-button"));var S=document.createElement("h3");S.className="yui-editor-skipheader";S.innerHTML=this.STR_CLOSE_WINDOW_NOTE;M.appendChild(S);form=document.createElement("form");form.setAttribute("method","GET");var W=K.name;A.on(form,"submit",function(Y){var X="window"+W+"Submit";P.fireEvent(X,{type:X,target:this});A.stopEvent(Y);},this,true);M.appendChild(form);if(D.isObject(K.body)){form.appendChild(K.body);}else{var F=document.createElement("div");F.innerHTML=K.body;form.appendChild(F);}var J=document.createElement("span");J.innerHTML="X";J.title=this.STR_CLOSE_WINDOW;J.className="close";A.on(J,"click",function(){this.closeWindow();},this,true);var H=document.createElement("span");H.innerHTML="^";H.className="knob";K._knob=H;var I=d!
 ocument.createElement("h3");I.innerHTML=K.header;N.cfg.setProperty("width",K.attrs.width);N.setHeader(" ");N.appendToHeader(I);I.appendChild(J);I.appendChild(H);N.setBody(" ");N.setFooter(" ");if(K.footer!==null){N.setFooter(K.footer);C.addClass(N.footer,"open");}else{C.removeClass(N.footer,"open");}N.appendToBody(M);var Q=function(){N.bringToTop();A.on(N.element,"click",function(X){A.stopPropagation(X);});this._setBusy(true);N.showEvent.unsubscribe(Q);};N.showEvent.subscribe(Q,this,true);var G=function(){this.currentWindow=null;var X="window"+W+"Close";this.fireEvent(X,{type:X,target:this});N.hideEvent.unsubscribe(G);};N.hideEvent.subscribe(G,this,true);this.currentWindow=K;this.moveWindow(true);N.show();this.fireEvent("afterOpenWindow",{type:"afterOpenWindow",win:K,panel:N});},moveWindow:function(G){if(!this.currentWindow){return false;}var I=this.currentWindow,J=C.getXY(this.currentElement[0]),Z=C.getXY(this.get("iframe").get("element")),O=this.get("panel"),X=[(J[0]+Z[0]!
 ),(J[1]+Z[1])],Q=(parseInt(I.attrs.width,10)/2),T="center",P=O!
 .cfg.get
Property("xy"),H=I._knob,W=0,L=0,S=false;X[0]=((X[0]-Q)+20);X[0]=X[0]-C.getDocumentScrollLeft(this._getDoc());X[1]=X[1]-C.getDocumentScrollTop(this._getDoc());if(this._isElement(this.currentElement[0],"img")){if(this.currentElement[0].src.indexOf(this.get("blankimage"))!=-1){X[0]=(X[0]+(75/2));X[1]=(X[1]+75);}else{var N=parseInt(this.currentElement[0].width,10);var V=parseInt(this.currentElement[0].height,10);X[0]=(X[0]+(N/2));X[1]=(X[1]+V);}X[1]=X[1]+15;}else{var K=C.getStyle(this.currentElement[0],"fontSize");if(K&&K.indexOf&&K.indexOf("px")!=-1){X[1]=X[1]+parseInt(C.getStyle(this.currentElement[0],"fontSize"),10)+5;}else{X[1]=X[1]+20;}}if(X[0]<Z[0]){X[0]=Z[0]+5;T="left";}if((X[0]+(Q*2))>(Z[0]+parseInt(this.get("iframe").get("element").clientWidth,10))){X[0]=((Z[0]+parseInt(this.get("iframe").get("element").clientWidth,10))-(Q*2)-5);T="right";}try{W=(X[0]-P[0]);L=(X[1]-P[1]);}catch(a){}W=((W<0)?(W*-1):W);L=((L<0)?(L*-1):L);if(((W>10)||(L>10))||G){var R=0,U=0;if(this.curren!
 tElement[0].width){U=(parseInt(this.currentElement[0].width,10)/2);}var M=J[0]+Z[0]+U;R=M-X[0];if(R>(parseInt(I.attrs.width,10)-40)){R=parseInt(I.attrs.width,10)-40;}else{if(R<40){R=40;}}if(isNaN(R)){R=40;}if(G){if(H){H.style.left=R+"px";}if(this.get("animate")){C.setStyle(O.element,"opacity","0");S=new YAHOO.util.Anim(O.element,{opacity:{from:0,to:1}},0.1,YAHOO.util.Easing.easeOut);O.cfg.setProperty("xy",X);S.onComplete.subscribe(function(){if(this.browser.ie){O.element.style.filter="none";}},this,true);S.animate();}else{O.cfg.setProperty("xy",X);}}else{if(this.get("animate")){S=new YAHOO.util.Anim(O.element,{},0.5,YAHOO.util.Easing.easeOut);S.attributes={top:{to:X[1]},left:{to:X[0]}};S.onComplete.subscribe(function(){O.cfg.setProperty("xy",X);});var Y=new YAHOO.util.Anim(O.iframe,S.attributes,0.5,YAHOO.util.Easing.easeOut);var F=new YAHOO.util.Anim(H,{left:{to:R}},0.6,YAHOO.util.Easing.easeOut);S.animate();Y.animate();F.animate();}else{H.style.left=R+"px";O.cfg.setPropert!
 y("xy",X);}}}},_closeWindow:function(F){if((F.charCode==87)&&F!
 .shiftKe
y&&F.ctrlKey){if(this.currentWindow){this.closeWindow();}}},closeWindow:function(){YAHOO.widget.EditorInfo.window={};this.fireEvent("closeWindow",{type:"closeWindow",win:this.currentWindow});this.currentWindow=null;this.get("panel").hide();this.get("panel").cfg.setProperty("xy",[-900,-900]);this.get("panel").syncIframe();this.unsubscribeAll("afterExecCommand");this.toolbar.set("disabled",false);this.toolbar.resetAllButtons();this._focusWindow();A.removeListener(document,"keypress",this._closeWindow);},cmd_heading:function(J){var G=true,H=null,I="heading",K=this._getSelection(),F=this._getSelectedElement();if(F){K=F;}if(this.browser.ie){I="formatblock";}if(J=="none"){if((K&&K.tagName&&(K.tagName.toLowerCase().substring(0,1)=="h"))||(K&&K.parentNode&&K.parentNode.tagName&&(K.parentNode.tagName.toLowerCase().substring(0,1)=="h"))){if(K.parentNode.tagName.toLowerCase().substring(0,1)=="h"){K=K.parentNode;}if(this._isElement(K,"html")){return[false];}H=this._swapEl(F,"span",funct!
 ion(L){L.className="yui-non";});this._selectNode(H);this.currentElement[0]=H;}G=false;}else{if(this._isElement(F,"h1")||this._isElement(F,"h2")||this._isElement(F,"h3")||this._isElement(F,"h4")||this._isElement(F,"h5")||this._isElement(F,"h6")){H=this._swapEl(F,J);this._selectNode(H);this.currentElement[0]=H;}else{this._createCurrentElement(J);this._selectNode(this.currentElement[0]);}G=false;}return[G,I];},cmd_hiddenelements:function(F){if(this._showingHiddenElements){this._lastButton=null;this._showingHiddenElements=false;this.toolbar.deselectButton("hiddenelements");C.removeClass(this._getDoc().body,this.CLASS_HIDDEN);}else{this._showingHiddenElements=true;C.addClass(this._getDoc().body,this.CLASS_HIDDEN);this.toolbar.selectButton("hiddenelements");}return[false];},cmd_removeformat:function(I){var G=true;if(this.browser.webkit&&!this._getDoc().queryCommandEnabled("removeformat")){var F=this._getSelection()+"";
-this._createCurrentElement("span");this.currentElement[0].className="yui-non";this.currentElement[0].innerHTML=F;for(var H=1;H<this.currentElement.length;H++){this.currentElement[H].parentNode.removeChild(this.currentElement[H]);}G=false;}return[G];},cmd_script:function(L,K){var H=true,F=L.toLowerCase().substring(0,3),I=null,G=this._getSelectedElement();if(this.browser.webkit){if(this._isElement(G,F)){I=this._swapEl(this.currentElement[0],"span",function(M){M.className="yui-non";});this._selectNode(I);}else{this._createCurrentElement(F);var J=this._swapEl(this.currentElement[0],F);this._selectNode(J);this.currentElement[0]=J;}H=false;}return H;},cmd_superscript:function(F){return[this.cmd_script("superscript",F)];},cmd_subscript:function(F){return[this.cmd_script("subscript",F)];},cmd_indent:function(I){var F=true,H=this._getSelectedElement(),J=null;if(this.browser.webkit||this.browser.ie||this.browser.gecko){if(this._isElement(H,"blockquote")){J=this._getDoc().createElemen!
 t("blockquote");J.innerHTML=H.innerHTML;H.innerHTML="";H.appendChild(J);this._selectNode(J);}else{this._createCurrentElement("blockquote");for(var G=0;G<this.currentElement.length;G++){J=this._getDoc().createElement("blockquote");J.innerHTML=this.currentElement[G].innerHTML;this.currentElement[G].parentNode.replaceChild(J,this.currentElement[G]);this.currentElement[G]=J;}this._selectNode(this.currentElement[0]);}F=false;}else{I="blockquote";}return[F,"indent",I];},cmd_outdent:function(J){var F=true,I=this._getSelectedElement(),K=null,G=null;if(this.browser.webkit||this.browser.ie||this.browser.gecko){I=this._getSelectedElement();if(this._isElement(I,"blockquote")){var H=I.parentNode;if(this._isElement(I.parentNode,"blockquote")){H.innerHTML=I.innerHTML;this._selectNode(H);}else{G=this._getDoc().createElement("span");G.innerHTML=I.innerHTML;YAHOO.util.Dom.addClass(G,"yui-non");H.replaceChild(G,I);this._selectNode(G);}}else{}F=false;}else{J="blockquote";}return[F,"indent",J];!
 },toString:function(){var F="Editor";if(this.get&&this.get("el!
 ement_co
nt")){F="Editor (#"+this.get("element_cont").get("id")+")"+((this.get("disabled")?" Disabled":""));}return F;}});YAHOO.widget.EditorWindow=function(G,F){this.name=G.replace(" ","_");this.attrs=F;};YAHOO.widget.EditorWindow.prototype={_cache:null,header:null,body:null,footer:null,setHeader:function(F){this.header=F;},setBody:function(F){this.body=F;},setFooter:function(F){this.footer=F;},toString:function(){return"Editor Window ("+this.name+")";}};})();YAHOO.register("editor",YAHOO.widget.Editor,{version:"2.4.1",build:"742"});
\ No newline at end of file
+(function(){var B=YAHOO.util.Dom,A=YAHOO.util.Event,C=YAHOO.lang;if(YAHOO.widget.Button){YAHOO.widget.ToolbarButtonAdvanced=YAHOO.widget.Button;YAHOO.widget.ToolbarButtonAdvanced.prototype.buttonType="rich";YAHOO.widget.ToolbarButtonAdvanced.prototype.checkValue=function(F){var E=this.getMenu().getItems();if(E.length===0){this.getMenu()._onBeforeShow();E=this.getMenu().getItems();}for(var D=0;D<E.length;D++){E[D].cfg.setProperty("checked",false);if(E[D].value==F){E[D].cfg.setProperty("checked",true);}}};}else{YAHOO.widget.ToolbarButtonAdvanced=function(){};}YAHOO.widget.ToolbarButton=function(E,D){if(C.isObject(arguments[0])&&!B.get(E).nodeType){D=E;}var G=(D||{});var F={element:null,attributes:G};if(!F.attributes.type){F.attributes.type="push";}F.element=document.createElement("span");F.element.setAttribute("unselectable","on");F.element.className="yui-button yui-"+F.attributes.type+"-button";F.element.innerHTML='<span class="first-child"><a href="#">LABEL</a></span>';F.el!
 ement.firstChild.firstChild.tabIndex="-1";F.attributes.id=B.generateId();YAHOO.widget.ToolbarButton.superclass.constructor.call(this,F.element,F.attributes);};YAHOO.extend(YAHOO.widget.ToolbarButton,YAHOO.util.Element,{buttonType:"normal",_handleMouseOver:function(){if(!this.get("disabled")){this.addClass("yui-button-hover");this.addClass("yui-"+this.get("type")+"-button-hover");}},_handleMouseOut:function(){this.removeClass("yui-button-hover");this.removeClass("yui-"+this.get("type")+"-button-hover");},checkValue:function(F){if(this.get("type")=="menu"){var E=this._button.options;for(var D=0;D<E.length;D++){if(E[D].value==F){E.selectedIndex=D;}}}},init:function(E,D){YAHOO.widget.ToolbarButton.superclass.init.call(this,E,D);this.on("mouseover",this._handleMouseOver,this,true);this.on("mouseout",this._handleMouseOut,this,true);},initAttributes:function(D){YAHOO.widget.ToolbarButton.superclass.initAttributes.call(this,D);this.setAttributeConfig("value",{value:D.value});this.s!
 etAttributeConfig("menu",{value:D.menu||false});this.setAttrib!
 uteConfi
g("type",{value:D.type,writeOnce:true,method:function(H){var G,F;if(!this._button){this._button=this.get("element").getElementsByTagName("a")[0];}switch(H){case"select":case"menu":G=document.createElement("select");var I=this.get("menu");for(var E=0;E<I.length;E++){F=document.createElement("option");F.innerHTML=I[E].text;F.value=I[E].value;if(I[E].checked){F.selected=true;}G.appendChild(F);}this._button.parentNode.replaceChild(G,this._button);A.on(G,"change",this._handleSelect,this,true);this._button=G;break;}}});this.setAttributeConfig("disabled",{value:D.disabled||false,method:function(E){if(E){this.addClass("yui-button-disabled");this.addClass("yui-"+this.get("type")+"-button-disabled");}else{this.removeClass("yui-button-disabled");this.removeClass("yui-"+this.get("type")+"-button-disabled");}if(this.get("type")=="menu"){this._button.disabled=E;}}});this.setAttributeConfig("label",{value:D.label,method:function(E){if(!this._button){this._button=this.get("element").getElem!
 entsByTagName("a")[0];}if(this.get("type")=="push"){this._button.innerHTML=E;}}});this.setAttributeConfig("title",{value:D.title});this.setAttributeConfig("container",{value:null,writeOnce:true,method:function(E){this.appendTo(E);}});},_handleSelect:function(E){var D=A.getTarget(E);var F=D.options[D.selectedIndex].value;this.fireEvent("change",{type:"change",value:F});},getMenu:function(){return this.get("menu");},destroy:function(){A.purgeElement(this.get("element"),true);this.get("element").parentNode.removeChild(this.get("element"));for(var D in this){if(C.hasOwnProperty(this,D)){this[D]=null;}}},fireEvent:function(E,D){if(this.DOM_EVENTS[E]&&this.get("disabled")){return ;}YAHOO.widget.ToolbarButton.superclass.fireEvent.call(this,E,D);},toString:function(){return"ToolbarButton ("+this.get("id")+")";}});})();(function(){var C=YAHOO.util.Dom,A=YAHOO.util.Event,E=YAHOO.lang;var B=function(G){var F=G;if(E.isString(G)){F=this.getButtonById(G);}if(E.isNumber(G)){F=this.getButt!
 onByIndex(G);}if((!(F instanceof YAHOO.widget.ToolbarButton))&!
 &(!(F in
stanceof YAHOO.widget.ToolbarButtonAdvanced))){F=this.getButtonByValue(G);}if((F instanceof YAHOO.widget.ToolbarButton)||(F instanceof YAHOO.widget.ToolbarButtonAdvanced)){return F;}return false;};YAHOO.widget.Toolbar=function(J,I){if(E.isObject(arguments[0])&&!C.get(J).nodeType){I=J;}var L=(I||{});var K={element:null,attributes:L};if(E.isString(J)&&C.get(J)){K.element=C.get(J);}else{if(E.isObject(J)&&C.get(J)&&C.get(J).nodeType){K.element=C.get(J);}}if(!K.element){K.element=document.createElement("DIV");K.element.id=C.generateId();if(L.container&&C.get(L.container)){C.get(L.container).appendChild(K.element);}}if(!K.element.id){K.element.id=((E.isString(J))?J:C.generateId());}var G=document.createElement("fieldset");var H=document.createElement("legend");H.innerHTML="Toolbar";G.appendChild(H);var F=document.createElement("DIV");K.attributes.cont=F;C.addClass(F,"yui-toolbar-subcont");G.appendChild(F);K.element.appendChild(G);K.element.tabIndex=-1;K.attributes.element=K.elemen!
 t;K.attributes.id=K.element.id;YAHOO.widget.Toolbar.superclass.constructor.call(this,K.element,K.attributes);};function D(I,F,J){C.addClass(this.element,"yui-toolbar-"+J.get("value")+"-menu");if(C.hasClass(J._button.parentNode.parentNode,"yui-toolbar-select")){C.addClass(this.element,"yui-toolbar-select-menu");}var G=this.getItems();for(var H=0;H<G.length;H++){C.addClass(G[H].element,"yui-toolbar-"+J.get("value")+"-"+((G[H].value)?G[H].value.replace(/ /g,"-").toLowerCase():G[H]._oText.nodeValue.replace(/ /g,"-").toLowerCase()));C.addClass(G[H].element,"yui-toolbar-"+J.get("value")+"-"+((G[H].value)?G[H].value.replace(/ /g,"-"):G[H]._oText.nodeValue.replace(/ /g,"-")));}}YAHOO.extend(YAHOO.widget.Toolbar,YAHOO.util.Element,{buttonType:YAHOO.widget.ToolbarButton,dd:null,_colorData:{"#111111":"Obsidian","#2D2D2D":"Dark Gray","#434343":"Shale","#5B5B5B":"Flint","#737373":"Gray","#8B8B8B":"Concrete","#A2A2A2":"Gray","#B9B9B9":"Titanium","#000000":"Black","#D0D0D0":"Light Gray","!
 #E6E6E6":"Silver","#FFFFFF":"White","#BFBF00":"Pumpkin","#FFFF!
 00":"Yel
low","#FFFF40":"Banana","#FFFF80":"Pale Yellow","#FFFFBF":"Butter","#525330":"Raw Siena","#898A49":"Mildew","#AEA945":"Olive","#7F7F00":"Paprika","#C3BE71":"Earth","#E0DCAA":"Khaki","#FCFAE1":"Cream","#60BF00":"Cactus","#80FF00":"Chartreuse","#A0FF40":"Green","#C0FF80":"Pale Lime","#DFFFBF":"Light Mint","#3B5738":"Green","#668F5A":"Lime Gray","#7F9757":"Yellow","#407F00":"Clover","#8A9B55":"Pistachio","#B7C296":"Light Jade","#E6EBD5":"Breakwater","#00BF00":"Spring Frost","#00FF80":"Pastel Green","#40FFA0":"Light Emerald","#80FFC0":"Sea Foam","#BFFFDF":"Sea Mist","#033D21":"Dark Forrest","#438059":"Moss","#7FA37C":"Medium Green","#007F40":"Pine","#8DAE94":"Yellow Gray Green","#ACC6B5":"Aqua Lung","#DDEBE2":"Sea Vapor","#00BFBF":"Fog","#00FFFF":"Cyan","#40FFFF":"Turquoise Blue","#80FFFF":"Light Aqua","#BFFFFF":"Pale Cyan","#033D3D":"Dark Teal","#347D7E":"Gray Turquoise","#609A9F":"Green Blue","#007F7F":"Seaweed","#96BDC4":"Green Gray","#B5D1D7":"Soapstone","#E2F1F4":"Light Tur!
 quoise","#0060BF":"Summer Sky","#0080FF":"Sky Blue","#40A0FF":"Electric Blue","#80C0FF":"Light Azure","#BFDFFF":"Ice Blue","#1B2C48":"Navy","#385376":"Biscay","#57708F":"Dusty Blue","#00407F":"Sea Blue","#7792AC":"Sky Blue Gray","#A8BED1":"Morning Sky","#DEEBF6":"Vapor","#0000BF":"Deep Blue","#0000FF":"Blue","#4040FF":"Cerulean Blue","#8080FF":"Evening Blue","#BFBFFF":"Light Blue","#212143":"Deep Indigo","#373E68":"Sea Blue","#444F75":"Night Blue","#00007F":"Indigo Blue","#585E82":"Dockside","#8687A4":"Blue Gray","#D2D1E1":"Light Blue Gray","#6000BF":"Neon Violet","#8000FF":"Blue Violet","#A040FF":"Violet Purple","#C080FF":"Violet Dusk","#DFBFFF":"Pale Lavender","#302449":"Cool Shale","#54466F":"Dark Indigo","#655A7F":"Dark Violet","#40007F":"Violet","#726284":"Smoky Violet","#9E8FA9":"Slate Gray","#DCD1DF":"Violet White","#BF00BF":"Royal Violet","#FF00FF":"Fuchsia","#FF40FF":"Magenta","#FF80FF":"Orchid","#FFBFFF":"Pale Magenta","#4A234A":"Dark Purple","#794A72":"Medium Pur!
 ple","#936386":"Cool Granite","#7F007F":"Purple","#9D7292":"Pu!
 rple Moo
n","#C0A0B6":"Pale Purple","#ECDAE5":"Pink Cloud","#BF005F":"Hot Pink","#FF007F":"Deep Pink","#FF409F":"Grape","#FF80BF":"Electric Pink","#FFBFDF":"Pink","#451528":"Purple Red","#823857":"Purple Dino","#A94A76":"Purple Gray","#7F003F":"Rose","#BC6F95":"Antique Mauve","#D8A5BB":"Cool Marble","#F7DDE9":"Pink Granite","#C00000":"Apple","#FF0000":"Fire Truck","#FF4040":"Pale Red","#FF8080":"Salmon","#FFC0C0":"Warm Pink","#441415":"Sepia","#82393C":"Rust","#AA4D4E":"Brick","#800000":"Brick Red","#BC6E6E":"Mauve","#D8A3A4":"Shrimp Pink","#F8DDDD":"Shell Pink","#BF5F00":"Dark Orange","#FF7F00":"Orange","#FF9F40":"Grapefruit","#FFBF80":"Canteloupe","#FFDFBF":"Wax","#482C1B":"Dark Brick","#855A40":"Dirt","#B27C51":"Tan","#7F3F00":"Nutmeg","#C49B71":"Mustard","#E1C4A8":"Pale Tan","#FDEEE0":"Marble"},_colorPicker:null,STR_COLLAPSE:"Collapse Toolbar",STR_SPIN_LABEL:"Spin Button with value {VALUE}. Use Control Shift Up Arrow and Control Shift Down arrow keys to increase or decrease the v!
 alue.",STR_SPIN_UP:"Click to increase the value of this input",STR_SPIN_DOWN:"Click to decrease the value of this input",_titlebar:null,browser:YAHOO.env.ua,_buttonList:null,_buttonGroupList:null,_sep:null,_sepCount:null,_dragHandle:null,_toolbarConfigs:{renderer:true},CLASS_CONTAINER:"yui-toolbar-container",CLASS_DRAGHANDLE:"yui-toolbar-draghandle",CLASS_SEPARATOR:"yui-toolbar-separator",CLASS_DISABLED:"yui-toolbar-disabled",CLASS_PREFIX:"yui-toolbar",init:function(G,F){YAHOO.widget.Toolbar.superclass.init.call(this,G,F);
+},initAttributes:function(F){YAHOO.widget.Toolbar.superclass.initAttributes.call(this,F);this.addClass(this.CLASS_CONTAINER);this.setAttributeConfig("buttonType",{value:F.buttonType||"basic",writeOnce:true,validator:function(G){switch(G){case"advanced":case"basic":return true;}return false;},method:function(G){if(G=="advanced"){if(YAHOO.widget.Button){this.buttonType=YAHOO.widget.ToolbarButtonAdvanced;}else{this.buttonType=YAHOO.widget.ToolbarButton;}}else{this.buttonType=YAHOO.widget.ToolbarButton;}}});this.setAttributeConfig("buttons",{value:[],writeOnce:true,method:function(H){for(var G in H){if(E.hasOwnProperty(H,G)){if(H[G].type=="separator"){this.addSeparator();}else{if(H[G].group!==undefined){this.addButtonGroup(H[G]);}else{this.addButton(H[G]);}}}}}});this.setAttributeConfig("disabled",{value:false,method:function(G){if(this.get("disabled")===G){return false;}if(G){this.addClass(this.CLASS_DISABLED);this.set("draggable",false);this.disableAllButtons();}else{this.rem!
 oveClass(this.CLASS_DISABLED);if(this._configs.draggable._initialConfig.value){this.set("draggable",true);}this.resetAllButtons();}}});this.setAttributeConfig("cont",{value:F.cont,readOnly:true});this.setAttributeConfig("grouplabels",{value:((F.grouplabels===false)?false:true),method:function(G){if(G){C.removeClass(this.get("cont"),(this.CLASS_PREFIX+"-nogrouplabels"));}else{C.addClass(this.get("cont"),(this.CLASS_PREFIX+"-nogrouplabels"));}}});this.setAttributeConfig("titlebar",{value:false,method:function(H){if(H){if(this._titlebar&&this._titlebar.parentNode){this._titlebar.parentNode.removeChild(this._titlebar);}this._titlebar=document.createElement("DIV");this._titlebar.tabIndex="-1";A.on(this._titlebar,"focus",function(){this._handleFocus();},this,true);C.addClass(this._titlebar,this.CLASS_PREFIX+"-titlebar");if(E.isString(H)){var G=document.createElement("h2");G.tabIndex="-1";G.innerHTML='<a href="#" tabIndex="0">'+H+"</a>";this._titlebar.appendChild(G);A.on(G.firstCh!
 ild,"click",function(I){A.stopEvent(I);});A.on([G,G.firstChild!
 ],"focus
",function(){this._handleFocus();},this,true);}if(this.get("firstChild")){this.insertBefore(this._titlebar,this.get("firstChild"));}else{this.appendChild(this._titlebar);}if(this.get("collapse")){this.set("collapse",true);}}else{if(this._titlebar){if(this._titlebar&&this._titlebar.parentNode){this._titlebar.parentNode.removeChild(this._titlebar);}}}}});this.setAttributeConfig("collapse",{value:false,method:function(I){if(this._titlebar){var H=null;var G=C.getElementsByClassName("collapse","span",this._titlebar);if(I){if(G.length>0){return true;}H=document.createElement("SPAN");H.innerHTML="X";H.title=this.STR_COLLAPSE;C.addClass(H,"collapse");this._titlebar.appendChild(H);A.addListener(H,"click",function(){if(C.hasClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed")){this.collapse(false);}else{this.collapse();}},this,true);}else{H=C.getElementsByClassName("collapse","span",this._titlebar);if(H[0]){if(C.hasClass(this.get("cont").parentNode,"yui-toolbar-contain!
 er-collapsed")){this.collapse(false);}H[0].parentNode.removeChild(H[0]);}}}}});this.setAttributeConfig("draggable",{value:(F.draggable||false),method:function(G){if(G&&!this.get("titlebar")){if(!this._dragHandle){this._dragHandle=document.createElement("SPAN");this._dragHandle.innerHTML="|";this._dragHandle.setAttribute("title","Click to drag the toolbar");this._dragHandle.id=this.get("id")+"_draghandle";C.addClass(this._dragHandle,this.CLASS_DRAGHANDLE);if(this.get("cont").hasChildNodes()){this.get("cont").insertBefore(this._dragHandle,this.get("cont").firstChild);}else{this.get("cont").appendChild(this._dragHandle);}this.dd=new YAHOO.util.DD(this.get("id"));this.dd.setHandleElId(this._dragHandle.id);}}else{if(this._dragHandle){this._dragHandle.parentNode.removeChild(this._dragHandle);this._dragHandle=null;this.dd=null;}}if(this._titlebar){if(G){this.dd=new YAHOO.util.DD(this.get("id"));this.dd.setHandleElId(this._titlebar);C.addClass(this._titlebar,"draggable");}else{C.re!
 moveClass(this._titlebar,"draggable");if(this.dd){this.dd.unre!
 g();this
.dd=null;}}}},validator:function(H){var G=true;if(!YAHOO.util.DD){G=false;}return G;}});},addButtonGroup:function(J){if(!this.get("element")){this._queue[this._queue.length]=["addButtonGroup",arguments];return false;}if(!this.hasClass(this.CLASS_PREFIX+"-grouped")){this.addClass(this.CLASS_PREFIX+"-grouped");}var K=document.createElement("DIV");C.addClass(K,this.CLASS_PREFIX+"-group");C.addClass(K,this.CLASS_PREFIX+"-group-"+J.group);if(J.label){var G=document.createElement("h3");G.innerHTML=J.label;K.appendChild(G);}if(!this.get("grouplabels")){C.addClass(this.get("cont"),this.CLASS_PREFIX,"-nogrouplabels");}this.get("cont").appendChild(K);var I=document.createElement("ul");K.appendChild(I);if(!this._buttonGroupList){this._buttonGroupList={};}this._buttonGroupList[J.group]=I;for(var H=0;H<J.buttons.length;H++){var F=document.createElement("li");F.className=this.CLASS_PREFIX+"-groupitem";I.appendChild(F);if((J.buttons[H].type!==undefined)&&J.buttons[H].type=="separator"){thi!
 s.addSeparator(F);}else{J.buttons[H].container=F;this.addButton(J.buttons[H]);}}},addButtonToGroup:function(H,I,J){var G=this._buttonGroupList[I];var F=document.createElement("li");F.className=this.CLASS_PREFIX+"-groupitem";H.container=F;this.addButton(H,J);G.appendChild(F);},addButton:function(K,J){if(!this.get("element")){this._queue[this._queue.length]=["addButton",arguments];return false;}if(!this._buttonList){this._buttonList=[];}if(!K.container){K.container=this.get("cont");}if((K.type=="menu")||(K.type=="split")||(K.type=="select")){if(E.isArray(K.menu)){for(var Q in K.menu){if(E.hasOwnProperty(K.menu,Q)){var W={fn:function(Z,X,Y){if(!K.menucmd){K.menucmd=K.value;}K.value=((Y.value)?Y.value:Y._oText.nodeValue);},scope:this};K.menu[Q].onclick=W;}}}}var R={},O=false;for(var M in K){if(E.hasOwnProperty(K,M)){if(!this._toolbarConfigs[M]){R[M]=K[M];}}}if(K.type=="select"){R.type="menu";}if(K.type=="spin"){R.type="push";
+}if(R.type=="color"){if(YAHOO.widget.Overlay){R=this._makeColorButton(R);}else{O=true;}}if(R.menu){if((YAHOO.widget.Overlay)&&(K.menu instanceof YAHOO.widget.Overlay)){K.menu.showEvent.subscribe(function(){this._button=R;});}else{for(var P=0;P<R.menu.length;P++){if(!R.menu[P].value){R.menu[P].value=R.menu[P].text;}}if(this.browser.webkit){R.focusmenu=false;}}}if(O){K=false;}else{this._configs.buttons.value[this._configs.buttons.value.length]=K;var U=new this.buttonType(R);U.get("element").tabIndex="-1";U.get("element").setAttribute("role","button");U._selected=true;if(!U.buttonType){U.buttonType="rich";U.checkValue=function(Z){var Y=this.getMenu().getItems();if(Y.length===0){this.getMenu()._onBeforeShow();Y=this.getMenu().getItems();}for(var X=0;X<Y.length;X++){Y[X].cfg.setProperty("checked",false);if(Y[X].value==Z){Y[X].cfg.setProperty("checked",true);}}};}if(this.get("disabled")){U.set("disabled",true);}if(!K.id){K.id=U.get("id");}if(J){var G=U.get("element");var N=null;i!
 f(J.get){N=J.get("element").nextSibling;}else{if(J.nextSibling){N=J.nextSibling;}}if(N){N.parentNode.insertBefore(G,N);}}U.addClass(this.CLASS_PREFIX+"-"+U.get("value"));var T=document.createElement("span");T.className=this.CLASS_PREFIX+"-icon";U.get("element").insertBefore(T,U.get("firstChild"));if(U._button.tagName.toLowerCase()=="button"){U.get("element").setAttribute("unselectable","on");var V=document.createElement("a");V.innerHTML=U._button.innerHTML;V.href="#";V.tabIndex="-1";A.on(V,"click",function(X){A.stopEvent(X);});U._button.parentNode.replaceChild(V,U._button);U._button=V;}if(K.type=="select"){if(U._button.tagName.toLowerCase()=="select"){T.parentNode.removeChild(T);var H=U._button;var S=U.get("element");S.parentNode.replaceChild(H,S);}else{U.addClass(this.CLASS_PREFIX+"-select");}}if(K.type=="spin"){if(!E.isArray(K.range)){K.range=[10,100];}this._makeSpinButton(U,K);}U.get("element").setAttribute("title",U.get("label"));if(K.type!="spin"){if((YAHOO.widget.Over!
 lay)&&(R.menu instanceof YAHOO.widget.Overlay)){var I=function!
 (Z){var 
X=true;if(Z.keyCode&&(Z.keyCode==9)){X=false;}if(X){if(this._colorPicker){this._colorPicker._button=K.value;}var Y=U.getMenu().element;if(C.getStyle(Y,"visibility")=="hidden"){U.getMenu().show();}else{U.getMenu().hide();}}YAHOO.util.Event.stopEvent(Z);};U.on("mousedown",I,K,this);U.on("keydown",I,K,this);}else{if((K.type!="menu")&&(K.type!="select")){U.on("keypress",this._buttonClick,K,this);U.on("mousedown",function(X){YAHOO.util.Event.stopEvent(X);this._buttonClick(X,K);},K,this);U.on("click",function(X){});}else{U.on("mousedown",function(X){YAHOO.util.Event.stopEvent(X);});U.on("click",function(X){YAHOO.util.Event.stopEvent(X);});U.on("change",function(X){if(!K.menucmd){K.menucmd=K.value;}K.value=X.value;this._buttonClick(X,K);},this,true);var L=this;if(U.getMenu().mouseDownEvent){U.getMenu().mouseDownEvent.subscribe(function(Z,Y){var X=Y[1];YAHOO.util.Event.stopEvent(Y[0]);U._onMenuClick(Y[0],U);if(!K.menucmd){K.menucmd=K.value;}K.value=((X.value)?X.value:X._oText.nodeVa!
 lue);L._buttonClick.call(L,Y[1],K);U._hideMenu();return false;});U.getMenu().clickEvent.subscribe(function(Y,X){YAHOO.util.Event.stopEvent(X[0]);});U.getMenu().mouseUpEvent.subscribe(function(Y,X){YAHOO.util.Event.stopEvent(X[0]);});}}}}else{U.on("mousedown",function(X){YAHOO.util.Event.stopEvent(X);});U.on("click",function(X){YAHOO.util.Event.stopEvent(X);});}if(this.browser.ie){}if(this.browser.webkit){U.hasFocus=function(){return true;};}this._buttonList[this._buttonList.length]=U;if((K.type=="menu")||(K.type=="split")||(K.type=="select")){if(E.isArray(K.menu)){var F=U.getMenu();if(F.renderEvent){F.renderEvent.subscribe(D,U);if(K.renderer){F.renderEvent.subscribe(K.renderer,U);}}}}}return K;},addSeparator:function(F,I){if(!this.get("element")){this._queue[this._queue.length]=["addSeparator",arguments];return false;}var G=((F)?F:this.get("cont"));if(!this.get("element")){this._queue[this._queue.length]=["addSeparator",arguments];return false;}if(this._sepCount===null){thi!
 s._sepCount=0;}if(!this._sep){this._sep=document.createElement!
 ("SPAN")
;C.addClass(this._sep,this.CLASS_SEPARATOR);this._sep.innerHTML="|";}var H=this._sep.cloneNode(true);this._sepCount++;C.addClass(H,this.CLASS_SEPARATOR+"-"+this._sepCount);if(I){var J=null;if(I.get){J=I.get("element").nextSibling;}else{if(I.nextSibling){J=I.nextSibling;}else{J=I;}}if(J){if(J==I){J.parentNode.appendChild(H);}else{J.parentNode.insertBefore(H,J);}}}else{G.appendChild(H);}return H;},_createColorPicker:function(I){if(C.get(I+"_colors")){C.get(I+"_colors").parentNode.removeChild(C.get(I+"_colors"));}var F=document.createElement("div");F.className="yui-toolbar-colors";F.id=I+"_colors";F.style.display="none";A.on(window,"load",function(){document.body.appendChild(F);},this,true);this._colorPicker=F;var H="";for(var G in this._colorData){if(E.hasOwnProperty(this._colorData,G)){H+='<a style="background-color: '+G+'" href="#">'+G.replace("#","")+"</a>";}}H+="<span><em>X</em><strong></strong></span>";window.setTimeout(function(){F.innerHTML=H;},0);A.on(F,"mouseover",fun!
 ction(N){var L=this._colorPicker;var M=L.getElementsByTagName("em")[0];var K=L.getElementsByTagName("strong")[0];var J=A.getTarget(N);if(J.tagName.toLowerCase()=="a"){M.style.backgroundColor=J.style.backgroundColor;K.innerHTML=this._colorData["#"+J.innerHTML]+"<br>"+J.innerHTML;}},this,true);A.on(F,"focus",function(J){A.stopEvent(J);});A.on(F,"click",function(J){A.stopEvent(J);});A.on(F,"mousedown",function(K){A.stopEvent(K);var J=A.getTarget(K);if(J.tagName.toLowerCase()=="a"){var M=this.fireEvent("colorPickerClicked",{type:"colorPickerClicked",target:this,button:this._colorPicker._button,color:J.innerHTML,colorName:this._colorData["#"+J.innerHTML]});if(M!==false){var L={color:J.innerHTML,colorName:this._colorData["#"+J.innerHTML],value:this._colorPicker._button};this.fireEvent("buttonClick",{type:"buttonClick",target:this.get("element"),button:L});}this.getButtonByValue(this._colorPicker._button).getMenu().hide();
+}},this,true);},_resetColorPicker:function(){var G=this._colorPicker.getElementsByTagName("em")[0];var F=this._colorPicker.getElementsByTagName("strong")[0];G.style.backgroundColor="transparent";F.innerHTML="";},_makeColorButton:function(F){if(!this._colorPicker){this._createColorPicker(this.get("id"));}F.type="color";F.menu=new YAHOO.widget.Overlay(this.get("id")+"_"+F.value+"_menu",{visible:false,position:"absolute",iframe:true});F.menu.setBody("");F.menu.render(this.get("cont"));C.addClass(F.menu.element,"yui-button-menu");C.addClass(F.menu.element,"yui-color-button-menu");F.menu.beforeShowEvent.subscribe(function(){F.menu.cfg.setProperty("zindex",5);F.menu.cfg.setProperty("context",[this.getButtonById(F.id).get("element"),"tl","bl"]);this._resetColorPicker();var G=this._colorPicker;if(G.parentNode){G.parentNode.removeChild(G);}F.menu.setBody("");F.menu.appendToBody(G);this._colorPicker.style.display="block";},this,true);return F;},_makeSpinButton:function(S,M){S.addClas!
 s(this.CLASS_PREFIX+"-spinbutton");var T=this,O=S._button.parentNode.parentNode,J=M.range,I=document.createElement("a"),H=document.createElement("a");I.href="#";H.href="#";I.tabIndex="-1";H.tabIndex="-1";I.className="up";I.title=this.STR_SPIN_UP;I.innerHTML=this.STR_SPIN_UP;H.className="down";H.title=this.STR_SPIN_DOWN;H.innerHTML=this.STR_SPIN_DOWN;O.appendChild(I);O.appendChild(H);var N=YAHOO.lang.substitute(this.STR_SPIN_LABEL,{VALUE:S.get("label")});S.set("title",N);var R=function(U){U=((U<J[0])?J[0]:U);U=((U>J[1])?J[1]:U);return U;};var Q=this.browser;var G=false;var L=this.STR_SPIN_LABEL;if(this._titlebar&&this._titlebar.firstChild){G=this._titlebar.firstChild;}var F=function(V){YAHOO.util.Event.stopEvent(V);if(!S.get("disabled")&&(V.keyCode!=9)){var W=parseInt(S.get("label"),10);W++;W=R(W);S.set("label",""+W);var U=YAHOO.lang.substitute(L,{VALUE:S.get("label")});S.set("title",U);if(!Q.webkit&&G){}T._buttonClick(V,M);}};var P=function(V){YAHOO.util.Event.stopEvent(V);!
 if(!S.get("disabled")&&(V.keyCode!=9)){var W=parseInt(S.get("l!
 abel"),1
0);W--;W=R(W);S.set("label",""+W);var U=YAHOO.lang.substitute(L,{VALUE:S.get("label")});S.set("title",U);if(!Q.webkit&&G){}T._buttonClick(V,M);}};var K=function(U){if(U.keyCode==38){F(U);}else{if(U.keyCode==40){P(U);}else{if(U.keyCode==107&&U.shiftKey){F(U);}else{if(U.keyCode==109&&U.shiftKey){P(U);}}}}};S.on("keydown",K,this,true);A.on(I,"mousedown",function(U){A.stopEvent(U);},this,true);A.on(H,"mousedown",function(U){A.stopEvent(U);},this,true);A.on(I,"click",F,this,true);A.on(H,"click",P,this,true);},_buttonClick:function(M,G){var F=true;if(M&&M.type=="keypress"){if(M.keyCode==9){F=false;}else{if((M.keyCode===13)||(M.keyCode===0)||(M.keyCode===32)){}else{F=false;}}}if(F){var O=true,I=false;if(G.value){I=this.fireEvent(G.value+"Click",{type:G.value+"Click",target:this.get("element"),button:G});if(I===false){O=false;}}if(G.menucmd&&O){I=this.fireEvent(G.menucmd+"Click",{type:G.menucmd+"Click",target:this.get("element"),button:G});if(I===false){O=false;}}if(O){this.fireEven!
 t("buttonClick",{type:"buttonClick",target:this.get("element"),button:G});}if(G.type=="select"){var L=this.getButtonById(G.id);if(L.buttonType=="rich"){var K=G.value;for(var J=0;J<G.menu.length;J++){if(G.menu[J].value==G.value){K=G.menu[J].text;break;}}L.set("label",'<span class="yui-toolbar-'+G.menucmd+"-"+(G.value).replace(/ /g,"-").toLowerCase()+'">'+K+"</span>");var N=L.getMenu().getItems();for(var H=0;H<N.length;H++){if(N[H].value.toLowerCase()==G.value.toLowerCase()){N[H].cfg.setProperty("checked",true);}else{N[H].cfg.setProperty("checked",false);}}}}if(M){A.stopEvent(M);}}},_keyNav:null,_navCounter:null,_navigateButtons:function(G){switch(G.keyCode){case 37:case 39:if(G.keyCode==37){this._navCounter--;}else{this._navCounter++;}if(this._navCounter>(this._buttonList.length-1)){this._navCounter=0;}if(this._navCounter<0){this._navCounter=(this._buttonList.length-1);}var F=this._buttonList[this._navCounter].get("element");if(this.browser.ie){F=this._buttonList[this._navCo!
 unter].get("element").getElementsByTagName("a")[0];}if(this._b!
 uttonLis
t[this._navCounter].get("disabled")){this._navigateButtons(G);}else{F.focus();}break;}},_handleFocus:function(){if(!this._keyNav){var F="keypress";if(this.browser.ie){F="keydown";}A.on(this.get("element"),F,this._navigateButtons,this,true);this._keyNav=true;this._navCounter=-1;}},getButtonById:function(H){var F=this._buttonList.length;for(var G=0;G<F;G++){if(this._buttonList[G].get("id")==H){return this._buttonList[G];}}return false;},getButtonByValue:function(L){var I=this.get("buttons");var G=I.length;for(var J=0;J<G;J++){if(I[J].group!==undefined){for(var F=0;F<I[J].buttons.length;F++){if((I[J].buttons[F].value==L)||(I[J].buttons[F].menucmd==L)){return this.getButtonById(I[J].buttons[F].id);}if(I[J].buttons[F].menu){for(var K=0;K<I[J].buttons[F].menu.length;K++){if(I[J].buttons[F].menu[K].value==L){return this.getButtonById(I[J].buttons[F].id);}}}}}else{if((I[J].value==L)||(I[J].menucmd==L)){return this.getButtonById(I[J].id);}if(I[J].menu){for(var H=0;H<I[J].menu.length;!
 H++){if(I[J].menu[H].value==L){return this.getButtonById(I[J].id);}}}}}return false;},getButtonByIndex:function(F){if(this._buttonList[F]){return this._buttonList[F];}else{return false;}},getButtons:function(){return this._buttonList;},disableButton:function(G){var F=B.call(this,G);if(F){F.set("disabled",true);}else{return false;}},enableButton:function(G){if(this.get("disabled")){return false;}var F=B.call(this,G);if(F){if(F.get("disabled")){F.set("disabled",false);}}else{return false;}},isSelected:function(G){var F=B.call(this,G);if(F){return F._selected;}return false;},selectButton:function(J,H){var G=B.call(this,J);if(G){G.addClass("yui-button-selected");G.addClass("yui-button-"+G.get("value")+"-selected");G._selected=true;if(H){if(G.buttonType=="rich"){var I=G.getMenu().getItems();for(var F=0;F<I.length;F++){if(I[F].value==H){I[F].cfg.setProperty("checked",true);G.set("label",'<span class="yui-toolbar-'+G.get("value")+"-"+(H).replace(/ /g,"-").toLowerCase()+'">'+I[F]._!
 oText.nodeValue+"</span>");
+}else{I[F].cfg.setProperty("checked",false);}}}}}else{return false;}},deselectButton:function(G){var F=B.call(this,G);if(F){F.removeClass("yui-button-selected");F.removeClass("yui-button-"+F.get("value")+"-selected");F.removeClass("yui-button-hover");F._selected=false;}else{return false;}},deselectAllButtons:function(){var F=this._buttonList.length;for(var G=0;G<F;G++){this.deselectButton(this._buttonList[G]);}},disableAllButtons:function(){if(this.get("disabled")){return false;}var F=this._buttonList.length;for(var G=0;G<F;G++){this.disableButton(this._buttonList[G]);}},enableAllButtons:function(){if(this.get("disabled")){return false;}var F=this._buttonList.length;for(var G=0;G<F;G++){this.enableButton(this._buttonList[G]);}},resetAllButtons:function(J){if(!E.isObject(J)){J={};}if(this.get("disabled")){return false;}var F=this._buttonList.length;for(var G=0;G<F;G++){var I=this._buttonList[G];var H=I._configs.disabled._initialConfig.value;if(J[I.get("id")]){this.enableButt!
 on(I);this.selectButton(I);}else{if(H){this.disableButton(I);}else{this.enableButton(I);}this.deselectButton(I);}}},destroyButton:function(J){var H=B.call(this,J);if(H){var I=H.get("id");H.destroy();var F=this._buttonList.length;for(var G=0;G<F;G++){if(this._buttonList[G].get("id")==I){this._buttonList[G]=null;}}}else{return false;}},destroy:function(){this.get("element").innerHTML="";this.get("element").className="";for(var F in this){if(E.hasOwnProperty(this,F)){this[F]=null;}}return true;},collapse:function(G){var F=C.getElementsByClassName("collapse","span",this._titlebar);if(G===false){C.removeClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed");if(F[0]){C.removeClass(F[0],"collapsed");}this.fireEvent("toolbarExpanded",{type:"toolbarExpanded",target:this});}else{if(F[0]){C.addClass(F[0],"collapsed");}C.addClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed");this.fireEvent("toolbarCollapsed",{type:"toolbarCollapsed",target:this});}},toStr!
 ing:function(){return"Toolbar (#"+this.get("element").id+") wi!
 th "+thi
s._buttonList.length+" buttons.";}});})();(function(){var C=YAHOO.util.Dom,A=YAHOO.util.Event,D=YAHOO.lang,B=YAHOO.widget.Toolbar;YAHOO.widget.SimpleEditor=function(I,N){var H={};if(D.isObject(I)&&(!I.tagName)&&!N){D.augmentObject(H,I);I=document.createElement("textarea");this.DOMReady=true;if(H.container){var L=C.get(H.container);L.appendChild(I);}else{document.body.appendChild(I);}}else{D.augmentObject(H,N);}var J={element:null,attributes:H},G=null;if(D.isString(I)){G=I;}else{if(J.attributes.id){G=J.attributes.id;}else{G=C.generateId(I);}}J.element=I;var K=document.createElement("DIV");J.attributes.element_cont=new YAHOO.util.Element(K,{id:G+"_container"});var F=document.createElement("div");C.addClass(F,"first-child");J.attributes.element_cont.appendChild(F);if(!J.attributes.toolbar_cont){J.attributes.toolbar_cont=document.createElement("DIV");J.attributes.toolbar_cont.id=G+"_toolbar";F.appendChild(J.attributes.toolbar_cont);}var M=document.createElement("DIV");F.appendCh!
 ild(M);J.attributes.editor_wrapper=M;YAHOO.widget.SimpleEditor.superclass.constructor.call(this,J.element,J.attributes);};function E(F){return F.replace(/ /g,"-").toLowerCase();}YAHOO.extend(YAHOO.widget.SimpleEditor,YAHOO.util.Element,{_docType:'<!DOCTYPE HTML PUBLIC "-/'+"/W3C/"+"/DTD HTML 4.01/"+'/EN" "http:/'+'/www.w3.org/TR/html4/strict.dtd">',editorDirty:null,_defaultCSS:"html { height: 95%; } body { padding: 7px; background-color: #fff; font:13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a { color: blue; text-decoration: underline; cursor: text; } .warning-localfile { border-bottom: 1px dashed red !important; } .yui-busy { cursor: wait !important; } img.selected { border: 2px dotted #808080; } img { cursor: pointer !important; border: none; }",_defaultToolbar:null,_lastButton:null,_baseHREF:function(){var F=document.location.href;if(F.indexOf("?")!==-1){F=F.substring(0,F.indexOf("?"));}F=F.substring(0,F.lastIndexOf("/"))+"/";return F;}()!
 ,_lastImage:null,_blankImageLoaded:null,_fixNodesTimer:null,_n!
 odeChang
eTimer:null,_lastNodeChangeEvent:null,_lastNodeChange:0,_rendered:null,DOMReady:null,_selection:null,_mask:null,_showingHiddenElements:null,currentWindow:null,currentEvent:null,operaEvent:null,currentFont:null,currentElement:null,dompath:null,beforeElement:null,afterElement:null,invalidHTML:{form:true,input:true,button:true,select:true,link:true,html:true,body:true,iframe:true,script:true,style:true,textarea:true},toolbar:null,_contentTimer:null,_contentTimerCounter:0,_disabled:["createlink","fontname","fontsize","forecolor","backcolor"],_alwaysDisabled:{},_alwaysEnabled:{},_semantic:{"bold":true,"italic":true,"underline":true},_tag2cmd:{"b":"bold","strong":"bold","i":"italic","em":"italic","u":"underline","sup":"superscript","sub":"subscript","img":"insertimage","a":"createlink","ul":"insertunorderedlist","ol":"insertorderedlist"},_createIframe:function(){var J=document.createElement("iframe");J.id=this.get("id")+"_editor";var H={border:"0",frameBorder:"0",marginWidth:"0",m!
 arginHeight:"0",leftMargin:"0",topMargin:"0",allowTransparency:"true",width:"100%"};if(this.get("autoHeight")){H.scrolling="no";}for(var I in H){if(D.hasOwnProperty(H,I)){J.setAttribute(I,H[I]);}}var G="javascript:;";if(this.browser.ie){G="about:blank";}J.setAttribute("src",G);var F=new YAHOO.util.Element(J);return F;},_isElement:function(G,F){if(G&&G.tagName&&(G.tagName.toLowerCase()==F)){return true;}if(G&&G.getAttribute&&(G.getAttribute("tag")==F)){return true;}return false;},_hasParent:function(G,F){if(!G||!G.parentNode){return false;}while(G.parentNode){if(this._isElement(G,F)){return G;}if(G.parentNode){G=G.parentNode;}else{return false;}}return false;},_getDoc:function(){var F=false;if(this.get){if(this.get("iframe")){if(this.get("iframe").get){if(this.get("iframe").get("element")){try{if(this.get("iframe").get("element").contentWindow){if(this.get("iframe").get("element").contentWindow.document){F=this.get("iframe").get("element").contentWindow.document;
+return F;}}}catch(G){}}}}}return false;},_getWindow:function(){return this.get("iframe").get("element").contentWindow;},_focusWindow:function(F){if(this.browser.webkit){if(F){this._getSelection().setBaseAndExtent(this._getDoc().body.firstChild,0,this._getDoc().body.firstChild,1);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(false);}}else{this._getSelection().setBaseAndExtent(this._getDoc().body,1,this._getDoc().body,1);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(false);}}this._getWindow().focus();}else{this._getWindow().focus();}},_hasSelection:function(){var H=this._getSelection();var F=this._getRange();var G=false;if(!H||!F){return G;}if(this.browser.ie||this.browser.opera){if(F.text){G=true;}if(F.html){G=true;}}else{if(this.browser.webkit){if(H+""!==""){G=true;}}else{if(H&&(H.toString()!=="")&&(H!==undefined)){G=true;}}}return G;},_getSelection:function(){var F=n!
 ull;if(this._getDoc()&&this._getWindow()){if(this._getDoc().selection){F=this._getDoc().selection;}else{F=this._getWindow().getSelection();}if(this.browser.webkit){if(F.baseNode){this._selection={};this._selection.baseNode=F.baseNode;this._selection.baseOffset=F.baseOffset;this._selection.extentNode=F.extentNode;this._selection.extentOffset=F.extentOffset;}else{if(this._selection!==null){F=this._getWindow().getSelection();F.setBaseAndExtent(this._selection.baseNode,this._selection.baseOffset,this._selection.extentNode,this._selection.extentOffset);this._selection=null;}}}}return F;},_selectNode:function(G){if(!G){return false;}var H=this._getSelection(),F=null;if(this.browser.ie){try{F=this._getDoc().body.createTextRange();F.moveToElementText(G);F.select();}catch(I){}}else{if(this.browser.webkit){H.setBaseAndExtent(G,0,G,G.innerText.length);}else{if(this.browser.opera){H=this._getWindow().getSelection();F=this._getDoc().createRange();F.selectNode(G);H.removeAllRanges();H.ad!
 dRange(F);}else{F=this._getDoc().createRange();F.selectNodeCon!
 tents(G)
;H.removeAllRanges();H.addRange(F);}}}},_getRange:function(){var F=this._getSelection();if(F===null){return null;}if(this.browser.webkit&&!F.getRangeAt){var H=this._getDoc().createRange();try{H.setStart(F.anchorNode,F.anchorOffset);H.setEnd(F.focusNode,F.focusOffset);}catch(G){H=this._getWindow().getSelection()+"";}return H;}if(this.browser.ie||this.browser.opera){try{return F.createRange();}catch(G){return null;}}if(F.rangeCount>0){return F.getRangeAt(0);}return null;},_setDesignMode:function(F){try{var H=true;if(this.browser.ie&&(F.toLowerCase()=="off")){H=false;}if(H){this._getDoc().designMode=F;}}catch(G){}},_toggleDesignMode:function(){var G=this._getDoc().designMode.toLowerCase(),F="on";if(G=="on"){F="off";}this._setDesignMode(F);return F;},_initEditor:function(){if(this.browser.ie){this._getDoc().body.style.margin="0";}if(!this.get("disabled")){if(this._getDoc().designMode.toLowerCase()!="on"){this._setDesignMode("on");this._contentTimerCounter=0;}}if(!this._getDoc().!
 body){this._contentTimerCounter=0;this._checkLoaded();return false;}this.toolbar.on("buttonClick",this._handleToolbarClick,this,true);A.on(this._getDoc(),"mouseup",this._handleMouseUp,this,true);A.on(this._getDoc(),"mousedown",this._handleMouseDown,this,true);A.on(this._getDoc(),"click",this._handleClick,this,true);A.on(this._getDoc(),"dblclick",this._handleDoubleClick,this,true);A.on(this._getDoc(),"keypress",this._handleKeyPress,this,true);A.on(this._getDoc(),"keyup",this._handleKeyUp,this,true);A.on(this._getDoc(),"keydown",this._handleKeyDown,this,true);if(!this.get("disabled")){this.toolbar.set("disabled",false);}this.fireEvent("editorContentLoaded",{type:"editorLoaded",target:this});if(this.get("dompath")){var F=this;setTimeout(function(){F._writeDomPath.call(F);},150);}this.nodeChange(true);this._setBusy(true);},_checkLoaded:function(){this._contentTimerCounter++;if(this._contentTimer){clearTimeout(this._contentTimer);}if(this._contentTimerCounter>500){return false;}!
 var H=false;try{if(this._getDoc()&&this._getDoc().body){if(thi!
 s.browse
r.ie){if(this._getDoc().body.readyState=="complete"){H=true;}}else{if(this._getDoc().body._rteLoaded===true){H=true;}}}}catch(G){H=false;}if(H===true){this._initEditor();}else{var F=this;this._contentTimer=setTimeout(function(){F._checkLoaded.call(F);},20);}},_setInitialContent:function(){var G=D.substitute(this.get("html"),{TITLE:this.STR_TITLE,CONTENT:this._cleanIncomingHTML(this.get("element").value),CSS:this.get("css"),HIDDEN_CSS:((this.get("hiddencss"))?this.get("hiddencss"):"/* No Hidden CSS */"),EXTRA_CSS:((this.get("extracss"))?this.get("extracss"):"/* No Extra CSS */")}),F=true;if(document.compatMode!="BackCompat"){G=this._docType+"\n"+G;}else{}if(this.browser.ie||this.browser.webkit||this.browser.opera||(navigator.userAgent.indexOf("Firefox/1.5")!=-1)){try{if(this.browser.air){var J=this._getDoc().implementation.createHTMLDocument();var K=this._getDoc();K.open();K.close();J.open();J.write(G);J.close();var H=K.importNode(J.getElementsByTagName("html")[0],true);K.rep!
 laceChild(H,K.getElementsByTagName("html")[0]);K.body._rteLoaded=true;}else{this._getDoc().open();this._getDoc().write(G);this._getDoc().close();}}catch(I){F=false;}}else{this.get("iframe").get("element").src="data:text/html;charset=utf-8,"+encodeURIComponent(G);}if(F){this._checkLoaded();}},_setMarkupType:function(F){switch(this.get("markup")){case"css":this._setEditorStyle(true);break;case"default":this._setEditorStyle(false);break;case"semantic":case"xhtml":if(this._semantic[F]){this._setEditorStyle(false);}else{this._setEditorStyle(true);}break;}},_setEditorStyle:function(G){try{this._getDoc().execCommand("useCSS",false,!G);}catch(F){}},_getSelectedElement:function(){var I=this._getDoc(),F=null,G=null,J=null;if(this.browser.ie){this.currentEvent=this._getWindow().event;F=this._getRange();if(F){J=F.item?F.item(0):F.parentElement();if(J==I.body){J=null;}}if((this.currentEvent!==null)&&(this.currentEvent.keyCode===0)){J=A.getTarget(this.currentEvent);
+}}else{G=this._getSelection();F=this._getRange();if(!G||!F){return null;}if(!this._hasSelection()){if(G.anchorNode&&(G.anchorNode.nodeType==3)){if(G.anchorNode.parentNode){J=G.anchorNode.parentNode;}if(G.anchorNode.nextSibling!=G.focusNode.nextSibling){J=G.anchorNode.nextSibling;}}if(this._isElement(J,"br")){J=null;}if(!J){J=F.commonAncestorContainer;if(!F.collapsed){if(F.startContainer==F.endContainer){if(F.startOffset-F.endOffset<2){if(F.startContainer.hasChildNodes()){J=F.startContainer.childNodes[F.startOffset];}}}}}}}if(this.currentEvent!==null){try{switch(this.currentEvent.type){case"click":case"mousedown":case"mouseup":J=A.getTarget(this.currentEvent);break;default:break;}}catch(H){}}else{if((this.currentElement&&this.currentElement[0])&&(!this.browser.ie)){J=this.currentElement[0];}}if(this.browser.opera||this.browser.webkit){if(this.currentEvent&&!J){J=YAHOO.util.Event.getTarget(this.currentEvent);}}if(!J||!J.tagName){J=I.body;}if(this._isElement(J,"html")){J=I.bod!
 y;}if(this._isElement(J,"body")){J=I.body;}if(J&&!J.parentNode){J=I.body;}if(J===undefined){J=null;}return J;},_getDomPath:function(F){if(!F){F=this._getSelectedElement();}var G=[];while(F!==null){if(F.ownerDocument!=this._getDoc()){F=null;break;}if(F.nodeName&&F.nodeType&&(F.nodeType==1)){G[G.length]=F;}if(this._isElement(F,"body")){break;}F=F.parentNode;}if(G.length===0){if(this._getDoc()&&this._getDoc().body){G[0]=this._getDoc().body;}}return G.reverse();},_writeDomPath:function(){var L=this._getDomPath(),J=[],H="",M="";for(var F=0;F<L.length;F++){var N=L[F].tagName.toLowerCase();if((N=="ol")&&(L[F].type)){N+=":"+L[F].type;}if(C.hasClass(L[F],"yui-tag")){N=L[F].getAttribute("tag");}if((this.get("markup")=="semantic")||(this.get("markup")=="xhtml")){switch(N){case"b":N="strong";break;case"i":N="em";break;}}if(!C.hasClass(L[F],"yui-non")){if(C.hasClass(L[F],"yui-tag")){M=N;}else{H=((L[F].className!=="")?"."+L[F].className.replace(/ /g,"."):"");if((H.indexOf("yui")!=-1)||(H!
 .toLowerCase().indexOf("apple-style-span")!=-1)){H="";}M=N+((L!
 [F].id)?
"#"+L[F].id:"")+H;}switch(N){case"a":if(L[F].getAttribute("href",2)){M+=":"+L[F].getAttribute("href",2).replace("mailto:","").replace("http:/"+"/","").replace("https:/"+"/","");}break;case"img":var G=L[F].height;var K=L[F].width;if(L[F].style.height){G=parseInt(L[F].style.height,10);}if(L[F].style.width){K=parseInt(L[F].style.width,10);}M+="("+G+"x"+K+")";break;}if(M.length>10){M='<span title="'+M+'">'+M.substring(0,10)+"..."+"</span>";}else{M='<span title="'+M+'">'+M+"</span>";}J[J.length]=M;}}var I=J.join(" "+this.SEP_DOMPATH+" ");if(this.dompath.innerHTML!=I){this.dompath.innerHTML=I;}},_fixNodes:function(){var K=this._getDoc(),I=[];for(var F in this.invalidHTML){if(YAHOO.lang.hasOwnProperty(this.invalidHTML,F)){if(F.toLowerCase()!="span"){var G=K.body.getElementsByTagName(F);if(G.length){for(var H=0;H<G.length;H++){I.push(G[H]);}}}}}for(var J=0;J<I.length;J++){if(I[J].parentNode){if(D.isObject(this.invalidHTML[I[J].tagName.toLowerCase()])&&this.invalidHTML[I[J].tagName.t!
 oLowerCase()].keepContents){this._swapEl(I[J],"span",function(M){M.className="yui-non";});}else{I[J].parentNode.removeChild(I[J]);}}}var L=this._getDoc().getElementsByTagName("img");C.addClass(L,"yui-img");},_isNonEditable:function(H){if(this.get("allowNoEdit")){var G=A.getTarget(H);if(this._isElement(G,"html")){G=null;}var J=this._getDomPath(G);for(var F=(J.length-1);F>-1;F--){if(C.hasClass(J[F],this.CLASS_NOEDIT)){try{this._getDoc().execCommand("enableObjectResizing",false,"false");}catch(I){}this.nodeChange();A.stopEvent(H);return true;}}try{this._getDoc().execCommand("enableObjectResizing",false,"true");}catch(I){}}return false;},_setCurrentEvent:function(F){this.currentEvent=F;},_handleClick:function(G){if(this._isNonEditable(G)){return false;}this._setCurrentEvent(G);if(this.currentWindow){this.closeWindow();}if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window!
 .scope);}if(this.browser.webkit){var F=A.getTarget(G);if(this.!
 _isEleme
nt(F,"a")||this._isElement(F.parentNode,"a")){A.stopEvent(G);this.nodeChange();}}else{this.nodeChange();}},_handleMouseUp:function(G){if(this._isNonEditable(G)){return false;}var F=this;if(this.browser.opera){var H=A.getTarget(G);if(this._isElement(H,"img")){this.nodeChange();if(this.operaEvent){clearTimeout(this.operaEvent);this.operaEvent=null;this._handleDoubleClick(G);}else{this.operaEvent=window.setTimeout(function(){F.operaEvent=false;},700);}}}if(this.browser.webkit||this.browser.opera){if(this.browser.webkit){A.stopEvent(G);}}this.nodeChange();this.fireEvent("editorMouseUp",{type:"editorMouseUp",target:this,ev:G});},_handleMouseDown:function(F){if(this._isNonEditable(F)){return false;}this._setCurrentEvent(F);var G=A.getTarget(F);if(this.browser.webkit&&this._hasSelection()){var H=this._getSelection();if(!this.browser.webkit3){H.collapse(true);}else{H.collapseToStart();}}if(this.browser.webkit&&this._lastImage){C.removeClass(this._lastImage,"selected");this._lastImag!
 e=null;}if(this._isElement(G,"img")||this._isElement(G,"a")){if(this.browser.webkit){A.stopEvent(F);if(this._isElement(G,"img")){C.addClass(G,"selected");this._lastImage=G;}}this.nodeChange();}this.fireEvent("editorMouseDown",{type:"editorMouseDown",target:this,ev:F});},_handleDoubleClick:function(F){if(this._isNonEditable(F)){return false;}this._setCurrentEvent(F);var G=A.getTarget(F);if(this._isElement(G,"img")){this.currentElement[0]=G;this.toolbar.fireEvent("insertimageClick",{type:"insertimageClick",target:this.toolbar});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});}else{if(this._hasParent(G,"a")){this.currentElement[0]=this._hasParent(G,"a");this.toolbar.fireEvent("createlinkClick",{type:"createlinkClick",target:this.toolbar});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});}}this.nodeChange();this.editorDirty=false;this.fireEvent("editorDoubleClick",{type:"editorDoubleClick",target:this,ev:F});
+},_handleKeyUp:function(G){if(this._isNonEditable(G)){return false;}this._setCurrentEvent(G);switch(G.keyCode){case 37:case 38:case 39:case 40:case 46:case 8:case 87:if((G.keyCode==87)&&this.currentWindow&&G.shiftKey&&G.ctrlKey){this.closeWindow();}else{if(!this.browser.ie){if(this._nodeChangeTimer){clearTimeout(this._nodeChangeTimer);}var F=this;this._nodeChangeTimer=setTimeout(function(){F._nodeChangeTimer=null;F.nodeChange.call(F);},100);}else{this.nodeChange();}this.editorDirty=true;}break;}this.fireEvent("editorKeyUp",{type:"editorKeyUp",target:this,ev:G});},_handleKeyPress:function(F){if(this.get("allowNoEdit")){if(F&&F.keyCode&&((F.keyCode==46)||F.keyCode==63272)){A.stopEvent(F);}}if(this._isNonEditable(F)){return false;}this._setCurrentEvent(F);if(this.browser.webkit){if(!this.browser.webkit3){if(F.keyCode&&(F.keyCode==122)&&(F.metaKey)){if(this._hasParent(this._getSelectedElement(),"li")){A.stopEvent(F);}}}this._listFix(F);}this.fireEvent("editorKeyPress",{type:"ed!
 itorKeyPress",target:this,ev:F});},_listFix:function(L){var O=null,J=null,F=false,H=null;if(this.browser.webkit){if(L.keyCode&&(L.keyCode==13)){if(this._hasParent(this._getSelectedElement(),"li")){var I=this._hasParent(this._getSelectedElement(),"li");var N=this._getDoc().createElement("li");N.innerHTML='<span class="yui-non"> </span> ';if(I.nextSibling){I.parentNode.insertBefore(N,I.nextSibling);}else{I.parentNode.appendChild(N);}this.currentElement[0]=N;this._selectNode(N.firstChild);if(!this.browser.webkit3){I.parentNode.style.display="list-item";setTimeout(function(){I.parentNode.style.display="block";},1);}A.stopEvent(L);}}}if(L.keyCode&&((!this.browser.webkit3&&(L.keyCode==25))||((this.browser.webkit3||!this.browser.webkit)&&((L.keyCode==9)&&L.shiftKey)))){O=this._getSelectedElement();if(this._hasParent(O,"li")){O=this._hasParent(O,"li");if(this._hasParent(O,"ul")||this._hasParent(O,"ol")){J=this._hasParent(O,"ul");if(!J){J=this._hasParent(O,"ol");}if(this._!
 isElement(J.previousSibling,"li")){J.removeChild(O);J.parentNo!
 de.inser
tBefore(O,J.nextSibling);if(this.browser.ie){H=this._getDoc().body.createTextRange();H.moveToElementText(O);H.collapse(false);H.select();}if(this.browser.webkit){if(!this.browser.webkit3){J.style.display="list-item";J.parentNode.style.display="list-item";setTimeout(function(){J.style.display="block";J.parentNode.style.display="block";},1);}}A.stopEvent(L);}}}}if(L.keyCode&&((L.keyCode==9)&&(!L.shiftKey))){var G=this._getSelectedElement();if(this._hasParent(G,"li")){F=this._hasParent(G,"li").innerHTML;}if(this.browser.webkit){this._getDoc().execCommand("inserttext",false,"\t");}O=this._getSelectedElement();if(this._hasParent(O,"li")){J=this._hasParent(O,"li");var K=this._getDoc().createElement(J.parentNode.tagName.toLowerCase());if(this.browser.webkit){var M=C.getElementsByClassName("Apple-tab-span","span",J);if(M[0]){J.removeChild(M[0]);J.innerHTML=D.trim(J.innerHTML);if(F){J.innerHTML='<span class="yui-non">'+F+"</span> ";}else{J.innerHTML='<span class="yui-non"> !
 </span> ';}}}else{if(F){J.innerHTML=F+" ";}else{J.innerHTML=" ";}}J.parentNode.replaceChild(K,J);K.appendChild(J);if(this.browser.webkit){this._getSelection().setBaseAndExtent(J.firstChild,1,J.firstChild,J.firstChild.innerText.length);if(!this.browser.webkit3){J.parentNode.parentNode.style.display="list-item";setTimeout(function(){J.parentNode.parentNode.style.display="block";},1);}}else{if(this.browser.ie){H=this._getDoc().body.createTextRange();H.moveToElementText(J);H.collapse(false);H.select();}else{this._selectNode(J);}}A.stopEvent(L);}if(this.browser.webkit){A.stopEvent(L);}this.nodeChange();}},_handleKeyDown:function(K){if(this._isNonEditable(K)){return false;}this._setCurrentEvent(K);if(this.currentWindow){this.closeWindow();}if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}var J=false,L=null,H=false;if(K.shiftKey&&K.ctrlKey){J=true!
 ;}switch(K.keyCode){case 84:if(K.shiftKey&&K.ctrlKey){var I=th!
 is.toolb
ar.getElementsByTagName("h2")[0];if(I){I.focus();}A.stopEvent(K);J=false;}break;case 27:if(K.shiftKey){this.afterElement.focus();A.stopEvent(K);H=false;}break;case 76:if(this._hasSelection()){if(K.shiftKey&&K.ctrlKey){var G=true;if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("createlink")){G=false;}}if(G){this.execCommand("createlink","");this.toolbar.fireEvent("createlinkClick",{type:"createlinkClick",target:this.toolbar});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});J=false;}}}break;case 65:if(K.metaKey&&this.browser.webkit){A.stopEvent(K);this._getSelection().setBaseAndExtent(this._getDoc().body,1,this._getDoc().body,this._getDoc().body.innerHTML.length);}break;case 66:L="bold";break;case 73:L="italic";break;case 85:L="underline";break;case 13:if(this.browser.ie){var M=this._getRange();var F=this._getSelectedElement();if(!this._isElement(F,"li")){if(M){M.pasteHTML("<br>");M.collapse(false);M.select();}A.stopEvent(K);}}}if(this.!
 browser.ie){this._listFix(K);}if(J&&L){this.execCommand(L,null);A.stopEvent(K);this.nodeChange();}this.fireEvent("editorKeyDown",{type:"editorKeyDown",target:this,ev:K});},nodeChange:function(G){var H=parseInt(this.get("nodeChangeThreshold"),10);var N=Math.round(new Date().getTime()/1000);if(G===true){this._lastNodeChange=0;}if((this._lastNodeChange+H)<N){var Q=this;if(this._fixNodesTimer===null){this._fixNodesTimer=window.setTimeout(function(){Q._fixNodes.call(Q);Q._fixNodesTimer=null;},0);}}this._lastNodeChange=N;if(this.currentEvent){this._lastNodeChangeEvent=this.currentEvent.type;}var Y=this.fireEvent("beforeNodeChange",{type:"beforeNodeChange",target:this});if(Y===false){return false;}if(this.get("dompath")){this._writeDomPath();}if(!this.get("disabled")){if(this.STOP_NODE_CHANGE){this.STOP_NODE_CHANGE=false;return false;}else{var S=this._getSelection(),P=this._getRange(),F=this._getSelectedElement(),L=this.toolbar.getButtonByValue("fontname"),K=this.toolbar.getButton!
 ByValue("fontsize");
+if(G!==true){this.editorDirty=true;}var M={};if(this._lastButton){M[this._lastButton.id]=true;}if(!this._isElement(F,"body")){if(L){M[L.get("id")]=true;}if(K){M[K.get("id")]=true;}}this.toolbar.resetAllButtons(M);for(var Z=0;Z<this._disabled.length;Z++){var O=this.toolbar.getButtonByValue(this._disabled[Z]);if(O&&O.get){if(this._lastButton&&(O.get("id")===this._lastButton.id)){}else{if(!this._hasSelection()){switch(this._disabled[Z]){case"fontname":case"fontsize":break;default:this.toolbar.disableButton(O);}}else{if(!this._alwaysDisabled[this._disabled[Z]]){this.toolbar.enableButton(O);}}if(!this._alwaysEnabled[this._disabled[Z]]){this.toolbar.deselectButton(O);}}}}var R=this._getDomPath();var a=null,V=null;for(var W=0;W<R.length;W++){a=R[W].tagName.toLowerCase();if(R[W].getAttribute("tag")){a=R[W].getAttribute("tag").toLowerCase();}V=this._tag2cmd[a];if(V===undefined){V=[];}if(!D.isArray(V)){V=[V];}if(R[W].style.fontWeight.toLowerCase()=="bold"){V[V.length]="bold";}if(R[W]!
 .style.fontStyle.toLowerCase()=="italic"){V[V.length]="italic";}if(R[W].style.textDecoration.toLowerCase()=="underline"){V[V.length]="underline";}if(V.length>0){for(var U=0;U<V.length;U++){this.toolbar.selectButton(V[U]);this.toolbar.enableButton(V[U]);}}switch(R[W].style.textAlign.toLowerCase()){case"left":case"right":case"center":case"justify":var T=R[W].style.textAlign.toLowerCase();if(R[W].style.textAlign.toLowerCase()=="justify"){T="full";}this.toolbar.selectButton("justify"+T);this.toolbar.enableButton("justify"+T);break;}}if(L){var X=L._configs.label._initialConfig.value;L.set("label",'<span class="yui-toolbar-fontname-'+E(X)+'">'+X+"</span>");this._updateMenuChecked("fontname",X);}if(K){K.set("label",K._configs.label._initialConfig.value);}var J=this.toolbar.getButtonByValue("heading");if(J){J.set("label",J._configs.label._initialConfig.value);this._updateMenuChecked("heading","none");}var I=this.toolbar.getButtonByValue("insertimage");if(I&&this.currentWindow&&(thi!
 s.currentWindow.name=="insertimage")){this.toolbar.disableButt!
 on(I);}}
}this.fireEvent("afterNodeChange",{type:"afterNodeChange",target:this});},_updateMenuChecked:function(F,G,I){if(!I){I=this.toolbar;}var H=I.getButtonByValue(F);H.checkValue(G);},_handleToolbarClick:function(G){var I="";var J="";var H=G.button.value;if(G.button.menucmd){I=H;H=G.button.menucmd;}this._lastButton=G.button;if(this.STOP_EXEC_COMMAND){this.STOP_EXEC_COMMAND=false;return false;}else{this.execCommand(H,I);if(!this.browser.webkit){var F=this;setTimeout(function(){F._focusWindow.call(F);},5);}}A.stopEvent(G);},_setupAfterElement:function(){if(!this.beforeElement){this.beforeElement=document.createElement("h2");this.beforeElement.className="yui-editor-skipheader";this.beforeElement.tabIndex="-1";this.beforeElement.innerHTML=this.STR_BEFORE_EDITOR;this.get("element_cont").get("firstChild").insertBefore(this.beforeElement,this.toolbar.get("nextSibling"));}if(!this.afterElement){this.afterElement=document.createElement("h2");this.afterElement.className="yui-editor-skiphead!
 er";this.afterElement.tabIndex="-1";this.afterElement.innerHTML=this.STR_LEAVE_EDITOR;this.get("element_cont").get("firstChild").appendChild(this.afterElement);}},_disableEditor:function(G){if(G){if(!this._mask){if(!!this.browser.ie){this._setDesignMode("off");}if(this.toolbar){this.toolbar.set("disabled",true);}this._mask=document.createElement("DIV");C.setStyle(this._mask,"height","100%");C.setStyle(this._mask,"width","100%");C.setStyle(this._mask,"position","absolute");C.setStyle(this._mask,"top","0");C.setStyle(this._mask,"left","0");C.setStyle(this._mask,"opacity",".5");C.addClass(this._mask,"yui-editor-masked");this.get("iframe").get("parentNode").appendChild(this._mask);}}else{if(this._mask){this._mask.parentNode.removeChild(this._mask);this._mask=null;if(this.toolbar){this.toolbar.set("disabled",false);}this._setDesignMode("on");this._focusWindow();var F=this;window.setTimeout(function(){F.nodeChange.call(F);},100);}}},EDITOR_PANEL_ID:"yui-editor-panel",SEP_DOMPATH:!
 "<",STR_LEAVE_EDITOR:"You have left the Rich Text Editor.",STR!
 _BEFORE_
EDITOR:"This text field can contain stylized text and graphics. To cycle through all formatting options, use the keyboard shortcut Control + Shift + T to place focus on the toolbar and navigate between option heading names. <h4>Common formatting keyboard shortcuts:</h4><ul><li>Control Shift B sets text to bold</li> <li>Control Shift I sets text to italic</li> <li>Control Shift U underlines text</li> <li>Control Shift L adds an HTML link</li> <li>To exit this text editor use the keyboard shortcut Control + Shift + ESC.</li></ul>",STR_TITLE:"Rich Text Area.",STR_IMAGE_HERE:"Image Url Here",STR_LINK_URL:"Link URL",STOP_EXEC_COMMAND:false,STOP_NODE_CHANGE:false,CLASS_NOEDIT:"yui-noedit",CLASS_CONTAINER:"yui-editor-container",CLASS_EDITABLE:"yui-editor-editable",CLASS_EDITABLE_CONT:"yui-editor-editable-container",CLASS_PREFIX:"yui-editor",browser:function(){var F=YAHOO.env.ua;if(F.webkit>=420){F.webkit3=F.webkit;}else{F.webkit3=0;}return F;}(),init:function(G,F){if(!this._default!
 Toolbar){this._defaultToolbar={collapse:true,titlebar:"Text Editing Tools",draggable:false,buttons:[{group:"fontstyle",label:"Font Name and Size",buttons:[{type:"select",label:"Arial",value:"fontname",disabled:true,menu:[{text:"Arial",checked:true},{text:"Arial Black"},{text:"Comic Sans MS"},{text:"Courier New"},{text:"Lucida Console"},{text:"Tahoma"},{text:"Times New Roman"},{text:"Trebuchet MS"},{text:"Verdana"}]},{type:"spin",label:"13",value:"fontsize",range:[9,75],disabled:true}]},{type:"separator"},{group:"textstyle",label:"Font Style",buttons:[{type:"push",label:"Bold CTRL + SHIFT + B",value:"bold"},{type:"push",label:"Italic CTRL + SHIFT + I",value:"italic"},{type:"push",label:"Underline CTRL + SHIFT + U",value:"underline"},{type:"separator"},{type:"color",label:"Font Color",value:"forecolor",disabled:true},{type:"color",label:"Background Color",value:"backcolor",disabled:true}]},{type:"separator"},{group:"indentlist",label:"Lists",buttons:[{type:"push",label:"Creat!
 e an Unordered List",value:"insertunorderedlist"},{type:"push"!
 ,label:"
Create an Ordered List",value:"insertorderedlist"}]},{type:"separator"},{group:"insertitem",label:"Insert Item",buttons:[{type:"push",label:"HTML Link CTRL + SHIFT + L",value:"createlink",disabled:true},{type:"push",label:"Insert Image",value:"insertimage"}]}]};
+}YAHOO.widget.SimpleEditor.superclass.init.call(this,G,F);YAHOO.widget.EditorInfo._instances[this.get("id")]=this;this.currentElement=[];this.on("contentReady",function(){this.DOMReady=true;this.fireQueue();},this,true);},initAttributes:function(F){YAHOO.widget.SimpleEditor.superclass.initAttributes.call(this,F);var G=this;this.setAttributeConfig("container",{writeOnce:true,value:F.container||false});this.setAttributeConfig("plainText",{writeOnce:true,value:F.plainText||false});this.setAttributeConfig("iframe",{value:null});this.setAttributeConfig("textarea",{value:null,writeOnce:true});this.setAttributeConfig("container",{readOnly:true,value:null});this.setAttributeConfig("nodeChangeThreshold",{value:F.nodeChangeThreshold||3,validator:YAHOO.lang.isNumber});this.setAttributeConfig("allowNoEdit",{value:F.allowNoEdit||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("limitCommands",{value:F.limitCommands||false,validator:YAHOO.lang.isBoolean});this.setAttributeC!
 onfig("element_cont",{value:F.element_cont});this.setAttributeConfig("editor_wrapper",{value:F.editor_wrapper||null,writeOnce:true});this.setAttributeConfig("height",{value:F.height||C.getStyle(G.get("element"),"height"),method:function(H){if(this._rendered){if(this.get("animate")){var I=new YAHOO.util.Anim(this.get("iframe").get("parentNode"),{height:{to:parseInt(H,10)}},0.5);I.animate();}else{C.setStyle(this.get("iframe").get("parentNode"),"height",H);}}}});this.setAttributeConfig("autoHeight",{value:F.autoHeight||false,method:function(H){if(H){if(this.get("iframe")){this.get("iframe").get("element").setAttribute("scrolling","no");}this.on("afterNodeChange",this._handleAutoHeight,this,true);this.on("editorKeyDown",this._handleAutoHeight,this,true);this.on("editorKeyPress",this._handleAutoHeight,this,true);}else{if(this.get("iframe")){this.get("iframe").get("element").setAttribute("scrolling","auto");}this.unsubscribe("afterNodeChange",this._handleAutoHeight);this.unsubscr!
 ibe("editorKeyDown",this._handleAutoHeight);this.unsubscribe("!
 editorKe
yPress",this._handleAutoHeight);}}});this.setAttributeConfig("width",{value:F.width||C.getStyle(this.get("element"),"width"),method:function(H){if(this._rendered){if(this.get("animate")){var I=new YAHOO.util.Anim(this.get("element_cont").get("element"),{width:{to:parseInt(H,10)}},0.5);I.animate();}else{this.get("element_cont").setStyle("width",H);}}}});this.setAttributeConfig("blankimage",{value:F.blankimage||this._getBlankImage()});this.setAttributeConfig("css",{value:F.css||this._defaultCSS,writeOnce:true});this.setAttributeConfig("html",{value:F.html||'<html><head><title>{TITLE}</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><base href="'+this._baseHREF+'"><style>{CSS}</style><style>{HIDDEN_CSS}</style><style>{EXTRA_CSS}</style></head><body onload="document.body._rteLoaded = true;">{CONTENT}</body></html>',writeOnce:true});this.setAttributeConfig("extracss",{value:F.extracss||"",writeOnce:true});this.setAttributeConfig("handleSubmit",{value:F.!
 handleSubmit||false,method:function(H){if(this.get("element").form){if(!this._formButtons){this._formButtons=[];}if(H){A.on(this.get("element").form,"submit",this._handleFormSubmit,this,true);var I=this.get("element").form.getElementsByTagName("input");for(var K=0;K<I.length;K++){var J=I[K].getAttribute("type");if(J&&(J.toLowerCase()=="submit")){A.on(I[K],"click",this._handleFormButtonClick,this,true);this._formButtons[this._formButtons.length]=I[K];}}}else{A.unsubscribe(this.get("element").form,"submit",this._handleFormSubmit);if(this._formButtons){A.unsubscribe(this._formButtons,"click",this._handleFormButtonClick);}}}}});this.setAttributeConfig("disabled",{value:false,method:function(H){if(this._rendered){this._disableEditor(H);}}});this.setAttributeConfig("toolbar_cont",{value:null,writeOnce:true});this.setAttributeConfig("toolbar",{value:F.toolbar||this._defaultToolbar,writeOnce:true,method:function(H){if(!H.buttonType){H.buttonType=this._defaultToolbar.buttonType;}thi!
 s._defaultToolbar=H;}});this.setAttributeConfig("animate",{val!
 ue:((F.a
nimate)?((YAHOO.util.Anim)?true:false):false),validator:function(I){var H=true;if(!YAHOO.util.Anim){H=false;}return H;}});this.setAttributeConfig("panel",{value:null,writeOnce:true,validator:function(I){var H=true;if(!YAHOO.widget.Overlay){H=false;}return H;}});this.setAttributeConfig("focusAtStart",{value:F.focusAtStart||false,writeOnce:true,method:function(){this.on("editorContentLoaded",function(){var H=this;setTimeout(function(){H._focusWindow.call(H,true);H.editorDirty=false;},400);},this,true);}});this.setAttributeConfig("dompath",{value:F.dompath||false,method:function(H){if(H&&!this.dompath){this.dompath=document.createElement("DIV");this.dompath.id=this.get("id")+"_dompath";C.addClass(this.dompath,"dompath");this.get("element_cont").get("firstChild").appendChild(this.dompath);if(this.get("iframe")){this._writeDomPath();}}else{if(!H&&this.dompath){this.dompath.parentNode.removeChild(this.dompath);this.dompath=null;}}}});this.setAttributeConfig("markup",{value:F.marku!
 p||"semantic",validator:function(H){switch(H.toLowerCase()){case"semantic":case"css":case"default":case"xhtml":return true;}return false;}});this.setAttributeConfig("removeLineBreaks",{value:F.removeLineBreaks||false,validator:YAHOO.lang.isBoolean});this.on("afterRender",function(){this._renderPanel();});},_getBlankImage:function(){if(!this.DOMReady){this._queue[this._queue.length]=["_getBlankImage",arguments];return"";}var F="";if(!this._blankImageLoaded){if(YAHOO.widget.EditorInfo.blankImage){this.set("blankimage",YAHOO.widget.EditorInfo.blankImage);this._blankImageLoaded=true;}else{var G=document.createElement("div");G.style.position="absolute";G.style.top="-9999px";G.style.left="-9999px";G.className=this.CLASS_PREFIX+"-blankimage";document.body.appendChild(G);F=YAHOO.util.Dom.getStyle(G,"background-image");F=F.replace("url(","").replace(")","").replace(/"/g,"");F=F.replace("app:/","");this.set("blankimage",F);
+this._blankImageLoaded=true;YAHOO.widget.EditorInfo.blankImage=F;}}else{F=this.get("blankimage");}return F;},_handleAutoHeight:function(){var J=this._getDoc(),G=J.body,K=J.documentElement;var F=parseInt(C.getStyle(this.get("editor_wrapper"),"height"),10);var H=G.scrollHeight;if(this.browser.webkit){H=K.scrollHeight;}if(H<parseInt(this.get("height"),10)){H=parseInt(this.get("height"),10);}if((F!=H)&&(H>=parseInt(this.get("height"),10))){C.setStyle(this.get("editor_wrapper"),"height",H+"px");if(this.browser.ie){this.get("iframe").setStyle("height","99%");this.get("iframe").setStyle("zoom","1");var I=this;window.setTimeout(function(){I.get("iframe").setStyle("height","100%");},1);}}},_formButtons:null,_formButtonClicked:null,_handleFormButtonClick:function(G){var F=A.getTarget(G);this._formButtonClicked=F;},_handleFormSubmit:function(I){A.stopEvent(I);this.saveHTML();var H=this.get("element").form;var F=this._formButtonClicked||false;var G=this;window.setTimeout(function(){YAH!
 OO.util.Event.removeListener(H,"submit",G._handleFormSubmit);if(YAHOO.env.ua.ie){H.fireEvent("onsubmit");if(F&&!F.disabled){F.click();}}else{if(F&&!F.disabled){F.click();}else{var J=document.createEvent("HTMLEvents");J.initEvent("submit",true,true);H.dispatchEvent(J);if(YAHOO.env.ua.webkit){if(YAHOO.lang.isFunction(H.submit)){H.submit();}}}}},200);},_handleFontSize:function(H){var F=this.toolbar.getButtonById(H.button.id);var G=F.get("label")+"px";this.execCommand("fontsize",G);this.STOP_EXEC_COMMAND=true;},_handleColorPicker:function(H){var G=H.button;var F="#"+H.color;if((G=="forecolor")||(G=="backcolor")){this.execCommand(G,F);}},_handleAlign:function(I){var H=null;for(var F=0;F<I.button.menu.length;F++){if(I.button.menu[F].value==I.button.value){H=I.button.menu[F].value;}}var G=this._getSelection();this.execCommand(H,G);this.STOP_EXEC_COMMAND=true;},_handleAfterNodeChange:function(){var R=this._getDomPath(),M=null,I=null,N=null,G=false;var K=this.toolbar.getButtonByValu!
 e("fontname");var L=this.toolbar.getButtonByValue("fontsize");!
 var F=th
is.toolbar.getButtonByValue("heading");for(var H=0;H<R.length;H++){M=R[H];var Q=M.tagName.toLowerCase();if(M.getAttribute("tag")){Q=M.getAttribute("tag");}I=M.getAttribute("face");if(C.getStyle(M,"font-family")){I=C.getStyle(M,"font-family");I=I.replace(/'/g,"");}if(Q.substring(0,1)=="h"){if(F){for(var J=0;J<F._configs.menu.value.length;J++){if(F._configs.menu.value[J].value.toLowerCase()==Q){F.set("label",F._configs.menu.value[J].text);}}this._updateMenuChecked("heading",Q);}}}if(K){for(var P=0;P<K._configs.menu.value.length;P++){if(I&&K._configs.menu.value[P].text.toLowerCase()==I.toLowerCase()){G=true;I=K._configs.menu.value[P].text;}}if(!G){I=K._configs.label._initialConfig.value;}var O='<span class="yui-toolbar-fontname-'+E(I)+'">'+I+"</span>";if(K.get("label")!=O){K.set("label",O);this._updateMenuChecked("fontname",I);}}if(L){N=parseInt(C.getStyle(M,"fontSize"),10);if((N===null)||isNaN(N)){N=L._configs.label._initialConfig.value;}L.set("label",""+N);}if(!this._isElemen!
 t(M,"body")&&!this._isElement(M,"img")){this.toolbar.enableButton(K);this.toolbar.enableButton(L);this.toolbar.enableButton("forecolor");this.toolbar.enableButton("backcolor");}if(this._isElement(M,"img")){if(YAHOO.widget.Overlay){this.toolbar.enableButton("createlink");}}if(this._isElement(M,"blockquote")){this.toolbar.selectButton("indent");this.toolbar.disableButton("indent");this.toolbar.enableButton("outdent");}if(this._hasParent(M,"ol")||this._hasParent(M,"ul")){this.toolbar.disableButton("indent");}this._lastButton=null;},_setBusy:function(F){},_handleInsertImageClick:function(){if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("insertimage")){return false;}}this.toolbar.set("disabled",true);this.on("afterExecCommand",function(){var F=this.currentElement[0],H="http://";if(!F){F=this._getSelectedElement();}if(F){if(F.getAttribute("src")){H=F.getAttribute("src",2);if(H.indexOf(this.get("blankimage"))!=-1){H=this.STR_IMAGE_HERE;}}}var G=prompt(this.STR_LIN!
 K_URL+": ",H);if((G!=="")&&(G!==null)){F.setAttribute("src",G)!
 ;}else{i
f(G===null){F.parentNode.removeChild(F);this.currentElement=[];this.nodeChange();}}this.closeWindow();this.toolbar.set("disabled",false);},this,true);},_handleInsertImageWindowClose:function(){this.nodeChange();},_isLocalFile:function(F){if((F!=="")&&((F.indexOf("file:/")!=-1)||(F.indexOf(":\\")!=-1))){return true;}return false;},_handleCreateLinkClick:function(){if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("createlink")){return false;}}this.toolbar.set("disabled",true);this.on("afterExecCommand",function(){var H=this.currentElement[0],G="";if(H){if(H.getAttribute("href",2)!==null){G=H.getAttribute("href",2);}}var J=prompt(this.STR_LINK_URL+": ",G);if((J!=="")&&(J!==null)){var I=J;if((I.indexOf(":/"+"/")==-1)&&(I.substring(0,1)!="/")&&(I.substring(0,6).toLowerCase()!="mailto")){if((I.indexOf("@")!=-1)&&(I.substring(0,6).toLowerCase()!="mailto")){I="mailto:"+I;}else{if(I.substring(0,1)!="#"){I="http:/"+"/"+I;}}}H.setAttribute("href",I);}else{if(J!==null){va!
 r F=this._getDoc().createElement("span");F.innerHTML=H.innerHTML;C.addClass(F,"yui-non");H.parentNode.replaceChild(F,H);}}this.closeWindow();this.toolbar.set("disabled",false);});},_handleCreateLinkWindowClose:function(){this.nodeChange();this.currentElement=[];},render:function(){if(this._rendered){return false;}if(!this.DOMReady){this._queue[this._queue.length]=["render",arguments];return false;}this._rendered=true;var F=this;window.setTimeout(function(){F._render.call(F);},4);},_render:function(){this._setBusy();var F=this;this.set("textarea",this.get("element"));this.get("element_cont").setStyle("display","none");this.get("element_cont").addClass(this.CLASS_CONTAINER);this.set("iframe",this._createIframe());window.setTimeout(function(){F._setInitialContent.call(F);},10);this.get("editor_wrapper").appendChild(this.get("iframe").get("element"));if(this.get("disabled")){this._disableEditor(true);}var G=this.get("toolbar");
+if(G instanceof B){this.toolbar=G;this.toolbar.set("disabled",true);}else{G.disabled=true;this.toolbar=new B(this.get("toolbar_cont"),G);}this.fireEvent("toolbarLoaded",{type:"toolbarLoaded",target:this.toolbar});this.toolbar.on("toolbarCollapsed",function(){if(this.currentWindow){this.moveWindow();}},this,true);this.toolbar.on("toolbarExpanded",function(){if(this.currentWindow){this.moveWindow();}},this,true);this.toolbar.on("fontsizeClick",function(H){this._handleFontSize(H);},this,true);this.toolbar.on("colorPickerClicked",function(H){this._handleColorPicker(H);return false;},this,true);this.toolbar.on("alignClick",function(H){this._handleAlign(H);},this,true);this.on("afterNodeChange",function(){this._handleAfterNodeChange();},this,true);this.toolbar.on("insertimageClick",function(){this._handleInsertImageClick();},this,true);this.on("windowinsertimageClose",function(){this._handleInsertImageWindowClose();},this,true);this.toolbar.on("createlinkClick",function(){this._h!
 andleCreateLinkClick();},this,true);this.on("windowcreatelinkClose",function(){this._handleCreateLinkWindowClose();},this,true);this.get("parentNode").replaceChild(this.get("element_cont").get("element"),this.get("element"));this.setStyle("visibility","hidden");this.setStyle("position","absolute");this.setStyle("top","-9999px");this.setStyle("left","-9999px");this.get("element_cont").appendChild(this.get("element"));this.get("element_cont").setStyle("display","block");C.addClass(this.get("iframe").get("parentNode"),this.CLASS_EDITABLE_CONT);this.get("iframe").addClass(this.CLASS_EDITABLE);this.get("element_cont").setStyle("width",this.get("width"));C.setStyle(this.get("iframe").get("parentNode"),"height",this.get("height"));this.get("iframe").setStyle("width","100%");this.get("iframe").setStyle("height","100%");window.setTimeout(function(){F._setupAfterElement.call(F);},0);this.fireEvent("afterRender",{type:"afterRender",target:this});},execCommand:function(H,G){var K=this.!
 fireEvent("beforeExecCommand",{type:"beforeExecCommand",target!
 :this,ar
gs:arguments});if((K===false)||(this.STOP_EXEC_COMMAND)){this.STOP_EXEC_COMMAND=false;return false;}this._setMarkupType(H);if(this.browser.ie){this._getWindow().focus();}var F=true;if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue(H)){F=false;}}this.editorDirty=true;if((typeof this["cmd_"+H.toLowerCase()]=="function")&&F){var J=this["cmd_"+H.toLowerCase()](G);F=J[0];if(J[1]){H=J[1];}if(J[2]){G=J[2];}}if(F){try{this._getDoc().execCommand(H,false,G);}catch(I){}}else{}this.on("afterExecCommand",function(){this.unsubscribeAll("afterExecCommand");this.nodeChange();});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});},cmd_backcolor:function(I){var F=true,G=this._getSelectedElement(),H="backcolor";if(this.browser.gecko||this.browser.opera){this._setEditorStyle(true);H="hilitecolor";}if(!this._isElement(G,"body")){C.setStyle(G,"background-color",I);this._selectNode(G);F=false;}else{this._createCurrentElement("span",{backgroundColor:I});this._sel!
 ectNode(this.currentElement[0]);F=false;}return[F,H];},cmd_forecolor:function(H){var F=true,G=this._getSelectedElement();if(!this._isElement(G,"body")){C.setStyle(G,"color",H);this._selectNode(G);F=false;}else{this._createCurrentElement("span",{color:H});this._selectNode(this.currentElement[0]);F=false;}return[F];},cmd_unlink:function(F){this._swapEl(this.currentElement[0],"span",function(G){G.className="yui-non";});return[false];},cmd_createlink:function(H){var G=this._getSelectedElement(),F=null;if(this._hasParent(G,"a")){this.currentElement[0]=this._hasParent(G,"a");}else{if(!this._isElement(G,"a")){this._createCurrentElement("a");F=this._swapEl(this.currentElement[0],"a");this.currentElement[0]=F;}else{this.currentElement[0]=G;}}return[false];},cmd_insertimage:function(K){var F=true,G=null,J="insertimage",I=this._getSelectedElement();if(K===""){K=this.get("blankimage");}if(this._isElement(I,"img")){this.currentElement[0]=I;F=false;}else{if(this._getDoc().queryCommandEna!
 bled(J)){this._getDoc().execCommand("insertimage",false,K);var!
  L=this.
_getDoc().getElementsByTagName("img");for(var H=0;H<L.length;H++){if(!YAHOO.util.Dom.hasClass(L[H],"yui-img")){YAHOO.util.Dom.addClass(L[H],"yui-img");this.currentElement[0]=L[H];}}F=false;}else{if(I==this._getDoc().body){G=this._getDoc().createElement("img");G.setAttribute("src",K);YAHOO.util.Dom.addClass(G,"yui-img");this._getDoc().body.appendChild(G);}else{this._createCurrentElement("img");G=this._getDoc().createElement("img");G.setAttribute("src",K);YAHOO.util.Dom.addClass(G,"yui-img");this.currentElement[0].parentNode.replaceChild(G,this.currentElement[0]);}this.currentElement[0]=G;F=false;}}return[F];},cmd_inserthtml:function(I){var F=true,H="inserthtml",G=null,J=null;if(this.browser.webkit&&!this._getDoc().queryCommandEnabled(H)){this._createCurrentElement("img");G=this._getDoc().createElement("span");G.innerHTML=I;this.currentElement[0].parentNode.replaceChild(G,this.currentElement[0]);F=false;}else{if(this.browser.ie){J=this._getRange();if(J.item){J.item(0).outerHTM!
 L=I;}else{J.pasteHTML(I);}F=false;}}return[F];},cmd_list:function(W){var Q=true,T=null,M=0,G=null,P="",U=this._getSelectedElement(),R="insertorderedlist";if(W=="ul"){R="insertunorderedlist";}if((this.browser.webkit&&!this._getDoc().queryCommandEnabled(R))){if(this._isElement(U,"li")&&this._isElement(U.parentNode,W)){G=U.parentNode;T=this._getDoc().createElement("span");YAHOO.util.Dom.addClass(T,"yui-non");P="";var F=G.getElementsByTagName("li");for(M=0;M<F.length;M++){P+="<div>"+F[M].innerHTML+"</div>";}T.innerHTML=P;this.currentElement[0]=G;this.currentElement[0].parentNode.replaceChild(T,this.currentElement[0]);}else{this._createCurrentElement(W.toLowerCase());T=this._getDoc().createElement(W);for(M=0;M<this.currentElement.length;M++){var J=this._getDoc().createElement("li");J.innerHTML=this.currentElement[M].innerHTML+'<span class="yui-non"> </span> ';T.appendChild(J);if(M>0){this.currentElement[M].parentNode.removeChild(this.currentElement[M]);
+}}this.currentElement[0].parentNode.replaceChild(T,this.currentElement[0]);this.currentElement[0]=T;var H=this.currentElement[0].firstChild;H=C.getElementsByClassName("yui-non","span",H)[0];this._getSelection().setBaseAndExtent(H,1,H,H.innerText.length);}Q=false;}else{G=this._getSelectedElement();if(this._isElement(G,"li")&&this._isElement(G.parentNode,W)||(this.browser.ie&&this._isElement(this._getRange().parentElement,"li"))||(this.browser.ie&&this._isElement(G,"ul"))||(this.browser.ie&&this._isElement(G,"ol"))){if(this.browser.ie){if((this.browser.ie&&this._isElement(G,"ul"))||(this.browser.ie&&this._isElement(G,"ol"))){G=G.getElementsByTagName("li")[0];}P="";var I=G.parentNode.getElementsByTagName("li");for(var S=0;S<I.length;S++){P+=I[S].innerHTML+"<br>";}var V=this._getDoc().createElement("span");V.innerHTML=P;G.parentNode.parentNode.replaceChild(V,G.parentNode);}else{this.nodeChange();this._getDoc().execCommand(R,"",G.parentNode);this.nodeChange();}Q=false;}if(this.b!
 rowser.opera){var O=this;window.setTimeout(function(){var X=O._getDoc().getElementsByTagName("li");for(var Y=0;Y<X.length;Y++){if(X[Y].innerHTML.toLowerCase()=="<br>"){X[Y].parentNode.parentNode.removeChild(X[Y].parentNode);}}},30);}if(this.browser.ie&&Q){var K="";if(this._getRange().html){K="<li>"+this._getRange().html+"</li>";}else{var L=this._getRange().text.split("\n");if(L.length>1){K="";for(var N=0;N<L.length;N++){K+="<li>"+L[N]+"</li>";}}else{K="<li>"+this._getRange().text+"</li>";}}this._getRange().pasteHTML("<"+W+">"+K+"</"+W+">");Q=false;}}return Q;},cmd_insertorderedlist:function(F){return[this.cmd_list("ol")];},cmd_insertunorderedlist:function(F){return[this.cmd_list("ul")];},cmd_fontname:function(H){var F=true,G=this._getSelectedElement();this.currentFont=H;if(G&&G.tagName&&!this._hasSelection()){YAHOO.util.Dom.setStyle(G,"font-family",H);F=false;}return[F];},cmd_fontsize:function(G){if(this.currentElement&&(this.currentElement.length>0)&&(!this._hasSelection()!
 )){YAHOO.util.Dom.setStyle(this.currentElement,"fontSize",G);}!
 else{if(
!this._isElement(this._getSelectedElement(),"body")){var F=this._getSelectedElement();YAHOO.util.Dom.setStyle(F,"fontSize",G);this._selectNode(F);}else{this._createCurrentElement("span",{"fontSize":G});this._selectNode(this.currentElement[0]);}}return[false];},_swapEl:function(G,F,I){var H=this._getDoc().createElement(F);H.innerHTML=G.innerHTML;if(typeof I=="function"){I.call(this,H);}G.parentNode.replaceChild(H,G);return H;},_createCurrentElement:function(H,U){H=((H)?H:"a");var b=null,G=[],I=this._getDoc();if(this.currentFont){if(!U){U={};}U.fontFamily=this.currentFont;this.currentFont=null;}this.currentElement=[];var X=function(){var f=null;switch(H){case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":f=I.createElement(H);break;default:f=I.createElement("span");YAHOO.util.Dom.addClass(f,"yui-tag-"+H);YAHOO.util.Dom.addClass(f,"yui-tag");f.setAttribute("tag",H);for(var e in U){if(YAHOO.util.Lang.hasOwnProperty(U,e)){f.style[e]=U[e];}}break;}return f;};if(!this._hasSelecti!
 on()){if(this._getDoc().queryCommandEnabled("insertimage")){this._getDoc().execCommand("insertimage",false,"yui-tmp-img");var W=this._getDoc().getElementsByTagName("img");for(var Z=0;Z<W.length;Z++){if(W[Z].getAttribute("src",2)=="yui-tmp-img"){G=X();W[Z].parentNode.replaceChild(G,W[Z]);this.currentElement[this.currentElement.length]=G;}}}else{if(this.currentEvent){b=YAHOO.util.Event.getTarget(this.currentEvent);}else{b=this._getDoc().body;}}if(b){G=X();if(this._isElement(b,"body")||this._isElement(b,"html")){if(this._isElement(b,"html")){b=this._getDoc().body;}b.appendChild(G);}else{if(b.nextSibling){b.parentNode.insertBefore(G,b.nextSibling);}else{b.parentNode.appendChild(G);}}this.currentElement[this.currentElement.length]=G;this.currentEvent=null;if(this.browser.webkit){this._getSelection().setBaseAndExtent(G,0,G,0);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(true);}}}}else{this._setEditorStyle(true);this._getDoc()!
 .execCommand("fontname",false,"yui-tmp");var F=[];var R=this._!
 getDoc()
.getElementsByTagName("font");var P=this._getDoc().getElementsByTagName(this._getSelectedElement().tagName);var M=this._getDoc().getElementsByTagName("span");var L=this._getDoc().getElementsByTagName("i");var K=this._getDoc().getElementsByTagName("b");var J=this._getDoc().getElementsByTagName(this._getSelectedElement().parentNode.tagName);for(var V=0;V<R.length;V++){F[F.length]=R[V];}for(var N=0;N<J.length;N++){F[F.length]=J[N];}for(var T=0;T<P.length;T++){F[F.length]=P[T];}for(var S=0;S<M.length;S++){F[F.length]=M[S];}for(var Q=0;Q<L.length;Q++){F[F.length]=L[Q];}for(var O=0;O<K.length;O++){F[F.length]=K[O];}for(var a=0;a<F.length;a++){if((YAHOO.util.Dom.getStyle(F[a],"font-family")=="yui-tmp")||(F[a].face&&(F[a].face=="yui-tmp"))){G=X();G.innerHTML=F[a].innerHTML;if(this._isElement(F[a],"ol")||(this._isElement(F[a],"ul"))){var Y=F[a].getElementsByTagName("li")[0];F[a].style.fontFamily="inherit";Y.style.fontFamily="inherit";G.innerHTML=Y.innerHTML;Y.innerHTML="";Y.appendChi!
 ld(G);this.currentElement[this.currentElement.length]=G;}else{if(this._isElement(F[a],"li")){F[a].innerHTML="";F[a].appendChild(G);F[a].style.fontFamily="inherit";this.currentElement[this.currentElement.length]=G;}else{if(F[a].parentNode){F[a].parentNode.replaceChild(G,F[a]);this.currentElement[this.currentElement.length]=G;this.currentEvent=null;if(this.browser.webkit){this._getSelection().setBaseAndExtent(G,0,G,0);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(true);}}if(this.browser.ie&&U&&U.fontSize){this._getSelection().empty();}if(this.browser.gecko){this._getSelection().collapseToStart();}}}}}}var c=this.currentElement.length;for(var d=0;d<c;d++){if((d+1)!=c){if(this.currentElement[d]&&this.currentElement[d].nextSibling){if(this._isElement(this.currentElement[d],"br")){this.currentElement[this.currentElement.length]=this.currentElement[d].nextSibling;
+}}}}}},saveHTML:function(){var F=this.cleanHTML();this.get("element").value=F;return F;},setEditorHTML:function(F){F=this._cleanIncomingHTML(F);this._getDoc().body.innerHTML=F;this.nodeChange();},getEditorHTML:function(){var F=this._getDoc().body;if(F===null){return null;}return this._getDoc().body.innerHTML;},show:function(){if(this.browser.gecko){this._setDesignMode("on");this._focusWindow();}if(this.browser.webkit){var F=this;window.setTimeout(function(){F._setInitialContent.call(F);},10);}if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}this.get("iframe").setStyle("position","static");this.get("iframe").setStyle("left","");},hide:function(){if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}if(this._fixNodesTimer){clearTimeout(this._f!
 ixNodesTimer);this._fixNodesTimer=null;}if(this._nodeChangeTimer){clearTimeout(this._nodeChangeTimer);this._nodeChangeTimer=null;}this._lastNodeChange=0;this.get("iframe").setStyle("position","absolute");this.get("iframe").setStyle("left","-9999px");},_cleanIncomingHTML:function(F){F=F.replace(/<strong([^>]*)>/gi,"<b$1>");F=F.replace(/<\/strong>/gi,"</b>");F=F.replace(/<embed([^>]*)>/gi,"<YUI_EMBED$1>");F=F.replace(/<\/embed>/gi,"</YUI_EMBED>");F=F.replace(/<em([^>]*)>/gi,"<i$1>");F=F.replace(/<\/em>/gi,"</i>");F=F.replace(/<YUI_EMBED([^>]*)>/gi,"<embed$1>");F=F.replace(/<\/YUI_EMBED>/gi,"</embed>");if(this.get("plainText")){F=F.replace(/\n/g,"<br>").replace(/\r/g,"<br>");F=F.replace(/  /gi,"  ");F=F.replace(/\t/gi,"    ");}F=F.replace(/<script([^>]*)>/gi,"<bad>");F=F.replace(/<\/script([^>]*)>/gi,"</bad>");F=F.replace(/<script([^>]*)>/gi,"<bad>");F=F.replace(/<\/script([^>]*)>/gi,"</bad>");F=F.replace(/\n/g,"<YUI_LF>").replace(/\r/!
 g,"<YUI_LF>");F=F.replace(new RegExp("<bad([^>]*)>(.*?)</bad>"!
 ,"gi"),"
");F=F.replace(/<YUI_LF>/g,"\n");return F;},cleanHTML:function(H){if(!H){H=this.getEditorHTML();}var G=this.get("markup");H=this.pre_filter_linebreaks(H,G);H=H.replace(/<img([^>]*)\/>/gi,"<YUI_IMG$1>");H=H.replace(/<img([^>]*)>/gi,"<YUI_IMG$1>");H=H.replace(/<input([^>]*)\/>/gi,"<YUI_INPUT$1>");H=H.replace(/<input([^>]*)>/gi,"<YUI_INPUT$1>");H=H.replace(/<ul([^>]*)>/gi,"<YUI_UL$1>");H=H.replace(/<\/ul>/gi,"</YUI_UL>");H=H.replace(/<blockquote([^>]*)>/gi,"<YUI_BQ$1>");H=H.replace(/<\/blockquote>/gi,"</YUI_BQ>");H=H.replace(/<embed([^>]*)>/gi,"<YUI_EMBED$1>");H=H.replace(/<\/embed>/gi,"</YUI_EMBED>");if((G=="semantic")||(G=="xhtml")){H=H.replace(/<i(\s+[^>]*)?>/gi,"<em$1>");H=H.replace(/<\/i>/gi,"</em>");H=H.replace(/<b([^>]*)>/gi,"<strong$1>");H=H.replace(/<\/b>/gi,"</strong>");}H=H.replace(/<font/gi,"<font");H=H.replace(/<\/font>/gi,"</font>");H=H.replace(/<span/gi,"<span");H=H.replace(/<\/span>/gi,"</span>");if((G=="semantic")||(G=="xhtml")||(G=="css")){H=H.replace(new RegE!
 xp('<font([^>]*)face="([^>]*)">(.*?)</font>',"gi"),'<span $1 style="font-family: $2;">$3</span>');H=H.replace(/<u/gi,'<span style="text-decoration: underline;"');if(this.browser.webkit){H=H.replace(new RegExp('<span class="Apple-style-span" style="font-weight: bold;">([^>]*)</span>',"gi"),"<strong>$1</strong>");H=H.replace(new RegExp('<span class="Apple-style-span" style="font-style: italic;">([^>]*)</span>',"gi"),"<em>$1</em>");}H=H.replace(/\/u>/gi,"/span>");if(G=="css"){H=H.replace(/<em([^>]*)>/gi,"<i$1>");H=H.replace(/<\/em>/gi,"</i>");H=H.replace(/<strong([^>]*)>/gi,"<b$1>");H=H.replace(/<\/strong>/gi,"</b>");H=H.replace(/<b/gi,'<span style="font-weight: bold;"');H=H.replace(/\/b>/gi,"/span>");H=H.replace(/<i/gi,'<span style="font-style: italic;"');H=H.replace(/\/i>/gi,"/span>");}H=H.replace(/  /gi," ");}else{H=H.replace(/<u/gi,"<u");H=H.replace(/\/u>/gi,"/u>");}H=H.replace(/<ol([^>]*)>/gi,"<ol$1>");H=H.replace(/\/ol>/gi,"/ol>");H=H.replace(/<li/gi,"<li");H=H.replace(/!
 \/li>/gi,"/li>");H=this.filter_safari(H);H=this.filter_interna!
 ls(H);H=
this.filter_all_rgb(H);H=this.post_filter_linebreaks(H,G);if(G=="xhtml"){H=H.replace(/<YUI_IMG([^>]*)>/g,"<img $1 />");H=H.replace(/<YUI_INPUT([^>]*)>/g,"<input $1 />");}else{H=H.replace(/<YUI_IMG([^>]*)>/g,"<img $1>");H=H.replace(/<YUI_INPUT([^>]*)>/g,"<input $1>");}H=H.replace(/<YUI_UL([^>]*)>/g,"<ul$1>");H=H.replace(/<\/YUI_UL>/g,"</ul>");H=this.filter_invalid_lists(H);H=H.replace(/<YUI_BQ([^>]*)>/g,"<blockquote$1>");H=H.replace(/<\/YUI_BQ>/g,"</blockquote>");H=H.replace(/<YUI_EMBED([^>]*)>/g,"<embed$1>");H=H.replace(/<\/YUI_EMBED>/g,"</embed>");H=YAHOO.lang.trim(H);if(this.get("removeLineBreaks")){H=H.replace(/\n/g,"").replace(/\r/g,"");H=H.replace(/  /gi," ");}if(H.substring(0,6).toLowerCase()=="<span>"){H=H.substring(6);if(H.substring(H.length-7,H.length).toLowerCase()=="</span>"){H=H.substring(0,H.length-7);}}for(var F in this.invalidHTML){if(YAHOO.lang.hasOwnProperty(this.invalidHTML,F)){if(D.isObject(F)&&F.keepContents){H=H.replace(new RegExp("<"+F+"([^>]*)>(.*?)</"!
 +F+">","gi"),"$1");}else{H=H.replace(new RegExp("<"+F+"([^>]*)>(.*?)</"+F+">","gi"),"");}}}this.fireEvent("cleanHTML",{type:"cleanHTML",target:this,html:H});return H;},filter_invalid_lists:function(F){F=F.replace(/<\/li>\n/gi,"</li>");F=F.replace(/<\/li><ol>/gi,"</li><li><ol>");F=F.replace(/<\/ol>/gi,"</ol></li>");F=F.replace(/<\/ol><\/li>\n/gi,"</ol>\n");F=F.replace(/<\/li><ul>/gi,"</li><li><ul>");F=F.replace(/<\/ul>/gi,"</ul></li>");F=F.replace(/<\/ul><\/li>\n/gi,"</ul>\n");F=F.replace(/<\/li>/gi,"</li>\n");F=F.replace(/<\/ol>/gi,"</ol>\n");F=F.replace(/<ol>/gi,"<ol>\n");F=F.replace(/<ul>/gi,"<ul>\n");return F;},filter_safari:function(F){if(this.browser.webkit){F=F.replace(/<span class="Apple-tab-span" style="white-space:pre">([^>])<\/span>/gi,"    ");F=F.replace(/Apple-style-span/gi,"");F=F.replace(/style="line-height: normal;"/gi,"");F=F.replace(/<li><\/li>/gi,"");F=F.replace(/<li> <\/li>/gi,"");
+F=F.replace(/<li>  <\/li>/gi,"");F=F.replace(/<div><\/div>/gi,"");F=F.replace(/<div> <\/div>/gi,"");}return F;},filter_internals:function(F){F=F.replace(/\r/g,"");F=F.replace(/<\/?(body|head|html)[^>]*>/gi,"");F=F.replace(/<YUI_BR><\/li>/gi,"</li>");F=F.replace(/yui-tag-span/gi,"");F=F.replace(/yui-tag/gi,"");F=F.replace(/yui-non/gi,"");F=F.replace(/yui-img/gi,"");F=F.replace(/ tag="span"/gi,"");F=F.replace(/ class=""/gi,"");F=F.replace(/ style=""/gi,"");F=F.replace(/ class=" "/gi,"");F=F.replace(/ class="  "/gi,"");F=F.replace(/ target=""/gi,"");F=F.replace(/ title=""/gi,"");if(this.browser.ie){F=F.replace(/ class= /gi,"");F=F.replace(/ class= >/gi,"");F=F.replace(/_height="([^>])"/gi,"");F=F.replace(/_width="([^>])"/gi,"");}return F;},filter_all_rgb:function(J){var I=new RegExp("rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)","gi");var F=J.match(I);if(D.isArray(F)){for(var H=0;H<F.length;H++){var G=this.filter_rgb(F[H]);J=J.replace(F[H].toString(),G);}}r!
 eturn J;},filter_rgb:function(H){if(H.toLowerCase().indexOf("rgb")!=-1){var K=new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)","gi");var G=H.replace(K,"$1,$2,$3,$4,$5").split(",");if(G.length==5){var J=parseInt(G[1],10).toString(16);var I=parseInt(G[2],10).toString(16);var F=parseInt(G[3],10).toString(16);J=J.length==1?"0"+J:J;I=I.length==1?"0"+I:I;F=F.length==1?"0"+F:F;H="#"+J+I+F;}}return H;},pre_filter_linebreaks:function(G,F){if(this.browser.webkit){G=G.replace(/<br class="khtml-block-placeholder">/gi,"<YUI_BR>");G=G.replace(/<br class="webkit-block-placeholder">/gi,"<YUI_BR>");}G=G.replace(/<br>/gi,"<YUI_BR>");G=G.replace(/<br (.*?)>/gi,"<YUI_BR>");G=G.replace(/<br\/>/gi,"<YUI_BR>");G=G.replace(/<br \/>/gi,"<YUI_BR>");G=G.replace(/<div><YUI_BR><\/div>/gi,"<YUI_BR>");G=G.replace(/<p>( | )<\/p>/g,"<YUI_BR>");G=G.replace(/<p><br> <\/p>/gi,"<YUI_BR>");G=G.replace(/<p> <\/p>/gi,"<YUI_BR>");G=G.replace(/<YUI_BR>$/,""!
 );G=G.replace(/<YUI_BR><\/p>/g,"</p>");return G;},post_filter_!
 linebrea
ks:function(G,F){if(F=="xhtml"){G=G.replace(/<YUI_BR>/g,"<br />");}else{G=G.replace(/<YUI_BR>/g,"<br>");}return G;},clearEditorDoc:function(){this._getDoc().body.innerHTML=" ";},_renderPanel:function(){},openWindow:function(F){},moveWindow:function(){},_closeWindow:function(){},closeWindow:function(){this.unsubscribeAll("afterExecCommand");this.toolbar.resetAllButtons();this._focusWindow();},destroy:function(){this.saveHTML();this.toolbar.destroy();this.setStyle("visibility","hidden");this.setStyle("position","absolute");this.setStyle("top","-9999px");this.setStyle("left","-9999px");var G=this.get("element");this.get("element_cont").get("parentNode").replaceChild(G,this.get("element_cont").get("element"));this.get("element_cont").get("element").innerHTML="";this.set("handleSubmit",false);for(var F in this){if(D.hasOwnProperty(this,F)){this[F]=null;}}return true;},toString:function(){var F="SimpleEditor";if(this.get&&this.get("element_cont")){F="SimpleEditor (#"+this.get!
 ("element_cont").get("id")+")"+((this.get("disabled")?" Disabled":""));}return F;}});YAHOO.widget.EditorInfo={_instances:{},blankImage:"",window:{},panel:null,getEditorById:function(F){if(!YAHOO.lang.isString(F)){F=F.id;}if(this._instances[F]){return this._instances[F];}return false;},toString:function(){var F=0;for(var G in this._instances){F++;}return"Editor Info ("+F+" registered intance"+((F>1)?"s":"")+")";}};})();(function(){var C=YAHOO.util.Dom,A=YAHOO.util.Event,D=YAHOO.lang,B=YAHOO.widget.Toolbar;YAHOO.widget.Editor=function(G,F){YAHOO.widget.Editor.superclass.constructor.call(this,G,F);};function E(F){return F.replace(/ /g,"-").toLowerCase();}YAHOO.extend(YAHOO.widget.Editor,YAHOO.widget.SimpleEditor,{STR_BEFORE_EDITOR:"This text field can contain stylized text and graphics. To cycle through all formatting options, use the keyboard shortcut Control + Shift + T to place focus on the toolbar and navigate between option heading names. <h4>Common formatting keyboard sh!
 ortcuts:</h4><ul><li>Control Shift B sets text to bold</li> <l!
 i>Contro
l Shift I sets text to italic</li> <li>Control Shift U underlines text</li> <li>Control Shift [ aligns text left</li> <li>Control Shift | centers text</li> <li>Control Shift ] aligns text right</li> <li>Control Shift L adds an HTML link</li> <li>To exit this text editor use the keyboard shortcut Control + Shift + ESC.</li></ul>",STR_CLOSE_WINDOW:"Close Window",STR_CLOSE_WINDOW_NOTE:"To close this window use the Control + Shift + W key",STR_IMAGE_PROP_TITLE:"Image Options",STR_IMAGE_URL:"Image Url",STR_IMAGE_TITLE:"Description",STR_IMAGE_SIZE:"Size",STR_IMAGE_ORIG_SIZE:"Original Size",STR_IMAGE_COPY:'<span class="tip"><span class="icon icon-info"></span><strong>Note:</strong>To move this image just highlight it, cut, and paste where ever you\'d like.</span>',STR_IMAGE_PADDING:"Padding",STR_IMAGE_BORDER:"Border",STR_IMAGE_TEXTFLOW:"Text Flow",STR_LOCAL_FILE_WARNING:'<span class="tip"><span class="icon icon-warn"></span><strong>Note:</strong>This image/link points to a file on !
 your computer and will not be accessible to others on the internet.</span>',STR_LINK_PROP_TITLE:"Link Options",STR_LINK_PROP_REMOVE:"Remove link from text",STR_LINK_NEW_WINDOW:"Open in a new window.",STR_LINK_TITLE:"Description",CLASS_LOCAL_FILE:"warning-localfile",CLASS_HIDDEN:"yui-hidden",init:function(G,F){this._defaultToolbar={collapse:true,titlebar:"Text Editing Tools",draggable:false,buttonType:"advanced",buttons:[{group:"fontstyle",label:"Font Name and Size",buttons:[{type:"select",label:"Arial",value:"fontname",disabled:true,menu:[{text:"Arial",checked:true},{text:"Arial Black"},{text:"Comic Sans MS"},{text:"Courier New"},{text:"Lucida Console"},{text:"Tahoma"},{text:"Times New Roman"},{text:"Trebuchet MS"},{text:"Verdana"}]},{type:"spin",label:"13",value:"fontsize",range:[9,75],disabled:true}]},{type:"separator"},{group:"textstyle",label:"Font Style",buttons:[{type:"push",label:"Bold CTRL + SHIFT + B",value:"bold"},{type:"push",label:"Italic CTRL + SHIFT + I",value!
 :"italic"},{type:"push",label:"Underline CTRL + SHIFT + U",val!
 ue:"unde
rline"},{type:"separator"},{type:"push",label:"Subscript",value:"subscript",disabled:true},{type:"push",label:"Superscript",value:"superscript",disabled:true},{type:"separator"},{type:"color",label:"Font Color",value:"forecolor",disabled:true},{type:"color",label:"Background Color",value:"backcolor",disabled:true},{type:"separator"},{type:"push",label:"Remove Formatting",value:"removeformat",disabled:true},{type:"push",label:"Show/Hide Hidden Elements",value:"hiddenelements"}]},{type:"separator"},{group:"alignment",label:"Alignment",buttons:[{type:"push",label:"Align Left CTRL + SHIFT + [",value:"justifyleft"},{type:"push",label:"Align Center CTRL + SHIFT + |",value:"justifycenter"},{type:"push",label:"Align Right CTRL + SHIFT + ]",value:"justifyright"},{type:"push",label:"Justify",value:"justifyfull"}]},{type:"separator"},{group:"parastyle",label:"Paragraph Style",buttons:[{type:"select",label:"Normal",value:"heading",disabled:true,menu:[{text:"Normal",value:"none",checked:!
 true},{text:"Header 1",value:"h1"},{text:"Header 2",value:"h2"},{text:"Header 3",value:"h3"},{text:"Header 4",value:"h4"},{text:"Header 5",value:"h5"},{text:"Header 6",value:"h6"}]}]},{type:"separator"},{group:"indentlist",label:"Indenting and Lists",buttons:[{type:"push",label:"Indent",value:"indent",disabled:true},{type:"push",label:"Outdent",value:"outdent",disabled:true},{type:"push",label:"Create an Unordered List",value:"insertunorderedlist"},{type:"push",label:"Create an Ordered List",value:"insertorderedlist"}]},{type:"separator"},{group:"insertitem",label:"Insert Item",buttons:[{type:"push",label:"HTML Link CTRL + SHIFT + L",value:"createlink",disabled:true},{type:"push",label:"Insert Image",value:"insertimage"}]}]};
+YAHOO.widget.Editor.superclass.init.call(this,G,F);},initAttributes:function(F){YAHOO.widget.Editor.superclass.initAttributes.call(this,F);this.setAttributeConfig("localFileWarning",{value:F.locaFileWarning||true});this.setAttributeConfig("hiddencss",{value:F.hiddencss||".yui-hidden font, .yui-hidden strong, .yui-hidden b, .yui-hidden em, .yui-hidden i, .yui-hidden u, .yui-hidden div,.yui-hidden p,.yui-hidden span,.yui-hidden img, .yui-hidden ul, .yui-hidden ol, .yui-hidden li, .yui-hidden table { border: 1px dotted #ccc; } .yui-hidden .yui-non { border: none; } .yui-hidden img { padding: 2px; }",writeOnce:true});},_fixNodes:function(){YAHOO.widget.Editor.superclass._fixNodes.call(this);var I="";var J=this._getDoc().getElementsByTagName("img");for(var G=0;G<J.length;G++){if(J[G].getAttribute("href",2)){I=J[G].getAttribute("src",2);if(this._isLocalFile(I)){C.addClass(J[G],this.CLASS_LOCAL_FILE);}else{C.removeClass(J[G],this.CLASS_LOCAL_FILE);}}}var H=this._getDoc().body.getE!
 lementsByTagName("a");for(var F=0;F<H.length;F++){if(H[F].getAttribute("href",2)){I=H[F].getAttribute("href",2);if(this._isLocalFile(I)){C.addClass(H[F],this.CLASS_LOCAL_FILE);}else{C.removeClass(H[F],this.CLASS_LOCAL_FILE);}}}},_disabled:["createlink","forecolor","backcolor","fontname","fontsize","superscript","subscript","removeformat","heading","indent"],_alwaysDisabled:{"outdent":true},_alwaysEnabled:{hiddenelements:true},_handleKeyDown:function(H){YAHOO.widget.Editor.superclass._handleKeyDown.call(this,H);var G=false,I=null,F=false;if(H.shiftKey&&H.ctrlKey){G=true;}switch(H.keyCode){case 219:I="justifyleft";break;case 220:I="justifycenter";break;case 221:I="justifyright";break;}if(G&&I){this.execCommand(I,null);A.stopEvent(H);this.nodeChange();}},_handleCreateLinkClick:function(){var F=this._getSelectedElement();if(this._isElement(F,"img")){this.STOP_EXEC_COMMAND=true;this.currentElement[0]=F;this.toolbar.fireEvent("insertimageClick",{type:"insertimageClick",target:thi!
 s.toolbar});this.fireEvent("afterExecCommand",{type:"afterExec!
 Command"
,target:this});return false;}if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("createlink")){return false;}}this.on("afterExecCommand",function(){var M=new YAHOO.widget.EditorWindow("createlink",{width:"350px"});var J=this.currentElement[0],I="",P="",N="",K=false;if(J){if(J.getAttribute("href",2)!==null){I=J.getAttribute("href",2);if(this._isLocalFile(I)){M.setFooter(this.STR_LOCAL_FILE_WARNING);K=true;}else{M.setFooter(" ");}}if(J.getAttribute("title")!==null){P=J.getAttribute("title");}if(J.getAttribute("target")!==null){N=J.getAttribute("target");}}var O='<label for="createlink_url"><strong>'+this.STR_LINK_URL+':</strong> <input type="text" name="createlink_url" id="createlink_url" value="'+I+'"'+((K)?' class="warning"':"")+"></label>";O+='<label for="createlink_target"><strong> </strong><input type="checkbox" name="createlink_target_" id="createlink_target" value="_blank"'+((N)?" checked":"")+"> "+this.STR_LINK_NEW_WINDOW+"</label>";O+='<label for="cr!
 eatelink_title"><strong>'+this.STR_LINK_TITLE+':</strong> <input type="text" name="createlink_title" id="createlink_title" value="'+P+'"></label>';var L=document.createElement("div");L.innerHTML=O;var H=document.createElement("div");H.className="removeLink";var G=document.createElement("a");G.href="#";G.innerHTML=this.STR_LINK_PROP_REMOVE;G.title=this.STR_LINK_PROP_REMOVE;A.on(G,"click",function(Q){A.stopEvent(Q);this.execCommand("unlink");this.closeWindow();},this,true);H.appendChild(G);L.appendChild(H);M.setHeader(this.STR_LINK_PROP_TITLE);M.setBody(L);A.onAvailable("createlink_url",function(){window.setTimeout(function(){try{YAHOO.util.Dom.get("createlink_url").focus();}catch(Q){}},50);A.on("createlink_url","blur",function(){var Q=C.get("createlink_url");if(this._isLocalFile(Q.value)){C.addClass(Q,"warning");this.get("panel").setFooter(this.STR_LOCAL_FILE_WARNING);}else{C.removeClass(Q,"warning");this.get("panel").setFooter(" ");}},this,true);},this,true);this.openWindow!
 (M);});},_handleCreateLinkWindowClose:function(){var H=C.get("!
 createli
nk_url"),J=C.get("createlink_target"),L=C.get("createlink_title"),I=this.currentElement[0],F=I;if(H&&H.value){var K=H.value;if((K.indexOf(":/"+"/")==-1)&&(K.substring(0,1)!="/")&&(K.substring(0,6).toLowerCase()!="mailto")){if((K.indexOf("@")!=-1)&&(K.substring(0,6).toLowerCase()!="mailto")){K="mailto:"+K;}else{if(K.substring(0,1)!="#"){K="http:/"+"/"+K;}}}I.setAttribute("href",K);if(J.checked){I.setAttribute("target",J.value);}else{I.setAttribute("target","");}I.setAttribute("title",((L.value)?L.value:""));}else{var G=this._getDoc().createElement("span");G.innerHTML=I.innerHTML;C.addClass(G,"yui-non");I.parentNode.replaceChild(G,I);}this.nodeChange();this.currentElement=[];},_handleInsertImageClick:function(){if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("insertimage")){return false;}}this._setBusy();this.on("afterExecCommand",function(){var I=this.currentElement[0],S=null,P="",e="",f="",O="",b="",V=75,Y=75,U=0,Q=0,N=0,W=false,M=new YAHOO.widget.EditorWindo!
 w("insertimage",{width:"415px"});if(!I){I=this._getSelectedElement();}if(I){if(I.getAttribute("src")){O=I.getAttribute("src",2);if(O.indexOf(this.get("blankimage"))!=-1){O=this.STR_IMAGE_HERE;W=true;}}if(I.getAttribute("alt",2)){f=I.getAttribute("alt",2);}if(I.getAttribute("title",2)){f=I.getAttribute("title",2);}if(I.parentNode&&this._isElement(I.parentNode,"a")){P=I.parentNode.getAttribute("href",2);if(I.parentNode.getAttribute("target")!==null){e=I.parentNode.getAttribute("target");}}V=parseInt(I.height,10);Y=parseInt(I.width,10);if(I.style.height){V=parseInt(I.style.height,10);}if(I.style.width){Y=parseInt(I.style.width,10);}if(I.style.margin){U=parseInt(I.style.margin,10);}if(!I._height){I._height=V;}if(!I._width){I._width=Y;}Q=I._height;N=I._width;}var Z='<label for="insertimage_url"><strong>'+this.STR_IMAGE_URL+':</strong> <input type="text" id="insertimage_url" value="'+O+'" size="40"></label>';S=document.createElement("div");
+S.innerHTML=Z;var K=document.createElement("div");K.id="img_toolbar";S.appendChild(K);var F='<label for="insertimage_title"><strong>'+this.STR_IMAGE_TITLE+':</strong> <input type="text" id="insertimage_title" value="'+f+'" size="40"></label>';F+='<label for="insertimage_link"><strong>'+this.STR_LINK_URL+':</strong> <input type="text" name="insertimage_link" id="insertimage_link" value="'+P+'"></label>';F+='<label for="insertimage_target"><strong> </strong><input type="checkbox" name="insertimage_target_" id="insertimage_target" value="_blank"'+((e)?" checked":"")+"> "+this.STR_LINK_NEW_WINDOW+"</label>";var T=document.createElement("div");T.innerHTML=F;S.appendChild(T);M.cache=S;var H=new YAHOO.widget.Toolbar(K,{buttonType:this._defaultToolbar.buttonType,buttons:[{group:"textflow",label:this.STR_IMAGE_TEXTFLOW+":",buttons:[{type:"push",label:"Left",value:"left"},{type:"push",label:"Inline",value:"inline"},{type:"push",label:"Block",value:"block"},{type:"push",label:"Ri!
 ght",value:"right"}]},{type:"separator"},{group:"padding",label:this.STR_IMAGE_PADDING+":",buttons:[{type:"spin",label:""+U,value:"padding",range:[0,50]}]},{type:"separator"},{group:"border",label:this.STR_IMAGE_BORDER+":",buttons:[{type:"select",label:"Border Size",value:"bordersize",menu:[{text:"none",value:"0",checked:true},{text:"1px",value:"1"},{text:"2px",value:"2"},{text:"3px",value:"3"},{text:"4px",value:"4"},{text:"5px",value:"5"}]},{type:"select",label:"Border Type",value:"bordertype",disabled:true,menu:[{text:"Solid",value:"solid",checked:true},{text:"Dashed",value:"dashed"},{text:"Dotted",value:"dotted"}]},{type:"color",label:"Border Color",value:"bordercolor",disabled:true}]}]});var G="0";var X="solid";if(I.style.borderLeftWidth){G=parseInt(I.style.borderLeftWidth,10);}if(I.style.borderLeftStyle){X=I.style.borderLeftStyle;}var d=H.getButtonByValue("bordersize");var a=((parseInt(G,10)>0)?"":"none");d.set("label",'<span class="yui-toolbar-bordersize-'+G+'">'+a+"<!
 /span>");this._updateMenuChecked("bordersize",G,H);var R=H.get!
 ButtonBy
Value("bordertype");R.set("label",'<span class="yui-toolbar-bordertype-'+X+'"></span>');this._updateMenuChecked("bordertype",X,H);if(parseInt(G,10)>0){H.enableButton(R);H.enableButton(d);}var J=H.get("cont");var c=document.createElement("div");c.className="yui-toolbar-group yui-toolbar-group-height-width height-width";c.innerHTML="<h3>"+this.STR_IMAGE_SIZE+":</h3>";var L="";if((V!=Q)||(Y!=N)){L='<span class="info">'+this.STR_IMAGE_ORIG_SIZE+"<br>"+N+" x "+Q+"</span>";}c.innerHTML+='<span tabIndex="-1"><input type="text" size="3" value="'+Y+'" id="insertimage_width"> x <input type="text" size="3" value="'+V+'" id="insertimage_height"></span>'+L;J.insertBefore(c,J.firstChild);A.onAvailable("insertimage_width",function(){A.on("insertimage_width","blur",function(){var g=parseInt(C.get("insertimage_width").value,10);if(g>5){I.style.width=g+"px";}},this,true);},this,true);A.onAvailable("insertimage_height",function(){A.on("insertimage_height","blur",function(){var g=parseInt(C.get!
 ("insertimage_height").value,10);if(g>5){I.style.height=g+"px";}},this,true);},this,true);if((I.align=="right")||(I.align=="left")){H.selectButton(I.align);}else{if(I.style.display=="block"){H.selectButton("block");}else{H.selectButton("inline");}}if(parseInt(I.style.marginLeft,10)>0){H.getButtonByValue("padding").set("label",""+parseInt(I.style.marginLeft,10));}if(I.style.borderSize){H.selectButton("bordersize");H.selectButton(parseInt(I.style.borderSize,10));}H.on("colorPickerClicked",function(k){var h="1",j="solid",g="black";if(I.style.borderLeftWidth){h=parseInt(I.style.borderLeftWidth,10);}if(I.style.borderLeftStyle){j=I.style.borderLeftStyle;}if(I.style.borderLeftColor){g=I.style.borderLeftColor;}var i=h+"px "+j+" #"+k.color;I.style.border=i;},this.toolbar,true);H.on("buttonClick",function(m){var k=m.button.value,j="";if(m.button.menucmd){k=m.button.menucmd;}var h="1",i="solid",g="black";if(I.style.borderLeftWidth){h=parseInt(I.style.borderLeftWidth,10);}if(I.style.bo!
 rderLeftStyle){i=I.style.borderLeftStyle;}if(I.style.borderLef!
 tColor){
g=I.style.borderLeftColor;}switch(k){case"bordersize":if(this.browser.webkit&&this._lastImage){C.removeClass(this._lastImage,"selected");this._lastImage=null;}j=parseInt(m.button.value,10)+"px "+i+" "+g;I.style.border=j;if(parseInt(m.button.value,10)>0){H.enableButton("bordertype");H.enableButton("bordercolor");}else{H.disableButton("bordertype");H.disableButton("bordercolor");}break;case"bordertype":if(this.browser.webkit&&this._lastImage){C.removeClass(this._lastImage,"selected");this._lastImage=null;}j=h+"px "+m.button.value+" "+g;I.style.border=j;break;case"right":case"left":H.deselectAllButtons();I.style.display="";I.align=m.button.value;break;case"inline":H.deselectAllButtons();I.style.display="";I.align="";break;case"block":H.deselectAllButtons();I.style.display="block";I.align="center";break;case"padding":var l=H.getButtonById(m.button.id);I.style.margin=l.get("label")+"px";break;}H.selectButton(m.button.value);this.moveWindow();},this,true);M.setHeader(this.STR_IMAG!
 E_PROP_TITLE);M.setBody(S);if((this.browser.webkit&&!this.browser.webkit3||this.browser.air)||this.browser.opera){M.setFooter(this.STR_IMAGE_COPY);}this.openWindow(M);A.onAvailable("insertimage_url",function(){this.toolbar.selectButton("insertimage");window.setTimeout(function(){YAHOO.util.Dom.get("insertimage_url").focus();if(W){YAHOO.util.Dom.get("insertimage_url").select();}},50);if(this.get("localFileWarning")){A.on("insertimage_link","blur",function(){var g=C.get("insertimage_link");if(this._isLocalFile(g.value)){C.addClass(g,"warning");this.get("panel").setFooter(this.STR_LOCAL_FILE_WARNING);}else{C.removeClass(g,"warning");this.get("panel").setFooter(" ");if((this.browser.webkit&&!this.browser.webkit3||this.browser.air)||this.browser.opera){this.get("panel").setFooter(this.STR_IMAGE_COPY);}}},this,true);A.on("insertimage_url","blur",function(){var i=C.get("insertimage_url");if(i.value&&I){if(i.value==I.getAttribute("src",2)){return false;
+}}if(this._isLocalFile(i.value)){C.addClass(i,"warning");this.get("panel").setFooter(this.STR_LOCAL_FILE_WARNING);}else{if(this.currentElement[0]){C.removeClass(i,"warning");this.get("panel").setFooter(" ");if((this.browser.webkit&&!this.browser.webkit3||this.browser.air)||this.browser.opera){this.get("panel").setFooter(this.STR_IMAGE_COPY);}if(i&&i.value&&(i.value!=this.STR_IMAGE_HERE)){this.currentElement[0].setAttribute("src",i.value);var h=this,g=new Image();g.onerror=function(){i.value=h.STR_IMAGE_HERE;g.setAttribute("src",h.get("blankimage"));h.currentElement[0].setAttribute("src",h.get("blankimage"));YAHOO.util.Dom.get("insertimage_height").value=g.height;YAHOO.util.Dom.get("insertimage_width").value=g.width;};window.setTimeout(function(){YAHOO.util.Dom.get("insertimage_height").value=g.height;YAHOO.util.Dom.get("insertimage_width").value=g.width;if(h.currentElement&&h.currentElement[0]){if(!h.currentElement[0]._height){h.currentElement[0]._height=g.height;}if(!h.cur!
 rentElement[0]._width){h.currentElement[0]._width=g.width;}}},800);if(i.value!=this.STR_IMAGE_HERE){g.src=i.value;}}}}},this,true);}},this,true);});},_handleInsertImageWindowClose:function(){var F=C.get("insertimage_url");var M=C.get("insertimage_title");var J=C.get("insertimage_link");var K=C.get("insertimage_target");var I=this.currentElement[0];if(F&&F.value&&(F.value!=this.STR_IMAGE_HERE)){I.setAttribute("src",F.value);I.setAttribute("title",M.value);I.setAttribute("alt",M.value);var H=I.parentNode;if(J.value){var L=J.value;if((L.indexOf(":/"+"/")==-1)&&(L.substring(0,1)!="/")&&(L.substring(0,6).toLowerCase()!="mailto")){if((L.indexOf("@")!=-1)&&(L.substring(0,6).toLowerCase()!="mailto")){L="mailto:"+L;}else{L="http:/"+"/"+L;}}if(H&&this._isElement(H,"a")){H.setAttribute("href",L);if(K.checked){H.setAttribute("target",K.value);}else{H.setAttribute("target","");}}else{var G=this._getDoc().createElement("a");G.setAttribute("href",L);if(K.checked){G.setAttribute("target",K!
 .value);}else{G.setAttribute("target","");}I.parentNode.replac!
 eChild(G
,I);G.appendChild(I);}}else{if(H&&this._isElement(H,"a")){H.parentNode.replaceChild(I,H);}}}else{I.parentNode.removeChild(I);}this.currentElement=[];this.nodeChange();},_renderPanel:function(){var F=null;if(!YAHOO.widget.EditorInfo.panel){F=new YAHOO.widget.Overlay(this.EDITOR_PANEL_ID,{width:"300px",iframe:true,visible:false,underlay:"none",draggable:false,close:false});YAHOO.widget.EditorInfo.panel=F;}else{F=YAHOO.widget.EditorInfo.panel;}this.set("panel",F);this.get("panel").setBody("---");this.get("panel").setHeader(" ");this.get("panel").setFooter(" ");if(this.DOMReady){this.get("panel").render(document.body);C.addClass(this.get("panel").element,"yui-editor-panel");}else{A.onDOMReady(function(){this.get("panel").render(document.body);C.addClass(this.get("panel").element,"yui-editor-panel");},this,true);}this.get("panel").showEvent.subscribe(function(){YAHOO.util.Dom.setStyle(this.element,"display","block");});return this.get("panel");},openWindow:function(K){this.toolba!
 r.set("disabled",true);A.on(document,"keypress",this._closeWindow,this,true);if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}YAHOO.widget.EditorInfo.window.win=K;YAHOO.widget.EditorInfo.window.scope=this;var P=this,L=C.getXY(this.currentElement[0]),U=C.getXY(this.get("iframe").get("element")),N=this.get("panel"),T=[(L[0]+U[0]-20),(L[1]+U[1]+10)],O=(parseInt(K.attrs.width,10)/2),R="center",M=null;this.fireEvent("beforeOpenWindow",{type:"beforeOpenWindow",win:K,panel:N});M=document.createElement("div");M.className=this.CLASS_PREFIX+"-body-cont";for(var V in this.browser){if(this.browser[V]){C.addClass(M,V);break;}}C.addClass(M,((YAHOO.widget.Button&&(this._defaultToolbar.buttonType=="advanced"))?"good-button":"no-button"));var S=document.createElement("h3");S.className="yui-editor-skipheader";S.innerHTML=this.STR_CLOSE_WINDOW_NOTE;M.appendChild(S);form=doc!
 ument.createElement("form");form.setAttribute("method","GET");!
 var W=K.
name;A.on(form,"submit",function(Y){var X="window"+W+"Submit";P.fireEvent(X,{type:X,target:this});A.stopEvent(Y);},this,true);M.appendChild(form);if(D.isObject(K.body)){form.appendChild(K.body);}else{var F=document.createElement("div");F.innerHTML=K.body;form.appendChild(F);}var J=document.createElement("span");J.innerHTML="X";J.title=this.STR_CLOSE_WINDOW;J.className="close";A.on(J,"click",function(){this.closeWindow();},this,true);var H=document.createElement("span");H.innerHTML="^";H.className="knob";K._knob=H;var I=document.createElement("h3");I.innerHTML=K.header;N.cfg.setProperty("width",K.attrs.width);N.setHeader(" ");N.appendToHeader(I);I.appendChild(J);I.appendChild(H);N.setBody(" ");N.setFooter(" ");if(K.footer!==null){N.setFooter(K.footer);C.addClass(N.footer,"open");}else{C.removeClass(N.footer,"open");}N.appendToBody(M);var Q=function(){N.bringToTop();A.on(N.element,"click",function(X){A.stopPropagation(X);});this._setBusy(true);N.showEvent.unsubscribe(Q);};N.sh!
 owEvent.subscribe(Q,this,true);var G=function(){this.currentWindow=null;var X="window"+W+"Close";this.fireEvent(X,{type:X,target:this});N.hideEvent.unsubscribe(G);};N.hideEvent.subscribe(G,this,true);this.currentWindow=K;this.moveWindow(true);N.show();this.fireEvent("afterOpenWindow",{type:"afterOpenWindow",win:K,panel:N});},moveWindow:function(G){if(!this.currentWindow){return false;}var J=this.currentWindow,K=C.getXY(this.currentElement[0]),b=C.getXY(this.get("iframe").get("element")),P=this.get("panel"),Z=[(K[0]+b[0]),(K[1]+b[1])],S=(parseInt(J.attrs.width,10)/2),V="center",R=P.cfg.getProperty("xy")||[0,0],H=J._knob,Y=0,M=0,U=false;Z[0]=((Z[0]-S)+20);Z[0]=Z[0]-C.getDocumentScrollLeft(this._getDoc());Z[1]=Z[1]-C.getDocumentScrollTop(this._getDoc());if(this._isElement(this.currentElement[0],"img")){if(this.currentElement[0].src.indexOf(this.get("blankimage"))!=-1){Z[0]=(Z[0]+(75/2));Z[1]=(Z[1]+75);}else{var O=parseInt(this.currentElement[0].width,10);
+var X=parseInt(this.currentElement[0].height,10);Z[0]=(Z[0]+(O/2));Z[1]=(Z[1]+X);}Z[1]=Z[1]+15;}else{var L=C.getStyle(this.currentElement[0],"fontSize");if(L&&L.indexOf&&L.indexOf("px")!=-1){Z[1]=Z[1]+parseInt(C.getStyle(this.currentElement[0],"fontSize"),10)+5;}else{Z[1]=Z[1]+20;}}if(Z[0]<b[0]){Z[0]=b[0]+5;V="left";}if((Z[0]+(S*2))>(b[0]+parseInt(this.get("iframe").get("element").clientWidth,10))){Z[0]=((b[0]+parseInt(this.get("iframe").get("element").clientWidth,10))-(S*2)-5);V="right";}try{Y=(Z[0]-R[0]);M=(Z[1]-R[1]);}catch(c){}var Q=b[1]+parseInt(this.get("height"),10);var I=b[0]+parseInt(this.get("width"),10);if(Z[1]>Q){Z[1]=Q;}if(Z[0]>I){Z[0]=(I/2);}Y=((Y<0)?(Y*-1):Y);M=((M<0)?(M*-1):M);if(((Y>10)||(M>10))||G){var T=0,W=0;if(this.currentElement[0].width){W=(parseInt(this.currentElement[0].width,10)/2);}var N=K[0]+b[0]+W;T=N-Z[0];if(T>(parseInt(J.attrs.width,10)-1)){T=((parseInt(J.attrs.width,10)-30)-1);}else{if(T<40){T=1;}}if(isNaN(T)){T=1;}if(G){if(H){H.style.left=T+!
 "px";}if(this.get("animate")){C.setStyle(P.element,"opacity","0");U=new YAHOO.util.Anim(P.element,{opacity:{from:0,to:1}},0.1,YAHOO.util.Easing.easeOut);P.cfg.setProperty("xy",Z);U.onComplete.subscribe(function(){if(this.browser.ie){P.element.style.filter="none";}},this,true);U.animate();}else{P.cfg.setProperty("xy",Z);}}else{if(this.get("animate")){U=new YAHOO.util.Anim(P.element,{},0.5,YAHOO.util.Easing.easeOut);U.attributes={top:{to:Z[1]},left:{to:Z[0]}};U.onComplete.subscribe(function(){P.cfg.setProperty("xy",Z);});var a=new YAHOO.util.Anim(P.iframe,U.attributes,0.5,YAHOO.util.Easing.easeOut);var F=new YAHOO.util.Anim(H,{left:{to:T}},0.6,YAHOO.util.Easing.easeOut);U.animate();a.animate();F.animate();}else{H.style.left=T+"px";P.cfg.setProperty("xy",Z);}}}},_closeWindow:function(F){if((F.charCode==87)&&F.shiftKey&&F.ctrlKey){if(this.currentWindow){this.closeWindow();}}},closeWindow:function(){YAHOO.widget.EditorInfo.window={};this.fireEvent("closeWindow",{type:"closeWindo!
 w",win:this.currentWindow});this.currentWindow=null;this.get("!
 panel").
hide();this.get("panel").cfg.setProperty("xy",[-900,-900]);this.get("panel").syncIframe();this.unsubscribeAll("afterExecCommand");this.toolbar.set("disabled",false);this.toolbar.resetAllButtons();this._focusWindow();A.removeListener(document,"keypress",this._closeWindow);},cmd_heading:function(J){var G=true,H=null,I="heading",K=this._getSelection(),F=this._getSelectedElement();if(F){K=F;}if(this.browser.ie){I="formatblock";}if(J=="none"){if((K&&K.tagName&&(K.tagName.toLowerCase().substring(0,1)=="h"))||(K&&K.parentNode&&K.parentNode.tagName&&(K.parentNode.tagName.toLowerCase().substring(0,1)=="h"))){if(K.parentNode.tagName.toLowerCase().substring(0,1)=="h"){K=K.parentNode;}if(this._isElement(K,"html")){return[false];}H=this._swapEl(F,"span",function(L){L.className="yui-non";});this._selectNode(H);this.currentElement[0]=H;}G=false;}else{if(this._isElement(F,"h1")||this._isElement(F,"h2")||this._isElement(F,"h3")||this._isElement(F,"h4")||this._isElement(F,"h5")||this._isEleme!
 nt(F,"h6")){H=this._swapEl(F,J);this._selectNode(H);this.currentElement[0]=H;}else{this._createCurrentElement(J);this._selectNode(this.currentElement[0]);}G=false;}return[G,I];},cmd_hiddenelements:function(F){if(this._showingHiddenElements){this._lastButton=null;this._showingHiddenElements=false;this.toolbar.deselectButton("hiddenelements");C.removeClass(this._getDoc().body,this.CLASS_HIDDEN);}else{this._showingHiddenElements=true;C.addClass(this._getDoc().body,this.CLASS_HIDDEN);this.toolbar.selectButton("hiddenelements");}return[false];},cmd_removeformat:function(I){var G=true;if(this.browser.webkit&&!this._getDoc().queryCommandEnabled("removeformat")){var F=this._getSelection()+"";this._createCurrentElement("span");this.currentElement[0].className="yui-non";this.currentElement[0].innerHTML=F;for(var H=1;H<this.currentElement.length;H++){this.currentElement[H].parentNode.removeChild(this.currentElement[H]);}G=false;}return[G];},cmd_script:function(L,K){var H=true,F=L.toLo!
 werCase().substring(0,3),I=null,G=this._getSelectedElement();i!
 f(this.b
rowser.webkit){if(this._isElement(G,F)){I=this._swapEl(this.currentElement[0],"span",function(M){M.className="yui-non";});this._selectNode(I);}else{this._createCurrentElement(F);var J=this._swapEl(this.currentElement[0],F);this._selectNode(J);this.currentElement[0]=J;}H=false;}return H;},cmd_superscript:function(F){return[this.cmd_script("superscript",F)];},cmd_subscript:function(F){return[this.cmd_script("subscript",F)];},cmd_indent:function(I){var F=true,H=this._getSelectedElement(),J=null;if(this.browser.webkit||this.browser.ie||this.browser.gecko){if(this._isElement(H,"blockquote")){J=this._getDoc().createElement("blockquote");J.innerHTML=H.innerHTML;H.innerHTML="";H.appendChild(J);this._selectNode(J);}else{this._createCurrentElement("blockquote");for(var G=0;G<this.currentElement.length;G++){J=this._getDoc().createElement("blockquote");J.innerHTML=this.currentElement[G].innerHTML;this.currentElement[G].parentNode.replaceChild(J,this.currentElement[G]);this.currentElemen!
 t[G]=J;}this._selectNode(this.currentElement[0]);}F=false;}else{I="blockquote";}return[F,"indent",I];},cmd_outdent:function(J){var F=true,I=this._getSelectedElement(),K=null,G=null;if(this.browser.webkit||this.browser.ie||this.browser.gecko){I=this._getSelectedElement();if(this._isElement(I,"blockquote")){var H=I.parentNode;if(this._isElement(I.parentNode,"blockquote")){H.innerHTML=I.innerHTML;this._selectNode(H);}else{G=this._getDoc().createElement("span");G.innerHTML=I.innerHTML;YAHOO.util.Dom.addClass(G,"yui-non");H.replaceChild(G,I);this._selectNode(G);}}else{}F=false;}else{J="blockquote";}return[F,"indent",J];},toString:function(){var F="Editor";if(this.get&&this.get("element_cont")){F="Editor (#"+this.get("element_cont").get("id")+")"+((this.get("disabled")?" Disabled":""));}return F;}});YAHOO.widget.EditorWindow=function(G,F){this.name=G.replace(" ","_");this.attrs=F;};YAHOO.widget.EditorWindow.prototype={_cache:null,header:null,body:null,footer:null,setHeader:functi!
 on(F){this.header=F;
+},setBody:function(F){this.body=F;},setFooter:function(F){this.footer=F;},toString:function(){return"Editor Window ("+this.name+")";}};})();YAHOO.register("editor",YAHOO.widget.Editor,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/editor/editor-beta.js
===================================================================
--- trunk/root/static/yui/editor/editor-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/editor/editor-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 (function() {
     /**
@@ -88,6 +88,7 @@
         oConfig.element.setAttribute('unselectable', 'on');
         oConfig.element.className = 'yui-button yui-' + oConfig.attributes.type + '-button';
         oConfig.element.innerHTML = '<span class="first-child"><a href="#">LABEL</a></span>';
+        oConfig.element.firstChild.firstChild.tabIndex = '-1';
         oConfig.attributes.id = Dom.generateId();
 
         YAHOO.widget.ToolbarButton.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
@@ -285,6 +286,20 @@
             return this.get('menu');
         },
         /** 
+        * @method destroy
+        * @description Destroy the button
+        */        
+        destroy: function() {
+            Event.purgeElement(this.get('element'), true);
+            this.get('element').parentNode.removeChild(this.get('element'));
+            //Brutal Object Destroy
+            for (var i in this) {
+                if (Lang.hasOwnProperty(this, i)) {
+                    this[i] = null;
+                }
+            }       
+        },
+        /** 
         * @method fireEvent
         * @description Overridden fireEvent method to prevent DOM events from firing if the button is disabled.
         */        
@@ -309,7 +324,6 @@
 })();
 /**
  * @description <p>Creates a rich Toolbar widget based on Button. Primarily used with the Rich Text Editor</p>
- * @class Toolbar
  * @namespace YAHOO.widget
  * @requires yahoo, dom, element, event, toolbarbutton
  * @optional container_core, dragdrop
@@ -322,10 +336,29 @@
 var Dom = YAHOO.util.Dom,
     Event = YAHOO.util.Event,
     Lang = YAHOO.lang;
+    
+    var getButton = function(id) {
+        var button = id;
+        if (Lang.isString(id)) {
+            button = this.getButtonById(id);
+        }
+        if (Lang.isNumber(id)) {
+            button = this.getButtonByIndex(id);
+        }
+        if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
+            button = this.getButtonByValue(id);
+        }
+        if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            return button;
+        }
+        return false;
+    };
 
     /**
      * Provides a rich toolbar widget based on the button and menu widgets
      * @constructor
+     * @class Toolbar
+     * @extends YAHOO.util.Element
      * @param {String/HTMLElement} el The element to turn into a toolbar.
      * @param {Object} attrs Object liternal containing configuration parameters.
     */
@@ -363,10 +396,19 @@
             oConfig.element.id = ((Lang.isString(el)) ? el : Dom.generateId());
         }
         
+        var fs = document.createElement('fieldset');
+        var lg = document.createElement('legend');
+        lg.innerHTML = 'Toolbar';
+        fs.appendChild(lg);
+        
         var cont = document.createElement('DIV');
         oConfig.attributes.cont = cont;
         Dom.addClass(cont, 'yui-toolbar-subcont');
-        oConfig.element.appendChild(cont);
+        fs.appendChild(cont);
+        oConfig.element.appendChild(fs);
+
+        oConfig.element.tabIndex = -1;
+
         
         oConfig.attributes.element = oConfig.element;
         oConfig.attributes.id = oConfig.element.id;
@@ -687,6 +729,7 @@
         */
         init: function(p_oElement, p_oAttributes) {
             YAHOO.widget.Toolbar.superclass.init.call(this, p_oElement, p_oAttributes);
+
         },
         /**
         * @method initAttributes
@@ -812,7 +855,7 @@
             * @type Boolean
             */
             this.setAttributeConfig('grouplabels', {
-                value: attr.grouplabels || true,
+                value: ((attr.grouplabels === false) ? false : true),
                 method: function(grouplabels) {
                     if (grouplabels) {
                         Dom.removeClass(this.get('cont'), (this.CLASS_PREFIX + '-nogrouplabels'));
@@ -836,12 +879,22 @@
                             this._titlebar.parentNode.removeChild(this._titlebar);
                         }
                         this._titlebar = document.createElement('DIV');
+                        this._titlebar.tabIndex = '-1';
+                        Event.on(this._titlebar, 'focus', function() {
+                            this._handleFocus();
+                        }, this, true);
                         Dom.addClass(this._titlebar, this.CLASS_PREFIX + '-titlebar');
                         if (Lang.isString(titlebar)) {
                             var h2 = document.createElement('h2');
                             h2.tabIndex = '-1';
-                            h2.innerHTML = titlebar;
+                            h2.innerHTML = '<a href="#" tabIndex="0">' + titlebar + '</a>';
                             this._titlebar.appendChild(h2);
+                            Event.on(h2.firstChild, 'click', function(ev) {
+                                Event.stopEvent(ev);
+                            });
+                            Event.on([h2, h2.firstChild], 'focus', function() {
+                                this._handleFocus();
+                            }, this, true);
                         }
                         if (this.get('firstChild')) {
                             this.insertBefore(this._titlebar, this.get('firstChild'));
@@ -870,34 +923,36 @@
             this.setAttributeConfig('collapse', {
                 value: false,
                 method: function(collapse) {
-                    var collapseEl = null;
-                    var el = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
-                    if (collapse) {
-                        if (el.length > 0) {
-                            //There is already a collapse button
-                            return true;
-                        }
-                        collapseEl = document.createElement('SPAN');
-                        collapseEl.innerHTML = 'X';
-                        collapseEl.title = this.STR_COLLAPSE;
+                    if (this._titlebar) {
+                        var collapseEl = null;
+                        var el = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
+                        if (collapse) {
+                            if (el.length > 0) {
+                                //There is already a collapse button
+                                return true;
+                            }
+                            collapseEl = document.createElement('SPAN');
+                            collapseEl.innerHTML = 'X';
+                            collapseEl.title = this.STR_COLLAPSE;
 
-                        Dom.addClass(collapseEl, 'collapse');
-                        this._titlebar.appendChild(collapseEl);
-                        Event.addListener(collapseEl, 'click', function() {
-                            if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
-                                this.collapse(false); //Expand Toolbar
-                            } else {
-                                this.collapse(); //Collapse Toolbar
+                            Dom.addClass(collapseEl, 'collapse');
+                            this._titlebar.appendChild(collapseEl);
+                            Event.addListener(collapseEl, 'click', function() {
+                                if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
+                                    this.collapse(false); //Expand Toolbar
+                                } else {
+                                    this.collapse(); //Collapse Toolbar
+                                }
+                            }, this, true);
+                        } else {
+                            collapseEl = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
+                            if (collapseEl[0]) {
+                                if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
+                                    //We are closed, reopen the titlebar..
+                                    this.collapse(false); //Expand Toolbar
+                                }
+                                collapseEl[0].parentNode.removeChild(collapseEl[0]);
                             }
-                        }, this, true);
-                    } else {
-                        collapseEl = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
-                        if (collapseEl[0]) {
-                            if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
-                                //We are closed, reopen the titlebar..
-                                this.collapse(false); //Expand Toolbar
-                            }
-                            collapseEl[0].parentNode.removeChild(collapseEl[0]);
                         }
                     }
                 }
@@ -968,7 +1023,7 @@
         /**
         * @method addButtonGroup
         * @description Add a new button group to the toolbar. (uses addButton)
-        * @param {Object} oGroup Object literal reference to the Groups Config (contains an array of button configs)
+        * @param {Object} oGroup Object literal reference to the Groups Config (contains an array of button configs as well as the group label)
         */
         addButtonGroup: function(oGroup) {
             if (!this.get('element')) {
@@ -982,7 +1037,6 @@
             var div = document.createElement('DIV');
             Dom.addClass(div, this.CLASS_PREFIX + '-group');
             Dom.addClass(div, this.CLASS_PREFIX + '-group-' + oGroup.group);
-            //if (oGroup.label && this.get('grouplabels')) {
             if (oGroup.label) {
                 var label = document.createElement('h3');
                 label.innerHTML = oGroup.label;
@@ -1061,9 +1115,6 @@
                                         oButton.menucmd = oButton.value;
                                     }
                                     oButton.value = ((oMenu.value) ? oMenu.value : oMenu._oText.nodeValue);
-                                    //This line made Opera fire the click event and the mousedown,
-                                    //  so events for menus where firing twice.
-                                    //this._buttonClick('click', oButton);
                                 },
                                 scope: this
                             };
@@ -1114,8 +1165,11 @@
             } else {
                 //Add to .get('buttons') manually
                 this._configs.buttons.value[this._configs.buttons.value.length] = oButton;
-
+                
                 var tmp = new this.buttonType(_oButton);
+                tmp.get('element').tabIndex = '-1';
+                tmp.get('element').setAttribute('role', 'button');
+                tmp._selected = true;
                 if (!tmp.buttonType) {
                     tmp.buttonType = 'rich';
                     tmp.checkValue = function(value) {
@@ -1164,6 +1218,7 @@
                     var a = document.createElement('a');
                     a.innerHTML = tmp._button.innerHTML;
                     a.href = '#';
+                    a.tabIndex = '-1';
                     Event.on(a, 'click', function(ev) {
                         Event.stopEvent(ev);
                     });
@@ -1197,7 +1252,9 @@
                                 exec = false;
                             }
                             if (exec) {
-                                this._colorPicker._button = oButton.value;
+                                if (this._colorPicker) {
+                                    this._colorPicker._button = oButton.value;
+                                }
                                 var menuEL = tmp.getMenu().element;
                                 if (Dom.getStyle(menuEL, 'visibility') == 'hidden') {
                                     tmp.getMenu().show();
@@ -1217,7 +1274,7 @@
                             this._buttonClick(ev, oButton);
                         }, oButton, this);
                         tmp.on('click', function(ev) {
-                            YAHOO.util.Event.stopEvent(ev);
+                            //YAHOO.util.Event.stopEvent(ev);
                         });
                     } else {
                         //Stop the mousedown event so we can trap the selection in the editor!
@@ -1234,6 +1291,7 @@
                             oButton.value = ev.value;
                             this._buttonClick(ev, oButton);
                         }, this, true);
+
                         var self = this;
                         //Hijack the mousedown event in the menu and make it fire a button click..
                         if (tmp.getMenu().mouseDownEvent) {
@@ -1268,6 +1326,7 @@
                     });
                 }
                 if (this.browser.ie) {
+                    /*
                     //Add a couple of new events for IE
                     tmp.DOM_EVENTS.focusin = true;
                     tmp.DOM_EVENTS.focusout = true;
@@ -1283,6 +1342,7 @@
                     tmp.on('click', function(ev) {
                         YAHOO.util.Event.stopEvent(ev);
                     }, oButton, this);
+                    */
                 }
                 if (this.browser.webkit) {
                     //This will keep the document from gaining focus and the editor from loosing it..
@@ -1381,11 +1441,14 @@
                 }
             }
             html += '<span><em>X</em><strong></strong></span>';
-            picker.innerHTML = html;
-            var em = picker.getElementsByTagName('em')[0];
-            var strong = picker.getElementsByTagName('strong')[0];
+            window.setTimeout(function() {
+                picker.innerHTML = html;
+            }, 0);
 
             Event.on(picker, 'mouseover', function(ev) {
+                var picker = this._colorPicker;
+                var em = picker.getElementsByTagName('em')[0];
+                var strong = picker.getElementsByTagName('strong')[0];
                 var tar = Event.getTarget(ev);
                 if (tar.tagName.toLowerCase() == 'a') {
                     em.style.backgroundColor = tar.style.backgroundColor;
@@ -1402,7 +1465,16 @@
                 Event.stopEvent(ev);
                 var tar = Event.getTarget(ev);
                 if (tar.tagName.toLowerCase() == 'a') {
-                    this.fireEvent('colorPickerClicked', { type: 'colorPickerClicked', target: this, button: this._colorPicker._button, color: tar.innerHTML, colorName: this._colorData['#' + tar.innerHTML] } );
+                    var retVal = this.fireEvent('colorPickerClicked', { type: 'colorPickerClicked', target: this, button: this._colorPicker._button, color: tar.innerHTML, colorName: this._colorData['#' + tar.innerHTML] } );
+                    if (retVal !== false) {
+                        var info = {
+                            color: tar.innerHTML,
+                            colorName: this._colorData['#' + tar.innerHTML],
+                            value: this._colorPicker._button 
+                        };
+                    
+                        this.fireEvent('buttonClick', { type: 'buttonClick', target: this.get('element'), button: info });
+                    }
                     this.getButtonByValue(this._colorPicker._button).getMenu().hide();
                 }
             }, this, true);
@@ -1465,6 +1537,8 @@
                 _b2 = document.createElement('a');
                 _b1.href = '#';
                 _b2.href = '#';
+                _b1.tabIndex = '-1';
+                _b2.tabIndex = '-1';
             
             //Setup the up and down arrows
             _b1.className = 'up';
@@ -1615,12 +1689,75 @@
                         }
                     }
                 }
+                if (ev) {
+                    Event.stopEvent(ev);
+                }
             }
-            if (ev) {
-                Event.stopEvent(ev);
+        },
+        /**
+        * @private
+        * @property _keyNav
+        * @description Flag to determine if the arrow nav listeners have been attached
+        * @type Boolean
+        */
+        _keyNav: null,
+        /**
+        * @private
+        * @property _navCounter
+        * @description Internal counter for walking the buttons in the toolbar with the arrow keys
+        * @type Number
+        */
+        _navCounter: null,
+        /**
+        * @private
+        * @method _navigateButtons
+        * @description Handles the navigation/focus of toolbar buttons with the Arrow Keys
+        * @param {Event} ev The Key Event
+        */
+        _navigateButtons: function(ev) {
+            switch (ev.keyCode) {
+                case 37:
+                case 39:
+                    if (ev.keyCode == 37) {
+                        this._navCounter--;
+                    } else {
+                        this._navCounter++;
+                    }
+                    if (this._navCounter > (this._buttonList.length - 1)) {
+                        this._navCounter = 0;
+                    }
+                    if (this._navCounter < 0) {
+                        this._navCounter = (this._buttonList.length - 1);
+                    }
+                    var el = this._buttonList[this._navCounter].get('element');
+                    if (this.browser.ie) {
+                        el = this._buttonList[this._navCounter].get('element').getElementsByTagName('a')[0];
+                    }
+                    if (this._buttonList[this._navCounter].get('disabled')) {
+                        this._navigateButtons(ev);
+                    } else {
+                        el.focus();
+                    }
+                    break;
             }
         },
         /**
+        * @private
+        * @method _handleFocus
+        * @description Sets up the listeners for the arrow key navigation
+        */
+        _handleFocus: function() {
+            if (!this._keyNav) {
+                var ev = 'keypress';
+                if (this.browser.ie) {
+                    ev = 'keydown';
+                }
+                Event.on(this.get('element'), ev, this._navigateButtons, this, true);
+                this._keyNav = true;
+                this._navCounter = -1;
+            }
+        },
+        /**
         * @method getButtonById
         * @description Gets a button instance from the toolbar by is Dom id.
         * @param {String} id The Dom id to query for.
@@ -1701,17 +1838,8 @@
         * @return {Boolean}
         */
         disableButton: function(id) {
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 button.set('disabled', true);
             } else {
                 return false;
@@ -1727,17 +1855,8 @@
             if (this.get('disabled')) {
                 return false;
             }
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 if (button.get('disabled')) {
                     button.set('disabled', false);
                 }
@@ -1746,42 +1865,46 @@
             }
         },
         /**
+        * @method isSelected
+        * @description Tells if a button is selected or not.
+        * @param {String/Number} id A button by it's id, index or value.
+        * @return {Boolean}
+        */
+        isSelected: function(id) {
+            var button = getButton.call(this, id);
+            if (button) {
+                return button._selected;
+            }
+            return false;
+        },
+        /**
         * @method selectButton
         * @description Selects a button in the toolbar.
         * @param {String/Number} id Select a button by it's id, index or value.
+        * @param {String} value If this is a Menu Button, check this item in the menu
         * @return {Boolean}
         */
         selectButton: function(id, value) {
-            var button = id;
-            if (id) {
-                if (Lang.isString(id)) {
-                    button = this.getButtonById(id);
-                }
-                if (Lang.isNumber(id)) {
-                    button = this.getButtonByIndex(id);
-                }
-                if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                    button = this.getButtonByValue(id);
-                }
-                if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
-                    button.addClass('yui-button-selected');
-                    button.addClass('yui-button-' + button.get('value') + '-selected');
-                    if (value) {
-                        if (button.buttonType == 'rich') {
-                            var _items = button.getMenu().getItems();
-                            for (var m = 0; m < _items.length; m++) {
-                                if (_items[m].value == value) {
-                                    _items[m].cfg.setProperty('checked', true);
-                                    button.set('label', '<span class="yui-toolbar-' + button.get('value') + '-' + (value).replace(/ /g, '-').toLowerCase() + '">' + _items[m]._oText.nodeValue + '</span>');
-                                } else {
-                                    _items[m].cfg.setProperty('checked', false);
-                                }
+            var button = getButton.call(this, id);
+            if (button) {
+                button.addClass('yui-button-selected');
+                button.addClass('yui-button-' + button.get('value') + '-selected');
+                button._selected = true;
+                if (value) {
+                    if (button.buttonType == 'rich') {
+                        var _items = button.getMenu().getItems();
+                        for (var m = 0; m < _items.length; m++) {
+                            if (_items[m].value == value) {
+                                _items[m].cfg.setProperty('checked', true);
+                                button.set('label', '<span class="yui-toolbar-' + button.get('value') + '-' + (value).replace(/ /g, '-').toLowerCase() + '">' + _items[m]._oText.nodeValue + '</span>');
+                            } else {
+                                _items[m].cfg.setProperty('checked', false);
                             }
                         }
                     }
-                } else {
-                    return false;
                 }
+            } else {
+                return false;
             }
         },
         /**
@@ -1791,20 +1914,12 @@
         * @return {Boolean}
         */
         deselectButton: function(id) {
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 button.removeClass('yui-button-selected');
                 button.removeClass('yui-button-' + button.get('value') + '-selected');
                 button.removeClass('yui-button-hover');
+                button._selected = false;
             } else {
                 return false;
             }
@@ -1885,17 +2000,8 @@
         * @return {Boolean}
         */
         destroyButton: function(id) {
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 var thisID = button.get('id');
                 button.destroy();
 
@@ -1908,7 +2014,6 @@
             } else {
                 return false;
             }
-
         },
         /**
         * @method destroy
@@ -2012,16 +2117,35 @@
     */
     
     YAHOO.widget.SimpleEditor = function(el, attrs) {
+        
+        var o = {};
+        if (Lang.isObject(el) && (!el.tagName) && !attrs) {
+            Lang.augmentObject(o, el); //Break the config reference
+            el = document.createElement('textarea');
+            this.DOMReady = true;
+            if (o.container) {
+                var c = Dom.get(o.container);
+                c.appendChild(el);
+            } else {
+                document.body.appendChild(el);
+            }
+        } else {
+            Lang.augmentObject(o, attrs); //Break the config reference
+        }
 
         var oConfig = {
             element: null,
-            attributes: (attrs || {})
+            attributes: o
         }, id = null;
 
         if (Lang.isString(el)) {
             id = el;
         } else {
-            id = el.id;
+            if (oConfig.attributes.id) {
+                id = oConfig.attributes.id;
+            } else {
+                id = Dom.generateId(el);
+            }
         }
         oConfig.element = el;
 
@@ -2050,7 +2174,7 @@
     * @method _cleanClassName
     * @description Makes a useable classname from dynamic data, by dropping it to lowercase and replacing spaces with -'s.
     * @param {String} str The classname to clean up
-    * @returns {String}
+    * @return {String}
     */
     function _cleanClassName(str) {
         return str.replace(/ /g, '-').toLowerCase();
@@ -2069,70 +2193,20 @@
         * @description This flag will be set when certain things in the Editor happen. It is to be used by the developer to check to see if content has changed.
         * @type Boolean
         */
-        editorDirty: false,
+        editorDirty: null,
         /**
         * @property _defaultCSS
         * @description The default CSS used in the config for 'css'. This way you can add to the config like this: { css: YAHOO.widget.SimpleEditor.prototype._defaultCSS + 'ADD MYY CSS HERE' }
         * @type String
         */
-        _defaultCSS: 'html { height: 95%; } body { height: 100%; padding: 7px; background-color: #fff; font:13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a { color: blue; text-decoration: underline; cursor: pointer; } .warning-localfile { border-bottom: 1px dashed red !important; } .yui-busy { cursor: wait !important; } img.selected { border: 2px dotted #808080; } img { cursor: pointer !important; border: none; }',
+        _defaultCSS: 'html { height: 95%; } body { padding: 7px; background-color: #fff; font:13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a { color: blue; text-decoration: underline; cursor: text; } .warning-localfile { border-bottom: 1px dashed red !important; } .yui-busy { cursor: wait !important; } img.selected { border: 2px dotted #808080; } img { cursor: pointer !important; border: none; }',
         /**
         * @property _defaultToolbar
         * @private
         * @description Default toolbar config.
         * @type Object
         */
-        _defaultToolbar: {
-            collapse: true,
-            titlebar: 'Text Editing Tools',
-            draggable: false,
-            buttons: [
-                { group: 'fontstyle', label: 'Font Name and Size',
-                    buttons: [
-                        { type: 'select', label: 'Arial', value: 'fontname', disabled: true,
-                            menu: [
-                                { text: 'Arial', checked: true },
-                                { text: 'Arial Black' },
-                                { text: 'Comic Sans MS' },
-                                { text: 'Courier New' },
-                                { text: 'Lucida Console' },
-                                { text: 'Tahoma' },
-                                { text: 'Times New Roman' },
-                                { text: 'Trebuchet MS' },
-                                { text: 'Verdana' }
-                            ]
-                        },
-                        { type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'textstyle', label: 'Font Style',
-                    buttons: [
-                        { type: 'push', label: 'Bold CTRL + SHIFT + B', value: 'bold' },
-                        { type: 'push', label: 'Italic CTRL + SHIFT + I', value: 'italic' },
-                        { type: 'push', label: 'Underline CTRL + SHIFT + U', value: 'underline' },
-                        { type: 'separator' },
-                        { type: 'color', label: 'Font Color', value: 'forecolor', disabled: true },
-                        { type: 'color', label: 'Background Color', value: 'backcolor', disabled: true }
-                        
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'indentlist', label: 'Lists',
-                    buttons: [
-                        { type: 'push', label: 'Create an Unordered List', value: 'insertunorderedlist' },
-                        { type: 'push', label: 'Create an Ordered List', value: 'insertorderedlist' }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'insertitem', label: 'Insert Item',
-                    buttons: [
-                        { type: 'push', label: 'HTML Link CTRL + SHIFT + L', value: 'createlink', disabled: true },
-                        { type: 'push', label: 'Insert Image', value: 'insertimage' }
-                    ]
-                }
-            ]
-        },
+        _defaultToolbar: null,
         /**
         * @property _lastButton
         * @private
@@ -2165,9 +2239,9 @@
         * @property _blankImageLoaded
         * @private
         * @description Don't load the blank image more than once..
-        * @type Date
+        * @type Boolean
         */
-        _blankImageLoaded: false,
+        _blankImageLoaded: null,
         /**
         * @property _fixNodesTimer
         * @private
@@ -2202,7 +2276,7 @@
         * @description Flag to determine if editor has been rendered or not
         * @type Boolean
         */
-        _rendered: false,
+        _rendered: null,
         /**
         * @property DOMReady
         * @private
@@ -2261,7 +2335,7 @@
         * @description A reference to the current working element in the editor
         * @type Array
         */
-        currentElement: [],
+        currentElement: null,
         /**
         * @property dompath
         * @description A reference to the dompath container for writing the current working dom path to.
@@ -2293,6 +2367,7 @@
             link: true,
             html: true,
             body: true,
+            iframe: true,
             script: true,
             style: true,
             textarea: true
@@ -2368,7 +2443,7 @@
         * @private _createIframe
         * @description Creates the DOM and YUI Element for the iFrame editor area.
         * @param {String} id The string ID to prefix the iframe with
-        * @returns {Object} iFrame object
+        * @return {Object} iFrame object
         */
         _createIframe: function() {
             var ifrmDom = document.createElement('iframe');
@@ -2383,6 +2458,9 @@
                 allowTransparency: 'true',
                 width: '100%'
             };
+            if (this.get('autoHeight')) {
+                config.scrolling = 'no';
+            }
             for (var i in config) {
                 if (Lang.hasOwnProperty(config, i)) {
                     ifrmDom.setAttribute(i, config[i]);
@@ -2390,9 +2468,7 @@
             }
             var isrc = 'javascript:;';
             if (this.browser.ie) {
-                if (window.location.href.toLowerCase().indexOf("https") !== 0) {
-                    isrc = 'about:blank';
-                }
+                isrc = 'about:blank';
             }
             ifrmDom.setAttribute('src', isrc);
             var ifrm = new YAHOO.util.Element(ifrmDom);
@@ -2404,7 +2480,7 @@
         * @description Checks to see if an Element reference is a valid one and has a certain tag type
         * @param {HTMLElement} el The element to check
         * @param {String} tag The tag that the element needs to be
-        * @returns {Boolean}
+        * @return {Boolean}
         */
         _isElement: function(el, tag) {
             if (el && el.tagName && (el.tagName.toLowerCase() == tag)) {
@@ -2420,7 +2496,7 @@
         * @description Checks to see if an Element reference or one of it's parents is a valid one and has a certain tag type
         * @param {HTMLElement} el The element to check
         * @param {String} tag The tag that the element needs to be
-        * @returns HTMLElement
+        * @return HTMLElement
         */
         _hasParent: function(el, tag) {
             if (!el || !el.parentNode) {
@@ -2512,13 +2588,17 @@
         * @private
         * @method _hasSelection
         * @description Determines if there is a selection in the editor document.
-        * @returns {Boolean}
+        * @return {Boolean}
         */
         _hasSelection: function() {
             var sel = this._getSelection();
             var range = this._getRange();
             var hasSel = false;
 
+            if (!sel || !range) {
+                return hasSel;
+            }
+
             //Internet Explorer
             if (this.browser.ie || this.browser.opera) {
                 if (range.text) {
@@ -2544,7 +2624,7 @@
         * @private
         * @method _getSelection
         * @description Handles the different selection objects across the A-Grade list.
-        * @returns {Object} Selection Object
+        * @return {Object} Selection Object
         */
         _getSelection: function() {
             var _sel = null;
@@ -2614,7 +2694,7 @@
         * @private
         * @method _getRange
         * @description Handles the different range objects across the A-Grade list.
-        * @returns {Object} Range Object
+        * @return {Object} Range Object
         */
         _getRange: function() {
             var sel = this._getSelection();
@@ -2635,7 +2715,11 @@
             }
 
             if (this.browser.ie || this.browser.opera) {
-                return sel.createRange();
+                try {
+                    return sel.createRange();
+                } catch (e) {
+                    return null;
+                }
             }
 
             if (sel.rangeCount > 0) {
@@ -2651,14 +2735,21 @@
         */
         _setDesignMode: function(state) {
             try {
-                this._getDoc().designMode = state;
+                var set = true;
+                //SourceForge Bug #1807057
+                if (this.browser.ie && (state.toLowerCase() == 'off')) {
+                    set = false;
+                }
+                if (set) {
+                    this._getDoc().designMode = state;
+                }
             } catch(e) { }
         },
         /**
         * @private
         * @method _toggleDesignMode
         * @description Toggles the designMode of the iFrame document on and off.
-        * @returns {String} The state that it was set to.
+        * @return {String} The state that it was set to.
         */
         _toggleDesignMode: function() {
             var _dMode = this._getDoc().designMode.toLowerCase(),
@@ -2679,8 +2770,16 @@
                 this._getDoc().body.style.margin = '0';
             }
             if (!this.get('disabled')) {
-                this._setDesignMode('on');
+                if (this._getDoc().designMode.toLowerCase() != 'on') {
+                    this._setDesignMode('on');
+                    this._contentTimerCounter = 0;
+                }
             }
+            if (!this._getDoc().body) {
+                this._contentTimerCounter = 0;
+                this._checkLoaded();
+                return false;
+            }
             
             this.toolbar.on('buttonClick', this._handleToolbarClick, this, true);
             //Setup Listeners on iFrame
@@ -2714,13 +2813,21 @@
             if (this._contentTimer) {
                 clearTimeout(this._contentTimer);
             }
-            if (this._contentTimerCounter > 250) {
+            if (this._contentTimerCounter > 500) {
                 return false;
             }
             var init = false;
             try {
-                if (this._getDoc() && this._getDoc().body && (this._getDoc().body._rteLoaded === true)) {
-                    init = true;
+                if (this._getDoc() && this._getDoc().body) {
+                    if (this.browser.ie) {
+                        if (this._getDoc().body.readyState == 'complete') {
+                            init = true;
+                        }
+                    } else {
+                        if (this._getDoc().body._rteLoaded === true) {
+                            init = true;
+                        }
+                    }
                 }
             } catch (e) {
                 init = false;
@@ -2758,9 +2865,23 @@
             if (this.browser.ie || this.browser.webkit || this.browser.opera || (navigator.userAgent.indexOf('Firefox/1.5') != -1)) {
                 //Firefox 1.5 doesn't like setting designMode on an document created with a data url
                 try {
-                    this._getDoc().open();
-                    this._getDoc().write(html);
-                    this._getDoc().close();
+                    //Adobe AIR Code
+                    if (this.browser.air) {
+                        var doc = this._getDoc().implementation.createHTMLDocument();
+                        var origDoc = this._getDoc();
+                        origDoc.open();
+                        origDoc.close();
+                        doc.open();
+                        doc.write(html);
+                        doc.close();
+                        var node = origDoc.importNode(doc.getElementsByTagName("html")[0], true);
+                        origDoc.replaceChild(node, origDoc.getElementsByTagName("html")[0]);
+                        origDoc.body._rteLoaded = true;
+                    } else {               
+                        this._getDoc().open();
+                        this._getDoc().write(html);
+                        this._getDoc().close();
+                    }
                 } catch (e) {
                     //Safari will only be here if we are hidden
                     check = false;
@@ -2811,7 +2932,7 @@
         * @private
         * @method _getSelectedElement
         * @description This method will attempt to locate the element that was last interacted with, either via selection, location or event.
-        * @returns {HTMLElement} The currently selected element.
+        * @return {HTMLElement} The currently selected element.
         */
         _getSelectedElement: function() {
             var doc = this._getDoc(),
@@ -2878,7 +2999,7 @@
                     }
                 } catch (e) {
                 }
-            } else if (this.currentElement && this.currentElement[0]) {
+            } else if ((this.currentElement && this.currentElement[0]) && (!this.browser.ie)) {
                 elm = this.currentElement[0];
             }
             if (this.browser.opera || this.browser.webkit) {
@@ -2910,7 +3031,7 @@
         * @method _getDomPath
         * @description This method will attempt to build the DOM path from the currently selected element.
         * @param HTMLElement el The element to start with, if not provided _getSelectedElement is used
-        * @returns {Array} An array of node references that will create the DOM Path.
+        * @return {Array} An array of node references that will create the DOM Path.
         */
         _getDomPath: function(el) {
             if (!el) {
@@ -3049,7 +3170,7 @@
         * @description Method is called at the beginning of all event handlers to check if this element or a parent element has the class yui-noedit (this.CLASS_NOEDIT) applied.
         * If it does, then this method will stop the event and return true. The event handlers will then return false and stop the nodeChange from occuring. This method will also
         * disable and enable the Editor's toolbar based on the noedit state.
-        * @returns Boolean
+        * @return Boolean
         */
         _isNonEditable: function(ev) {
             if (this.get('allowNoEdit')) {
@@ -3453,7 +3574,10 @@
             switch (ev.keyCode) {
                 case 84: //Focus Toolbar Header -- Ctrl + Shift + T
                     if (ev.shiftKey && ev.ctrlKey) {
-                        this.toolbar._titlebar.firstChild.focus();
+                        var h = this.toolbar.getElementsByTagName('h2')[0];
+                        if (h) {
+                            h.focus();
+                        }
                         Event.stopEvent(ev);
                         doExec = false;
                     }
@@ -3740,6 +3864,13 @@
         * @description Creates the accessibility h2 header and places it after the iframe in the Dom for navigation.
         */
         _setupAfterElement: function() {
+            if (!this.beforeElement) {
+                this.beforeElement = document.createElement('h2');
+                this.beforeElement.className = 'yui-editor-skipheader';
+                this.beforeElement.tabIndex = '-1';
+                this.beforeElement.innerHTML = this.STR_BEFORE_EDITOR;
+                this.get('element_cont').get('firstChild').insertBefore(this.beforeElement, this.toolbar.get('nextSibling'));
+            }
             if (!this.afterElement) {
                 this.afterElement = document.createElement('h2');
                 this.afterElement.className = 'yui-editor-skipheader';
@@ -3757,7 +3888,9 @@
         _disableEditor: function(disabled) {
             if (disabled) {
                 if (!this._mask) {
-                    this._setDesignMode('off');
+                    if (!!this.browser.ie) {
+                        this._setDesignMode('off');
+                    }
                     if (this.toolbar) {
                         this.toolbar.set('disabled', true);
                     }
@@ -3886,7 +4019,7 @@
         browser: function() {
             var br = YAHOO.env.ua;
             //Check for webkit3
-            if (br.webkit > 420) {
+            if (br.webkit >= 420) {
                 br.webkit3 = br.webkit;
             } else {
                 br.webkit3 = 0;
@@ -3898,9 +4031,66 @@
         * @description The Editor class' initialization method
         */
         init: function(p_oElement, p_oAttributes) {
+
+            if (!this._defaultToolbar) {
+                this._defaultToolbar = {
+                    collapse: true,
+                    titlebar: 'Text Editing Tools',
+                    draggable: false,
+                    buttons: [
+                        { group: 'fontstyle', label: 'Font Name and Size',
+                            buttons: [
+                                { type: 'select', label: 'Arial', value: 'fontname', disabled: true,
+                                    menu: [
+                                        { text: 'Arial', checked: true },
+                                        { text: 'Arial Black' },
+                                        { text: 'Comic Sans MS' },
+                                        { text: 'Courier New' },
+                                        { text: 'Lucida Console' },
+                                        { text: 'Tahoma' },
+                                        { text: 'Times New Roman' },
+                                        { text: 'Trebuchet MS' },
+                                        { text: 'Verdana' }
+                                    ]
+                                },
+                                { type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true }
+                            ]
+                        },
+                        { type: 'separator' },
+                        { group: 'textstyle', label: 'Font Style',
+                            buttons: [
+                                { type: 'push', label: 'Bold CTRL + SHIFT + B', value: 'bold' },
+                                { type: 'push', label: 'Italic CTRL + SHIFT + I', value: 'italic' },
+                                { type: 'push', label: 'Underline CTRL + SHIFT + U', value: 'underline' },
+                                { type: 'separator' },
+                                { type: 'color', label: 'Font Color', value: 'forecolor', disabled: true },
+                                { type: 'color', label: 'Background Color', value: 'backcolor', disabled: true }
+                                
+                            ]
+                        },
+                        { type: 'separator' },
+                        { group: 'indentlist', label: 'Lists',
+                            buttons: [
+                                { type: 'push', label: 'Create an Unordered List', value: 'insertunorderedlist' },
+                                { type: 'push', label: 'Create an Ordered List', value: 'insertorderedlist' }
+                            ]
+                        },
+                        { type: 'separator' },
+                        { group: 'insertitem', label: 'Insert Item',
+                            buttons: [
+                                { type: 'push', label: 'HTML Link CTRL + SHIFT + L', value: 'createlink', disabled: true },
+                                { type: 'push', label: 'Insert Image', value: 'insertimage' }
+                            ]
+                        }
+                    ]
+                };
+            }
+
             YAHOO.widget.SimpleEditor.superclass.init.call(this, p_oElement, p_oAttributes);
             YAHOO.widget.EditorInfo._instances[this.get('id')] = this;
 
+
+            this.currentElement = [];
             this.on('contentReady', function() {
                 this.DOMReady = true;
                 this.fireQueue();
@@ -3919,6 +4109,27 @@
             var self = this;
 
             /**
+            * @config container
+            * @description Used when dynamically creating the Editor from Javascript with no default textarea.
+            * We will create one and place it in this container. If no container is passed we will append to document.body.
+            * @default false
+            * @type HTMLElement
+            */
+            this.setAttributeConfig('container', {
+                writeOnce: true,
+                value: attr.container || false
+            });
+            /**
+            * @config plainText
+            * @description Process the inital textarea data as if it was plain text. Accounting for spaces, tabs and line feeds.
+            * @default false
+            * @type Boolean
+            */
+            this.setAttributeConfig('plainText', {
+                writeOnce: true,
+                value: attr.plainText || false
+            });
+            /**
             * @private
             * @config iframe
             * @description Internal config for holding the iframe element.
@@ -3941,6 +4152,17 @@
                 writeOnce: true
             });
             /**
+            * @private
+            * @config container
+            * @description Internal config for holding a reference to the container to append a dynamic editor to.
+            * @default null
+            * @type HTMLElement
+            */
+            this.setAttributeConfig('container', {
+                readOnly: true,
+                value: null
+            });
+            /**
             * @config nodeChangeThreshold
             * @description The number of seconds that need to be in between nodeChange processing
             * @default 3
@@ -4016,6 +4238,32 @@
                 }
             });
             /**
+            * @config autoHeight
+            * @description Remove the scrollbars from the edit area and resize it to fit the content. It will not go any lower than the current config height.
+            * @default false
+            * @type Boolean || Number
+            */
+            this.setAttributeConfig('autoHeight', {
+                value: attr.autoHeight || false,
+                method: function(a) {
+                    if (a) {
+                        if (this.get('iframe')) {
+                            this.get('iframe').get('element').setAttribute('scrolling', 'no');
+                        }
+                        this.on('afterNodeChange', this._handleAutoHeight, this, true);
+                        this.on('editorKeyDown', this._handleAutoHeight, this, true);
+                        this.on('editorKeyPress', this._handleAutoHeight, this, true);
+                    } else {
+                        if (this.get('iframe')) {
+                            this.get('iframe').get('element').setAttribute('scrolling', 'auto');
+                        }
+                        this.unsubscribe('afterNodeChange', this._handleAutoHeight);
+                        this.unsubscribe('editorKeyDown', this._handleAutoHeight);
+                        this.unsubscribe('editorKeyPress', this._handleAutoHeight);
+                    }
+                }
+            });
+            /**
             * @attribute width
             * @description The width of the editor container.
             * @default Best guessed size of the textarea, for best results use CSS to style the width of the textarea or pass it in as an argument
@@ -4126,7 +4374,7 @@
             * @type String
             */            
             this.setAttributeConfig('extracss', {
-                value: attr.css || '',
+                value: attr.extracss || '',
                 writeOnce: true
             });
 
@@ -4139,22 +4387,28 @@
             * @type Boolean
             */            
             this.setAttributeConfig('handleSubmit', {
-                value: false,
-                writeOnce: true,
+                value: attr.handleSubmit || false,
                 method: function(exec) {
-                    if (exec) {
-                        var ta = this.get('element');
-                        if (ta.form) {
-                            var submitForm = function(ev) {
-                                Event.stopEvent(ev);
-                                this.saveHTML();
-                                window.setTimeout(function() {
-                                    YAHOO.util.Event.removeListener(ta.form, 'submit', submitForm);
-                                    ta.form.submit();
-                                }, 200);
-                            };
-                            Event.on(ta.form, 'submit', submitForm, this, true);
+                    if (this.get('element').form) {
+                        if (!this._formButtons) {
+                            this._formButtons = [];
                         }
+                        if (exec) {
+                            Event.on(this.get('element').form, 'submit', this._handleFormSubmit, this, true);
+                            var i = this.get('element').form.getElementsByTagName('input');
+                            for (var s = 0; s < i.length; s++) {
+                                var type = i[s].getAttribute('type');
+                                if (type && (type.toLowerCase() == 'submit')) {
+                                    Event.on(i[s], 'click', this._handleFormButtonClick, this, true);
+                                    this._formButtons[this._formButtons.length] = i[s];
+                                }
+                            }
+                        } else {
+                            Event.unsubscribe(this.get('element').form, 'submit', this._handleFormSubmit);
+                            if (this._formButtons) {
+                                Event.unsubscribe(this._formButtons, 'click', this._handleFormButtonClick);
+                            }
+                        }
                     }
                 }
             });
@@ -4213,7 +4467,7 @@
                         ret = false;
                     }
                     return ret;
-                }               
+                }
             });
             /**
             * @config panel
@@ -4272,7 +4526,6 @@
                         this.dompath.parentNode.removeChild(this.dompath);
                         this.dompath = null;
                     }
-                    this._setupAfterElement();
                 }
             });
             /**
@@ -4314,7 +4567,7 @@
         * @private
         * @method _getBlankImage
         * @description Retrieves the full url of the image to use as the blank image.
-        * @returns {String} The URL to the blank image
+        * @return {String} The URL to the blank image
         */
         _getBlankImage: function() {
             if (!this.DOMReady) {
@@ -4323,16 +4576,24 @@
             }
             var img = '';
             if (!this._blankImageLoaded) {
-                var div = document.createElement('div');
-                div.style.position = 'absolute';
-                div.style.top = '-9999px';
-                div.style.left = '-9999px';
-                div.className = this.CLASS_PREFIX + '-blankimage';
-                document.body.appendChild(div);
-                img = YAHOO.util.Dom.getStyle(div, 'background-image');
-                img = img.replace('url(', '').replace(')', '').replace(/"/g, '');
-                this.set('blankimage', img);
-                this._blankImageLoaded = true;
+                if (YAHOO.widget.EditorInfo.blankImage) {
+                    this.set('blankimage', YAHOO.widget.EditorInfo.blankImage);
+                    this._blankImageLoaded = true;
+                } else {
+                    var div = document.createElement('div');
+                    div.style.position = 'absolute';
+                    div.style.top = '-9999px';
+                    div.style.left = '-9999px';
+                    div.className = this.CLASS_PREFIX + '-blankimage';
+                    document.body.appendChild(div);
+                    img = YAHOO.util.Dom.getStyle(div, 'background-image');
+                    img = img.replace('url(', '').replace(')', '').replace(/"/g, '');
+                    //Adobe AIR Code
+                    img = img.replace('app:/', '');                    
+                    this.set('blankimage', img);
+                    this._blankImageLoaded = true;
+                    YAHOO.widget.EditorInfo.blankImage = img;
+                }
             } else {
                 img = this.get('blankimage');
             }
@@ -4340,6 +4601,81 @@
         },
         /**
         * @private
+        * @method _handleAutoHeight
+        * @description Handles resizing the editor's height based on the content
+        */
+        _handleAutoHeight: function() {
+            var doc = this._getDoc(),
+                body = doc.body,
+                docEl = doc.documentElement;
+
+            var height = parseInt(Dom.getStyle(this.get('editor_wrapper'), 'height'), 10);
+            var newHeight = body.scrollHeight;
+            if (this.browser.webkit) {
+                newHeight = docEl.scrollHeight;
+            }
+            if (newHeight < parseInt(this.get('height'), 10)) {
+                newHeight = parseInt(this.get('height'), 10);
+            }
+            if ((height != newHeight) && (newHeight >= parseInt(this.get('height'), 10))) {   
+                Dom.setStyle(this.get('editor_wrapper'), 'height', newHeight + 'px');
+                if (this.browser.ie) {
+                    //Internet Explorer needs this
+                    this.get('iframe').setStyle('height', '99%');
+                    this.get('iframe').setStyle('zoom', '1');
+                    var self = this;
+                    window.setTimeout(function() {
+                        self.get('iframe').setStyle('height', '100%');
+                    }, 1);
+                }
+            }
+        },
+        _formButtons: null,
+        _formButtonClicked: null,
+        _handleFormButtonClick: function(ev) {
+            var tar = Event.getTarget(ev);
+            this._formButtonClicked = tar;
+        },
+        /**
+        * @private
+        * @method _handleFormSubmit
+        * @description Handles the form submission.
+        * @param {Object} ev The Form Submit Event
+        */
+        _handleFormSubmit: function(ev) {
+            Event.stopEvent(ev);
+            
+            this.saveHTML();
+            var form = this.get('element').form;
+            var tar = this._formButtonClicked || false;
+            var self = this;
+
+            window.setTimeout(function() {
+                YAHOO.util.Event.removeListener(form, 'submit', self._handleFormSubmit);
+                if (YAHOO.env.ua.ie) {
+                    form.fireEvent("onsubmit");
+                    if (tar && !tar.disabled) {
+                        tar.click();
+                    }
+                } else {  // Gecko, Opera, and Safari
+                    if (tar && !tar.disabled) {
+                        tar.click();
+                    } else {
+                        var oEvent = document.createEvent("HTMLEvents");
+                        oEvent.initEvent("submit", true, true);
+                        form.dispatchEvent(oEvent);
+                        if (YAHOO.env.ua.webkit) {
+                            if (YAHOO.lang.isFunction(form.submit)) {
+                                form.submit();
+                            }
+                        }
+                    }
+                }
+            }, 200);
+            
+        },
+        /**
+        * @private
         * @method _handleFontSize
         * @description Handles the font size button in the toolbar.
         * @param {Object} o Object returned from Toolbar's buttonClick Event
@@ -4408,6 +4744,8 @@
                 family = elm.getAttribute('face');
                 if (Dom.getStyle(elm, 'font-family')) {
                     family = Dom.getStyle(elm, 'font-family');
+                    //Adobe AIR Code
+                    family = family.replace(/'/g, '');                    
                 }
 
                 if (tag.substring(0, 1) == 'h') {
@@ -4463,7 +4801,6 @@
                 this.toolbar.disableButton('indent');
                 this.toolbar.enableButton('outdent');
             }
-            //if (this._isElement(elm, 'ol') || this._isElement(elm, 'ul') || this._isElement(elm, 'li')) {
             if (this._hasParent(elm, 'ol') || this._hasParent(elm, 'ul')) {
                 this.toolbar.disableButton('indent');
             }
@@ -4471,6 +4808,7 @@
             
         },
         _setBusy: function(off) {
+            /*
             if (off) {
                 Dom.removeClass(document.body, 'yui-busy');
                 Dom.removeClass(this._getDoc().body, 'yui-busy');
@@ -4478,6 +4816,7 @@
                 Dom.addClass(document.body, 'yui-busy');
                 Dom.addClass(this._getDoc().body, 'yui-busy');
             }
+            */
         },
         /**
         * @private
@@ -4509,9 +4848,10 @@
                 var str = prompt(this.STR_LINK_URL + ': ', src);
                 if ((str !== '') && (str !== null)) {
                     el.setAttribute('src', str);
-                } else if (str !== null) {
+                } else if (str === null) {
                     el.parentNode.removeChild(el);
                     this.currentElement = [];
+                    this.nodeChange();
                 }
                 this.closeWindow();
                 this.toolbar.set('disabled', false);
@@ -4595,7 +4935,7 @@
         },
         /**
         * @method render
-        * @description Causes the toolbar and the editor to render and replace the textarea.
+        * @description Calls the private method _render in a setTimeout to allow for other things on the page to continue to load.
         */
         render: function() {
             if (this._rendered) {
@@ -4605,10 +4945,20 @@
                 this._queue[this._queue.length] = ['render', arguments];
                 return false;
             }
-            this._setBusy();
             this._rendered = true;
             var self = this;
-
+            window.setTimeout(function() {
+                self._render.call(self);
+            }, 4);
+        },
+        /**
+        * @private
+        * @method _render
+        * @description Causes the toolbar and the editor to render and replace the textarea.
+        */
+        _render: function() {
+            this._setBusy();
+            var self = this;
             this.set('textarea', this.get('element'));
 
             this.get('element_cont').setStyle('display', 'none');
@@ -4656,6 +5006,7 @@
             
             this.toolbar.on('colorPickerClicked', function(o) {
                 this._handleColorPicker(o);
+                return false; //Stop the buttonClick event
             }, this, true);
 
             this.toolbar.on('alignClick', function(o) {
@@ -4679,18 +5030,9 @@
             
 
             //Replace Textarea with editable area
-            
             this.get('parentNode').replaceChild(this.get('element_cont').get('element'), this.get('element'));
 
             
-            if (!this.beforeElement) {
-                this.beforeElement = document.createElement('h2');
-                this.beforeElement.className = 'yui-editor-skipheader';
-                this.beforeElement.tabIndex = '-1';
-                this.beforeElement.innerHTML = this.STR_BEFORE_EDITOR;
-                this.get('element_cont').get('firstChild').insertBefore(this.beforeElement, this.toolbar.get('nextSibling'));
-            }
-
             this.setStyle('visibility', 'hidden');
             this.setStyle('position', 'absolute');
             this.setStyle('top', '-9999px');
@@ -4709,9 +5051,9 @@
             this.get('iframe').setStyle('width', '100%'); //WIDTH
             this.get('iframe').setStyle('height', '100%');
 
-            if (this.browser.ie == 7) {
-            }
-
+            window.setTimeout(function() {
+                self._setupAfterElement.call(self);
+            }, 0);
             this.fireEvent('afterRender', { type: 'afterRender', target: this });
         },
         /**
@@ -4997,8 +5339,11 @@
                 exec = false;
             } else {
                 el = this._getSelectedElement();
-                if (this._isElement(el, 'li') && this._isElement(el.parentNode, tag) || (this.browser.ie && this._isElement(this._getRange().parentElement, 'li'))) { //we are in a list..
+                if (this._isElement(el, 'li') && this._isElement(el.parentNode, tag) || (this.browser.ie && this._isElement(this._getRange().parentElement, 'li')) || (this.browser.ie && this._isElement(el, 'ul')) || (this.browser.ie && this._isElement(el, 'ol'))) { //we are in a list..
                     if (this.browser.ie) {
+                        if ((this.browser.ie && this._isElement(el, 'ul')) || (this.browser.ie && this._isElement(el, 'ol'))) {
+                            el = el.getElementsByTagName('li')[0];
+                        }
                         str = '';
                         var lis2 = el.parentNode.getElementsByTagName('li');
                         for (var j = 0; j < lis2.length; j++) {
@@ -5030,7 +5375,15 @@
                     if (this._getRange().html) {
                         html = '<li>' + this._getRange().html+ '</li>';
                     } else {
-                        html = '<li>' + this._getRange().text + '</li>';
+                        var t = this._getRange().text.split('\n');
+                        if (t.length > 1) {
+                            html = '';
+                            for (var ie = 0; ie < t.length; ie++) {
+                                html += '<li>' + t[ie] + '</li>';
+                            }
+                        } else {
+                            html = '<li>' + this._getRange().text + '</li>';
+                        }
                     }
 
                     this._getRange().pasteHTML('<' + tag + '>' + html + '</' + tag + '>');
@@ -5077,7 +5430,7 @@
         * @description This is an execCommand override method. It is called from execCommand when the execCommand('fontsize') is used.
         */
         cmd_fontsize: function(value) {
-            if ((this.currentElement.length > 0) && (!this._hasSelection())) {
+            if (this.currentElement && (this.currentElement.length > 0) && (!this._hasSelection())) {
                 YAHOO.util.Dom.setStyle(this.currentElement, 'fontSize', value);
             } else if (!this._isElement(this._getSelectedElement(), 'body')) {
                 var el = this._getSelectedElement();
@@ -5294,6 +5647,7 @@
         /**
         * @method saveHTML
         * @description Cleans the HTML with the cleanHTML method then places that string back into the textarea.
+        * @return String
         */
         saveHTML: function() {
             var html = this.cleanHTML();
@@ -5315,6 +5669,10 @@
         * @description Gets the unprocessed/unfiltered HTML from the editor
         */
         getEditorHTML: function() {
+            var b = this._getDoc().body;
+            if (b === null) {
+                return null;
+            }
             return this._getDoc().body.innerHTML;
         },
         /**
@@ -5366,20 +5724,45 @@
         * @method _cleanIncomingHTML
         * @param {String} html The unfiltered HTML
         * @description Process the HTML with a few regexes to clean it up and stabilize the input
-        * @returns {String} The filtered HTML
+        * @return {String} The filtered HTML
         */
         _cleanIncomingHTML: function(html) {
             html = html.replace(/<strong([^>]*)>/gi, '<b$1>');
             html = html.replace(/<\/strong>/gi, '</b>');   
+
+            //replace embed before em check
+            html = html.replace(/<embed([^>]*)>/gi, '<YUI_EMBED$1>');
+            html = html.replace(/<\/embed>/gi, '</YUI_EMBED>');
+
             html = html.replace(/<em([^>]*)>/gi, '<i$1>');
             html = html.replace(/<\/em>/gi, '</i>');
+            
+            //Put embed tags back in..
+            html = html.replace(/<YUI_EMBED([^>]*)>/gi, '<embed$1>');
+            html = html.replace(/<\/YUI_EMBED>/gi, '</embed>');
+            if (this.get('plainText')) {
+                html = html.replace(/\n/g, '<br>').replace(/\r/g, '<br>');
+                html = html.replace(/  /gi, '  '); //Replace all double spaces
+                html = html.replace(/\t/gi, '    '); //Replace all tabs
+            }
+            //Removing Script Tags from the Editor
+            html = html.replace(/<script([^>]*)>/gi, '<bad>');
+            html = html.replace(/<\/script([^>]*)>/gi, '</bad>');
+            html = html.replace(/<script([^>]*)>/gi, '<bad>');
+            html = html.replace(/<\/script([^>]*)>/gi, '</bad>');
+            //Replace the line feeds
+            html = html.replace(/\n/g, '<YUI_LF>').replace(/\r/g, '<YUI_LF>');
+            //Remove Bad HTML elements (used to be script nodes)
+            html = html.replace(new RegExp('<bad([^>]*)>(.*?)<\/bad>', 'gi'), '');
+            //Replace the lines feeds
+            html = html.replace(/<YUI_LF>/g, '\n');
             return html;
         },
         /**
         * @method cleanHTML
         * @param {String} html The unfiltered HTML
         * @description Process the HTML with a few regexes to clean it up and stabilize the output
-        * @returns {String} The filtered HTML
+        * @return {String} The filtered HTML
         */
         cleanHTML: function(html) {
             //Start Filtering Output
@@ -5402,9 +5785,12 @@
 		    html = html.replace(/<blockquote([^>]*)>/gi, '<YUI_BQ$1>');
 		    html = html.replace(/<\/blockquote>/gi, '<\/YUI_BQ>');
 
+		    html = html.replace(/<embed([^>]*)>/gi, '<YUI_EMBED$1>');
+		    html = html.replace(/<\/embed>/gi, '<\/YUI_EMBED>');
+
             //Convert b and i tags to strong and em tags
             if ((markup == 'semantic') || (markup == 'xhtml')) {
-                html = html.replace(/<i([^>]*)>/gi, '<em$1>');
+                html = html.replace(/<i(\s+[^>]*)?>/gi, '<em$1>');
                 html = html.replace(/<\/i>/gi, '</em>');
                 html = html.replace(/<b([^>]*)>/gi, '<strong$1>');
                 html = html.replace(/<\/b>/gi, '</strong>');
@@ -5418,6 +5804,10 @@
             if ((markup == 'semantic') || (markup == 'xhtml') || (markup == 'css')) {
                 html = html.replace(new RegExp('<font([^>]*)face="([^>]*)">(.*?)<\/font>', 'gi'), '<span $1 style="font-family: $2;">$3</span>');
                 html = html.replace(/<u/gi, '<span style="text-decoration: underline;"');
+                if (this.browser.webkit) {
+                    html = html.replace(new RegExp('<span class="Apple-style-span" style="font-weight: bold;">([^>]*)<\/span>', 'gi'), '<strong>$1</strong>');
+                    html = html.replace(new RegExp('<span class="Apple-style-span" style="font-style: italic;">([^>]*)<\/span>', 'gi'), '<em>$1</em>');
+                }
                 html = html.replace(/\/u>/gi, '/span>');
                 if (markup == 'css') {
                     html = html.replace(/<em([^>]*)>/gi, '<i$1>');
@@ -5448,8 +5838,8 @@
             html = this.post_filter_linebreaks(html, markup);
 
             if (markup == 'xhtml') {
-		        html = html.replace(/<YUI_IMG([^>]*)>/g, '<img $1/>');
-		        html = html.replace(/<YUI_INPUT([^>]*)>/g, '<input $1/>');
+		        html = html.replace(/<YUI_IMG([^>]*)>/g, '<img $1 />');
+		        html = html.replace(/<YUI_INPUT([^>]*)>/g, '<input $1 />');
             } else {
 		        html = html.replace(/<YUI_IMG([^>]*)>/g, '<img $1>');
 		        html = html.replace(/<YUI_INPUT([^>]*)>/g, '<input $1>');
@@ -5462,6 +5852,9 @@
 		    html = html.replace(/<YUI_BQ([^>]*)>/g, '<blockquote$1>');
 		    html = html.replace(/<\/YUI_BQ>/g, '<\/blockquote>');
 
+		    html = html.replace(/<YUI_EMBED([^>]*)>/g, '<embed$1>');
+		    html = html.replace(/<\/YUI_EMBED>/g, '<\/embed>');
+
             //Trim the output, removing whitespace from the beginning and end
             html = YAHOO.lang.trim(html);
 
@@ -5473,13 +5866,12 @@
             //First empty span
             if (html.substring(0, 6).toLowerCase() == '<span>')  {
                 html = html.substring(6);
+                //Last empty span
+                if (html.substring(html.length - 7, html.length).toLowerCase() == '</span>')  {
+                    html = html.substring(0, html.length - 7);
+                }
             }
-            //Last empty span
-            if (html.substring(html.length - 7, html.length).toLowerCase() == '</span>')  {
-                html = html.substring(0, html.length - 7);
-            }
 
-
             for (var v in this.invalidHTML) {
                 if (YAHOO.lang.hasOwnProperty(this.invalidHTML, v)) {
                     if (Lang.isObject(v) && v.keepContents) {
@@ -5498,7 +5890,6 @@
         * @method filter_invalid_lists
         * @param String html The HTML string to filter
         * @description Filters invalid ol and ul list markup, converts this: <li></li><ol>..</ol> to this: <li></li><li><ol>..</ol></li>
-        * @returns String
         */
         filter_invalid_lists: function(html) {
             html = html.replace(/<\/li>\n/gi, '</li>');
@@ -5521,10 +5912,12 @@
         * @method filter_safari
         * @param String html The HTML string to filter
         * @description Filters strings specific to Safari
-        * @returns String
+        * @return String
         */
         filter_safari: function(html) {
             if (this.browser.webkit) {
+                //<span class="Apple-tab-span" style="white-space:pre">	</span>
+                html = html.replace(/<span class="Apple-tab-span" style="white-space:pre">([^>])<\/span>/gi, '    ');
                 html = html.replace(/Apple-style-span/gi, '');
                 html = html.replace(/style="line-height: normal;"/gi, '');
                 //Remove bogus LI's
@@ -5541,7 +5934,7 @@
         * @method filter_internals
         * @param String html The HTML string to filter
         * @description Filters internal RTE strings and bogus attrs we don't want
-        * @returns String
+        * @return String
         */
         filter_internals: function(html) {
 		    html = html.replace(/\r/g, '');
@@ -5575,7 +5968,7 @@
         * @method filter_all_rgb
         * @param String str The HTML string to filter
         * @description Converts all RGB color strings found in passed string to a hex color, example: style="color: rgb(0, 255, 0)" converts to style="color: #00ff00"
-        * @returns String
+        * @return String
         */
         filter_all_rgb: function(str) {
             var exp = new RegExp("rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)", "gi");
@@ -5593,7 +5986,7 @@
         * @method filter_rgb
         * @param String css The CSS string containing rgb(#,#,#);
         * @description Converts an RGB color string to a hex color, example: rgb(0, 255, 0) converts to #00ff00
-        * @returns String
+        * @return String
         */
         filter_rgb: function(css) {
             if (css.toLowerCase().indexOf('rgb') != -1) {
@@ -5619,7 +6012,7 @@
         * @param String html The HTML to filter
         * @param String markup The markup type to filter to
         * @description HTML Pre Filter
-        * @returns String
+        * @return String
         */
         pre_filter_linebreaks: function(html, markup) {
             if (this.browser.webkit) {
@@ -5645,11 +6038,11 @@
         * @param String html The HTML to filter
         * @param String markup The markup type to filter to
         * @description HTML Pre Filter
-        * @returns String
+        * @return String
         */
         post_filter_linebreaks: function(html, markup) {
             if (markup == 'xhtml') {
-		        html = html.replace(/<YUI_BR>/g, '<br/>');
+		        html = html.replace(/<YUI_BR>/g, '<br />');
             } else {
 		        html = html.replace(/<YUI_BR>/g, '<br>');
             }
@@ -5712,6 +6105,7 @@
             var textArea = this.get('element');
             this.get('element_cont').get('parentNode').replaceChild(textArea, this.get('element_cont').get('element'));
             this.get('element_cont').get('element').innerHTML = '';
+            this.set('handleSubmit', false); //Remove the submit handler
             //Brutal Object Destroy
             for (var i in this) {
                 if (Lang.hasOwnProperty(this, i)) {
@@ -5826,6 +6220,13 @@
         _instances: {},
         /**
         * @private
+        * @property blankImage
+        * @description A reference to the blankImage url
+        * @type String 
+        */
+        blankImage: '',
+        /**
+        * @private
         * @property window
         * @description A reference to the currently open window object in any editor on the page.
         * @type Object <a href="YAHOO.widget.EditorWindow.html">YAHOO.widget.EditorWindow</a>
@@ -5842,7 +6243,7 @@
         * @method getEditorById
         * @description Returns a reference to the Editor object associated with the given textarea
         * @param {String/HTMLElement} id The id or reference of the textarea to return the Editor instance of
-        * @returns Object <a href="YAHOO.widget.Editor.html">YAHOO.widget.Editor</a>
+        * @return Object <a href="YAHOO.widget.Editor.html">YAHOO.widget.Editor</a>
         */
         getEditorById: function(id) {
             if (!YAHOO.lang.isString(id)) {
@@ -5897,19 +6298,7 @@
     */
     
     YAHOO.widget.Editor = function(el, attrs) {
-        
-        var oConfig = {
-            element: null,
-            attributes: (attrs || {})
-        }, id = null;
-
-        if (Lang.isString(el)) {
-            id = el;
-        } else {
-            id = el.id;
-        }
-        oConfig.element = el;
-        YAHOO.widget.Editor.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
+        YAHOO.widget.Editor.superclass.constructor.call(this, el, attrs);
     };
 
     /**
@@ -5917,7 +6306,7 @@
     * @method _cleanClassName
     * @description Makes a useable classname from dynamic data, by dropping it to lowercase and replacing spaces with -'s.
     * @param {String} str The classname to clean up
-    * @returns {String}
+    * @return {String}
     */
     function _cleanClassName(str) {
         return str.replace(/ /g, '-').toLowerCase();
@@ -6046,7 +6435,94 @@
         * @description The Editor class' initialization method
         */
         init: function(p_oElement, p_oAttributes) {
+
+            this._defaultToolbar = {
+                collapse: true,
+                titlebar: 'Text Editing Tools',
+                draggable: false,
+                buttonType: 'advanced',
+                buttons: [
+                    { group: 'fontstyle', label: 'Font Name and Size',
+                        buttons: [
+                            { type: 'select', label: 'Arial', value: 'fontname', disabled: true,
+                                menu: [
+                                    { text: 'Arial', checked: true },
+                                    { text: 'Arial Black' },
+                                    { text: 'Comic Sans MS' },
+                                    { text: 'Courier New' },
+                                    { text: 'Lucida Console' },
+                                    { text: 'Tahoma' },
+                                    { text: 'Times New Roman' },
+                                    { text: 'Trebuchet MS' },
+                                    { text: 'Verdana' }
+                                ]
+                            },
+                            { type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true }
+                        ]
+                    },
+                    { type: 'separator' },
+                    { group: 'textstyle', label: 'Font Style',
+                        buttons: [
+                            { type: 'push', label: 'Bold CTRL + SHIFT + B', value: 'bold' },
+                            { type: 'push', label: 'Italic CTRL + SHIFT + I', value: 'italic' },
+                            { type: 'push', label: 'Underline CTRL + SHIFT + U', value: 'underline' },
+                            { type: 'separator' },
+                            { type: 'push', label: 'Subscript', value: 'subscript', disabled: true },
+                            { type: 'push', label: 'Superscript', value: 'superscript', disabled: true },
+                            { type: 'separator' },
+                            { type: 'color', label: 'Font Color', value: 'forecolor', disabled: true },
+                            { type: 'color', label: 'Background Color', value: 'backcolor', disabled: true },
+                            { type: 'separator' },
+                            { type: 'push', label: 'Remove Formatting', value: 'removeformat', disabled: true },
+                            { type: 'push', label: 'Show/Hide Hidden Elements', value: 'hiddenelements' }
+                        ]
+                    },
+                    { type: 'separator' },
+                    { group: 'alignment', label: 'Alignment',
+                        buttons: [
+                            { type: 'push', label: 'Align Left CTRL + SHIFT + [', value: 'justifyleft' },
+                            { type: 'push', label: 'Align Center CTRL + SHIFT + |', value: 'justifycenter' },
+                            { type: 'push', label: 'Align Right CTRL + SHIFT + ]', value: 'justifyright' },
+                            { type: 'push', label: 'Justify', value: 'justifyfull' }
+                        ]
+                    },
+                    { type: 'separator' },
+                    { group: 'parastyle', label: 'Paragraph Style',
+                        buttons: [
+                        { type: 'select', label: 'Normal', value: 'heading', disabled: true,
+                            menu: [
+                                { text: 'Normal', value: 'none', checked: true },
+                                { text: 'Header 1', value: 'h1' },
+                                { text: 'Header 2', value: 'h2' },
+                                { text: 'Header 3', value: 'h3' },
+                                { text: 'Header 4', value: 'h4' },
+                                { text: 'Header 5', value: 'h5' },
+                                { text: 'Header 6', value: 'h6' }
+                            ]
+                        }
+                        ]
+                    },
+                    { type: 'separator' },
+                    { group: 'indentlist', label: 'Indenting and Lists',
+                        buttons: [
+                            { type: 'push', label: 'Indent', value: 'indent', disabled: true },
+                            { type: 'push', label: 'Outdent', value: 'outdent', disabled: true },
+                            { type: 'push', label: 'Create an Unordered List', value: 'insertunorderedlist' },
+                            { type: 'push', label: 'Create an Ordered List', value: 'insertorderedlist' }
+                        ]
+                    },
+                    { type: 'separator' },
+                    { group: 'insertitem', label: 'Insert Item',
+                        buttons: [
+                            { type: 'push', label: 'HTML Link CTRL + SHIFT + L', value: 'createlink', disabled: true },
+                            { type: 'push', label: 'Insert Image', value: 'insertimage' }
+                        ]
+                    }
+                ]
+            };
+
             YAHOO.widget.Editor.superclass.init.call(this, p_oElement, p_oAttributes);
+
         },
         /**
         * @method initAttributes
@@ -6143,97 +6619,7 @@
         */
         _alwaysEnabled: { hiddenelements: true },
         /**
-        * @property _defaultToolbar
         * @private
-        * @description Default toolbar config.
-        * @type Object
-        */
-        _defaultToolbar: {
-            collapse: true,
-            titlebar: 'Text Editing Tools',
-            draggable: false,
-            buttonType: 'advanced',
-            buttons: [
-                { group: 'fontstyle', label: 'Font Name and Size',
-                    buttons: [
-                        { type: 'select', label: 'Arial', value: 'fontname', disabled: true,
-                            menu: [
-                                { text: 'Arial', checked: true },
-                                { text: 'Arial Black' },
-                                { text: 'Comic Sans MS' },
-                                { text: 'Courier New' },
-                                { text: 'Lucida Console' },
-                                { text: 'Tahoma' },
-                                { text: 'Times New Roman' },
-                                { text: 'Trebuchet MS' },
-                                { text: 'Verdana' }
-                            ]
-                        },
-                        { type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'textstyle', label: 'Font Style',
-                    buttons: [
-                        { type: 'push', label: 'Bold CTRL + SHIFT + B', value: 'bold' },
-                        { type: 'push', label: 'Italic CTRL + SHIFT + I', value: 'italic' },
-                        { type: 'push', label: 'Underline CTRL + SHIFT + U', value: 'underline' },
-                        { type: 'separator' },
-                        { type: 'push', label: 'Subscript', value: 'subscript', disabled: true },
-                        { type: 'push', label: 'Superscript', value: 'superscript', disabled: true },
-                        { type: 'separator' },
-                        { type: 'color', label: 'Font Color', value: 'forecolor', disabled: true },
-                        { type: 'color', label: 'Background Color', value: 'backcolor', disabled: true },
-                        { type: 'separator' },
-                        { type: 'push', label: 'Remove Formatting', value: 'removeformat', disabled: true },
-                        { type: 'push', label: 'Show/Hide Hidden Elements', value: 'hiddenelements' }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'alignment', label: 'Alignment',
-                    buttons: [
-                        { type: 'push', label: 'Align Left CTRL + SHIFT + [', value: 'justifyleft' },
-                        { type: 'push', label: 'Align Center CTRL + SHIFT + |', value: 'justifycenter' },
-                        { type: 'push', label: 'Align Right CTRL + SHIFT + ]', value: 'justifyright' },
-                        { type: 'push', label: 'Justify', value: 'justifyfull' }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'parastyle', label: 'Paragraph Style',
-                    buttons: [
-                    { type: 'select', label: 'Normal', value: 'heading', disabled: true,
-                        menu: [
-                            { text: 'Normal', value: 'none', checked: true },
-                            { text: 'Header 1', value: 'h1' },
-                            { text: 'Header 2', value: 'h2' },
-                            { text: 'Header 3', value: 'h3' },
-                            { text: 'Header 4', value: 'h4' },
-                            { text: 'Header 5', value: 'h5' },
-                            { text: 'Header 6', value: 'h6' }
-                        ]
-                    }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'indentlist', label: 'Indenting and Lists',
-                    buttons: [
-                        { type: 'push', label: 'Indent', value: 'indent', disabled: true },
-                        { type: 'push', label: 'Outdent', value: 'outdent', disabled: true },
-                        { type: 'push', label: 'Create an Unordered List', value: 'insertunorderedlist' },
-                        { type: 'push', label: 'Create an Ordered List', value: 'insertorderedlist' }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'insertitem', label: 'Insert Item',
-                    buttons: [
-                        { type: 'push', label: 'HTML Link CTRL + SHIFT + L', value: 'createlink', disabled: true },
-                        { type: 'push', label: 'Insert Image', value: 'insertimage' }
-                    ]
-                }
-            ]
-        },
-        /**
-        * @private
         * @method _handleKeyDown
         * @param {Event} ev The event we are working on.
         * @description Override method that handles some new keydown events inside the iFrame document.
@@ -6560,7 +6946,7 @@
                 if ((height != oheight) || (width != owidth)) {
                     orgSize = '<span class="info">' + this.STR_IMAGE_ORIG_SIZE + '<br>'+ owidth +' x ' + oheight + '</span>';
                 }
-                hw.innerHTML += '<span><input type="text" size="3" value="'+width+'" id="insertimage_width"> x <input type="text" size="3" value="'+height+'" id="insertimage_height"></span>' + orgSize;
+                hw.innerHTML += '<span tabIndex="-1"><input type="text" size="3" value="'+width+'" id="insertimage_width"> x <input type="text" size="3" value="'+height+'" id="insertimage_height"></span>' + orgSize;
                 cont.insertBefore(hw, cont.firstChild);
 
                 Event.onAvailable('insertimage_width', function() {
@@ -6568,7 +6954,8 @@
                         var value = parseInt(Dom.get('insertimage_width').value, 10);
                         if (value > 5) {
                             el.style.width = value + 'px';
-                            this.moveWindow();
+                            //Removed moveWindow call so the window doesn't jump
+                            //this.moveWindow();
                         }
                     }, this, true);
                 }, this, true);
@@ -6577,7 +6964,8 @@
                         var value = parseInt(Dom.get('insertimage_height').value, 10);
                         if (value > 5) {
                             el.style.height = value + 'px';
-                            this.moveWindow();
+                            //Removed moveWindow call so the window doesn't jump
+                            //this.moveWindow();
                         }
                     }, this, true);
                 }, this, true);
@@ -6685,7 +7073,8 @@
 
                 win.setHeader(this.STR_IMAGE_PROP_TITLE);
                 win.setBody(body);
-                if ((this.browser.webkit && !this.browser.webkit3) || this.browser.opera) {
+                //Adobe AIR Code
+                if ((this.browser.webkit && !this.browser.webkit3 || this.browser.air) || this.browser.opera) {                
                     win.setFooter(this.STR_IMAGE_COPY);
                 }
                 this.openWindow(win);
@@ -6712,7 +7101,8 @@
                             } else {
                                 Dom.removeClass(url, 'warning');
                                 this.get('panel').setFooter(' ');
-                                if ((this.browser.webkit && !this.browser.webkit3) || this.browser.opera) {
+                                //Adobe AIR Code
+                                if ((this.browser.webkit && !this.browser.webkit3 || this.browser.air) || this.browser.opera) {                
                                     this.get('panel').setFooter(this.STR_IMAGE_COPY);
                                 }
                             }
@@ -6720,6 +7110,11 @@
 
                         Event.on('insertimage_url', 'blur', function() {
                             var url = Dom.get('insertimage_url');
+                            if (url.value && el) {
+                                if (url.value == el.getAttribute('src', 2)) {
+                                    return false;
+                                }
+                            }
                             if (this._isLocalFile(url.value)) {
                                 //Local File throw Warning
                                 Dom.addClass(url, 'warning');
@@ -6727,7 +7122,8 @@
                             } else if (this.currentElement[0]) {
                                 Dom.removeClass(url, 'warning');
                                 this.get('panel').setFooter(' ');
-                                if ((this.browser.webkit && !this.browser.webkit3) || this.browser.opera) {
+                                //Adobe AIR Code
+                                if ((this.browser.webkit && !this.browser.webkit3 || this.browser.air) || this.browser.opera) {                
                                     this.get('panel').setFooter(this.STR_IMAGE_COPY);
                                 }
                                 
@@ -6754,8 +7150,9 @@
                                                 self.currentElement[0]._width = img.width;
                                             }
                                         }
-                                        self.moveWindow();
-                                    }, 200);
+                                        //Removed moveWindow call so the window doesn't jump
+                                        //self.moveWindow();
+                                    }, 800); //Bumped the timeout up to account for larger images..
 
                                     if (url.value != this.STR_IMAGE_HERE) {
                                         img.src = url.value;
@@ -6828,7 +7225,7 @@
         * @private
         * @method _renderPanel
         * @description Renders the panel used for Editor Windows to the document so we can start using it..
-        * @returns {<a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>}
+        * @return {<a href="YAHOO.widget.Overlay.html">YAHOO.widget.Overlay</a>}
         */
         _renderPanel: function() {
             var panel = null;
@@ -6987,19 +7384,18 @@
                 newXY = [(xy[0] + elXY[0]), (xy[1] + elXY[1])],
                 wWidth = (parseInt(win.attrs.width, 10) / 2),
                 align = 'center',
-                orgXY = panel.cfg.getProperty('xy'),
+                orgXY = panel.cfg.getProperty('xy') || [0,0],
                 _knob = win._knob,
                 xDiff = 0,
                 yDiff = 0,
                 anim = false;
 
+
             newXY[0] = ((newXY[0] - wWidth) + 20);
             //Account for the Scroll bars in a scrolled editor window.
             newXY[0] = newXY[0] - Dom.getDocumentScrollLeft(this._getDoc());
             newXY[1] = newXY[1] - Dom.getDocumentScrollTop(this._getDoc());
             
-
-
             if (this._isElement(this.currentElement[0], 'img')) {
                 if (this.currentElement[0].src.indexOf(this.get('blankimage')) != -1) {
                     newXY[0] = (newXY[0] + (75 / 2)); //Placeholder size
@@ -7033,6 +7429,16 @@
                 xDiff = (newXY[0] - orgXY[0]);
                 yDiff = (newXY[1] - orgXY[1]);
             } catch (e) {}
+
+
+            var iTop = elXY[1] + parseInt(this.get('height'), 10);
+            var iLeft = elXY[0] + parseInt(this.get('width'), 10);
+            if (newXY[1] > iTop) {
+                newXY[1] = iTop;
+            }
+            if (newXY[0] > iLeft) {
+                newXY[0] = (iLeft / 2);
+            }
             
             //Convert negative numbers to positive so we can get the difference in distance
             xDiff = ((xDiff < 0) ? (xDiff * -1) : xDiff);
@@ -7049,13 +7455,13 @@
                 var leftOffset = xy[0] + elXY[0] + elW;
                 _knobLeft = leftOffset - newXY[0];
                 //Check to see if the knob will go off either side & reposition it
-                if (_knobLeft > (parseInt(win.attrs.width, 10) - 40)) {
-                    _knobLeft = parseInt(win.attrs.width, 10) - 40;
+                if (_knobLeft > (parseInt(win.attrs.width, 10) - 1)) {
+                    _knobLeft = ((parseInt(win.attrs.width, 10) - 30) - 1);
                 } else if (_knobLeft < 40) {
-                    _knobLeft = 40;
+                    _knobLeft = 1;
                 }
                 if (isNaN(_knobLeft)) {
-                    _knobLeft = 40;
+                    _knobLeft = 1;
                 }
                 if (force) {
                     if (_knob) {
@@ -7475,4 +7881,4 @@
 */
 
 })();
-YAHOO.register("editor", YAHOO.widget.Editor, {version: "2.4.1", build: "742"});
+YAHOO.register("editor", YAHOO.widget.Editor, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/editor/simpleeditor-beta-debug.js
===================================================================
--- trunk/root/static/yui/editor/simpleeditor-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/editor/simpleeditor-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 (function() {
     /**
@@ -90,6 +90,7 @@
         oConfig.element.setAttribute('unselectable', 'on');
         oConfig.element.className = 'yui-button yui-' + oConfig.attributes.type + '-button';
         oConfig.element.innerHTML = '<span class="first-child"><a href="#">LABEL</a></span>';
+        oConfig.element.firstChild.firstChild.tabIndex = '-1';
         oConfig.attributes.id = Dom.generateId();
 
         YAHOO.widget.ToolbarButton.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
@@ -287,6 +288,20 @@
             return this.get('menu');
         },
         /** 
+        * @method destroy
+        * @description Destroy the button
+        */        
+        destroy: function() {
+            Event.purgeElement(this.get('element'), true);
+            this.get('element').parentNode.removeChild(this.get('element'));
+            //Brutal Object Destroy
+            for (var i in this) {
+                if (Lang.hasOwnProperty(this, i)) {
+                    this[i] = null;
+                }
+            }       
+        },
+        /** 
         * @method fireEvent
         * @description Overridden fireEvent method to prevent DOM events from firing if the button is disabled.
         */        
@@ -311,7 +326,6 @@
 })();
 /**
  * @description <p>Creates a rich Toolbar widget based on Button. Primarily used with the Rich Text Editor</p>
- * @class Toolbar
  * @namespace YAHOO.widget
  * @requires yahoo, dom, element, event, toolbarbutton
  * @optional container_core, dragdrop
@@ -324,10 +338,29 @@
 var Dom = YAHOO.util.Dom,
     Event = YAHOO.util.Event,
     Lang = YAHOO.lang;
+    
+    var getButton = function(id) {
+        var button = id;
+        if (Lang.isString(id)) {
+            button = this.getButtonById(id);
+        }
+        if (Lang.isNumber(id)) {
+            button = this.getButtonByIndex(id);
+        }
+        if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
+            button = this.getButtonByValue(id);
+        }
+        if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            return button;
+        }
+        return false;
+    };
 
     /**
      * Provides a rich toolbar widget based on the button and menu widgets
      * @constructor
+     * @class Toolbar
+     * @extends YAHOO.util.Element
      * @param {String/HTMLElement} el The element to turn into a toolbar.
      * @param {Object} attrs Object liternal containing configuration parameters.
     */
@@ -371,10 +404,19 @@
         }
         YAHOO.log('Initing toolbar with id: ' + oConfig.element.id, 'info', 'Toolbar');
         
+        var fs = document.createElement('fieldset');
+        var lg = document.createElement('legend');
+        lg.innerHTML = 'Toolbar';
+        fs.appendChild(lg);
+        
         var cont = document.createElement('DIV');
         oConfig.attributes.cont = cont;
         Dom.addClass(cont, 'yui-toolbar-subcont');
-        oConfig.element.appendChild(cont);
+        fs.appendChild(cont);
+        oConfig.element.appendChild(fs);
+
+        oConfig.element.tabIndex = -1;
+
         
         oConfig.attributes.element = oConfig.element;
         oConfig.attributes.id = oConfig.element.id;
@@ -695,6 +737,7 @@
         */
         init: function(p_oElement, p_oAttributes) {
             YAHOO.widget.Toolbar.superclass.init.call(this, p_oElement, p_oAttributes);
+
         },
         /**
         * @method initAttributes
@@ -821,7 +864,7 @@
             * @type Boolean
             */
             this.setAttributeConfig('grouplabels', {
-                value: attr.grouplabels || true,
+                value: ((attr.grouplabels === false) ? false : true),
                 method: function(grouplabels) {
                     if (grouplabels) {
                         Dom.removeClass(this.get('cont'), (this.CLASS_PREFIX + '-nogrouplabels'));
@@ -845,12 +888,22 @@
                             this._titlebar.parentNode.removeChild(this._titlebar);
                         }
                         this._titlebar = document.createElement('DIV');
+                        this._titlebar.tabIndex = '-1';
+                        Event.on(this._titlebar, 'focus', function() {
+                            this._handleFocus();
+                        }, this, true);
                         Dom.addClass(this._titlebar, this.CLASS_PREFIX + '-titlebar');
                         if (Lang.isString(titlebar)) {
                             var h2 = document.createElement('h2');
                             h2.tabIndex = '-1';
-                            h2.innerHTML = titlebar;
+                            h2.innerHTML = '<a href="#" tabIndex="0">' + titlebar + '</a>';
                             this._titlebar.appendChild(h2);
+                            Event.on(h2.firstChild, 'click', function(ev) {
+                                Event.stopEvent(ev);
+                            });
+                            Event.on([h2, h2.firstChild], 'focus', function() {
+                                this._handleFocus();
+                            }, this, true);
                         }
                         if (this.get('firstChild')) {
                             this.insertBefore(this._titlebar, this.get('firstChild'));
@@ -879,34 +932,36 @@
             this.setAttributeConfig('collapse', {
                 value: false,
                 method: function(collapse) {
-                    var collapseEl = null;
-                    var el = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
-                    if (collapse) {
-                        if (el.length > 0) {
-                            //There is already a collapse button
-                            return true;
-                        }
-                        collapseEl = document.createElement('SPAN');
-                        collapseEl.innerHTML = 'X';
-                        collapseEl.title = this.STR_COLLAPSE;
+                    if (this._titlebar) {
+                        var collapseEl = null;
+                        var el = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
+                        if (collapse) {
+                            if (el.length > 0) {
+                                //There is already a collapse button
+                                return true;
+                            }
+                            collapseEl = document.createElement('SPAN');
+                            collapseEl.innerHTML = 'X';
+                            collapseEl.title = this.STR_COLLAPSE;
 
-                        Dom.addClass(collapseEl, 'collapse');
-                        this._titlebar.appendChild(collapseEl);
-                        Event.addListener(collapseEl, 'click', function() {
-                            if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
-                                this.collapse(false); //Expand Toolbar
-                            } else {
-                                this.collapse(); //Collapse Toolbar
+                            Dom.addClass(collapseEl, 'collapse');
+                            this._titlebar.appendChild(collapseEl);
+                            Event.addListener(collapseEl, 'click', function() {
+                                if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
+                                    this.collapse(false); //Expand Toolbar
+                                } else {
+                                    this.collapse(); //Collapse Toolbar
+                                }
+                            }, this, true);
+                        } else {
+                            collapseEl = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
+                            if (collapseEl[0]) {
+                                if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
+                                    //We are closed, reopen the titlebar..
+                                    this.collapse(false); //Expand Toolbar
+                                }
+                                collapseEl[0].parentNode.removeChild(collapseEl[0]);
                             }
-                        }, this, true);
-                    } else {
-                        collapseEl = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
-                        if (collapseEl[0]) {
-                            if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
-                                //We are closed, reopen the titlebar..
-                                this.collapse(false); //Expand Toolbar
-                            }
-                            collapseEl[0].parentNode.removeChild(collapseEl[0]);
                         }
                     }
                 }
@@ -979,7 +1034,7 @@
         /**
         * @method addButtonGroup
         * @description Add a new button group to the toolbar. (uses addButton)
-        * @param {Object} oGroup Object literal reference to the Groups Config (contains an array of button configs)
+        * @param {Object} oGroup Object literal reference to the Groups Config (contains an array of button configs as well as the group label)
         */
         addButtonGroup: function(oGroup) {
             if (!this.get('element')) {
@@ -993,7 +1048,6 @@
             var div = document.createElement('DIV');
             Dom.addClass(div, this.CLASS_PREFIX + '-group');
             Dom.addClass(div, this.CLASS_PREFIX + '-group-' + oGroup.group);
-            //if (oGroup.label && this.get('grouplabels')) {
             if (oGroup.label) {
                 var label = document.createElement('h3');
                 label.innerHTML = oGroup.label;
@@ -1073,9 +1127,6 @@
                                         oButton.menucmd = oButton.value;
                                     }
                                     oButton.value = ((oMenu.value) ? oMenu.value : oMenu._oText.nodeValue);
-                                    //This line made Opera fire the click event and the mousedown,
-                                    //  so events for menus where firing twice.
-                                    //this._buttonClick('click', oButton);
                                 },
                                 scope: this
                             };
@@ -1126,8 +1177,11 @@
             } else {
                 //Add to .get('buttons') manually
                 this._configs.buttons.value[this._configs.buttons.value.length] = oButton;
-
+                
                 var tmp = new this.buttonType(_oButton);
+                tmp.get('element').tabIndex = '-1';
+                tmp.get('element').setAttribute('role', 'button');
+                tmp._selected = true;
                 if (!tmp.buttonType) {
                     tmp.buttonType = 'rich';
                     tmp.checkValue = function(value) {
@@ -1177,6 +1231,7 @@
                     var a = document.createElement('a');
                     a.innerHTML = tmp._button.innerHTML;
                     a.href = '#';
+                    a.tabIndex = '-1';
                     Event.on(a, 'click', function(ev) {
                         Event.stopEvent(ev);
                     });
@@ -1210,7 +1265,9 @@
                                 exec = false;
                             }
                             if (exec) {
-                                this._colorPicker._button = oButton.value;
+                                if (this._colorPicker) {
+                                    this._colorPicker._button = oButton.value;
+                                }
                                 var menuEL = tmp.getMenu().element;
                                 if (Dom.getStyle(menuEL, 'visibility') == 'hidden') {
                                     tmp.getMenu().show();
@@ -1230,7 +1287,7 @@
                             this._buttonClick(ev, oButton);
                         }, oButton, this);
                         tmp.on('click', function(ev) {
-                            YAHOO.util.Event.stopEvent(ev);
+                            //YAHOO.util.Event.stopEvent(ev);
                         });
                     } else {
                         //Stop the mousedown event so we can trap the selection in the editor!
@@ -1247,6 +1304,7 @@
                             oButton.value = ev.value;
                             this._buttonClick(ev, oButton);
                         }, this, true);
+
                         var self = this;
                         //Hijack the mousedown event in the menu and make it fire a button click..
                         if (tmp.getMenu().mouseDownEvent) {
@@ -1284,6 +1342,7 @@
                     });
                 }
                 if (this.browser.ie) {
+                    /*
                     //Add a couple of new events for IE
                     tmp.DOM_EVENTS.focusin = true;
                     tmp.DOM_EVENTS.focusout = true;
@@ -1299,6 +1358,7 @@
                     tmp.on('click', function(ev) {
                         YAHOO.util.Event.stopEvent(ev);
                     }, oButton, this);
+                    */
                 }
                 if (this.browser.webkit) {
                     //This will keep the document from gaining focus and the editor from loosing it..
@@ -1400,11 +1460,14 @@
                 }
             }
             html += '<span><em>X</em><strong></strong></span>';
-            picker.innerHTML = html;
-            var em = picker.getElementsByTagName('em')[0];
-            var strong = picker.getElementsByTagName('strong')[0];
+            window.setTimeout(function() {
+                picker.innerHTML = html;
+            }, 0);
 
             Event.on(picker, 'mouseover', function(ev) {
+                var picker = this._colorPicker;
+                var em = picker.getElementsByTagName('em')[0];
+                var strong = picker.getElementsByTagName('strong')[0];
                 var tar = Event.getTarget(ev);
                 if (tar.tagName.toLowerCase() == 'a') {
                     em.style.backgroundColor = tar.style.backgroundColor;
@@ -1421,7 +1484,16 @@
                 Event.stopEvent(ev);
                 var tar = Event.getTarget(ev);
                 if (tar.tagName.toLowerCase() == 'a') {
-                    this.fireEvent('colorPickerClicked', { type: 'colorPickerClicked', target: this, button: this._colorPicker._button, color: tar.innerHTML, colorName: this._colorData['#' + tar.innerHTML] } );
+                    var retVal = this.fireEvent('colorPickerClicked', { type: 'colorPickerClicked', target: this, button: this._colorPicker._button, color: tar.innerHTML, colorName: this._colorData['#' + tar.innerHTML] } );
+                    if (retVal !== false) {
+                        var info = {
+                            color: tar.innerHTML,
+                            colorName: this._colorData['#' + tar.innerHTML],
+                            value: this._colorPicker._button 
+                        };
+                    
+                        this.fireEvent('buttonClick', { type: 'buttonClick', target: this.get('element'), button: info });
+                    }
                     this.getButtonByValue(this._colorPicker._button).getMenu().hide();
                 }
             }, this, true);
@@ -1484,6 +1556,8 @@
                 _b2 = document.createElement('a');
                 _b1.href = '#';
                 _b2.href = '#';
+                _b1.tabIndex = '-1';
+                _b2.tabIndex = '-1';
             
             //Setup the up and down arrows
             _b1.className = 'up';
@@ -1637,12 +1711,75 @@
                         }
                     }
                 }
+                if (ev) {
+                    Event.stopEvent(ev);
+                }
             }
-            if (ev) {
-                Event.stopEvent(ev);
+        },
+        /**
+        * @private
+        * @property _keyNav
+        * @description Flag to determine if the arrow nav listeners have been attached
+        * @type Boolean
+        */
+        _keyNav: null,
+        /**
+        * @private
+        * @property _navCounter
+        * @description Internal counter for walking the buttons in the toolbar with the arrow keys
+        * @type Number
+        */
+        _navCounter: null,
+        /**
+        * @private
+        * @method _navigateButtons
+        * @description Handles the navigation/focus of toolbar buttons with the Arrow Keys
+        * @param {Event} ev The Key Event
+        */
+        _navigateButtons: function(ev) {
+            switch (ev.keyCode) {
+                case 37:
+                case 39:
+                    if (ev.keyCode == 37) {
+                        this._navCounter--;
+                    } else {
+                        this._navCounter++;
+                    }
+                    if (this._navCounter > (this._buttonList.length - 1)) {
+                        this._navCounter = 0;
+                    }
+                    if (this._navCounter < 0) {
+                        this._navCounter = (this._buttonList.length - 1);
+                    }
+                    var el = this._buttonList[this._navCounter].get('element');
+                    if (this.browser.ie) {
+                        el = this._buttonList[this._navCounter].get('element').getElementsByTagName('a')[0];
+                    }
+                    if (this._buttonList[this._navCounter].get('disabled')) {
+                        this._navigateButtons(ev);
+                    } else {
+                        el.focus();
+                    }
+                    break;
             }
         },
         /**
+        * @private
+        * @method _handleFocus
+        * @description Sets up the listeners for the arrow key navigation
+        */
+        _handleFocus: function() {
+            if (!this._keyNav) {
+                var ev = 'keypress';
+                if (this.browser.ie) {
+                    ev = 'keydown';
+                }
+                Event.on(this.get('element'), ev, this._navigateButtons, this, true);
+                this._keyNav = true;
+                this._navCounter = -1;
+            }
+        },
+        /**
         * @method getButtonById
         * @description Gets a button instance from the toolbar by is Dom id.
         * @param {String} id The Dom id to query for.
@@ -1723,17 +1860,8 @@
         * @return {Boolean}
         */
         disableButton: function(id) {
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 button.set('disabled', true);
             } else {
                 return false;
@@ -1749,17 +1877,8 @@
             if (this.get('disabled')) {
                 return false;
             }
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 if (button.get('disabled')) {
                     button.set('disabled', false);
                 }
@@ -1768,42 +1887,46 @@
             }
         },
         /**
+        * @method isSelected
+        * @description Tells if a button is selected or not.
+        * @param {String/Number} id A button by it's id, index or value.
+        * @return {Boolean}
+        */
+        isSelected: function(id) {
+            var button = getButton.call(this, id);
+            if (button) {
+                return button._selected;
+            }
+            return false;
+        },
+        /**
         * @method selectButton
         * @description Selects a button in the toolbar.
         * @param {String/Number} id Select a button by it's id, index or value.
+        * @param {String} value If this is a Menu Button, check this item in the menu
         * @return {Boolean}
         */
         selectButton: function(id, value) {
-            var button = id;
-            if (id) {
-                if (Lang.isString(id)) {
-                    button = this.getButtonById(id);
-                }
-                if (Lang.isNumber(id)) {
-                    button = this.getButtonByIndex(id);
-                }
-                if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                    button = this.getButtonByValue(id);
-                }
-                if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
-                    button.addClass('yui-button-selected');
-                    button.addClass('yui-button-' + button.get('value') + '-selected');
-                    if (value) {
-                        if (button.buttonType == 'rich') {
-                            var _items = button.getMenu().getItems();
-                            for (var m = 0; m < _items.length; m++) {
-                                if (_items[m].value == value) {
-                                    _items[m].cfg.setProperty('checked', true);
-                                    button.set('label', '<span class="yui-toolbar-' + button.get('value') + '-' + (value).replace(/ /g, '-').toLowerCase() + '">' + _items[m]._oText.nodeValue + '</span>');
-                                } else {
-                                    _items[m].cfg.setProperty('checked', false);
-                                }
+            var button = getButton.call(this, id);
+            if (button) {
+                button.addClass('yui-button-selected');
+                button.addClass('yui-button-' + button.get('value') + '-selected');
+                button._selected = true;
+                if (value) {
+                    if (button.buttonType == 'rich') {
+                        var _items = button.getMenu().getItems();
+                        for (var m = 0; m < _items.length; m++) {
+                            if (_items[m].value == value) {
+                                _items[m].cfg.setProperty('checked', true);
+                                button.set('label', '<span class="yui-toolbar-' + button.get('value') + '-' + (value).replace(/ /g, '-').toLowerCase() + '">' + _items[m]._oText.nodeValue + '</span>');
+                            } else {
+                                _items[m].cfg.setProperty('checked', false);
                             }
                         }
                     }
-                } else {
-                    return false;
                 }
+            } else {
+                return false;
             }
         },
         /**
@@ -1813,20 +1936,12 @@
         * @return {Boolean}
         */
         deselectButton: function(id) {
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 button.removeClass('yui-button-selected');
                 button.removeClass('yui-button-' + button.get('value') + '-selected');
                 button.removeClass('yui-button-hover');
+                button._selected = false;
             } else {
                 return false;
             }
@@ -1907,17 +2022,8 @@
         * @return {Boolean}
         */
         destroyButton: function(id) {
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 var thisID = button.get('id');
                 button.destroy();
 
@@ -1930,7 +2036,6 @@
             } else {
                 return false;
             }
-
         },
         /**
         * @method destroy
@@ -2035,16 +2140,35 @@
     
     YAHOO.widget.SimpleEditor = function(el, attrs) {
         YAHOO.log('SimpleEditor Initalizing', 'info', 'SimpleEditor');
+        
+        var o = {};
+        if (Lang.isObject(el) && (!el.tagName) && !attrs) {
+            Lang.augmentObject(o, el); //Break the config reference
+            el = document.createElement('textarea');
+            this.DOMReady = true;
+            if (o.container) {
+                var c = Dom.get(o.container);
+                c.appendChild(el);
+            } else {
+                document.body.appendChild(el);
+            }
+        } else {
+            Lang.augmentObject(o, attrs); //Break the config reference
+        }
 
         var oConfig = {
             element: null,
-            attributes: (attrs || {})
+            attributes: o
         }, id = null;
 
         if (Lang.isString(el)) {
             id = el;
         } else {
-            id = el.id;
+            if (oConfig.attributes.id) {
+                id = oConfig.attributes.id;
+            } else {
+                id = Dom.generateId(el);
+            }
         }
         oConfig.element = el;
 
@@ -2073,7 +2197,7 @@
     * @method _cleanClassName
     * @description Makes a useable classname from dynamic data, by dropping it to lowercase and replacing spaces with -'s.
     * @param {String} str The classname to clean up
-    * @returns {String}
+    * @return {String}
     */
     function _cleanClassName(str) {
         return str.replace(/ /g, '-').toLowerCase();
@@ -2092,70 +2216,20 @@
         * @description This flag will be set when certain things in the Editor happen. It is to be used by the developer to check to see if content has changed.
         * @type Boolean
         */
-        editorDirty: false,
+        editorDirty: null,
         /**
         * @property _defaultCSS
         * @description The default CSS used in the config for 'css'. This way you can add to the config like this: { css: YAHOO.widget.SimpleEditor.prototype._defaultCSS + 'ADD MYY CSS HERE' }
         * @type String
         */
-        _defaultCSS: 'html { height: 95%; } body { height: 100%; padding: 7px; background-color: #fff; font:13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a { color: blue; text-decoration: underline; cursor: pointer; } .warning-localfile { border-bottom: 1px dashed red !important; } .yui-busy { cursor: wait !important; } img.selected { border: 2px dotted #808080; } img { cursor: pointer !important; border: none; }',
+        _defaultCSS: 'html { height: 95%; } body { padding: 7px; background-color: #fff; font:13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a { color: blue; text-decoration: underline; cursor: text; } .warning-localfile { border-bottom: 1px dashed red !important; } .yui-busy { cursor: wait !important; } img.selected { border: 2px dotted #808080; } img { cursor: pointer !important; border: none; }',
         /**
         * @property _defaultToolbar
         * @private
         * @description Default toolbar config.
         * @type Object
         */
-        _defaultToolbar: {
-            collapse: true,
-            titlebar: 'Text Editing Tools',
-            draggable: false,
-            buttons: [
-                { group: 'fontstyle', label: 'Font Name and Size',
-                    buttons: [
-                        { type: 'select', label: 'Arial', value: 'fontname', disabled: true,
-                            menu: [
-                                { text: 'Arial', checked: true },
-                                { text: 'Arial Black' },
-                                { text: 'Comic Sans MS' },
-                                { text: 'Courier New' },
-                                { text: 'Lucida Console' },
-                                { text: 'Tahoma' },
-                                { text: 'Times New Roman' },
-                                { text: 'Trebuchet MS' },
-                                { text: 'Verdana' }
-                            ]
-                        },
-                        { type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'textstyle', label: 'Font Style',
-                    buttons: [
-                        { type: 'push', label: 'Bold CTRL + SHIFT + B', value: 'bold' },
-                        { type: 'push', label: 'Italic CTRL + SHIFT + I', value: 'italic' },
-                        { type: 'push', label: 'Underline CTRL + SHIFT + U', value: 'underline' },
-                        { type: 'separator' },
-                        { type: 'color', label: 'Font Color', value: 'forecolor', disabled: true },
-                        { type: 'color', label: 'Background Color', value: 'backcolor', disabled: true }
-                        
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'indentlist', label: 'Lists',
-                    buttons: [
-                        { type: 'push', label: 'Create an Unordered List', value: 'insertunorderedlist' },
-                        { type: 'push', label: 'Create an Ordered List', value: 'insertorderedlist' }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'insertitem', label: 'Insert Item',
-                    buttons: [
-                        { type: 'push', label: 'HTML Link CTRL + SHIFT + L', value: 'createlink', disabled: true },
-                        { type: 'push', label: 'Insert Image', value: 'insertimage' }
-                    ]
-                }
-            ]
-        },
+        _defaultToolbar: null,
         /**
         * @property _lastButton
         * @private
@@ -2188,9 +2262,9 @@
         * @property _blankImageLoaded
         * @private
         * @description Don't load the blank image more than once..
-        * @type Date
+        * @type Boolean
         */
-        _blankImageLoaded: false,
+        _blankImageLoaded: null,
         /**
         * @property _fixNodesTimer
         * @private
@@ -2225,7 +2299,7 @@
         * @description Flag to determine if editor has been rendered or not
         * @type Boolean
         */
-        _rendered: false,
+        _rendered: null,
         /**
         * @property DOMReady
         * @private
@@ -2284,7 +2358,7 @@
         * @description A reference to the current working element in the editor
         * @type Array
         */
-        currentElement: [],
+        currentElement: null,
         /**
         * @property dompath
         * @description A reference to the dompath container for writing the current working dom path to.
@@ -2316,6 +2390,7 @@
             link: true,
             html: true,
             body: true,
+            iframe: true,
             script: true,
             style: true,
             textarea: true
@@ -2391,7 +2466,7 @@
         * @private _createIframe
         * @description Creates the DOM and YUI Element for the iFrame editor area.
         * @param {String} id The string ID to prefix the iframe with
-        * @returns {Object} iFrame object
+        * @return {Object} iFrame object
         */
         _createIframe: function() {
             var ifrmDom = document.createElement('iframe');
@@ -2406,6 +2481,9 @@
                 allowTransparency: 'true',
                 width: '100%'
             };
+            if (this.get('autoHeight')) {
+                config.scrolling = 'no';
+            }
             for (var i in config) {
                 if (Lang.hasOwnProperty(config, i)) {
                     ifrmDom.setAttribute(i, config[i]);
@@ -2413,9 +2491,7 @@
             }
             var isrc = 'javascript:;';
             if (this.browser.ie) {
-                if (window.location.href.toLowerCase().indexOf("https") !== 0) {
-                    isrc = 'about:blank';
-                }
+                isrc = 'about:blank';
             }
             ifrmDom.setAttribute('src', isrc);
             var ifrm = new YAHOO.util.Element(ifrmDom);
@@ -2427,7 +2503,7 @@
         * @description Checks to see if an Element reference is a valid one and has a certain tag type
         * @param {HTMLElement} el The element to check
         * @param {String} tag The tag that the element needs to be
-        * @returns {Boolean}
+        * @return {Boolean}
         */
         _isElement: function(el, tag) {
             if (el && el.tagName && (el.tagName.toLowerCase() == tag)) {
@@ -2443,7 +2519,7 @@
         * @description Checks to see if an Element reference or one of it's parents is a valid one and has a certain tag type
         * @param {HTMLElement} el The element to check
         * @param {String} tag The tag that the element needs to be
-        * @returns HTMLElement
+        * @return HTMLElement
         */
         _hasParent: function(el, tag) {
             if (!el || !el.parentNode) {
@@ -2535,13 +2611,17 @@
         * @private
         * @method _hasSelection
         * @description Determines if there is a selection in the editor document.
-        * @returns {Boolean}
+        * @return {Boolean}
         */
         _hasSelection: function() {
             var sel = this._getSelection();
             var range = this._getRange();
             var hasSel = false;
 
+            if (!sel || !range) {
+                return hasSel;
+            }
+
             //Internet Explorer
             if (this.browser.ie || this.browser.opera) {
                 if (range.text) {
@@ -2567,7 +2647,7 @@
         * @private
         * @method _getSelection
         * @description Handles the different selection objects across the A-Grade list.
-        * @returns {Object} Selection Object
+        * @return {Object} Selection Object
         */
         _getSelection: function() {
             var _sel = null;
@@ -2638,7 +2718,7 @@
         * @private
         * @method _getRange
         * @description Handles the different range objects across the A-Grade list.
-        * @returns {Object} Range Object
+        * @return {Object} Range Object
         */
         _getRange: function() {
             var sel = this._getSelection();
@@ -2659,7 +2739,11 @@
             }
 
             if (this.browser.ie || this.browser.opera) {
-                return sel.createRange();
+                try {
+                    return sel.createRange();
+                } catch (e) {
+                    return null;
+                }
             }
 
             if (sel.rangeCount > 0) {
@@ -2675,14 +2759,21 @@
         */
         _setDesignMode: function(state) {
             try {
-                this._getDoc().designMode = state;
+                var set = true;
+                //SourceForge Bug #1807057
+                if (this.browser.ie && (state.toLowerCase() == 'off')) {
+                    set = false;
+                }
+                if (set) {
+                    this._getDoc().designMode = state;
+                }
             } catch(e) { }
         },
         /**
         * @private
         * @method _toggleDesignMode
         * @description Toggles the designMode of the iFrame document on and off.
-        * @returns {String} The state that it was set to.
+        * @return {String} The state that it was set to.
         */
         _toggleDesignMode: function() {
             var _dMode = this._getDoc().designMode.toLowerCase(),
@@ -2699,14 +2790,23 @@
         * @description This method is fired from _checkLoaded when the document is ready. It turns on designMode and set's up the listeners.
         */
         _initEditor: function() {
-            YAHOO.log('editorLoaded', 'info', 'SimpleEditor');
             if (this.browser.ie) {
                 this._getDoc().body.style.margin = '0';
             }
             if (!this.get('disabled')) {
-                this._setDesignMode('on');
+                if (this._getDoc().designMode.toLowerCase() != 'on') {
+                    this._setDesignMode('on');
+                    this._contentTimerCounter = 0;
+                }
             }
+            if (!this._getDoc().body) {
+                YAHOO.log('Body is null, check again', 'error', 'SimpleEditor');
+                this._contentTimerCounter = 0;
+                this._checkLoaded();
+                return false;
+            }
             
+            YAHOO.log('editorLoaded', 'info', 'SimpleEditor');
             this.toolbar.on('buttonClick', this._handleToolbarClick, this, true);
             //Setup Listeners on iFrame
             Event.on(this._getDoc(), 'mouseup', this._handleMouseUp, this, true);
@@ -2740,14 +2840,22 @@
             if (this._contentTimer) {
                 clearTimeout(this._contentTimer);
             }
-            if (this._contentTimerCounter > 250) {
+            if (this._contentTimerCounter > 500) {
                 YAHOO.log('ERROR: Body Did Not load', 'error', 'SimpleEditor');
                 return false;
             }
             var init = false;
             try {
-                if (this._getDoc() && this._getDoc().body && (this._getDoc().body._rteLoaded === true)) {
-                    init = true;
+                if (this._getDoc() && this._getDoc().body) {
+                    if (this.browser.ie) {
+                        if (this._getDoc().body.readyState == 'complete') {
+                            init = true;
+                        }
+                    } else {
+                        if (this._getDoc().body._rteLoaded === true) {
+                            init = true;
+                        }
+                    }
                 }
             } catch (e) {
                 init = false;
@@ -2789,9 +2897,23 @@
             if (this.browser.ie || this.browser.webkit || this.browser.opera || (navigator.userAgent.indexOf('Firefox/1.5') != -1)) {
                 //Firefox 1.5 doesn't like setting designMode on an document created with a data url
                 try {
-                    this._getDoc().open();
-                    this._getDoc().write(html);
-                    this._getDoc().close();
+                    //Adobe AIR Code
+                    if (this.browser.air) {
+                        var doc = this._getDoc().implementation.createHTMLDocument();
+                        var origDoc = this._getDoc();
+                        origDoc.open();
+                        origDoc.close();
+                        doc.open();
+                        doc.write(html);
+                        doc.close();
+                        var node = origDoc.importNode(doc.getElementsByTagName("html")[0], true);
+                        origDoc.replaceChild(node, origDoc.getElementsByTagName("html")[0]);
+                        origDoc.body._rteLoaded = true;
+                    } else {               
+                        this._getDoc().open();
+                        this._getDoc().write(html);
+                        this._getDoc().close();
+                    }
                 } catch (e) {
                     YAHOO.log('Setting doc failed.. (_setInitialContent)', 'error', 'SimpleEditor');
                     //Safari will only be here if we are hidden
@@ -2843,7 +2965,7 @@
         * @private
         * @method _getSelectedElement
         * @description This method will attempt to locate the element that was last interacted with, either via selection, location or event.
-        * @returns {HTMLElement} The currently selected element.
+        * @return {HTMLElement} The currently selected element.
         */
         _getSelectedElement: function() {
             var doc = this._getDoc(),
@@ -2911,7 +3033,7 @@
                 } catch (e) {
                     YAHOO.log('Firefox 1.5 errors here: ' + e, 'error', 'SimpleEditor');
                 }
-            } else if (this.currentElement && this.currentElement[0]) {
+            } else if ((this.currentElement && this.currentElement[0]) && (!this.browser.ie)) {
                 elm = this.currentElement[0];
             }
             if (this.browser.opera || this.browser.webkit) {
@@ -2943,7 +3065,7 @@
         * @method _getDomPath
         * @description This method will attempt to build the DOM path from the currently selected element.
         * @param HTMLElement el The element to start with, if not provided _getSelectedElement is used
-        * @returns {Array} An array of node references that will create the DOM Path.
+        * @return {Array} An array of node references that will create the DOM Path.
         */
         _getDomPath: function(el) {
             if (!el) {
@@ -3082,7 +3204,7 @@
         * @description Method is called at the beginning of all event handlers to check if this element or a parent element has the class yui-noedit (this.CLASS_NOEDIT) applied.
         * If it does, then this method will stop the event and return true. The event handlers will then return false and stop the nodeChange from occuring. This method will also
         * disable and enable the Editor's toolbar based on the noedit state.
-        * @returns Boolean
+        * @return Boolean
         */
         _isNonEditable: function(ev) {
             if (this.get('allowNoEdit')) {
@@ -3497,7 +3619,10 @@
             switch (ev.keyCode) {
                 case 84: //Focus Toolbar Header -- Ctrl + Shift + T
                     if (ev.shiftKey && ev.ctrlKey) {
-                        this.toolbar._titlebar.firstChild.focus();
+                        var h = this.toolbar.getElementsByTagName('h2')[0];
+                        if (h) {
+                            h.focus();
+                        }
                         Event.stopEvent(ev);
                         doExec = false;
                     }
@@ -3787,6 +3912,13 @@
         * @description Creates the accessibility h2 header and places it after the iframe in the Dom for navigation.
         */
         _setupAfterElement: function() {
+            if (!this.beforeElement) {
+                this.beforeElement = document.createElement('h2');
+                this.beforeElement.className = 'yui-editor-skipheader';
+                this.beforeElement.tabIndex = '-1';
+                this.beforeElement.innerHTML = this.STR_BEFORE_EDITOR;
+                this.get('element_cont').get('firstChild').insertBefore(this.beforeElement, this.toolbar.get('nextSibling'));
+            }
             if (!this.afterElement) {
                 this.afterElement = document.createElement('h2');
                 this.afterElement.className = 'yui-editor-skipheader';
@@ -3804,7 +3936,9 @@
         _disableEditor: function(disabled) {
             if (disabled) {
                 if (!this._mask) {
-                    this._setDesignMode('off');
+                    if (!!this.browser.ie) {
+                        this._setDesignMode('off');
+                    }
                     if (this.toolbar) {
                         this.toolbar.set('disabled', true);
                     }
@@ -3933,7 +4067,7 @@
         browser: function() {
             var br = YAHOO.env.ua;
             //Check for webkit3
-            if (br.webkit > 420) {
+            if (br.webkit >= 420) {
                 br.webkit3 = br.webkit;
             } else {
                 br.webkit3 = 0;
@@ -3946,9 +4080,66 @@
         */
         init: function(p_oElement, p_oAttributes) {
             YAHOO.log('init', 'info', 'SimpleEditor');
+
+            if (!this._defaultToolbar) {
+                this._defaultToolbar = {
+                    collapse: true,
+                    titlebar: 'Text Editing Tools',
+                    draggable: false,
+                    buttons: [
+                        { group: 'fontstyle', label: 'Font Name and Size',
+                            buttons: [
+                                { type: 'select', label: 'Arial', value: 'fontname', disabled: true,
+                                    menu: [
+                                        { text: 'Arial', checked: true },
+                                        { text: 'Arial Black' },
+                                        { text: 'Comic Sans MS' },
+                                        { text: 'Courier New' },
+                                        { text: 'Lucida Console' },
+                                        { text: 'Tahoma' },
+                                        { text: 'Times New Roman' },
+                                        { text: 'Trebuchet MS' },
+                                        { text: 'Verdana' }
+                                    ]
+                                },
+                                { type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true }
+                            ]
+                        },
+                        { type: 'separator' },
+                        { group: 'textstyle', label: 'Font Style',
+                            buttons: [
+                                { type: 'push', label: 'Bold CTRL + SHIFT + B', value: 'bold' },
+                                { type: 'push', label: 'Italic CTRL + SHIFT + I', value: 'italic' },
+                                { type: 'push', label: 'Underline CTRL + SHIFT + U', value: 'underline' },
+                                { type: 'separator' },
+                                { type: 'color', label: 'Font Color', value: 'forecolor', disabled: true },
+                                { type: 'color', label: 'Background Color', value: 'backcolor', disabled: true }
+                                
+                            ]
+                        },
+                        { type: 'separator' },
+                        { group: 'indentlist', label: 'Lists',
+                            buttons: [
+                                { type: 'push', label: 'Create an Unordered List', value: 'insertunorderedlist' },
+                                { type: 'push', label: 'Create an Ordered List', value: 'insertorderedlist' }
+                            ]
+                        },
+                        { type: 'separator' },
+                        { group: 'insertitem', label: 'Insert Item',
+                            buttons: [
+                                { type: 'push', label: 'HTML Link CTRL + SHIFT + L', value: 'createlink', disabled: true },
+                                { type: 'push', label: 'Insert Image', value: 'insertimage' }
+                            ]
+                        }
+                    ]
+                };
+            }
+
             YAHOO.widget.SimpleEditor.superclass.init.call(this, p_oElement, p_oAttributes);
             YAHOO.widget.EditorInfo._instances[this.get('id')] = this;
 
+
+            this.currentElement = [];
             this.on('contentReady', function() {
                 this.DOMReady = true;
                 this.fireQueue();
@@ -3967,6 +4158,27 @@
             var self = this;
 
             /**
+            * @config container
+            * @description Used when dynamically creating the Editor from Javascript with no default textarea.
+            * We will create one and place it in this container. If no container is passed we will append to document.body.
+            * @default false
+            * @type HTMLElement
+            */
+            this.setAttributeConfig('container', {
+                writeOnce: true,
+                value: attr.container || false
+            });
+            /**
+            * @config plainText
+            * @description Process the inital textarea data as if it was plain text. Accounting for spaces, tabs and line feeds.
+            * @default false
+            * @type Boolean
+            */
+            this.setAttributeConfig('plainText', {
+                writeOnce: true,
+                value: attr.plainText || false
+            });
+            /**
             * @private
             * @config iframe
             * @description Internal config for holding the iframe element.
@@ -3989,6 +4201,17 @@
                 writeOnce: true
             });
             /**
+            * @private
+            * @config container
+            * @description Internal config for holding a reference to the container to append a dynamic editor to.
+            * @default null
+            * @type HTMLElement
+            */
+            this.setAttributeConfig('container', {
+                readOnly: true,
+                value: null
+            });
+            /**
             * @config nodeChangeThreshold
             * @description The number of seconds that need to be in between nodeChange processing
             * @default 3
@@ -4064,6 +4287,32 @@
                 }
             });
             /**
+            * @config autoHeight
+            * @description Remove the scrollbars from the edit area and resize it to fit the content. It will not go any lower than the current config height.
+            * @default false
+            * @type Boolean || Number
+            */
+            this.setAttributeConfig('autoHeight', {
+                value: attr.autoHeight || false,
+                method: function(a) {
+                    if (a) {
+                        if (this.get('iframe')) {
+                            this.get('iframe').get('element').setAttribute('scrolling', 'no');
+                        }
+                        this.on('afterNodeChange', this._handleAutoHeight, this, true);
+                        this.on('editorKeyDown', this._handleAutoHeight, this, true);
+                        this.on('editorKeyPress', this._handleAutoHeight, this, true);
+                    } else {
+                        if (this.get('iframe')) {
+                            this.get('iframe').get('element').setAttribute('scrolling', 'auto');
+                        }
+                        this.unsubscribe('afterNodeChange', this._handleAutoHeight);
+                        this.unsubscribe('editorKeyDown', this._handleAutoHeight);
+                        this.unsubscribe('editorKeyPress', this._handleAutoHeight);
+                    }
+                }
+            });
+            /**
             * @attribute width
             * @description The width of the editor container.
             * @default Best guessed size of the textarea, for best results use CSS to style the width of the textarea or pass it in as an argument
@@ -4174,7 +4423,7 @@
             * @type String
             */            
             this.setAttributeConfig('extracss', {
-                value: attr.css || '',
+                value: attr.extracss || '',
                 writeOnce: true
             });
 
@@ -4187,22 +4436,28 @@
             * @type Boolean
             */            
             this.setAttributeConfig('handleSubmit', {
-                value: false,
-                writeOnce: true,
+                value: attr.handleSubmit || false,
                 method: function(exec) {
-                    if (exec) {
-                        var ta = this.get('element');
-                        if (ta.form) {
-                            var submitForm = function(ev) {
-                                Event.stopEvent(ev);
-                                this.saveHTML();
-                                window.setTimeout(function() {
-                                    YAHOO.util.Event.removeListener(ta.form, 'submit', submitForm);
-                                    ta.form.submit();
-                                }, 200);
-                            };
-                            Event.on(ta.form, 'submit', submitForm, this, true);
+                    if (this.get('element').form) {
+                        if (!this._formButtons) {
+                            this._formButtons = [];
                         }
+                        if (exec) {
+                            Event.on(this.get('element').form, 'submit', this._handleFormSubmit, this, true);
+                            var i = this.get('element').form.getElementsByTagName('input');
+                            for (var s = 0; s < i.length; s++) {
+                                var type = i[s].getAttribute('type');
+                                if (type && (type.toLowerCase() == 'submit')) {
+                                    Event.on(i[s], 'click', this._handleFormButtonClick, this, true);
+                                    this._formButtons[this._formButtons.length] = i[s];
+                                }
+                            }
+                        } else {
+                            Event.unsubscribe(this.get('element').form, 'submit', this._handleFormSubmit);
+                            if (this._formButtons) {
+                                Event.unsubscribe(this._formButtons, 'click', this._handleFormButtonClick);
+                            }
+                        }
                     }
                 }
             });
@@ -4261,7 +4516,7 @@
                         ret = false;
                     }
                     return ret;
-                }               
+                }
             });
             /**
             * @config panel
@@ -4320,7 +4575,6 @@
                         this.dompath.parentNode.removeChild(this.dompath);
                         this.dompath = null;
                     }
-                    this._setupAfterElement();
                 }
             });
             /**
@@ -4362,7 +4616,7 @@
         * @private
         * @method _getBlankImage
         * @description Retrieves the full url of the image to use as the blank image.
-        * @returns {String} The URL to the blank image
+        * @return {String} The URL to the blank image
         */
         _getBlankImage: function() {
             if (!this.DOMReady) {
@@ -4371,16 +4625,24 @@
             }
             var img = '';
             if (!this._blankImageLoaded) {
-                var div = document.createElement('div');
-                div.style.position = 'absolute';
-                div.style.top = '-9999px';
-                div.style.left = '-9999px';
-                div.className = this.CLASS_PREFIX + '-blankimage';
-                document.body.appendChild(div);
-                img = YAHOO.util.Dom.getStyle(div, 'background-image');
-                img = img.replace('url(', '').replace(')', '').replace(/"/g, '');
-                this.set('blankimage', img);
-                this._blankImageLoaded = true;
+                if (YAHOO.widget.EditorInfo.blankImage) {
+                    this.set('blankimage', YAHOO.widget.EditorInfo.blankImage);
+                    this._blankImageLoaded = true;
+                } else {
+                    var div = document.createElement('div');
+                    div.style.position = 'absolute';
+                    div.style.top = '-9999px';
+                    div.style.left = '-9999px';
+                    div.className = this.CLASS_PREFIX + '-blankimage';
+                    document.body.appendChild(div);
+                    img = YAHOO.util.Dom.getStyle(div, 'background-image');
+                    img = img.replace('url(', '').replace(')', '').replace(/"/g, '');
+                    //Adobe AIR Code
+                    img = img.replace('app:/', '');                    
+                    this.set('blankimage', img);
+                    this._blankImageLoaded = true;
+                    YAHOO.widget.EditorInfo.blankImage = img;
+                }
             } else {
                 img = this.get('blankimage');
             }
@@ -4388,6 +4650,82 @@
         },
         /**
         * @private
+        * @method _handleAutoHeight
+        * @description Handles resizing the editor's height based on the content
+        */
+        _handleAutoHeight: function() {
+            var doc = this._getDoc(),
+                body = doc.body,
+                docEl = doc.documentElement;
+
+            var height = parseInt(Dom.getStyle(this.get('editor_wrapper'), 'height'), 10);
+            var newHeight = body.scrollHeight;
+            if (this.browser.webkit) {
+                newHeight = docEl.scrollHeight;
+            }
+            if (newHeight < parseInt(this.get('height'), 10)) {
+                newHeight = parseInt(this.get('height'), 10);
+            }
+            if ((height != newHeight) && (newHeight >= parseInt(this.get('height'), 10))) {   
+                Dom.setStyle(this.get('editor_wrapper'), 'height', newHeight + 'px');
+                if (this.browser.ie) {
+                    //Internet Explorer needs this
+                    this.get('iframe').setStyle('height', '99%');
+                    this.get('iframe').setStyle('zoom', '1');
+                    var self = this;
+                    window.setTimeout(function() {
+                        self.get('iframe').setStyle('height', '100%');
+                    }, 1);
+                }
+            }
+        },
+        _formButtons: null,
+        _formButtonClicked: null,
+        _handleFormButtonClick: function(ev) {
+            var tar = Event.getTarget(ev);
+            this._formButtonClicked = tar;
+        },
+        /**
+        * @private
+        * @method _handleFormSubmit
+        * @description Handles the form submission.
+        * @param {Object} ev The Form Submit Event
+        */
+        _handleFormSubmit: function(ev) {
+            Event.stopEvent(ev);
+            YAHOO.log('Button: ' + this._formButtonClicked.id, 'info', 'SimpleEditor');
+            
+            this.saveHTML();
+            var form = this.get('element').form;
+            var tar = this._formButtonClicked || false;
+            var self = this;
+
+            window.setTimeout(function() {
+                YAHOO.util.Event.removeListener(form, 'submit', self._handleFormSubmit);
+                if (YAHOO.env.ua.ie) {
+                    form.fireEvent("onsubmit");
+                    if (tar && !tar.disabled) {
+                        tar.click();
+                    }
+                } else {  // Gecko, Opera, and Safari
+                    if (tar && !tar.disabled) {
+                        tar.click();
+                    } else {
+                        var oEvent = document.createEvent("HTMLEvents");
+                        oEvent.initEvent("submit", true, true);
+                        form.dispatchEvent(oEvent);
+                        if (YAHOO.env.ua.webkit) {
+                            if (YAHOO.lang.isFunction(form.submit)) {
+                                form.submit();
+                            }
+                        }
+                    }
+                }
+            }, 200);
+            
+        },
+        /**
+        * @private
         * @method _handleFontSize
         * @description Handles the font size button in the toolbar.
         * @param {Object} o Object returned from Toolbar's buttonClick Event
@@ -4456,6 +4794,8 @@
                 family = elm.getAttribute('face');
                 if (Dom.getStyle(elm, 'font-family')) {
                     family = Dom.getStyle(elm, 'font-family');
+                    //Adobe AIR Code
+                    family = family.replace(/'/g, '');                    
                 }
 
                 if (tag.substring(0, 1) == 'h') {
@@ -4511,7 +4851,6 @@
                 this.toolbar.disableButton('indent');
                 this.toolbar.enableButton('outdent');
             }
-            //if (this._isElement(elm, 'ol') || this._isElement(elm, 'ul') || this._isElement(elm, 'li')) {
             if (this._hasParent(elm, 'ol') || this._hasParent(elm, 'ul')) {
                 this.toolbar.disableButton('indent');
             }
@@ -4519,6 +4858,7 @@
             
         },
         _setBusy: function(off) {
+            /*
             if (off) {
                 Dom.removeClass(document.body, 'yui-busy');
                 Dom.removeClass(this._getDoc().body, 'yui-busy');
@@ -4526,6 +4866,7 @@
                 Dom.addClass(document.body, 'yui-busy');
                 Dom.addClass(this._getDoc().body, 'yui-busy');
             }
+            */
         },
         /**
         * @private
@@ -4558,9 +4899,10 @@
                 var str = prompt(this.STR_LINK_URL + ': ', src);
                 if ((str !== '') && (str !== null)) {
                     el.setAttribute('src', str);
-                } else if (str !== null) {
+                } else if (str === null) {
                     el.parentNode.removeChild(el);
                     this.currentElement = [];
+                    this.nodeChange();
                 }
                 this.closeWindow();
                 this.toolbar.set('disabled', false);
@@ -4645,7 +4987,7 @@
         },
         /**
         * @method render
-        * @description Causes the toolbar and the editor to render and replace the textarea.
+        * @description Calls the private method _render in a setTimeout to allow for other things on the page to continue to load.
         */
         render: function() {
             if (this._rendered) {
@@ -4656,10 +4998,20 @@
                 this._queue[this._queue.length] = ['render', arguments];
                 return false;
             }
-            this._setBusy();
             this._rendered = true;
             var self = this;
-
+            window.setTimeout(function() {
+                self._render.call(self);
+            }, 4);
+        },
+        /**
+        * @private
+        * @method _render
+        * @description Causes the toolbar and the editor to render and replace the textarea.
+        */
+        _render: function() {
+            this._setBusy();
+            var self = this;
             this.set('textarea', this.get('element'));
 
             this.get('element_cont').setStyle('display', 'none');
@@ -4708,6 +5060,7 @@
             
             this.toolbar.on('colorPickerClicked', function(o) {
                 this._handleColorPicker(o);
+                return false; //Stop the buttonClick event
             }, this, true);
 
             this.toolbar.on('alignClick', function(o) {
@@ -4731,18 +5084,9 @@
             
 
             //Replace Textarea with editable area
-            
             this.get('parentNode').replaceChild(this.get('element_cont').get('element'), this.get('element'));
 
             
-            if (!this.beforeElement) {
-                this.beforeElement = document.createElement('h2');
-                this.beforeElement.className = 'yui-editor-skipheader';
-                this.beforeElement.tabIndex = '-1';
-                this.beforeElement.innerHTML = this.STR_BEFORE_EDITOR;
-                this.get('element_cont').get('firstChild').insertBefore(this.beforeElement, this.toolbar.get('nextSibling'));
-            }
-
             this.setStyle('visibility', 'hidden');
             this.setStyle('position', 'absolute');
             this.setStyle('top', '-9999px');
@@ -4761,9 +5105,9 @@
             this.get('iframe').setStyle('width', '100%'); //WIDTH
             this.get('iframe').setStyle('height', '100%');
 
-            if (this.browser.ie == 7) {
-            }
-
+            window.setTimeout(function() {
+                self._setupAfterElement.call(self);
+            }, 0);
             this.fireEvent('afterRender', { type: 'afterRender', target: this });
         },
         /**
@@ -5058,9 +5402,13 @@
                 exec = false;
             } else {
                 el = this._getSelectedElement();
-                if (this._isElement(el, 'li') && this._isElement(el.parentNode, tag) || (this.browser.ie && this._isElement(this._getRange().parentElement, 'li'))) { //we are in a list..
+                YAHOO.log(el.tagName);
+                if (this._isElement(el, 'li') && this._isElement(el.parentNode, tag) || (this.browser.ie && this._isElement(this._getRange().parentElement, 'li')) || (this.browser.ie && this._isElement(el, 'ul')) || (this.browser.ie && this._isElement(el, 'ol'))) { //we are in a list..
                     YAHOO.log('We already have a list, undo it', 'info', 'SimpleEditor');
                     if (this.browser.ie) {
+                        if ((this.browser.ie && this._isElement(el, 'ul')) || (this.browser.ie && this._isElement(el, 'ol'))) {
+                            el = el.getElementsByTagName('li')[0];
+                        }
                         YAHOO.log('Undo IE', 'info', 'SimpleEditor');
                         str = '';
                         var lis2 = el.parentNode.getElementsByTagName('li');
@@ -5093,7 +5441,15 @@
                     if (this._getRange().html) {
                         html = '<li>' + this._getRange().html+ '</li>';
                     } else {
-                        html = '<li>' + this._getRange().text + '</li>';
+                        var t = this._getRange().text.split('\n');
+                        if (t.length > 1) {
+                            html = '';
+                            for (var ie = 0; ie < t.length; ie++) {
+                                html += '<li>' + t[ie] + '</li>';
+                            }
+                        } else {
+                            html = '<li>' + this._getRange().text + '</li>';
+                        }
                     }
 
                     this._getRange().pasteHTML('<' + tag + '>' + html + '</' + tag + '>');
@@ -5140,7 +5496,7 @@
         * @description This is an execCommand override method. It is called from execCommand when the execCommand('fontsize') is used.
         */
         cmd_fontsize: function(value) {
-            if ((this.currentElement.length > 0) && (!this._hasSelection())) {
+            if (this.currentElement && (this.currentElement.length > 0) && (!this._hasSelection())) {
                 YAHOO.util.Dom.setStyle(this.currentElement, 'fontSize', value);
             } else if (!this._isElement(this._getSelectedElement(), 'body')) {
                 var el = this._getSelectedElement();
@@ -5357,6 +5713,7 @@
         /**
         * @method saveHTML
         * @description Cleans the HTML with the cleanHTML method then places that string back into the textarea.
+        * @return String
         */
         saveHTML: function() {
             var html = this.cleanHTML();
@@ -5378,6 +5735,11 @@
         * @description Gets the unprocessed/unfiltered HTML from the editor
         */
         getEditorHTML: function() {
+            var b = this._getDoc().body;
+            if (b === null) {
+                YAHOO.log('Body is null, returning null.', 'error', 'SimpleEditor');
+                return null;
+            }
             return this._getDoc().body.innerHTML;
         },
         /**
@@ -5429,20 +5791,46 @@
         * @method _cleanIncomingHTML
         * @param {String} html The unfiltered HTML
         * @description Process the HTML with a few regexes to clean it up and stabilize the input
-        * @returns {String} The filtered HTML
+        * @return {String} The filtered HTML
         */
         _cleanIncomingHTML: function(html) {
             html = html.replace(/<strong([^>]*)>/gi, '<b$1>');
             html = html.replace(/<\/strong>/gi, '</b>');   
+
+            //replace embed before em check
+            html = html.replace(/<embed([^>]*)>/gi, '<YUI_EMBED$1>');
+            html = html.replace(/<\/embed>/gi, '</YUI_EMBED>');
+
             html = html.replace(/<em([^>]*)>/gi, '<i$1>');
             html = html.replace(/<\/em>/gi, '</i>');
+            
+            //Put embed tags back in..
+            html = html.replace(/<YUI_EMBED([^>]*)>/gi, '<embed$1>');
+            html = html.replace(/<\/YUI_EMBED>/gi, '</embed>');
+            if (this.get('plainText')) {
+                YAHOO.log('Filtering as plain text', 'info', 'SimpleEditor');
+                html = html.replace(/\n/g, '<br>').replace(/\r/g, '<br>');
+                html = html.replace(/  /gi, '  '); //Replace all double spaces
+                html = html.replace(/\t/gi, '    '); //Replace all tabs
+            }
+            //Removing Script Tags from the Editor
+            html = html.replace(/<script([^>]*)>/gi, '<bad>');
+            html = html.replace(/<\/script([^>]*)>/gi, '</bad>');
+            html = html.replace(/<script([^>]*)>/gi, '<bad>');
+            html = html.replace(/<\/script([^>]*)>/gi, '</bad>');
+            //Replace the line feeds
+            html = html.replace(/\n/g, '<YUI_LF>').replace(/\r/g, '<YUI_LF>');
+            //Remove Bad HTML elements (used to be script nodes)
+            html = html.replace(new RegExp('<bad([^>]*)>(.*?)<\/bad>', 'gi'), '');
+            //Replace the lines feeds
+            html = html.replace(/<YUI_LF>/g, '\n');
             return html;
         },
         /**
         * @method cleanHTML
         * @param {String} html The unfiltered HTML
         * @description Process the HTML with a few regexes to clean it up and stabilize the output
-        * @returns {String} The filtered HTML
+        * @return {String} The filtered HTML
         */
         cleanHTML: function(html) {
             //Start Filtering Output
@@ -5465,9 +5853,12 @@
 		    html = html.replace(/<blockquote([^>]*)>/gi, '<YUI_BQ$1>');
 		    html = html.replace(/<\/blockquote>/gi, '<\/YUI_BQ>');
 
+		    html = html.replace(/<embed([^>]*)>/gi, '<YUI_EMBED$1>');
+		    html = html.replace(/<\/embed>/gi, '<\/YUI_EMBED>');
+
             //Convert b and i tags to strong and em tags
             if ((markup == 'semantic') || (markup == 'xhtml')) {
-                html = html.replace(/<i([^>]*)>/gi, '<em$1>');
+                html = html.replace(/<i(\s+[^>]*)?>/gi, '<em$1>');
                 html = html.replace(/<\/i>/gi, '</em>');
                 html = html.replace(/<b([^>]*)>/gi, '<strong$1>');
                 html = html.replace(/<\/b>/gi, '</strong>');
@@ -5481,6 +5872,10 @@
             if ((markup == 'semantic') || (markup == 'xhtml') || (markup == 'css')) {
                 html = html.replace(new RegExp('<font([^>]*)face="([^>]*)">(.*?)<\/font>', 'gi'), '<span $1 style="font-family: $2;">$3</span>');
                 html = html.replace(/<u/gi, '<span style="text-decoration: underline;"');
+                if (this.browser.webkit) {
+                    html = html.replace(new RegExp('<span class="Apple-style-span" style="font-weight: bold;">([^>]*)<\/span>', 'gi'), '<strong>$1</strong>');
+                    html = html.replace(new RegExp('<span class="Apple-style-span" style="font-style: italic;">([^>]*)<\/span>', 'gi'), '<em>$1</em>');
+                }
                 html = html.replace(/\/u>/gi, '/span>');
                 if (markup == 'css') {
                     html = html.replace(/<em([^>]*)>/gi, '<i$1>');
@@ -5511,8 +5906,8 @@
             html = this.post_filter_linebreaks(html, markup);
 
             if (markup == 'xhtml') {
-		        html = html.replace(/<YUI_IMG([^>]*)>/g, '<img $1/>');
-		        html = html.replace(/<YUI_INPUT([^>]*)>/g, '<input $1/>');
+		        html = html.replace(/<YUI_IMG([^>]*)>/g, '<img $1 />');
+		        html = html.replace(/<YUI_INPUT([^>]*)>/g, '<input $1 />');
             } else {
 		        html = html.replace(/<YUI_IMG([^>]*)>/g, '<img $1>');
 		        html = html.replace(/<YUI_INPUT([^>]*)>/g, '<input $1>');
@@ -5525,6 +5920,9 @@
 		    html = html.replace(/<YUI_BQ([^>]*)>/g, '<blockquote$1>');
 		    html = html.replace(/<\/YUI_BQ>/g, '<\/blockquote>');
 
+		    html = html.replace(/<YUI_EMBED([^>]*)>/g, '<embed$1>');
+		    html = html.replace(/<\/YUI_EMBED>/g, '<\/embed>');
+
             //Trim the output, removing whitespace from the beginning and end
             html = YAHOO.lang.trim(html);
 
@@ -5536,13 +5934,12 @@
             //First empty span
             if (html.substring(0, 6).toLowerCase() == '<span>')  {
                 html = html.substring(6);
+                //Last empty span
+                if (html.substring(html.length - 7, html.length).toLowerCase() == '</span>')  {
+                    html = html.substring(0, html.length - 7);
+                }
             }
-            //Last empty span
-            if (html.substring(html.length - 7, html.length).toLowerCase() == '</span>')  {
-                html = html.substring(0, html.length - 7);
-            }
 
-
             for (var v in this.invalidHTML) {
                 if (YAHOO.lang.hasOwnProperty(this.invalidHTML, v)) {
                     if (Lang.isObject(v) && v.keepContents) {
@@ -5561,7 +5958,6 @@
         * @method filter_invalid_lists
         * @param String html The HTML string to filter
         * @description Filters invalid ol and ul list markup, converts this: <li></li><ol>..</ol> to this: <li></li><li><ol>..</ol></li>
-        * @returns String
         */
         filter_invalid_lists: function(html) {
             html = html.replace(/<\/li>\n/gi, '</li>');
@@ -5584,10 +5980,12 @@
         * @method filter_safari
         * @param String html The HTML string to filter
         * @description Filters strings specific to Safari
-        * @returns String
+        * @return String
         */
         filter_safari: function(html) {
             if (this.browser.webkit) {
+                //<span class="Apple-tab-span" style="white-space:pre">	</span>
+                html = html.replace(/<span class="Apple-tab-span" style="white-space:pre">([^>])<\/span>/gi, '    ');
                 html = html.replace(/Apple-style-span/gi, '');
                 html = html.replace(/style="line-height: normal;"/gi, '');
                 //Remove bogus LI's
@@ -5604,7 +6002,7 @@
         * @method filter_internals
         * @param String html The HTML string to filter
         * @description Filters internal RTE strings and bogus attrs we don't want
-        * @returns String
+        * @return String
         */
         filter_internals: function(html) {
 		    html = html.replace(/\r/g, '');
@@ -5638,7 +6036,7 @@
         * @method filter_all_rgb
         * @param String str The HTML string to filter
         * @description Converts all RGB color strings found in passed string to a hex color, example: style="color: rgb(0, 255, 0)" converts to style="color: #00ff00"
-        * @returns String
+        * @return String
         */
         filter_all_rgb: function(str) {
             var exp = new RegExp("rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)", "gi");
@@ -5656,7 +6054,7 @@
         * @method filter_rgb
         * @param String css The CSS string containing rgb(#,#,#);
         * @description Converts an RGB color string to a hex color, example: rgb(0, 255, 0) converts to #00ff00
-        * @returns String
+        * @return String
         */
         filter_rgb: function(css) {
             if (css.toLowerCase().indexOf('rgb') != -1) {
@@ -5682,7 +6080,7 @@
         * @param String html The HTML to filter
         * @param String markup The markup type to filter to
         * @description HTML Pre Filter
-        * @returns String
+        * @return String
         */
         pre_filter_linebreaks: function(html, markup) {
             if (this.browser.webkit) {
@@ -5708,11 +6106,11 @@
         * @param String html The HTML to filter
         * @param String markup The markup type to filter to
         * @description HTML Pre Filter
-        * @returns String
+        * @return String
         */
         post_filter_linebreaks: function(html, markup) {
             if (markup == 'xhtml') {
-		        html = html.replace(/<YUI_BR>/g, '<br/>');
+		        html = html.replace(/<YUI_BR>/g, '<br />');
             } else {
 		        html = html.replace(/<YUI_BR>/g, '<br>');
             }
@@ -5775,6 +6173,7 @@
             var textArea = this.get('element');
             this.get('element_cont').get('parentNode').replaceChild(textArea, this.get('element_cont').get('element'));
             this.get('element_cont').get('element').innerHTML = '';
+            this.set('handleSubmit', false); //Remove the submit handler
             //Brutal Object Destroy
             for (var i in this) {
                 if (Lang.hasOwnProperty(this, i)) {
@@ -5889,6 +6288,13 @@
         _instances: {},
         /**
         * @private
+        * @property blankImage
+        * @description A reference to the blankImage url
+        * @type String 
+        */
+        blankImage: '',
+        /**
+        * @private
         * @property window
         * @description A reference to the currently open window object in any editor on the page.
         * @type Object <a href="YAHOO.widget.EditorWindow.html">YAHOO.widget.EditorWindow</a>
@@ -5905,7 +6311,7 @@
         * @method getEditorById
         * @description Returns a reference to the Editor object associated with the given textarea
         * @param {String/HTMLElement} id The id or reference of the textarea to return the Editor instance of
-        * @returns Object <a href="YAHOO.widget.Editor.html">YAHOO.widget.Editor</a>
+        * @return Object <a href="YAHOO.widget.Editor.html">YAHOO.widget.Editor</a>
         */
         getEditorById: function(id) {
             if (!YAHOO.lang.isString(id)) {
@@ -5935,4 +6341,4 @@
 
     
 })();
-YAHOO.register("simpleeditor", YAHOO.widget.SimpleEditor, {version: "2.4.1", build: "742"});
+YAHOO.register("simpleeditor", YAHOO.widget.SimpleEditor, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/editor/simpleeditor-beta-min.js
===================================================================
--- trunk/root/static/yui/editor/simpleeditor-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/editor/simpleeditor-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,20 +1,21 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-(function(){var B=YAHOO.util.Dom,A=YAHOO.util.Event,C=YAHOO.lang;if(YAHOO.widget.Button){YAHOO.widget.ToolbarButtonAdvanced=YAHOO.widget.Button;YAHOO.widget.ToolbarButtonAdvanced.prototype.buttonType="rich";YAHOO.widget.ToolbarButtonAdvanced.prototype.checkValue=function(F){var E=this.getMenu().getItems();if(E.length===0){this.getMenu()._onBeforeShow();E=this.getMenu().getItems();}for(var D=0;D<E.length;D++){E[D].cfg.setProperty("checked",false);if(E[D].value==F){E[D].cfg.setProperty("checked",true);}}};}else{YAHOO.widget.ToolbarButtonAdvanced=function(){};}YAHOO.widget.ToolbarButton=function(E,D){if(C.isObject(arguments[0])&&!B.get(E).nodeType){D=E;}var G=(D||{});var F={element:null,attributes:G};if(!F.attributes.type){F.attributes.type="push";}F.element=document.createElement("span");F.element.setAttribute("unselectable","on");F.element.className="yui-button yui-"+F.attributes.type+"-button";F.element.innerHTML="<span class=\"first-child\"><a href=\"#\">LABEL</a></span>";!
 F.attributes.id=B.generateId();YAHOO.widget.ToolbarButton.superclass.constructor.call(this,F.element,F.attributes);};YAHOO.extend(YAHOO.widget.ToolbarButton,YAHOO.util.Element,{buttonType:"normal",_handleMouseOver:function(){if(!this.get("disabled")){this.addClass("yui-button-hover");this.addClass("yui-"+this.get("type")+"-button-hover");}},_handleMouseOut:function(){this.removeClass("yui-button-hover");this.removeClass("yui-"+this.get("type")+"-button-hover");},checkValue:function(F){if(this.get("type")=="menu"){var E=this._button.options;for(var D=0;D<E.length;D++){if(E[D].value==F){E.selectedIndex=D;}}}},init:function(E,D){YAHOO.widget.ToolbarButton.superclass.init.call(this,E,D);this.on("mouseover",this._handleMouseOver,this,true);this.on("mouseout",this._handleMouseOut,this,true);},initAttributes:function(D){YAHOO.widget.ToolbarButton.superclass.initAttributes.call(this,D);this.setAttributeConfig("value",{value:D.value});this.setAttributeConfig("menu",{value:D.menu||fa!
 lse});this.setAttributeConfig("type",{value:D.type,writeOnce:t!
 rue,meth
od:function(H){var G,F;if(!this._button){this._button=this.get("element").getElementsByTagName("a")[0];}switch(H){case"select":case"menu":G=document.createElement("select");var I=this.get("menu");for(var E=0;E<I.length;E++){F=document.createElement("option");F.innerHTML=I[E].text;F.value=I[E].value;if(I[E].checked){F.selected=true;}G.appendChild(F);}this._button.parentNode.replaceChild(G,this._button);A.on(G,"change",this._handleSelect,this,true);this._button=G;break;}}});this.setAttributeConfig("disabled",{value:D.disabled||false,method:function(E){if(E){this.addClass("yui-button-disabled");this.addClass("yui-"+this.get("type")+"-button-disabled");}else{this.removeClass("yui-button-disabled");this.removeClass("yui-"+this.get("type")+"-button-disabled");}if(this.get("type")=="menu"){this._button.disabled=E;}}});this.setAttributeConfig("label",{value:D.label,method:function(E){if(!this._button){this._button=this.get("element").getElementsByTagName("a")[0];}if(this.get("type")!
 =="push"){this._button.innerHTML=E;}}});this.setAttributeConfig("title",{value:D.title});this.setAttributeConfig("container",{value:null,writeOnce:true,method:function(E){this.appendTo(E);}});},_handleSelect:function(E){var D=A.getTarget(E);var F=D.options[D.selectedIndex].value;this.fireEvent("change",{type:"change",value:F});},getMenu:function(){return this.get("menu");},fireEvent:function(E,D){if(this.DOM_EVENTS[E]&&this.get("disabled")){return ;}YAHOO.widget.ToolbarButton.superclass.fireEvent.call(this,E,D);},toString:function(){return"ToolbarButton ("+this.get("id")+")";}});})();(function(){var B=YAHOO.util.Dom,A=YAHOO.util.Event,D=YAHOO.lang;YAHOO.widget.Toolbar=function(G,F){if(D.isObject(arguments[0])&&!B.get(G).nodeType){F=G;}var I=(F||{});var H={element:null,attributes:I};if(D.isString(G)&&B.get(G)){H.element=B.get(G);}else{if(D.isObject(G)&&B.get(G)&&B.get(G).nodeType){H.element=B.get(G);}}if(!H.element){H.element=document.createElement("DIV");H.element.id=B.gene!
 rateId();if(I.container&&B.get(I.container)){B.get(I.container!
 ).append
Child(H.element);}}if(!H.element.id){H.element.id=((D.isString(G))?G:B.generateId());}var E=document.createElement("DIV");H.attributes.cont=E;B.addClass(E,"yui-toolbar-subcont");H.element.appendChild(E);H.attributes.element=H.element;H.attributes.id=H.element.id;YAHOO.widget.Toolbar.superclass.constructor.call(this,H.element,H.attributes);};function C(H,E,I){B.addClass(this.element,"yui-toolbar-"+I.get("value")+"-menu");if(B.hasClass(I._button.parentNode.parentNode,"yui-toolbar-select")){B.addClass(this.element,"yui-toolbar-select-menu");}var F=this.getItems();for(var G=0;G<F.length;G++){B.addClass(F[G].element,"yui-toolbar-"+I.get("value")+"-"+((F[G].value)?F[G].value.replace(/ /g,"-").toLowerCase():F[G]._oText.nodeValue.replace(/ /g,"-").toLowerCase()));B.addClass(F[G].element,"yui-toolbar-"+I.get("value")+"-"+((F[G].value)?F[G].value.replace(/ /g,"-"):F[G]._oText.nodeValue.replace(/ /g,"-")));}}YAHOO.extend(YAHOO.widget.Toolbar,YAHOO.util.Element,{buttonType:YAHOO.widget.!
 ToolbarButton,dd:null,_colorData:{"#111111":"Obsidian","#2D2D2D":"Dark Gray","#434343":"Shale","#5B5B5B":"Flint","#737373":"Gray","#8B8B8B":"Concrete","#A2A2A2":"Gray","#B9B9B9":"Titanium","#000000":"Black","#D0D0D0":"Light Gray","#E6E6E6":"Silver","#FFFFFF":"White","#BFBF00":"Pumpkin","#FFFF00":"Yellow","#FFFF40":"Banana","#FFFF80":"Pale Yellow","#FFFFBF":"Butter","#525330":"Raw Siena","#898A49":"Mildew","#AEA945":"Olive","#7F7F00":"Paprika","#C3BE71":"Earth","#E0DCAA":"Khaki","#FCFAE1":"Cream","#60BF00":"Cactus","#80FF00":"Chartreuse","#A0FF40":"Green","#C0FF80":"Pale Lime","#DFFFBF":"Light Mint","#3B5738":"Green","#668F5A":"Lime Gray","#7F9757":"Yellow","#407F00":"Clover","#8A9B55":"Pistachio","#B7C296":"Light Jade","#E6EBD5":"Breakwater","#00BF00":"Spring Frost","#00FF80":"Pastel Green","#40FFA0":"Light Emerald","#80FFC0":"Sea Foam","#BFFFDF":"Sea Mist","#033D21":"Dark Forrest","#438059":"Moss","#7FA37C":"Medium Green","#007F40":"Pine","#8DAE94":"Yellow Gray Green","#AC!
 C6B5":"Aqua Lung","#DDEBE2":"Sea Vapor","#00BFBF":"Fog","#00FF!
 FF":"Cya
n","#40FFFF":"Turquoise Blue","#80FFFF":"Light Aqua","#BFFFFF":"Pale Cyan","#033D3D":"Dark Teal","#347D7E":"Gray Turquoise","#609A9F":"Green Blue","#007F7F":"Seaweed","#96BDC4":"Green Gray","#B5D1D7":"Soapstone","#E2F1F4":"Light Turquoise","#0060BF":"Summer Sky","#0080FF":"Sky Blue","#40A0FF":"Electric Blue","#80C0FF":"Light Azure","#BFDFFF":"Ice Blue","#1B2C48":"Navy","#385376":"Biscay","#57708F":"Dusty Blue","#00407F":"Sea Blue","#7792AC":"Sky Blue Gray","#A8BED1":"Morning Sky","#DEEBF6":"Vapor","#0000BF":"Deep Blue","#0000FF":"Blue","#4040FF":"Cerulean Blue","#8080FF":"Evening Blue","#BFBFFF":"Light Blue","#212143":"Deep Indigo","#373E68":"Sea Blue","#444F75":"Night Blue","#00007F":"Indigo Blue","#585E82":"Dockside","#8687A4":"Blue Gray","#D2D1E1":"Light Blue Gray","#6000BF":"Neon Violet","#8000FF":"Blue Violet","#A040FF":"Violet Purple","#C080FF":"Violet Dusk","#DFBFFF":"Pale Lavender","#302449":"Cool Shale","#54466F":"Dark Indigo","#655A7F":"Dark Violet","#40007F":"Viol!
 et","#726284":"Smoky Violet","#9E8FA9":"Slate Gray","#DCD1DF":"Violet White","#BF00BF":"Royal Violet","#FF00FF":"Fuchsia","#FF40FF":"Magenta","#FF80FF":"Orchid","#FFBFFF":"Pale Magenta","#4A234A":"Dark Purple","#794A72":"Medium Purple","#936386":"Cool Granite","#7F007F":"Purple","#9D7292":"Purple Moon","#C0A0B6":"Pale Purple","#ECDAE5":"Pink Cloud","#BF005F":"Hot Pink","#FF007F":"Deep Pink","#FF409F":"Grape","#FF80BF":"Electric Pink","#FFBFDF":"Pink","#451528":"Purple Red","#823857":"Purple Dino","#A94A76":"Purple Gray","#7F003F":"Rose","#BC6F95":"Antique Mauve","#D8A5BB":"Cool Marble","#F7DDE9":"Pink Granite","#C00000":"Apple","#FF0000":"Fire Truck","#FF4040":"Pale Red","#FF8080":"Salmon","#FFC0C0":"Warm Pink","#441415":"Sepia","#82393C":"Rust","#AA4D4E":"Brick","#800000":"Brick Red","#BC6E6E":"Mauve","#D8A3A4":"Shrimp Pink","#F8DDDD":"Shell Pink","#BF5F00":"Dark Orange","#FF7F00":"Orange","#FF9F40":"Grapefruit","#FFBF80":"Canteloupe","#FFDFBF":"Wax","#482C1B":"Dark Brick"!
 ,"#855A40":"Dirt","#B27C51":"Tan","#7F3F00":"Nutmeg","#C49B71"!
 :"Mustar
d","#E1C4A8":"Pale Tan","#FDEEE0":"Marble"},_colorPicker:null,STR_COLLAPSE:"Collapse Toolbar",STR_SPIN_LABEL:"Spin Button with value {VALUE}. Use Control Shift Up Arrow and Control Shift Down arrow keys to increase or decrease the value.",STR_SPIN_UP:"Click to increase the value of this input",STR_SPIN_DOWN:"Click to decrease the value of this input",_titlebar:null,browser:YAHOO.env.ua,_buttonList:null,_buttonGroupList:null,_sep:null,_sepCount:null,_dragHandle:null,_toolbarConfigs:{renderer:true},CLASS_CONTAINER:"yui-toolbar-container",CLASS_DRAGHANDLE:"yui-toolbar-draghandle",CLASS_SEPARATOR:"yui-toolbar-separator",CLASS_DISABLED:"yui-toolbar-disabled",CLASS_PREFIX:"yui-toolbar",init:function(F,E){YAHOO.widget.Toolbar.superclass.init.call(this,F,E);
-},initAttributes:function(E){YAHOO.widget.Toolbar.superclass.initAttributes.call(this,E);this.addClass(this.CLASS_CONTAINER);this.setAttributeConfig("buttonType",{value:E.buttonType||"basic",writeOnce:true,validator:function(F){switch(F){case"advanced":case"basic":return true;}return false;},method:function(F){if(F=="advanced"){if(YAHOO.widget.Button){this.buttonType=YAHOO.widget.ToolbarButtonAdvanced;}else{this.buttonType=YAHOO.widget.ToolbarButton;}}else{this.buttonType=YAHOO.widget.ToolbarButton;}}});this.setAttributeConfig("buttons",{value:[],writeOnce:true,method:function(G){for(var F in G){if(D.hasOwnProperty(G,F)){if(G[F].type=="separator"){this.addSeparator();}else{if(G[F].group!==undefined){this.addButtonGroup(G[F]);}else{this.addButton(G[F]);}}}}}});this.setAttributeConfig("disabled",{value:false,method:function(F){if(this.get("disabled")===F){return false;}if(F){this.addClass(this.CLASS_DISABLED);this.set("draggable",false);this.disableAllButtons();}else{this.rem!
 oveClass(this.CLASS_DISABLED);if(this._configs.draggable._initialConfig.value){this.set("draggable",true);}this.resetAllButtons();}}});this.setAttributeConfig("cont",{value:E.cont,readOnly:true});this.setAttributeConfig("grouplabels",{value:E.grouplabels||true,method:function(F){if(F){B.removeClass(this.get("cont"),(this.CLASS_PREFIX+"-nogrouplabels"));}else{B.addClass(this.get("cont"),(this.CLASS_PREFIX+"-nogrouplabels"));}}});this.setAttributeConfig("titlebar",{value:false,method:function(G){if(G){if(this._titlebar&&this._titlebar.parentNode){this._titlebar.parentNode.removeChild(this._titlebar);}this._titlebar=document.createElement("DIV");B.addClass(this._titlebar,this.CLASS_PREFIX+"-titlebar");if(D.isString(G)){var F=document.createElement("h2");F.tabIndex="-1";F.innerHTML=G;this._titlebar.appendChild(F);}if(this.get("firstChild")){this.insertBefore(this._titlebar,this.get("firstChild"));}else{this.appendChild(this._titlebar);}if(this.get("collapse")){this.set("collaps!
 e",true);}}else{if(this._titlebar){if(this._titlebar&&this._ti!
 tlebar.p
arentNode){this._titlebar.parentNode.removeChild(this._titlebar);}}}}});this.setAttributeConfig("collapse",{value:false,method:function(H){var G=null;var F=B.getElementsByClassName("collapse","span",this._titlebar);if(H){if(F.length>0){return true;}G=document.createElement("SPAN");G.innerHTML="X";G.title=this.STR_COLLAPSE;B.addClass(G,"collapse");this._titlebar.appendChild(G);A.addListener(G,"click",function(){if(B.hasClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed")){this.collapse(false);}else{this.collapse();}},this,true);}else{G=B.getElementsByClassName("collapse","span",this._titlebar);if(G[0]){if(B.hasClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed")){this.collapse(false);}G[0].parentNode.removeChild(G[0]);}}}});this.setAttributeConfig("draggable",{value:(E.draggable||false),method:function(F){if(F&&!this.get("titlebar")){if(!this._dragHandle){this._dragHandle=document.createElement("SPAN");this._dragHandle.innerHTML="|";this._dragH!
 andle.setAttribute("title","Click to drag the toolbar");this._dragHandle.id=this.get("id")+"_draghandle";B.addClass(this._dragHandle,this.CLASS_DRAGHANDLE);if(this.get("cont").hasChildNodes()){this.get("cont").insertBefore(this._dragHandle,this.get("cont").firstChild);}else{this.get("cont").appendChild(this._dragHandle);}this.dd=new YAHOO.util.DD(this.get("id"));this.dd.setHandleElId(this._dragHandle.id);}}else{if(this._dragHandle){this._dragHandle.parentNode.removeChild(this._dragHandle);this._dragHandle=null;this.dd=null;}}if(this._titlebar){if(F){this.dd=new YAHOO.util.DD(this.get("id"));this.dd.setHandleElId(this._titlebar);B.addClass(this._titlebar,"draggable");}else{B.removeClass(this._titlebar,"draggable");if(this.dd){this.dd.unreg();this.dd=null;}}}},validator:function(G){var F=true;if(!YAHOO.util.DD){F=false;}return F;}});},addButtonGroup:function(I){if(!this.get("element")){this._queue[this._queue.length]=["addButtonGroup",arguments];return false;}if(!this.hasClas!
 s(this.CLASS_PREFIX+"-grouped")){this.addClass(this.CLASS_PREF!
 IX+"-gro
uped");}var J=document.createElement("DIV");B.addClass(J,this.CLASS_PREFIX+"-group");B.addClass(J,this.CLASS_PREFIX+"-group-"+I.group);if(I.label){var F=document.createElement("h3");F.innerHTML=I.label;J.appendChild(F);}if(!this.get("grouplabels")){B.addClass(this.get("cont"),this.CLASS_PREFIX,"-nogrouplabels");}this.get("cont").appendChild(J);var H=document.createElement("ul");J.appendChild(H);if(!this._buttonGroupList){this._buttonGroupList={};}this._buttonGroupList[I.group]=H;for(var G=0;G<I.buttons.length;G++){var E=document.createElement("li");E.className=this.CLASS_PREFIX+"-groupitem";H.appendChild(E);if((I.buttons[G].type!==undefined)&&I.buttons[G].type=="separator"){this.addSeparator(E);}else{I.buttons[G].container=E;this.addButton(I.buttons[G]);}}},addButtonToGroup:function(G,H,I){var F=this._buttonGroupList[H];var E=document.createElement("li");E.className=this.CLASS_PREFIX+"-groupitem";G.container=E;this.addButton(G,I);F.appendChild(E);},addButton:function(J,I){if!
 (!this.get("element")){this._queue[this._queue.length]=["addButton",arguments];return false;}if(!this._buttonList){this._buttonList=[];}if(!J.container){J.container=this.get("cont");}if((J.type=="menu")||(J.type=="split")||(J.type=="select")){if(D.isArray(J.menu)){for(var P in J.menu){if(D.hasOwnProperty(J.menu,P)){var V={fn:function(Y,W,X){if(!J.menucmd){J.menucmd=J.value;}J.value=((X.value)?X.value:X._oText.nodeValue);},scope:this};J.menu[P].onclick=V;}}}}var Q={},N=false;for(var L in J){if(D.hasOwnProperty(J,L)){if(!this._toolbarConfigs[L]){Q[L]=J[L];}}}if(J.type=="select"){Q.type="menu";}if(J.type=="spin"){Q.type="push";}if(Q.type=="color"){if(YAHOO.widget.Overlay){Q=this._makeColorButton(Q);}else{N=true;}}if(Q.menu){if((YAHOO.widget.Overlay)&&(J.menu instanceof YAHOO.widget.Overlay)){J.menu.showEvent.subscribe(function(){this._button=Q;});}else{for(var O=0;O<Q.menu.length;O++){if(!Q.menu[O].value){Q.menu[O].value=Q.menu[O].text;
-}}if(this.browser.webkit){Q.focusmenu=false;}}}if(N){J=false;}else{this._configs.buttons.value[this._configs.buttons.value.length]=J;var T=new this.buttonType(Q);if(!T.buttonType){T.buttonType="rich";T.checkValue=function(Y){var X=this.getMenu().getItems();if(X.length===0){this.getMenu()._onBeforeShow();X=this.getMenu().getItems();}for(var W=0;W<X.length;W++){X[W].cfg.setProperty("checked",false);if(X[W].value==Y){X[W].cfg.setProperty("checked",true);}}};}if(this.get("disabled")){T.set("disabled",true);}if(!J.id){J.id=T.get("id");}if(I){var F=T.get("element");var M=null;if(I.get){M=I.get("element").nextSibling;}else{if(I.nextSibling){M=I.nextSibling;}}if(M){M.parentNode.insertBefore(F,M);}}T.addClass(this.CLASS_PREFIX+"-"+T.get("value"));var S=document.createElement("span");S.className=this.CLASS_PREFIX+"-icon";T.get("element").insertBefore(S,T.get("firstChild"));if(T._button.tagName.toLowerCase()=="button"){T.get("element").setAttribute("unselectable","on");var U=document.!
 createElement("a");U.innerHTML=T._button.innerHTML;U.href="#";A.on(U,"click",function(W){A.stopEvent(W);});T._button.parentNode.replaceChild(U,T._button);T._button=U;}if(J.type=="select"){if(T._button.tagName.toLowerCase()=="select"){S.parentNode.removeChild(S);var G=T._button;var R=T.get("element");R.parentNode.replaceChild(G,R);}else{T.addClass(this.CLASS_PREFIX+"-select");}}if(J.type=="spin"){if(!D.isArray(J.range)){J.range=[10,100];}this._makeSpinButton(T,J);}T.get("element").setAttribute("title",T.get("label"));if(J.type!="spin"){if((YAHOO.widget.Overlay)&&(Q.menu instanceof YAHOO.widget.Overlay)){var H=function(Y){var W=true;if(Y.keyCode&&(Y.keyCode==9)){W=false;}if(W){this._colorPicker._button=J.value;var X=T.getMenu().element;if(B.getStyle(X,"visibility")=="hidden"){T.getMenu().show();}else{T.getMenu().hide();}}YAHOO.util.Event.stopEvent(Y);};T.on("mousedown",H,J,this);T.on("keydown",H,J,this);}else{if((J.type!="menu")&&(J.type!="select")){T.on("keypress",this._butt!
 onClick,J,this);T.on("mousedown",function(W){YAHOO.util.Event.!
 stopEven
t(W);this._buttonClick(W,J);},J,this);T.on("click",function(W){YAHOO.util.Event.stopEvent(W);});}else{T.on("mousedown",function(W){YAHOO.util.Event.stopEvent(W);});T.on("click",function(W){YAHOO.util.Event.stopEvent(W);});T.on("change",function(W){if(!J.menucmd){J.menucmd=J.value;}J.value=W.value;this._buttonClick(W,J);},this,true);var K=this;if(T.getMenu().mouseDownEvent){T.getMenu().mouseDownEvent.subscribe(function(Y,X){var W=X[1];YAHOO.util.Event.stopEvent(X[0]);T._onMenuClick(X[0],T);if(!J.menucmd){J.menucmd=J.value;}J.value=((W.value)?W.value:W._oText.nodeValue);K._buttonClick.call(K,X[1],J);T._hideMenu();return false;});T.getMenu().clickEvent.subscribe(function(X,W){YAHOO.util.Event.stopEvent(W[0]);});T.getMenu().mouseUpEvent.subscribe(function(X,W){YAHOO.util.Event.stopEvent(W[0]);});}}}}else{T.on("mousedown",function(W){YAHOO.util.Event.stopEvent(W);});T.on("click",function(W){YAHOO.util.Event.stopEvent(W);});}if(this.browser.ie){T.DOM_EVENTS.focusin=true;T.DOM_EVEN!
 TS.focusout=true;T.on("focusin",function(W){YAHOO.util.Event.stopEvent(W);},J,this);T.on("focusout",function(W){YAHOO.util.Event.stopEvent(W);},J,this);T.on("click",function(W){YAHOO.util.Event.stopEvent(W);},J,this);}if(this.browser.webkit){T.hasFocus=function(){return true;};}this._buttonList[this._buttonList.length]=T;if((J.type=="menu")||(J.type=="split")||(J.type=="select")){if(D.isArray(J.menu)){var E=T.getMenu();if(E.renderEvent){E.renderEvent.subscribe(C,T);if(J.renderer){E.renderEvent.subscribe(J.renderer,T);}}}}}return J;},addSeparator:function(E,H){if(!this.get("element")){this._queue[this._queue.length]=["addSeparator",arguments];return false;}var F=((E)?E:this.get("cont"));if(!this.get("element")){this._queue[this._queue.length]=["addSeparator",arguments];return false;}if(this._sepCount===null){this._sepCount=0;}if(!this._sep){this._sep=document.createElement("SPAN");B.addClass(this._sep,this.CLASS_SEPARATOR);this._sep.innerHTML="|";}var G=this._sep.cloneNode(t!
 rue);this._sepCount++;B.addClass(G,this.CLASS_SEPARATOR+"-"+th!
 is._sepC
ount);if(H){var I=null;if(H.get){I=H.get("element").nextSibling;}else{if(H.nextSibling){I=H.nextSibling;}else{I=H;}}if(I){if(I==H){I.parentNode.appendChild(G);}else{I.parentNode.insertBefore(G,I);}}}else{F.appendChild(G);}return G;},_createColorPicker:function(J){if(B.get(J+"_colors")){B.get(J+"_colors").parentNode.removeChild(B.get(J+"_colors"));}var F=document.createElement("div");F.className="yui-toolbar-colors";F.id=J+"_colors";F.style.display="none";A.on(window,"load",function(){document.body.appendChild(F);},this,true);this._colorPicker=F;var I="";for(var H in this._colorData){if(D.hasOwnProperty(this._colorData,H)){I+="<a style=\"background-color: "+H+"\" href=\"#\">"+H.replace("#","")+"</a>";}}I+="<span><em>X</em><strong></strong></span>";F.innerHTML=I;var G=F.getElementsByTagName("em")[0];var E=F.getElementsByTagName("strong")[0];A.on(F,"mouseover",function(L){var K=A.getTarget(L);if(K.tagName.toLowerCase()=="a"){G.style.backgroundColor=K.style.backgroundColor;E.inn!
 erHTML=this._colorData["#"+K.innerHTML]+"<br>"+K.innerHTML;}},this,true);A.on(F,"focus",function(K){A.stopEvent(K);});A.on(F,"click",function(K){A.stopEvent(K);});A.on(F,"mousedown",function(L){A.stopEvent(L);var K=A.getTarget(L);if(K.tagName.toLowerCase()=="a"){this.fireEvent("colorPickerClicked",{type:"colorPickerClicked",target:this,button:this._colorPicker._button,color:K.innerHTML,colorName:this._colorData["#"+K.innerHTML]});this.getButtonByValue(this._colorPicker._button).getMenu().hide();}},this,true);},_resetColorPicker:function(){var F=this._colorPicker.getElementsByTagName("em")[0];var E=this._colorPicker.getElementsByTagName("strong")[0];F.style.backgroundColor="transparent";E.innerHTML="";},_makeColorButton:function(E){if(!this._colorPicker){this._createColorPicker(this.get("id"));}E.type="color";E.menu=new YAHOO.widget.Overlay(this.get("id")+"_"+E.value+"_menu",{visible:false,position:"absolute",iframe:true});
-E.menu.setBody("");E.menu.render(this.get("cont"));B.addClass(E.menu.element,"yui-button-menu");B.addClass(E.menu.element,"yui-color-button-menu");E.menu.beforeShowEvent.subscribe(function(){E.menu.cfg.setProperty("zindex",5);E.menu.cfg.setProperty("context",[this.getButtonById(E.id).get("element"),"tl","bl"]);this._resetColorPicker();var F=this._colorPicker;if(F.parentNode){F.parentNode.removeChild(F);}E.menu.setBody("");E.menu.appendToBody(F);this._colorPicker.style.display="block";},this,true);return E;},_makeSpinButton:function(R,L){R.addClass(this.CLASS_PREFIX+"-spinbutton");var S=this,N=R._button.parentNode.parentNode,I=L.range,H=document.createElement("a"),G=document.createElement("a");H.href="#";G.href="#";H.className="up";H.title=this.STR_SPIN_UP;H.innerHTML=this.STR_SPIN_UP;G.className="down";G.title=this.STR_SPIN_DOWN;G.innerHTML=this.STR_SPIN_DOWN;N.appendChild(H);N.appendChild(G);var M=YAHOO.lang.substitute(this.STR_SPIN_LABEL,{VALUE:R.get("label")});R.set("tit!
 le",M);var Q=function(T){T=((T<I[0])?I[0]:T);T=((T>I[1])?I[1]:T);return T;};var P=this.browser;var F=false;var K=this.STR_SPIN_LABEL;if(this._titlebar&&this._titlebar.firstChild){F=this._titlebar.firstChild;}var E=function(U){YAHOO.util.Event.stopEvent(U);if(!R.get("disabled")&&(U.keyCode!=9)){var V=parseInt(R.get("label"),10);V++;V=Q(V);R.set("label",""+V);var T=YAHOO.lang.substitute(K,{VALUE:R.get("label")});R.set("title",T);if(!P.webkit&&F){}S._buttonClick(U,L);}};var O=function(U){YAHOO.util.Event.stopEvent(U);if(!R.get("disabled")&&(U.keyCode!=9)){var V=parseInt(R.get("label"),10);V--;V=Q(V);R.set("label",""+V);var T=YAHOO.lang.substitute(K,{VALUE:R.get("label")});R.set("title",T);if(!P.webkit&&F){}S._buttonClick(U,L);}};var J=function(T){if(T.keyCode==38){E(T);}else{if(T.keyCode==40){O(T);}else{if(T.keyCode==107&&T.shiftKey){E(T);}else{if(T.keyCode==109&&T.shiftKey){O(T);}}}}};R.on("keydown",J,this,true);A.on(H,"mousedown",function(T){A.stopEvent(T);},this,true);A.on(!
 G,"mousedown",function(T){A.stopEvent(T);},this,true);A.on(H,"!
 click",E
,this,true);A.on(G,"click",O,this,true);},_buttonClick:function(L,F){var E=true;if(L&&L.type=="keypress"){if(L.keyCode==9){E=false;}else{if((L.keyCode===13)||(L.keyCode===0)||(L.keyCode===32)){}else{E=false;}}}if(E){var N=true,H=false;if(F.value){H=this.fireEvent(F.value+"Click",{type:F.value+"Click",target:this.get("element"),button:F});if(H===false){N=false;}}if(F.menucmd&&N){H=this.fireEvent(F.menucmd+"Click",{type:F.menucmd+"Click",target:this.get("element"),button:F});if(H===false){N=false;}}if(N){this.fireEvent("buttonClick",{type:"buttonClick",target:this.get("element"),button:F});}if(F.type=="select"){var K=this.getButtonById(F.id);if(K.buttonType=="rich"){var J=F.value;for(var I=0;I<F.menu.length;I++){if(F.menu[I].value==F.value){J=F.menu[I].text;break;}}K.set("label","<span class=\"yui-toolbar-"+F.menucmd+"-"+(F.value).replace(/ /g,"-").toLowerCase()+"\">"+J+"</span>");var M=K.getMenu().getItems();for(var G=0;G<M.length;G++){if(M[G].value.toLowerCase()==F.value.toL!
 owerCase()){M[G].cfg.setProperty("checked",true);}else{M[G].cfg.setProperty("checked",false);}}}}}if(L){A.stopEvent(L);}},getButtonById:function(G){var E=this._buttonList.length;for(var F=0;F<E;F++){if(this._buttonList[F].get("id")==G){return this._buttonList[F];}}return false;},getButtonByValue:function(K){var H=this.get("buttons");var F=H.length;for(var I=0;I<F;I++){if(H[I].group!==undefined){for(var E=0;E<H[I].buttons.length;E++){if((H[I].buttons[E].value==K)||(H[I].buttons[E].menucmd==K)){return this.getButtonById(H[I].buttons[E].id);}if(H[I].buttons[E].menu){for(var J=0;J<H[I].buttons[E].menu.length;J++){if(H[I].buttons[E].menu[J].value==K){return this.getButtonById(H[I].buttons[E].id);}}}}}else{if((H[I].value==K)||(H[I].menucmd==K)){return this.getButtonById(H[I].id);}if(H[I].menu){for(var G=0;G<H[I].menu.length;G++){if(H[I].menu[G].value==K){return this.getButtonById(H[I].id);}}}}}return false;},getButtonByIndex:function(E){if(this._buttonList[E]){return this._button!
 List[E];}else{return false;}},getButtons:function(){return thi!
 s._butto
nList;},disableButton:function(F){var E=F;if(D.isString(F)){E=this.getButtonById(F);}if(D.isNumber(F)){E=this.getButtonByIndex(F);}if((!(E instanceof YAHOO.widget.ToolbarButton))&&(!(E instanceof YAHOO.widget.ToolbarButtonAdvanced))){E=this.getButtonByValue(F);}if((E instanceof YAHOO.widget.ToolbarButton)||(E instanceof YAHOO.widget.ToolbarButtonAdvanced)){E.set("disabled",true);}else{return false;}},enableButton:function(F){if(this.get("disabled")){return false;}var E=F;if(D.isString(F)){E=this.getButtonById(F);}if(D.isNumber(F)){E=this.getButtonByIndex(F);}if((!(E instanceof YAHOO.widget.ToolbarButton))&&(!(E instanceof YAHOO.widget.ToolbarButtonAdvanced))){E=this.getButtonByValue(F);}if((E instanceof YAHOO.widget.ToolbarButton)||(E instanceof YAHOO.widget.ToolbarButtonAdvanced)){if(E.get("disabled")){E.set("disabled",false);}}else{return false;}},selectButton:function(I,G){var F=I;if(I){if(D.isString(I)){F=this.getButtonById(I);}if(D.isNumber(I)){F=this.getButtonByIndex(I!
 );}if((!(F instanceof YAHOO.widget.ToolbarButton))&&(!(F instanceof YAHOO.widget.ToolbarButtonAdvanced))){F=this.getButtonByValue(I);}if((F instanceof YAHOO.widget.ToolbarButton)||(F instanceof YAHOO.widget.ToolbarButtonAdvanced)){F.addClass("yui-button-selected");F.addClass("yui-button-"+F.get("value")+"-selected");if(G){if(F.buttonType=="rich"){var H=F.getMenu().getItems();for(var E=0;E<H.length;E++){if(H[E].value==G){H[E].cfg.setProperty("checked",true);F.set("label","<span class=\"yui-toolbar-"+F.get("value")+"-"+(G).replace(/ /g,"-").toLowerCase()+"\">"+H[E]._oText.nodeValue+"</span>");}else{H[E].cfg.setProperty("checked",false);}}}}}else{return false;}}},deselectButton:function(F){var E=F;if(D.isString(F)){E=this.getButtonById(F);}if(D.isNumber(F)){E=this.getButtonByIndex(F);}if((!(E instanceof YAHOO.widget.ToolbarButton))&&(!(E instanceof YAHOO.widget.ToolbarButtonAdvanced))){E=this.getButtonByValue(F);
-}if((E instanceof YAHOO.widget.ToolbarButton)||(E instanceof YAHOO.widget.ToolbarButtonAdvanced)){E.removeClass("yui-button-selected");E.removeClass("yui-button-"+E.get("value")+"-selected");E.removeClass("yui-button-hover");}else{return false;}},deselectAllButtons:function(){var E=this._buttonList.length;for(var F=0;F<E;F++){this.deselectButton(this._buttonList[F]);}},disableAllButtons:function(){if(this.get("disabled")){return false;}var E=this._buttonList.length;for(var F=0;F<E;F++){this.disableButton(this._buttonList[F]);}},enableAllButtons:function(){if(this.get("disabled")){return false;}var E=this._buttonList.length;for(var F=0;F<E;F++){this.enableButton(this._buttonList[F]);}},resetAllButtons:function(I){if(!D.isObject(I)){I={};}if(this.get("disabled")){return false;}var E=this._buttonList.length;for(var F=0;F<E;F++){var H=this._buttonList[F];var G=H._configs.disabled._initialConfig.value;if(I[H.get("id")]){this.enableButton(H);this.selectButton(H);}else{if(G){this.!
 disableButton(H);}else{this.enableButton(H);}this.deselectButton(H);}}},destroyButton:function(I){var G=I;if(D.isString(I)){G=this.getButtonById(I);}if(D.isNumber(I)){G=this.getButtonByIndex(I);}if((!(G instanceof YAHOO.widget.ToolbarButton))&&(!(G instanceof YAHOO.widget.ToolbarButtonAdvanced))){G=this.getButtonByValue(I);}if((G instanceof YAHOO.widget.ToolbarButton)||(G instanceof YAHOO.widget.ToolbarButtonAdvanced)){var H=G.get("id");G.destroy();var E=this._buttonList.length;for(var F=0;F<E;F++){if(this._buttonList[F].get("id")==H){this._buttonList[F]=null;}}}else{return false;}},destroy:function(){this.get("element").innerHTML="";this.get("element").className="";for(var E in this){if(D.hasOwnProperty(this,E)){this[E]=null;}}return true;},collapse:function(F){var E=B.getElementsByClassName("collapse","span",this._titlebar);if(F===false){B.removeClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed");if(E[0]){B.removeClass(E[0],"collapsed");}this.fireEvent("t!
 oolbarExpanded",{type:"toolbarExpanded",target:this});}else{if!
 (E[0]){B
.addClass(E[0],"collapsed");}B.addClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed");this.fireEvent("toolbarCollapsed",{type:"toolbarCollapsed",target:this});}},toString:function(){return"Toolbar (#"+this.get("element").id+") with "+this._buttonList.length+" buttons.";}});})();(function(){var C=YAHOO.util.Dom,A=YAHOO.util.Event,D=YAHOO.lang,B=YAHOO.widget.Toolbar;YAHOO.widget.SimpleEditor=function(H,F){var J={element:null,attributes:(F||{})},L=null;if(D.isString(H)){L=H;}else{L=H.id;}J.element=H;var G=document.createElement("DIV");J.attributes.element_cont=new YAHOO.util.Element(G,{id:L+"_container"});var K=document.createElement("div");C.addClass(K,"first-child");J.attributes.element_cont.appendChild(K);if(!J.attributes.toolbar_cont){J.attributes.toolbar_cont=document.createElement("DIV");J.attributes.toolbar_cont.id=L+"_toolbar";K.appendChild(J.attributes.toolbar_cont);}var I=document.createElement("DIV");K.appendChild(I);J.attributes.editor_wrapper=I;YAH!
 OO.widget.SimpleEditor.superclass.constructor.call(this,J.element,J.attributes);};function E(F){return F.replace(/ /g,"-").toLowerCase();}YAHOO.extend(YAHOO.widget.SimpleEditor,YAHOO.util.Element,{_docType:"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">",editorDirty:false,_defaultCSS:"html { height: 95%; } body { height: 100%; padding: 7px; background-color: #fff; font:13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a { color: blue; text-decoration: underline; cursor: pointer; } .warning-localfile { border-bottom: 1px dashed red !important; } .yui-busy { cursor: wait !important; } img.selected { border: 2px dotted #808080; } img { cursor: pointer !important; border: none; }",_defaultToolbar:{collapse:true,titlebar:"Text Editing Tools",draggable:false,buttons:[{group:"fontstyle",label:"Font Name and Size",buttons:[{type:"select",label:"Arial",value:"fontname",disabled:true,menu:[{text:"Arial",checke!
 d:true},{text:"Arial Black"},{text:"Comic Sans MS"},{text:"Cou!
 rier New
"},{text:"Lucida Console"},{text:"Tahoma"},{text:"Times New Roman"},{text:"Trebuchet MS"},{text:"Verdana"}]},{type:"spin",label:"13",value:"fontsize",range:[9,75],disabled:true}]},{type:"separator"},{group:"textstyle",label:"Font Style",buttons:[{type:"push",label:"Bold CTRL + SHIFT + B",value:"bold"},{type:"push",label:"Italic CTRL + SHIFT + I",value:"italic"},{type:"push",label:"Underline CTRL + SHIFT + U",value:"underline"},{type:"separator"},{type:"color",label:"Font Color",value:"forecolor",disabled:true},{type:"color",label:"Background Color",value:"backcolor",disabled:true}]},{type:"separator"},{group:"indentlist",label:"Lists",buttons:[{type:"push",label:"Create an Unordered List",value:"insertunorderedlist"},{type:"push",label:"Create an Ordered List",value:"insertorderedlist"}]},{type:"separator"},{group:"insertitem",label:"Insert Item",buttons:[{type:"push",label:"HTML Link CTRL + SHIFT + L",value:"createlink",disabled:true},{type:"push",label:"Insert Image",value!
 :"insertimage"}]}]},_lastButton:null,_baseHREF:function(){var F=document.location.href;if(F.indexOf("?")!==-1){F=F.substring(0,F.indexOf("?"));}F=F.substring(0,F.lastIndexOf("/"))+"/";return F;}(),_lastImage:null,_blankImageLoaded:false,_fixNodesTimer:null,_nodeChangeTimer:null,_lastNodeChangeEvent:null,_lastNodeChange:0,_rendered:false,DOMReady:null,_selection:null,_mask:null,_showingHiddenElements:null,currentWindow:null,currentEvent:null,operaEvent:null,currentFont:null,currentElement:[],dompath:null,beforeElement:null,afterElement:null,invalidHTML:{form:true,input:true,button:true,select:true,link:true,html:true,body:true,script:true,style:true,textarea:true},toolbar:null,_contentTimer:null,_contentTimerCounter:0,_disabled:["createlink","fontname","fontsize","forecolor","backcolor"],_alwaysDisabled:{},_alwaysEnabled:{},_semantic:{"bold":true,"italic":true,"underline":true},_tag2cmd:{"b":"bold","strong":"bold","i":"italic","em":"italic","u":"underline","sup":"superscript!
 ","sub":"subscript","img":"insertimage","a":"createlink","ul":!
 "insertu
norderedlist","ol":"insertorderedlist"},_createIframe:function(){var J=document.createElement("iframe");
-J.id=this.get("id")+"_editor";var H={border:"0",frameBorder:"0",marginWidth:"0",marginHeight:"0",leftMargin:"0",topMargin:"0",allowTransparency:"true",width:"100%"};for(var I in H){if(D.hasOwnProperty(H,I)){J.setAttribute(I,H[I]);}}var G="javascript:;";if(this.browser.ie){if(window.location.href.toLowerCase().indexOf("https")!==0){G="about:blank";}}J.setAttribute("src",G);var F=new YAHOO.util.Element(J);return F;},_isElement:function(G,F){if(G&&G.tagName&&(G.tagName.toLowerCase()==F)){return true;}if(G&&G.getAttribute&&(G.getAttribute("tag")==F)){return true;}return false;},_hasParent:function(G,F){if(!G||!G.parentNode){return false;}while(G.parentNode){if(this._isElement(G,F)){return G;}if(G.parentNode){G=G.parentNode;}else{return false;}}return false;},_getDoc:function(){var F=false;if(this.get){if(this.get("iframe")){if(this.get("iframe").get){if(this.get("iframe").get("element")){try{if(this.get("iframe").get("element").contentWindow){if(this.get("iframe").get("element"!
 ).contentWindow.document){F=this.get("iframe").get("element").contentWindow.document;return F;}}}catch(G){}}}}}return false;},_getWindow:function(){return this.get("iframe").get("element").contentWindow;},_focusWindow:function(F){if(this.browser.webkit){if(F){this._getSelection().setBaseAndExtent(this._getDoc().body.firstChild,0,this._getDoc().body.firstChild,1);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(false);}}else{this._getSelection().setBaseAndExtent(this._getDoc().body,1,this._getDoc().body,1);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(false);}}this._getWindow().focus();}else{this._getWindow().focus();}},_hasSelection:function(){var H=this._getSelection();var F=this._getRange();var G=false;if(this.browser.ie||this.browser.opera){if(F.text){G=true;}if(F.html){G=true;}}else{if(this.browser.webkit){if(H+""!==""){G=true;}}else{if(H&&(H.toString()!=="")&&(H!==u!
 ndefined)){G=true;}}}return G;},_getSelection:function(){var F!
 =null;if
(this._getDoc()&&this._getWindow()){if(this._getDoc().selection){F=this._getDoc().selection;}else{F=this._getWindow().getSelection();}if(this.browser.webkit){if(F.baseNode){this._selection={};this._selection.baseNode=F.baseNode;this._selection.baseOffset=F.baseOffset;this._selection.extentNode=F.extentNode;this._selection.extentOffset=F.extentOffset;}else{if(this._selection!==null){F=this._getWindow().getSelection();F.setBaseAndExtent(this._selection.baseNode,this._selection.baseOffset,this._selection.extentNode,this._selection.extentOffset);this._selection=null;}}}}return F;},_selectNode:function(G){if(!G){return false;}var H=this._getSelection(),F=null;if(this.browser.ie){try{F=this._getDoc().body.createTextRange();F.moveToElementText(G);F.select();}catch(I){}}else{if(this.browser.webkit){H.setBaseAndExtent(G,0,G,G.innerText.length);}else{if(this.browser.opera){H=this._getWindow().getSelection();F=this._getDoc().createRange();F.selectNode(G);H.removeAllRanges();H.addRange(!
 F);}else{F=this._getDoc().createRange();F.selectNodeContents(G);H.removeAllRanges();H.addRange(F);}}}},_getRange:function(){var F=this._getSelection();if(F===null){return null;}if(this.browser.webkit&&!F.getRangeAt){var H=this._getDoc().createRange();try{H.setStart(F.anchorNode,F.anchorOffset);H.setEnd(F.focusNode,F.focusOffset);}catch(G){H=this._getWindow().getSelection()+"";}return H;}if(this.browser.ie||this.browser.opera){return F.createRange();}if(F.rangeCount>0){return F.getRangeAt(0);}return null;},_setDesignMode:function(F){try{this._getDoc().designMode=F;}catch(G){}},_toggleDesignMode:function(){var G=this._getDoc().designMode.toLowerCase(),F="on";if(G=="on"){F="off";}this._setDesignMode(F);return F;},_initEditor:function(){if(this.browser.ie){this._getDoc().body.style.margin="0";}if(!this.get("disabled")){this._setDesignMode("on");}this.toolbar.on("buttonClick",this._handleToolbarClick,this,true);A.on(this._getDoc(),"mouseup",this._handleMouseUp,this,true);A.on(th!
 is._getDoc(),"mousedown",this._handleMouseDown,this,true);A.on!
 (this._g
etDoc(),"click",this._handleClick,this,true);A.on(this._getDoc(),"dblclick",this._handleDoubleClick,this,true);A.on(this._getDoc(),"keypress",this._handleKeyPress,this,true);A.on(this._getDoc(),"keyup",this._handleKeyUp,this,true);A.on(this._getDoc(),"keydown",this._handleKeyDown,this,true);if(!this.get("disabled")){this.toolbar.set("disabled",false);}this.fireEvent("editorContentLoaded",{type:"editorLoaded",target:this});if(this.get("dompath")){var F=this;setTimeout(function(){F._writeDomPath.call(F);},150);}this.nodeChange(true);this._setBusy(true);},_checkLoaded:function(){this._contentTimerCounter++;if(this._contentTimer){clearTimeout(this._contentTimer);}if(this._contentTimerCounter>250){return false;}var H=false;try{if(this._getDoc()&&this._getDoc().body&&(this._getDoc().body._rteLoaded===true)){H=true;}}catch(G){H=false;}if(H===true){this._initEditor();}else{var F=this;this._contentTimer=setTimeout(function(){F._checkLoaded.call(F);},20);}},_setInitialContent:function!
 (){var G=D.substitute(this.get("html"),{TITLE:this.STR_TITLE,CONTENT:this._cleanIncomingHTML(this.get("element").value),CSS:this.get("css"),HIDDEN_CSS:((this.get("hiddencss"))?this.get("hiddencss"):"/* No Hidden CSS */"),EXTRA_CSS:((this.get("extracss"))?this.get("extracss"):"/* No Extra CSS */")}),F=true;if(document.compatMode!="BackCompat"){G=this._docType+"\n"+G;}else{}if(this.browser.ie||this.browser.webkit||this.browser.opera||(navigator.userAgent.indexOf("Firefox/1.5")!=-1)){try{this._getDoc().open();this._getDoc().write(G);this._getDoc().close();}catch(H){F=false;}}else{this.get("iframe").get("element").src="data:text/html;charset=utf-8,"+encodeURIComponent(G);}if(F){this._checkLoaded();}},_setMarkupType:function(F){switch(this.get("markup")){case"css":this._setEditorStyle(true);break;case"default":this._setEditorStyle(false);break;case"semantic":case"xhtml":if(this._semantic[F]){this._setEditorStyle(false);
-}else{this._setEditorStyle(true);}break;}},_setEditorStyle:function(G){try{this._getDoc().execCommand("useCSS",false,!G);}catch(F){}},_getSelectedElement:function(){var I=this._getDoc(),F=null,G=null,J=null;if(this.browser.ie){this.currentEvent=this._getWindow().event;F=this._getRange();if(F){J=F.item?F.item(0):F.parentElement();if(J==I.body){J=null;}}if((this.currentEvent!==null)&&(this.currentEvent.keyCode===0)){J=A.getTarget(this.currentEvent);}}else{G=this._getSelection();F=this._getRange();if(!G||!F){return null;}if(!this._hasSelection()){if(G.anchorNode&&(G.anchorNode.nodeType==3)){if(G.anchorNode.parentNode){J=G.anchorNode.parentNode;}if(G.anchorNode.nextSibling!=G.focusNode.nextSibling){J=G.anchorNode.nextSibling;}}if(this._isElement(J,"br")){J=null;}if(!J){J=F.commonAncestorContainer;if(!F.collapsed){if(F.startContainer==F.endContainer){if(F.startOffset-F.endOffset<2){if(F.startContainer.hasChildNodes()){J=F.startContainer.childNodes[F.startOffset];}}}}}}}if(this.c!
 urrentEvent!==null){try{switch(this.currentEvent.type){case"click":case"mousedown":case"mouseup":J=A.getTarget(this.currentEvent);break;default:break;}}catch(H){}}else{if(this.currentElement&&this.currentElement[0]){J=this.currentElement[0];}}if(this.browser.opera||this.browser.webkit){if(this.currentEvent&&!J){J=YAHOO.util.Event.getTarget(this.currentEvent);}}if(!J||!J.tagName){J=I.body;}if(this._isElement(J,"html")){J=I.body;}if(this._isElement(J,"body")){J=I.body;}if(J&&!J.parentNode){J=I.body;}if(J===undefined){J=null;}return J;},_getDomPath:function(F){if(!F){F=this._getSelectedElement();}var G=[];while(F!==null){if(F.ownerDocument!=this._getDoc()){F=null;break;}if(F.nodeName&&F.nodeType&&(F.nodeType==1)){G[G.length]=F;}if(this._isElement(F,"body")){break;}F=F.parentNode;}if(G.length===0){if(this._getDoc()&&this._getDoc().body){G[0]=this._getDoc().body;}}return G.reverse();},_writeDomPath:function(){var L=this._getDomPath(),J=[],H="",M="";for(var F=0;F<L.length;F++){va!
 r N=L[F].tagName.toLowerCase();if((N=="ol")&&(L[F].type)){N+="!
 :"+L[F].
type;}if(C.hasClass(L[F],"yui-tag")){N=L[F].getAttribute("tag");}if((this.get("markup")=="semantic")||(this.get("markup")=="xhtml")){switch(N){case"b":N="strong";break;case"i":N="em";break;}}if(!C.hasClass(L[F],"yui-non")){if(C.hasClass(L[F],"yui-tag")){M=N;}else{H=((L[F].className!=="")?"."+L[F].className.replace(/ /g,"."):"");if((H.indexOf("yui")!=-1)||(H.toLowerCase().indexOf("apple-style-span")!=-1)){H="";}M=N+((L[F].id)?"#"+L[F].id:"")+H;}switch(N){case"a":if(L[F].getAttribute("href",2)){M+=":"+L[F].getAttribute("href",2).replace("mailto:","").replace("http://","").replace("https://","");}break;case"img":var G=L[F].height;var K=L[F].width;if(L[F].style.height){G=parseInt(L[F].style.height,10);}if(L[F].style.width){K=parseInt(L[F].style.width,10);}M+="("+G+"x"+K+")";break;}if(M.length>10){M="<span title=\""+M+"\">"+M.substring(0,10)+"...</span>";}else{M="<span title=\""+M+"\">"+M+"</span>";}J[J.length]=M;}}var I=J.join(" "+this.SEP_DOMPATH+" ");if(this.dompath.innerHTML!!
 =I){this.dompath.innerHTML=I;}},_fixNodes:function(){var K=this._getDoc(),I=[];for(var F in this.invalidHTML){if(YAHOO.lang.hasOwnProperty(this.invalidHTML,F)){if(F.toLowerCase()!="span"){var G=K.body.getElementsByTagName(F);if(G.length){for(var H=0;H<G.length;H++){I.push(G[H]);}}}}}for(var J=0;J<I.length;J++){if(I[J].parentNode){if(D.isObject(this.invalidHTML[I[J].tagName.toLowerCase()])&&this.invalidHTML[I[J].tagName.toLowerCase()].keepContents){this._swapEl(I[J],"span",function(M){M.className="yui-non";});}else{I[J].parentNode.removeChild(I[J]);}}}var L=this._getDoc().getElementsByTagName("img");C.addClass(L,"yui-img");},_isNonEditable:function(H){if(this.get("allowNoEdit")){var G=A.getTarget(H);if(this._isElement(G,"html")){G=null;}var J=this._getDomPath(G);for(var F=(J.length-1);F>-1;F--){if(C.hasClass(J[F],this.CLASS_NOEDIT)){try{this._getDoc().execCommand("enableObjectResizing",false,"false");}catch(I){}this.nodeChange();A.stopEvent(H);return true;}}try{this._getDoc(!
 ).execCommand("enableObjectResizing",false,"true");}catch(I){}!
 }return 
false;},_setCurrentEvent:function(F){this.currentEvent=F;},_handleClick:function(G){if(this._isNonEditable(G)){return false;}this._setCurrentEvent(G);if(this.currentWindow){this.closeWindow();}if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}if(this.browser.webkit){var F=A.getTarget(G);if(this._isElement(F,"a")||this._isElement(F.parentNode,"a")){A.stopEvent(G);this.nodeChange();}}else{this.nodeChange();}},_handleMouseUp:function(G){if(this._isNonEditable(G)){return false;}var F=this;if(this.browser.opera){var H=A.getTarget(G);if(this._isElement(H,"img")){this.nodeChange();if(this.operaEvent){clearTimeout(this.operaEvent);this.operaEvent=null;this._handleDoubleClick(G);}else{this.operaEvent=window.setTimeout(function(){F.operaEvent=false;},700);}}}if(this.browser.webkit||this.browser.opera){if(this.browser.webkit){A.stopEvent(G);}}this.nodeChange();this.fi!
 reEvent("editorMouseUp",{type:"editorMouseUp",target:this,ev:G});},_handleMouseDown:function(F){if(this._isNonEditable(F)){return false;}this._setCurrentEvent(F);var G=A.getTarget(F);if(this.browser.webkit&&this._hasSelection()){var H=this._getSelection();if(!this.browser.webkit3){H.collapse(true);}else{H.collapseToStart();}}if(this.browser.webkit&&this._lastImage){C.removeClass(this._lastImage,"selected");this._lastImage=null;}if(this._isElement(G,"img")||this._isElement(G,"a")){if(this.browser.webkit){A.stopEvent(F);if(this._isElement(G,"img")){C.addClass(G,"selected");this._lastImage=G;}}this.nodeChange();}this.fireEvent("editorMouseDown",{type:"editorMouseDown",target:this,ev:F});},_handleDoubleClick:function(F){if(this._isNonEditable(F)){return false;}this._setCurrentEvent(F);var G=A.getTarget(F);if(this._isElement(G,"img")){this.currentElement[0]=G;this.toolbar.fireEvent("insertimageClick",{type:"insertimageClick",target:this.toolbar});
-this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});}else{if(this._hasParent(G,"a")){this.currentElement[0]=this._hasParent(G,"a");this.toolbar.fireEvent("createlinkClick",{type:"createlinkClick",target:this.toolbar});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});}}this.nodeChange();this.editorDirty=false;this.fireEvent("editorDoubleClick",{type:"editorDoubleClick",target:this,ev:F});},_handleKeyUp:function(G){if(this._isNonEditable(G)){return false;}this._setCurrentEvent(G);switch(G.keyCode){case 37:case 38:case 39:case 40:case 46:case 8:case 87:if((G.keyCode==87)&&this.currentWindow&&G.shiftKey&&G.ctrlKey){this.closeWindow();}else{if(!this.browser.ie){if(this._nodeChangeTimer){clearTimeout(this._nodeChangeTimer);}var F=this;this._nodeChangeTimer=setTimeout(function(){F._nodeChangeTimer=null;F.nodeChange.call(F);},100);}else{this.nodeChange();}this.editorDirty=true;}break;}this.fireEvent("editorKeyUp",{type:"editorKeyUp",targ!
 et:this,ev:G});},_handleKeyPress:function(F){if(this.get("allowNoEdit")){if(F&&F.keyCode&&((F.keyCode==46)||F.keyCode==63272)){A.stopEvent(F);}}if(this._isNonEditable(F)){return false;}this._setCurrentEvent(F);if(this.browser.webkit){if(!this.browser.webkit3){if(F.keyCode&&(F.keyCode==122)&&(F.metaKey)){if(this._hasParent(this._getSelectedElement(),"li")){A.stopEvent(F);}}}this._listFix(F);}this.fireEvent("editorKeyPress",{type:"editorKeyPress",target:this,ev:F});},_listFix:function(L){var O=null,J=null,F=false,H=null;if(this.browser.webkit){if(L.keyCode&&(L.keyCode==13)){if(this._hasParent(this._getSelectedElement(),"li")){var I=this._hasParent(this._getSelectedElement(),"li");var N=this._getDoc().createElement("li");N.innerHTML="<span class=\"yui-non\"> </span> ";if(I.nextSibling){I.parentNode.insertBefore(N,I.nextSibling);}else{I.parentNode.appendChild(N);}this.currentElement[0]=N;this._selectNode(N.firstChild);if(!this.browser.webkit3){I.parentNode.style.displ!
 ay="list-item";setTimeout(function(){I.parentNode.style.displa!
 y="block
";},1);}A.stopEvent(L);}}}if(L.keyCode&&((!this.browser.webkit3&&(L.keyCode==25))||((this.browser.webkit3||!this.browser.webkit)&&((L.keyCode==9)&&L.shiftKey)))){O=this._getSelectedElement();if(this._hasParent(O,"li")){O=this._hasParent(O,"li");if(this._hasParent(O,"ul")||this._hasParent(O,"ol")){J=this._hasParent(O,"ul");if(!J){J=this._hasParent(O,"ol");}if(this._isElement(J.previousSibling,"li")){J.removeChild(O);J.parentNode.insertBefore(O,J.nextSibling);if(this.browser.ie){H=this._getDoc().body.createTextRange();H.moveToElementText(O);H.collapse(false);H.select();}if(this.browser.webkit){if(!this.browser.webkit3){J.style.display="list-item";J.parentNode.style.display="list-item";setTimeout(function(){J.style.display="block";J.parentNode.style.display="block";},1);}}A.stopEvent(L);}}}}if(L.keyCode&&((L.keyCode==9)&&(!L.shiftKey))){var G=this._getSelectedElement();if(this._hasParent(G,"li")){F=this._hasParent(G,"li").innerHTML;}if(this.browser.webkit){this._getDoc().execCo!
 mmand("inserttext",false,"\t");}O=this._getSelectedElement();if(this._hasParent(O,"li")){J=this._hasParent(O,"li");var K=this._getDoc().createElement(J.parentNode.tagName.toLowerCase());if(this.browser.webkit){var M=C.getElementsByClassName("Apple-tab-span","span",J);if(M[0]){J.removeChild(M[0]);J.innerHTML=D.trim(J.innerHTML);if(F){J.innerHTML="<span class=\"yui-non\">"+F+"</span> ";}else{J.innerHTML="<span class=\"yui-non\"> </span> ";}}}else{if(F){J.innerHTML=F+" ";}else{J.innerHTML=" ";}}J.parentNode.replaceChild(K,J);K.appendChild(J);if(this.browser.webkit){this._getSelection().setBaseAndExtent(J.firstChild,1,J.firstChild,J.firstChild.innerText.length);if(!this.browser.webkit3){J.parentNode.parentNode.style.display="list-item";setTimeout(function(){J.parentNode.parentNode.style.display="block";},1);}}else{if(this.browser.ie){H=this._getDoc().body.createTextRange();H.moveToElementText(J);H.collapse(false);H.select();}else{this._selectNode(J);}}A!
 .stopEvent(L);}if(this.browser.webkit){A.stopEvent(L);}this.no!
 deChange
();}},_handleKeyDown:function(J){if(this._isNonEditable(J)){return false;}this._setCurrentEvent(J);if(this.currentWindow){this.closeWindow();}if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}var I=false,K=null,H=false;if(J.shiftKey&&J.ctrlKey){I=true;}switch(J.keyCode){case 84:if(J.shiftKey&&J.ctrlKey){this.toolbar._titlebar.firstChild.focus();A.stopEvent(J);I=false;}break;case 27:if(J.shiftKey){this.afterElement.focus();A.stopEvent(J);H=false;}break;case 76:if(this._hasSelection()){if(J.shiftKey&&J.ctrlKey){var G=true;if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("createlink")){G=false;}}if(G){this.execCommand("createlink","");this.toolbar.fireEvent("createlinkClick",{type:"createlinkClick",target:this.toolbar});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});I=false;}}}break;case 65:if(J.metaKey&&this.browser.we!
 bkit){A.stopEvent(J);this._getSelection().setBaseAndExtent(this._getDoc().body,1,this._getDoc().body,this._getDoc().body.innerHTML.length);}break;case 66:K="bold";break;case 73:K="italic";break;case 85:K="underline";break;case 13:if(this.browser.ie){var L=this._getRange();var F=this._getSelectedElement();if(!this._isElement(F,"li")){if(L){L.pasteHTML("<br>");L.collapse(false);L.select();}A.stopEvent(J);}}}if(this.browser.ie){this._listFix(J);}if(I&&K){this.execCommand(K,null);A.stopEvent(J);this.nodeChange();}this.fireEvent("editorKeyDown",{type:"editorKeyDown",target:this,ev:J});},nodeChange:function(G){var H=parseInt(this.get("nodeChangeThreshold"),10);var N=Math.round(new Date().getTime()/1000);if(G===true){this._lastNodeChange=0;}if((this._lastNodeChange+H)<N){var Q=this;if(this._fixNodesTimer===null){this._fixNodesTimer=window.setTimeout(function(){Q._fixNodes.call(Q);Q._fixNodesTimer=null;},0);}}this._lastNodeChange=N;
-if(this.currentEvent){this._lastNodeChangeEvent=this.currentEvent.type;}var Y=this.fireEvent("beforeNodeChange",{type:"beforeNodeChange",target:this});if(Y===false){return false;}if(this.get("dompath")){this._writeDomPath();}if(!this.get("disabled")){if(this.STOP_NODE_CHANGE){this.STOP_NODE_CHANGE=false;return false;}else{var S=this._getSelection(),P=this._getRange(),F=this._getSelectedElement(),L=this.toolbar.getButtonByValue("fontname"),K=this.toolbar.getButtonByValue("fontsize");if(G!==true){this.editorDirty=true;}var M={};if(this._lastButton){M[this._lastButton.id]=true;}if(!this._isElement(F,"body")){if(L){M[L.get("id")]=true;}if(K){M[K.get("id")]=true;}}this.toolbar.resetAllButtons(M);for(var Z=0;Z<this._disabled.length;Z++){var O=this.toolbar.getButtonByValue(this._disabled[Z]);if(O&&O.get){if(this._lastButton&&(O.get("id")===this._lastButton.id)){}else{if(!this._hasSelection()){switch(this._disabled[Z]){case"fontname":case"fontsize":break;default:this.toolbar.disabl!
 eButton(O);}}else{if(!this._alwaysDisabled[this._disabled[Z]]){this.toolbar.enableButton(O);}}if(!this._alwaysEnabled[this._disabled[Z]]){this.toolbar.deselectButton(O);}}}}var R=this._getDomPath();var a=null,V=null;for(var W=0;W<R.length;W++){a=R[W].tagName.toLowerCase();if(R[W].getAttribute("tag")){a=R[W].getAttribute("tag").toLowerCase();}V=this._tag2cmd[a];if(V===undefined){V=[];}if(!D.isArray(V)){V=[V];}if(R[W].style.fontWeight.toLowerCase()=="bold"){V[V.length]="bold";}if(R[W].style.fontStyle.toLowerCase()=="italic"){V[V.length]="italic";}if(R[W].style.textDecoration.toLowerCase()=="underline"){V[V.length]="underline";}if(V.length>0){for(var U=0;U<V.length;U++){this.toolbar.selectButton(V[U]);this.toolbar.enableButton(V[U]);}}switch(R[W].style.textAlign.toLowerCase()){case"left":case"right":case"center":case"justify":var T=R[W].style.textAlign.toLowerCase();if(R[W].style.textAlign.toLowerCase()=="justify"){T="full";}this.toolbar.selectButton("justify"+T);this.toolbar.!
 enableButton("justify"+T);break;}}if(L){var X=L._configs.label!
 ._initia
lConfig.value;L.set("label","<span class=\"yui-toolbar-fontname-"+E(X)+"\">"+X+"</span>");this._updateMenuChecked("fontname",X);}if(K){K.set("label",K._configs.label._initialConfig.value);}var J=this.toolbar.getButtonByValue("heading");if(J){J.set("label",J._configs.label._initialConfig.value);this._updateMenuChecked("heading","none");}var I=this.toolbar.getButtonByValue("insertimage");if(I&&this.currentWindow&&(this.currentWindow.name=="insertimage")){this.toolbar.disableButton(I);}}}this.fireEvent("afterNodeChange",{type:"afterNodeChange",target:this});},_updateMenuChecked:function(F,G,I){if(!I){I=this.toolbar;}var H=I.getButtonByValue(F);H.checkValue(G);},_handleToolbarClick:function(G){var I="";var J="";var H=G.button.value;if(G.button.menucmd){I=H;H=G.button.menucmd;}this._lastButton=G.button;if(this.STOP_EXEC_COMMAND){this.STOP_EXEC_COMMAND=false;return false;}else{this.execCommand(H,I);if(!this.browser.webkit){var F=this;setTimeout(function(){F._focusWindow.call(F);},!
 5);}}A.stopEvent(G);},_setupAfterElement:function(){if(!this.afterElement){this.afterElement=document.createElement("h2");this.afterElement.className="yui-editor-skipheader";this.afterElement.tabIndex="-1";this.afterElement.innerHTML=this.STR_LEAVE_EDITOR;this.get("element_cont").get("firstChild").appendChild(this.afterElement);}},_disableEditor:function(G){if(G){if(!this._mask){this._setDesignMode("off");if(this.toolbar){this.toolbar.set("disabled",true);}this._mask=document.createElement("DIV");C.setStyle(this._mask,"height","100%");C.setStyle(this._mask,"width","100%");C.setStyle(this._mask,"position","absolute");C.setStyle(this._mask,"top","0");C.setStyle(this._mask,"left","0");C.setStyle(this._mask,"opacity",".5");C.addClass(this._mask,"yui-editor-masked");this.get("iframe").get("parentNode").appendChild(this._mask);}}else{if(this._mask){this._mask.parentNode.removeChild(this._mask);this._mask=null;if(this.toolbar){this.toolbar.set("disabled",false);}this._setDesignMod!
 e("on");this._focusWindow();var F=this;window.setTimeout(funct!
 ion(){F.
nodeChange.call(F);},100);}}},EDITOR_PANEL_ID:"yui-editor-panel",SEP_DOMPATH:"<",STR_LEAVE_EDITOR:"You have left the Rich Text Editor.",STR_BEFORE_EDITOR:"This text field can contain stylized text and graphics. To cycle through all formatting options, use the keyboard shortcut Control + Shift + T to place focus on the toolbar and navigate between option heading names. <h4>Common formatting keyboard shortcuts:</h4><ul><li>Control Shift B sets text to bold</li> <li>Control Shift I sets text to italic</li> <li>Control Shift U underlines text</li> <li>Control Shift L adds an HTML link</li> <li>To exit this text editor use the keyboard shortcut Control + Shift + ESC.</li></ul>",STR_TITLE:"Rich Text Area.",STR_IMAGE_HERE:"Image Url Here",STR_LINK_URL:"Link URL",STOP_EXEC_COMMAND:false,STOP_NODE_CHANGE:false,CLASS_NOEDIT:"yui-noedit",CLASS_CONTAINER:"yui-editor-container",CLASS_EDITABLE:"yui-editor-editable",CLASS_EDITABLE_CONT:"yui-editor-editable-container",CLASS_PREFIX:"yui-edit!
 or",browser:function(){var F=YAHOO.env.ua;if(F.webkit>420){F.webkit3=F.webkit;}else{F.webkit3=0;}return F;}(),init:function(G,F){YAHOO.widget.SimpleEditor.superclass.init.call(this,G,F);YAHOO.widget.EditorInfo._instances[this.get("id")]=this;this.on("contentReady",function(){this.DOMReady=true;this.fireQueue();},this,true);},initAttributes:function(F){YAHOO.widget.SimpleEditor.superclass.initAttributes.call(this,F);var G=this;this.setAttributeConfig("iframe",{value:null});this.setAttributeConfig("textarea",{value:null,writeOnce:true});this.setAttributeConfig("nodeChangeThreshold",{value:F.nodeChangeThreshold||3,validator:YAHOO.lang.isNumber});this.setAttributeConfig("allowNoEdit",{value:F.allowNoEdit||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("limitCommands",{value:F.limitCommands||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("element_cont",{value:F.element_cont});this.setAttributeConfig("editor_wrapper",{value:F.editor_wrapper||null,w!
 riteOnce:true});
-this.setAttributeConfig("height",{value:F.height||C.getStyle(G.get("element"),"height"),method:function(H){if(this._rendered){if(this.get("animate")){var I=new YAHOO.util.Anim(this.get("iframe").get("parentNode"),{height:{to:parseInt(H,10)}},0.5);I.animate();}else{C.setStyle(this.get("iframe").get("parentNode"),"height",H);}}}});this.setAttributeConfig("width",{value:F.width||C.getStyle(this.get("element"),"width"),method:function(H){if(this._rendered){if(this.get("animate")){var I=new YAHOO.util.Anim(this.get("element_cont").get("element"),{width:{to:parseInt(H,10)}},0.5);I.animate();}else{this.get("element_cont").setStyle("width",H);}}}});this.setAttributeConfig("blankimage",{value:F.blankimage||this._getBlankImage()});this.setAttributeConfig("css",{value:F.css||this._defaultCSS,writeOnce:true});this.setAttributeConfig("html",{value:F.html||"<html><head><title>{TITLE}</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><base href=\""+this._base!
 HREF+"\"><style>{CSS}</style><style>{HIDDEN_CSS}</style><style>{EXTRA_CSS}</style></head><body onload=\"document.body._rteLoaded = true;\">{CONTENT}</body></html>",writeOnce:true});this.setAttributeConfig("extracss",{value:F.css||"",writeOnce:true});this.setAttributeConfig("handleSubmit",{value:false,writeOnce:true,method:function(H){if(H){var J=this.get("element");if(J.form){var I=function(K){A.stopEvent(K);this.saveHTML();window.setTimeout(function(){YAHOO.util.Event.removeListener(J.form,"submit",I);J.form.submit();},200);};A.on(J.form,"submit",I,this,true);}}}});this.setAttributeConfig("disabled",{value:false,method:function(H){if(this._rendered){this._disableEditor(H);}}});this.setAttributeConfig("toolbar_cont",{value:null,writeOnce:true});this.setAttributeConfig("toolbar",{value:F.toolbar||this._defaultToolbar,writeOnce:true,method:function(H){if(!H.buttonType){H.buttonType=this._defaultToolbar.buttonType;}this._defaultToolbar=H;}});this.setAttributeConfig("animate",{!
 value:((F.animate)?((YAHOO.util.Anim)?true:false):false),valid!
 ator:fun
ction(I){var H=true;if(!YAHOO.util.Anim){H=false;}return H;}});this.setAttributeConfig("panel",{value:null,writeOnce:true,validator:function(I){var H=true;if(!YAHOO.widget.Overlay){H=false;}return H;}});this.setAttributeConfig("focusAtStart",{value:F.focusAtStart||false,writeOnce:true,method:function(){this.on("editorContentLoaded",function(){var H=this;setTimeout(function(){H._focusWindow.call(H,true);H.editorDirty=false;},400);},this,true);}});this.setAttributeConfig("dompath",{value:F.dompath||false,method:function(H){if(H&&!this.dompath){this.dompath=document.createElement("DIV");this.dompath.id=this.get("id")+"_dompath";C.addClass(this.dompath,"dompath");this.get("element_cont").get("firstChild").appendChild(this.dompath);if(this.get("iframe")){this._writeDomPath();}}else{if(!H&&this.dompath){this.dompath.parentNode.removeChild(this.dompath);this.dompath=null;}}this._setupAfterElement();}});this.setAttributeConfig("markup",{value:F.markup||"semantic",validator:function(!
 H){switch(H.toLowerCase()){case"semantic":case"css":case"default":case"xhtml":return true;}return false;}});this.setAttributeConfig("removeLineBreaks",{value:F.removeLineBreaks||false,validator:YAHOO.lang.isBoolean});this.on("afterRender",function(){this._renderPanel();});},_getBlankImage:function(){if(!this.DOMReady){this._queue[this._queue.length]=["_getBlankImage",arguments];return"";}var F="";if(!this._blankImageLoaded){var G=document.createElement("div");G.style.position="absolute";G.style.top="-9999px";G.style.left="-9999px";G.className=this.CLASS_PREFIX+"-blankimage";document.body.appendChild(G);F=YAHOO.util.Dom.getStyle(G,"background-image");F=F.replace("url(","").replace(")","").replace(/"/g,"");this.set("blankimage",F);this._blankImageLoaded=true;}else{F=this.get("blankimage");}return F;},_handleFontSize:function(H){var F=this.toolbar.getButtonById(H.button.id);var G=F.get("label")+"px";this.execCommand("fontsize",G);this.STOP_EXEC_COMMAND=true;},_handleColorPicke!
 r:function(H){var G=H.button;var F="#"+H.color;if((G=="forecol!
 or")||(G
=="backcolor")){this.execCommand(G,F);}},_handleAlign:function(I){var H=null;for(var F=0;F<I.button.menu.length;F++){if(I.button.menu[F].value==I.button.value){H=I.button.menu[F].value;}}var G=this._getSelection();this.execCommand(H,G);this.STOP_EXEC_COMMAND=true;},_handleAfterNodeChange:function(){var R=this._getDomPath(),M=null,I=null,N=null,G=false;var K=this.toolbar.getButtonByValue("fontname");var L=this.toolbar.getButtonByValue("fontsize");var F=this.toolbar.getButtonByValue("heading");for(var H=0;H<R.length;H++){M=R[H];var Q=M.tagName.toLowerCase();if(M.getAttribute("tag")){Q=M.getAttribute("tag");}I=M.getAttribute("face");if(C.getStyle(M,"font-family")){I=C.getStyle(M,"font-family");}if(Q.substring(0,1)=="h"){if(F){for(var J=0;J<F._configs.menu.value.length;J++){if(F._configs.menu.value[J].value.toLowerCase()==Q){F.set("label",F._configs.menu.value[J].text);}}this._updateMenuChecked("heading",Q);}}}if(K){for(var P=0;P<K._configs.menu.value.length;P++){if(I&&K._config!
 s.menu.value[P].text.toLowerCase()==I.toLowerCase()){G=true;I=K._configs.menu.value[P].text;}}if(!G){I=K._configs.label._initialConfig.value;}var O="<span class=\"yui-toolbar-fontname-"+E(I)+"\">"+I+"</span>";if(K.get("label")!=O){K.set("label",O);this._updateMenuChecked("fontname",I);}}if(L){N=parseInt(C.getStyle(M,"fontSize"),10);if((N===null)||isNaN(N)){N=L._configs.label._initialConfig.value;}L.set("label",""+N);}if(!this._isElement(M,"body")&&!this._isElement(M,"img")){this.toolbar.enableButton(K);this.toolbar.enableButton(L);this.toolbar.enableButton("forecolor");this.toolbar.enableButton("backcolor");}if(this._isElement(M,"img")){if(YAHOO.widget.Overlay){this.toolbar.enableButton("createlink");}}if(this._isElement(M,"blockquote")){this.toolbar.selectButton("indent");this.toolbar.disableButton("indent");this.toolbar.enableButton("outdent");}if(this._hasParent(M,"ol")||this._hasParent(M,"ul")){this.toolbar.disableButton("indent");
-}this._lastButton=null;},_setBusy:function(F){if(F){C.removeClass(document.body,"yui-busy");C.removeClass(this._getDoc().body,"yui-busy");}else{C.addClass(document.body,"yui-busy");C.addClass(this._getDoc().body,"yui-busy");}},_handleInsertImageClick:function(){if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("insertimage")){return false;}}this.toolbar.set("disabled",true);this.on("afterExecCommand",function(){var F=this.currentElement[0],H="http://";if(!F){F=this._getSelectedElement();}if(F){if(F.getAttribute("src")){H=F.getAttribute("src",2);if(H.indexOf(this.get("blankimage"))!=-1){H=this.STR_IMAGE_HERE;}}}var G=prompt(this.STR_LINK_URL+": ",H);if((G!=="")&&(G!==null)){F.setAttribute("src",G);}else{if(G!==null){F.parentNode.removeChild(F);this.currentElement=[];}}this.closeWindow();this.toolbar.set("disabled",false);},this,true);},_handleInsertImageWindowClose:function(){this.nodeChange();},_isLocalFile:function(F){if((F!=="")&&((F.indexOf("file:/")!=-1)||!
 (F.indexOf(":\\")!=-1))){return true;}return false;},_handleCreateLinkClick:function(){if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("createlink")){return false;}}this.toolbar.set("disabled",true);this.on("afterExecCommand",function(){var H=this.currentElement[0],G="";if(H){if(H.getAttribute("href",2)!==null){G=H.getAttribute("href",2);}}var J=prompt(this.STR_LINK_URL+": ",G);if((J!=="")&&(J!==null)){var I=J;if((I.indexOf("://")==-1)&&(I.substring(0,1)!="/")&&(I.substring(0,6).toLowerCase()!="mailto")){if((I.indexOf("@")!=-1)&&(I.substring(0,6).toLowerCase()!="mailto")){I="mailto:"+I;}else{if(I.substring(0,1)!="#"){I="http://"+I;}}}H.setAttribute("href",I);}else{if(J!==null){var F=this._getDoc().createElement("span");F.innerHTML=H.innerHTML;C.addClass(F,"yui-non");H.parentNode.replaceChild(F,H);}}this.closeWindow();this.toolbar.set("disabled",false);});},_handleCreateLinkWindowClose:function(){this.nodeChange();this.currentElement=[];},render:function(){if!
 (this._rendered){return false;}if(!this.DOMReady){this._queue[!
 this._qu
eue.length]=["render",arguments];return false;}this._setBusy();this._rendered=true;var F=this;this.set("textarea",this.get("element"));this.get("element_cont").setStyle("display","none");this.get("element_cont").addClass(this.CLASS_CONTAINER);this.set("iframe",this._createIframe());window.setTimeout(function(){F._setInitialContent.call(F);},10);this.get("editor_wrapper").appendChild(this.get("iframe").get("element"));if(this.get("disabled")){this._disableEditor(true);}var G=this.get("toolbar");if(G instanceof B){this.toolbar=G;this.toolbar.set("disabled",true);}else{G.disabled=true;this.toolbar=new B(this.get("toolbar_cont"),G);}this.fireEvent("toolbarLoaded",{type:"toolbarLoaded",target:this.toolbar});this.toolbar.on("toolbarCollapsed",function(){if(this.currentWindow){this.moveWindow();}},this,true);this.toolbar.on("toolbarExpanded",function(){if(this.currentWindow){this.moveWindow();}},this,true);this.toolbar.on("fontsizeClick",function(H){this._handleFontSize(H);},this,t!
 rue);this.toolbar.on("colorPickerClicked",function(H){this._handleColorPicker(H);},this,true);this.toolbar.on("alignClick",function(H){this._handleAlign(H);},this,true);this.on("afterNodeChange",function(){this._handleAfterNodeChange();},this,true);this.toolbar.on("insertimageClick",function(){this._handleInsertImageClick();},this,true);this.on("windowinsertimageClose",function(){this._handleInsertImageWindowClose();},this,true);this.toolbar.on("createlinkClick",function(){this._handleCreateLinkClick();},this,true);this.on("windowcreatelinkClose",function(){this._handleCreateLinkWindowClose();},this,true);this.get("parentNode").replaceChild(this.get("element_cont").get("element"),this.get("element"));if(!this.beforeElement){this.beforeElement=document.createElement("h2");this.beforeElement.className="yui-editor-skipheader";this.beforeElement.tabIndex="-1";this.beforeElement.innerHTML=this.STR_BEFORE_EDITOR;this.get("element_cont").get("firstChild").insertBefore(this.beforeE!
 lement,this.toolbar.get("nextSibling"));}this.setStyle("visibi!
 lity","h
idden");this.setStyle("position","absolute");this.setStyle("top","-9999px");this.setStyle("left","-9999px");this.get("element_cont").appendChild(this.get("element"));this.get("element_cont").setStyle("display","block");C.addClass(this.get("iframe").get("parentNode"),this.CLASS_EDITABLE_CONT);this.get("iframe").addClass(this.CLASS_EDITABLE);this.get("element_cont").setStyle("width",this.get("width"));C.setStyle(this.get("iframe").get("parentNode"),"height",this.get("height"));this.get("iframe").setStyle("width","100%");this.get("iframe").setStyle("height","100%");if(this.browser.ie==7){}this.fireEvent("afterRender",{type:"afterRender",target:this});},execCommand:function(H,G){var K=this.fireEvent("beforeExecCommand",{type:"beforeExecCommand",target:this,args:arguments});if((K===false)||(this.STOP_EXEC_COMMAND)){this.STOP_EXEC_COMMAND=false;return false;}this._setMarkupType(H);if(this.browser.ie){this._getWindow().focus();}var F=true;if(this.get("limitCommands")){if(!this.tool!
 bar.getButtonByValue(H)){F=false;}}this.editorDirty=true;if((typeof this["cmd_"+H.toLowerCase()]=="function")&&F){var J=this["cmd_"+H.toLowerCase()](G);F=J[0];if(J[1]){H=J[1];}if(J[2]){G=J[2];}}if(F){try{this._getDoc().execCommand(H,false,G);}catch(I){}}else{}this.on("afterExecCommand",function(){this.unsubscribeAll("afterExecCommand");this.nodeChange();});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});},cmd_backcolor:function(I){var F=true,G=this._getSelectedElement(),H="backcolor";if(this.browser.gecko||this.browser.opera){this._setEditorStyle(true);H="hilitecolor";}if(!this._isElement(G,"body")){C.setStyle(G,"background-color",I);this._selectNode(G);F=false;}else{this._createCurrentElement("span",{backgroundColor:I});this._selectNode(this.currentElement[0]);F=false;}return[F,H];},cmd_forecolor:function(H){var F=true,G=this._getSelectedElement();if(!this._isElement(G,"body")){C.setStyle(G,"color",H);
-this._selectNode(G);F=false;}else{this._createCurrentElement("span",{color:H});this._selectNode(this.currentElement[0]);F=false;}return[F];},cmd_unlink:function(F){this._swapEl(this.currentElement[0],"span",function(G){G.className="yui-non";});return[false];},cmd_createlink:function(H){var G=this._getSelectedElement(),F=null;if(this._hasParent(G,"a")){this.currentElement[0]=this._hasParent(G,"a");}else{if(!this._isElement(G,"a")){this._createCurrentElement("a");F=this._swapEl(this.currentElement[0],"a");this.currentElement[0]=F;}else{this.currentElement[0]=G;}}return[false];},cmd_insertimage:function(K){var F=true,G=null,J="insertimage",I=this._getSelectedElement();if(K===""){K=this.get("blankimage");}if(this._isElement(I,"img")){this.currentElement[0]=I;F=false;}else{if(this._getDoc().queryCommandEnabled(J)){this._getDoc().execCommand("insertimage",false,K);var L=this._getDoc().getElementsByTagName("img");for(var H=0;H<L.length;H++){if(!YAHOO.util.Dom.hasClass(L[H],"yui-im!
 g")){YAHOO.util.Dom.addClass(L[H],"yui-img");this.currentElement[0]=L[H];}}F=false;}else{if(I==this._getDoc().body){G=this._getDoc().createElement("img");G.setAttribute("src",K);YAHOO.util.Dom.addClass(G,"yui-img");this._getDoc().body.appendChild(G);}else{this._createCurrentElement("img");G=this._getDoc().createElement("img");G.setAttribute("src",K);YAHOO.util.Dom.addClass(G,"yui-img");this.currentElement[0].parentNode.replaceChild(G,this.currentElement[0]);}this.currentElement[0]=G;F=false;}}return[F];},cmd_inserthtml:function(I){var F=true,H="inserthtml",G=null,J=null;if(this.browser.webkit&&!this._getDoc().queryCommandEnabled(H)){this._createCurrentElement("img");G=this._getDoc().createElement("span");G.innerHTML=I;this.currentElement[0].parentNode.replaceChild(G,this.currentElement[0]);F=false;}else{if(this.browser.ie){J=this._getRange();if(J.item){J.item(0).outerHTML=I;}else{J.pasteHTML(I);}F=false;}}return[F];},cmd_list:function(U){var H=true,O=null,R=0,F=null,P="",L=!
 this._getSelectedElement(),I="insertorderedlist";if(U=="ul"){I!
 ="insert
unorderedlist";}if((this.browser.webkit&&!this._getDoc().queryCommandEnabled(I))){if(this._isElement(L,"li")&&this._isElement(L.parentNode,U)){F=L.parentNode;O=this._getDoc().createElement("span");YAHOO.util.Dom.addClass(O,"yui-non");P="";var T=F.getElementsByTagName("li");for(R=0;R<T.length;R++){P+="<div>"+T[R].innerHTML+"</div>";}O.innerHTML=P;this.currentElement[0]=F;this.currentElement[0].parentNode.replaceChild(O,this.currentElement[0]);}else{this._createCurrentElement(U.toLowerCase());O=this._getDoc().createElement(U);for(R=0;R<this.currentElement.length;R++){var Q=this._getDoc().createElement("li");Q.innerHTML=this.currentElement[R].innerHTML+"<span class=\"yui-non\"> </span> ";O.appendChild(Q);if(R>0){this.currentElement[R].parentNode.removeChild(this.currentElement[R]);}}this.currentElement[0].parentNode.replaceChild(O,this.currentElement[0]);this.currentElement[0]=O;var K=this.currentElement[0].firstChild;K=C.getElementsByClassName("yui-non","span",K)[0];!
 this._getSelection().setBaseAndExtent(K,1,K,K.innerText.length);}H=false;}else{F=this._getSelectedElement();if(this._isElement(F,"li")&&this._isElement(F.parentNode,U)||(this.browser.ie&&this._isElement(this._getRange().parentElement,"li"))){if(this.browser.ie){P="";var N=F.parentNode.getElementsByTagName("li");for(var J=0;J<N.length;J++){P+=N[J].innerHTML+"<br>";}var G=this._getDoc().createElement("span");G.innerHTML=P;F.parentNode.parentNode.replaceChild(G,F.parentNode);}else{this.nodeChange();this._getDoc().execCommand(I,"",F.parentNode);this.nodeChange();}H=false;}if(this.browser.opera){var S=this;window.setTimeout(function(){var V=S._getDoc().getElementsByTagName("li");for(var W=0;W<V.length;W++){if(V[W].innerHTML.toLowerCase()=="<br>"){V[W].parentNode.parentNode.removeChild(V[W].parentNode);}}},30);}if(this.browser.ie&&H){var M="";if(this._getRange().html){M="<li>"+this._getRange().html+"</li>";}else{M="<li>"+this._getRange().text+"</li>";}this._getRange().pasteHTML("!
 <"+U+">"+M+"</"+U+">");H=false;}}return H;},cmd_insertorderedl!
 ist:func
tion(F){return[this.cmd_list("ol")];},cmd_insertunorderedlist:function(F){return[this.cmd_list("ul")];},cmd_fontname:function(H){var F=true,G=this._getSelectedElement();this.currentFont=H;if(G&&G.tagName&&!this._hasSelection()){YAHOO.util.Dom.setStyle(G,"font-family",H);F=false;}return[F];},cmd_fontsize:function(G){if((this.currentElement.length>0)&&(!this._hasSelection())){YAHOO.util.Dom.setStyle(this.currentElement,"fontSize",G);}else{if(!this._isElement(this._getSelectedElement(),"body")){var F=this._getSelectedElement();YAHOO.util.Dom.setStyle(F,"fontSize",G);this._selectNode(F);}else{this._createCurrentElement("span",{"fontSize":G});this._selectNode(this.currentElement[0]);}}return[false];},_swapEl:function(G,F,I){var H=this._getDoc().createElement(F);H.innerHTML=G.innerHTML;if(typeof I=="function"){I.call(this,H);}G.parentNode.replaceChild(H,G);return H;},_createCurrentElement:function(H,U){H=((H)?H:"a");var b=null,G=[],I=this._getDoc();if(this.currentFont){if(!U){U={}!
 ;}U.fontFamily=this.currentFont;this.currentFont=null;}this.currentElement=[];var X=function(){var f=null;switch(H){case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":f=I.createElement(H);break;default:f=I.createElement("span");YAHOO.util.Dom.addClass(f,"yui-tag-"+H);YAHOO.util.Dom.addClass(f,"yui-tag");f.setAttribute("tag",H);for(var e in U){if(YAHOO.util.Lang.hasOwnProperty(U,e)){f.style[e]=U[e];}}break;}return f;};if(!this._hasSelection()){if(this._getDoc().queryCommandEnabled("insertimage")){this._getDoc().execCommand("insertimage",false,"yui-tmp-img");var W=this._getDoc().getElementsByTagName("img");for(var Z=0;Z<W.length;Z++){if(W[Z].getAttribute("src",2)=="yui-tmp-img"){G=X();W[Z].parentNode.replaceChild(G,W[Z]);this.currentElement[this.currentElement.length]=G;}}}else{if(this.currentEvent){b=YAHOO.util.Event.getTarget(this.currentEvent);}else{b=this._getDoc().body;}}if(b){G=X();if(this._isElement(b,"body")||this._isElement(b,"html")){if(this._isElement(b,"html"))!
 {b=this._getDoc().body;
-}b.appendChild(G);}else{if(b.nextSibling){b.parentNode.insertBefore(G,b.nextSibling);}else{b.parentNode.appendChild(G);}}this.currentElement[this.currentElement.length]=G;this.currentEvent=null;if(this.browser.webkit){this._getSelection().setBaseAndExtent(G,0,G,0);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(true);}}}}else{this._setEditorStyle(true);this._getDoc().execCommand("fontname",false,"yui-tmp");var F=[];var R=this._getDoc().getElementsByTagName("font");var P=this._getDoc().getElementsByTagName(this._getSelectedElement().tagName);var M=this._getDoc().getElementsByTagName("span");var L=this._getDoc().getElementsByTagName("i");var K=this._getDoc().getElementsByTagName("b");var J=this._getDoc().getElementsByTagName(this._getSelectedElement().parentNode.tagName);for(var V=0;V<R.length;V++){F[F.length]=R[V];}for(var N=0;N<J.length;N++){F[F.length]=J[N];}for(var T=0;T<P.length;T++){F[F.length]=P[T];}for(var S=0;S<M.le!
 ngth;S++){F[F.length]=M[S];}for(var Q=0;Q<L.length;Q++){F[F.length]=L[Q];}for(var O=0;O<K.length;O++){F[F.length]=K[O];}for(var a=0;a<F.length;a++){if((YAHOO.util.Dom.getStyle(F[a],"font-family")=="yui-tmp")||(F[a].face&&(F[a].face=="yui-tmp"))){G=X();G.innerHTML=F[a].innerHTML;if(this._isElement(F[a],"ol")||(this._isElement(F[a],"ul"))){var Y=F[a].getElementsByTagName("li")[0];F[a].style.fontFamily="inherit";Y.style.fontFamily="inherit";G.innerHTML=Y.innerHTML;Y.innerHTML="";Y.appendChild(G);this.currentElement[this.currentElement.length]=G;}else{if(this._isElement(F[a],"li")){F[a].innerHTML="";F[a].appendChild(G);F[a].style.fontFamily="inherit";this.currentElement[this.currentElement.length]=G;}else{if(F[a].parentNode){F[a].parentNode.replaceChild(G,F[a]);this.currentElement[this.currentElement.length]=G;this.currentEvent=null;if(this.browser.webkit){this._getSelection().setBaseAndExtent(G,0,G,0);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._!
 getSelection().collapse(true);}}if(this.browser.ie&&U&&U.fontS!
 ize){thi
s._getSelection().empty();}if(this.browser.gecko){this._getSelection().collapseToStart();}}}}}}var c=this.currentElement.length;for(var d=0;d<c;d++){if((d+1)!=c){if(this.currentElement[d]&&this.currentElement[d].nextSibling){if(this._isElement(this.currentElement[d],"br")){this.currentElement[this.currentElement.length]=this.currentElement[d].nextSibling;}}}}}},saveHTML:function(){var F=this.cleanHTML();this.get("element").value=F;return F;},setEditorHTML:function(F){F=this._cleanIncomingHTML(F);this._getDoc().body.innerHTML=F;this.nodeChange();},getEditorHTML:function(){return this._getDoc().body.innerHTML;},show:function(){if(this.browser.gecko){this._setDesignMode("on");this._focusWindow();}if(this.browser.webkit){var F=this;window.setTimeout(function(){F._setInitialContent.call(F);},10);}if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}this.get("iframe!
 ").setStyle("position","static");this.get("iframe").setStyle("left","");},hide:function(){if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}if(this._fixNodesTimer){clearTimeout(this._fixNodesTimer);this._fixNodesTimer=null;}if(this._nodeChangeTimer){clearTimeout(this._nodeChangeTimer);this._nodeChangeTimer=null;}this._lastNodeChange=0;this.get("iframe").setStyle("position","absolute");this.get("iframe").setStyle("left","-9999px");},_cleanIncomingHTML:function(F){F=F.replace(/<strong([^>]*)>/gi,"<b$1>");F=F.replace(/<\/strong>/gi,"</b>");F=F.replace(/<em([^>]*)>/gi,"<i$1>");F=F.replace(/<\/em>/gi,"</i>");return F;},cleanHTML:function(H){if(!H){H=this.getEditorHTML();}var G=this.get("markup");H=this.pre_filter_linebreaks(H,G);H=H.replace(/<img([^>]*)\/>/gi,"<YUI_IMG$1>");H=H.replace(/<img([^>]*)>/gi,"<YUI_IMG$1>");H=H.replace(/<input([^>]*)\/>/gi,"<YUI_INPUT!
 $1>");H=H.replace(/<input([^>]*)>/gi,"<YUI_INPUT$1>");H=H.repl!
 ace(/<ul
([^>]*)>/gi,"<YUI_UL$1>");H=H.replace(/<\/ul>/gi,"</YUI_UL>");H=H.replace(/<blockquote([^>]*)>/gi,"<YUI_BQ$1>");H=H.replace(/<\/blockquote>/gi,"</YUI_BQ>");if((G=="semantic")||(G=="xhtml")){H=H.replace(/<i([^>]*)>/gi,"<em$1>");H=H.replace(/<\/i>/gi,"</em>");H=H.replace(/<b([^>]*)>/gi,"<strong$1>");H=H.replace(/<\/b>/gi,"</strong>");}H=H.replace(/<font/gi,"<font");H=H.replace(/<\/font>/gi,"</font>");H=H.replace(/<span/gi,"<span");H=H.replace(/<\/span>/gi,"</span>");if((G=="semantic")||(G=="xhtml")||(G=="css")){H=H.replace(new RegExp("<font([^>]*)face=\"([^>]*)\">(.*?)</font>","gi"),"<span $1 style=\"font-family: $2;\">$3</span>");H=H.replace(/<u/gi,"<span style=\"text-decoration: underline;\"");H=H.replace(/\/u>/gi,"/span>");if(G=="css"){H=H.replace(/<em([^>]*)>/gi,"<i$1>");H=H.replace(/<\/em>/gi,"</i>");H=H.replace(/<strong([^>]*)>/gi,"<b$1>");H=H.replace(/<\/strong>/gi,"</b>");H=H.replace(/<b/gi,"<span style=\"font-weight: bold;\"");H=H.replace(/\/b>/gi,"/span>");H=H.replac!
 e(/<i/gi,"<span style=\"font-style: italic;\"");H=H.replace(/\/i>/gi,"/span>");}H=H.replace(/  /gi," ");}else{H=H.replace(/<u/gi,"<u");H=H.replace(/\/u>/gi,"/u>");}H=H.replace(/<ol([^>]*)>/gi,"<ol$1>");H=H.replace(/\/ol>/gi,"/ol>");H=H.replace(/<li/gi,"<li");H=H.replace(/\/li>/gi,"/li>");H=this.filter_safari(H);H=this.filter_internals(H);H=this.filter_all_rgb(H);H=this.post_filter_linebreaks(H,G);if(G=="xhtml"){H=H.replace(/<YUI_IMG([^>]*)>/g,"<img $1/>");H=H.replace(/<YUI_INPUT([^>]*)>/g,"<input $1/>");}else{H=H.replace(/<YUI_IMG([^>]*)>/g,"<img $1>");H=H.replace(/<YUI_INPUT([^>]*)>/g,"<input $1>");}H=H.replace(/<YUI_UL([^>]*)>/g,"<ul$1>");H=H.replace(/<\/YUI_UL>/g,"</ul>");H=this.filter_invalid_lists(H);H=H.replace(/<YUI_BQ([^>]*)>/g,"<blockquote$1>");H=H.replace(/<\/YUI_BQ>/g,"</blockquote>");H=YAHOO.lang.trim(H);if(this.get("removeLineBreaks")){H=H.replace(/\n/g,"").replace(/\r/g,"");H=H.replace(/  /gi," ");
-}if(H.substring(0,6).toLowerCase()=="<span>"){H=H.substring(6);}if(H.substring(H.length-7,H.length).toLowerCase()=="</span>"){H=H.substring(0,H.length-7);}for(var F in this.invalidHTML){if(YAHOO.lang.hasOwnProperty(this.invalidHTML,F)){if(D.isObject(F)&&F.keepContents){H=H.replace(new RegExp("<"+F+"([^>]*)>(.*?)</"+F+">","gi"),"$1");}else{H=H.replace(new RegExp("<"+F+"([^>]*)>(.*?)</"+F+">","gi"),"");}}}this.fireEvent("cleanHTML",{type:"cleanHTML",target:this,html:H});return H;},filter_invalid_lists:function(F){F=F.replace(/<\/li>\n/gi,"</li>");F=F.replace(/<\/li><ol>/gi,"</li><li><ol>");F=F.replace(/<\/ol>/gi,"</ol></li>");F=F.replace(/<\/ol><\/li>\n/gi,"</ol>\n");F=F.replace(/<\/li><ul>/gi,"</li><li><ul>");F=F.replace(/<\/ul>/gi,"</ul></li>");F=F.replace(/<\/ul><\/li>\n/gi,"</ul>\n");F=F.replace(/<\/li>/gi,"</li>\n");F=F.replace(/<\/ol>/gi,"</ol>\n");F=F.replace(/<ol>/gi,"<ol>\n");F=F.replace(/<ul>/gi,"<ul>\n");return F;},filter_safari:function(F){if(this.browser.webkit){!
 F=F.replace(/Apple-style-span/gi,"");F=F.replace(/style="line-height: normal;"/gi,"");F=F.replace(/<li><\/li>/gi,"");F=F.replace(/<li> <\/li>/gi,"");F=F.replace(/<li>  <\/li>/gi,"");F=F.replace(/<div><\/div>/gi,"");F=F.replace(/<div> <\/div>/gi,"");}return F;},filter_internals:function(F){F=F.replace(/\r/g,"");F=F.replace(/<\/?(body|head|html)[^>]*>/gi,"");F=F.replace(/<YUI_BR><\/li>/gi,"</li>");F=F.replace(/yui-tag-span/gi,"");F=F.replace(/yui-tag/gi,"");F=F.replace(/yui-non/gi,"");F=F.replace(/yui-img/gi,"");F=F.replace(/ tag="span"/gi,"");F=F.replace(/ class=""/gi,"");F=F.replace(/ style=""/gi,"");F=F.replace(/ class=" "/gi,"");F=F.replace(/ class="  "/gi,"");F=F.replace(/ target=""/gi,"");F=F.replace(/ title=""/gi,"");if(this.browser.ie){F=F.replace(/ class= /gi,"");F=F.replace(/ class= >/gi,"");F=F.replace(/_height="([^>])"/gi,"");F=F.replace(/_width="([^>])"/gi,"");}return F;},filter_all_rgb:function(J){var I=new RegExp("rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\!
 s*?([0-9]+).*?\\)","gi");var F=J.match(I);if(D.isArray(F)){for!
 (var H=0
;H<F.length;H++){var G=this.filter_rgb(F[H]);J=J.replace(F[H].toString(),G);}}return J;},filter_rgb:function(H){if(H.toLowerCase().indexOf("rgb")!=-1){var K=new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)","gi");var G=H.replace(K,"$1,$2,$3,$4,$5").split(",");if(G.length==5){var J=parseInt(G[1],10).toString(16);var I=parseInt(G[2],10).toString(16);var F=parseInt(G[3],10).toString(16);J=J.length==1?"0"+J:J;I=I.length==1?"0"+I:I;F=F.length==1?"0"+F:F;H="#"+J+I+F;}}return H;},pre_filter_linebreaks:function(G,F){if(this.browser.webkit){G=G.replace(/<br class="khtml-block-placeholder">/gi,"<YUI_BR>");G=G.replace(/<br class="webkit-block-placeholder">/gi,"<YUI_BR>");}G=G.replace(/<br>/gi,"<YUI_BR>");G=G.replace(/<br (.*?)>/gi,"<YUI_BR>");G=G.replace(/<br\/>/gi,"<YUI_BR>");G=G.replace(/<br \/>/gi,"<YUI_BR>");G=G.replace(/<div><YUI_BR><\/div>/gi,"<YUI_BR>");G=G.replace(/<p>( | )<\/p>/g,"<YUI_BR>");G=G.replace(/<p><br> <\/p>/gi,"<Y!
 UI_BR>");G=G.replace(/<p> <\/p>/gi,"<YUI_BR>");G=G.replace(/<YUI_BR>$/,"");G=G.replace(/<YUI_BR><\/p>/g,"</p>");return G;},post_filter_linebreaks:function(G,F){if(F=="xhtml"){G=G.replace(/<YUI_BR>/g,"<br/>");}else{G=G.replace(/<YUI_BR>/g,"<br>");}return G;},clearEditorDoc:function(){this._getDoc().body.innerHTML=" ";},_renderPanel:function(){},openWindow:function(F){},moveWindow:function(){},_closeWindow:function(){},closeWindow:function(){this.unsubscribeAll("afterExecCommand");this.toolbar.resetAllButtons();this._focusWindow();},destroy:function(){this.saveHTML();this.toolbar.destroy();this.setStyle("visibility","hidden");this.setStyle("position","absolute");this.setStyle("top","-9999px");this.setStyle("left","-9999px");var G=this.get("element");this.get("element_cont").get("parentNode").replaceChild(G,this.get("element_cont").get("element"));this.get("element_cont").get("element").innerHTML="";for(var F in this){if(D.hasOwnProperty(this,F)){this[F]=null;}}retur!
 n true;},toString:function(){var F="SimpleEditor";if(this.get&!
 &this.ge
t("element_cont")){F="SimpleEditor (#"+this.get("element_cont").get("id")+")"+((this.get("disabled")?" Disabled":""));}return F;}});YAHOO.widget.EditorInfo={_instances:{},window:{},panel:null,getEditorById:function(F){if(!YAHOO.lang.isString(F)){F=F.id;}if(this._instances[F]){return this._instances[F];}return false;},toString:function(){var F=0;for(var G in this._instances){F++;}return"Editor Info ("+F+" registered intance"+((F>1)?"s":"")+")";}};})();YAHOO.register("simpleeditor",YAHOO.widget.SimpleEditor,{version:"2.4.1",build:"742"});
\ No newline at end of file
+(function(){var B=YAHOO.util.Dom,A=YAHOO.util.Event,C=YAHOO.lang;if(YAHOO.widget.Button){YAHOO.widget.ToolbarButtonAdvanced=YAHOO.widget.Button;YAHOO.widget.ToolbarButtonAdvanced.prototype.buttonType="rich";YAHOO.widget.ToolbarButtonAdvanced.prototype.checkValue=function(F){var E=this.getMenu().getItems();if(E.length===0){this.getMenu()._onBeforeShow();E=this.getMenu().getItems();}for(var D=0;D<E.length;D++){E[D].cfg.setProperty("checked",false);if(E[D].value==F){E[D].cfg.setProperty("checked",true);}}};}else{YAHOO.widget.ToolbarButtonAdvanced=function(){};}YAHOO.widget.ToolbarButton=function(E,D){if(C.isObject(arguments[0])&&!B.get(E).nodeType){D=E;}var G=(D||{});var F={element:null,attributes:G};if(!F.attributes.type){F.attributes.type="push";}F.element=document.createElement("span");F.element.setAttribute("unselectable","on");F.element.className="yui-button yui-"+F.attributes.type+"-button";F.element.innerHTML='<span class="first-child"><a href="#">LABEL</a></span>';F.el!
 ement.firstChild.firstChild.tabIndex="-1";F.attributes.id=B.generateId();YAHOO.widget.ToolbarButton.superclass.constructor.call(this,F.element,F.attributes);};YAHOO.extend(YAHOO.widget.ToolbarButton,YAHOO.util.Element,{buttonType:"normal",_handleMouseOver:function(){if(!this.get("disabled")){this.addClass("yui-button-hover");this.addClass("yui-"+this.get("type")+"-button-hover");}},_handleMouseOut:function(){this.removeClass("yui-button-hover");this.removeClass("yui-"+this.get("type")+"-button-hover");},checkValue:function(F){if(this.get("type")=="menu"){var E=this._button.options;for(var D=0;D<E.length;D++){if(E[D].value==F){E.selectedIndex=D;}}}},init:function(E,D){YAHOO.widget.ToolbarButton.superclass.init.call(this,E,D);this.on("mouseover",this._handleMouseOver,this,true);this.on("mouseout",this._handleMouseOut,this,true);},initAttributes:function(D){YAHOO.widget.ToolbarButton.superclass.initAttributes.call(this,D);this.setAttributeConfig("value",{value:D.value});this.s!
 etAttributeConfig("menu",{value:D.menu||false});this.setAttrib!
 uteConfi
g("type",{value:D.type,writeOnce:true,method:function(H){var G,F;if(!this._button){this._button=this.get("element").getElementsByTagName("a")[0];}switch(H){case"select":case"menu":G=document.createElement("select");var I=this.get("menu");for(var E=0;E<I.length;E++){F=document.createElement("option");F.innerHTML=I[E].text;F.value=I[E].value;if(I[E].checked){F.selected=true;}G.appendChild(F);}this._button.parentNode.replaceChild(G,this._button);A.on(G,"change",this._handleSelect,this,true);this._button=G;break;}}});this.setAttributeConfig("disabled",{value:D.disabled||false,method:function(E){if(E){this.addClass("yui-button-disabled");this.addClass("yui-"+this.get("type")+"-button-disabled");}else{this.removeClass("yui-button-disabled");this.removeClass("yui-"+this.get("type")+"-button-disabled");}if(this.get("type")=="menu"){this._button.disabled=E;}}});this.setAttributeConfig("label",{value:D.label,method:function(E){if(!this._button){this._button=this.get("element").getElem!
 entsByTagName("a")[0];}if(this.get("type")=="push"){this._button.innerHTML=E;}}});this.setAttributeConfig("title",{value:D.title});this.setAttributeConfig("container",{value:null,writeOnce:true,method:function(E){this.appendTo(E);}});},_handleSelect:function(E){var D=A.getTarget(E);var F=D.options[D.selectedIndex].value;this.fireEvent("change",{type:"change",value:F});},getMenu:function(){return this.get("menu");},destroy:function(){A.purgeElement(this.get("element"),true);this.get("element").parentNode.removeChild(this.get("element"));for(var D in this){if(C.hasOwnProperty(this,D)){this[D]=null;}}},fireEvent:function(E,D){if(this.DOM_EVENTS[E]&&this.get("disabled")){return ;}YAHOO.widget.ToolbarButton.superclass.fireEvent.call(this,E,D);},toString:function(){return"ToolbarButton ("+this.get("id")+")";}});})();(function(){var C=YAHOO.util.Dom,A=YAHOO.util.Event,E=YAHOO.lang;var B=function(G){var F=G;if(E.isString(G)){F=this.getButtonById(G);}if(E.isNumber(G)){F=this.getButt!
 onByIndex(G);}if((!(F instanceof YAHOO.widget.ToolbarButton))&!
 &(!(F in
stanceof YAHOO.widget.ToolbarButtonAdvanced))){F=this.getButtonByValue(G);}if((F instanceof YAHOO.widget.ToolbarButton)||(F instanceof YAHOO.widget.ToolbarButtonAdvanced)){return F;}return false;};YAHOO.widget.Toolbar=function(J,I){if(E.isObject(arguments[0])&&!C.get(J).nodeType){I=J;}var L=(I||{});var K={element:null,attributes:L};if(E.isString(J)&&C.get(J)){K.element=C.get(J);}else{if(E.isObject(J)&&C.get(J)&&C.get(J).nodeType){K.element=C.get(J);}}if(!K.element){K.element=document.createElement("DIV");K.element.id=C.generateId();if(L.container&&C.get(L.container)){C.get(L.container).appendChild(K.element);}}if(!K.element.id){K.element.id=((E.isString(J))?J:C.generateId());}var G=document.createElement("fieldset");var H=document.createElement("legend");H.innerHTML="Toolbar";G.appendChild(H);var F=document.createElement("DIV");K.attributes.cont=F;C.addClass(F,"yui-toolbar-subcont");G.appendChild(F);K.element.appendChild(G);K.element.tabIndex=-1;K.attributes.element=K.elemen!
 t;K.attributes.id=K.element.id;YAHOO.widget.Toolbar.superclass.constructor.call(this,K.element,K.attributes);};function D(I,F,J){C.addClass(this.element,"yui-toolbar-"+J.get("value")+"-menu");if(C.hasClass(J._button.parentNode.parentNode,"yui-toolbar-select")){C.addClass(this.element,"yui-toolbar-select-menu");}var G=this.getItems();for(var H=0;H<G.length;H++){C.addClass(G[H].element,"yui-toolbar-"+J.get("value")+"-"+((G[H].value)?G[H].value.replace(/ /g,"-").toLowerCase():G[H]._oText.nodeValue.replace(/ /g,"-").toLowerCase()));C.addClass(G[H].element,"yui-toolbar-"+J.get("value")+"-"+((G[H].value)?G[H].value.replace(/ /g,"-"):G[H]._oText.nodeValue.replace(/ /g,"-")));}}YAHOO.extend(YAHOO.widget.Toolbar,YAHOO.util.Element,{buttonType:YAHOO.widget.ToolbarButton,dd:null,_colorData:{"#111111":"Obsidian","#2D2D2D":"Dark Gray","#434343":"Shale","#5B5B5B":"Flint","#737373":"Gray","#8B8B8B":"Concrete","#A2A2A2":"Gray","#B9B9B9":"Titanium","#000000":"Black","#D0D0D0":"Light Gray","!
 #E6E6E6":"Silver","#FFFFFF":"White","#BFBF00":"Pumpkin","#FFFF!
 00":"Yel
low","#FFFF40":"Banana","#FFFF80":"Pale Yellow","#FFFFBF":"Butter","#525330":"Raw Siena","#898A49":"Mildew","#AEA945":"Olive","#7F7F00":"Paprika","#C3BE71":"Earth","#E0DCAA":"Khaki","#FCFAE1":"Cream","#60BF00":"Cactus","#80FF00":"Chartreuse","#A0FF40":"Green","#C0FF80":"Pale Lime","#DFFFBF":"Light Mint","#3B5738":"Green","#668F5A":"Lime Gray","#7F9757":"Yellow","#407F00":"Clover","#8A9B55":"Pistachio","#B7C296":"Light Jade","#E6EBD5":"Breakwater","#00BF00":"Spring Frost","#00FF80":"Pastel Green","#40FFA0":"Light Emerald","#80FFC0":"Sea Foam","#BFFFDF":"Sea Mist","#033D21":"Dark Forrest","#438059":"Moss","#7FA37C":"Medium Green","#007F40":"Pine","#8DAE94":"Yellow Gray Green","#ACC6B5":"Aqua Lung","#DDEBE2":"Sea Vapor","#00BFBF":"Fog","#00FFFF":"Cyan","#40FFFF":"Turquoise Blue","#80FFFF":"Light Aqua","#BFFFFF":"Pale Cyan","#033D3D":"Dark Teal","#347D7E":"Gray Turquoise","#609A9F":"Green Blue","#007F7F":"Seaweed","#96BDC4":"Green Gray","#B5D1D7":"Soapstone","#E2F1F4":"Light Tur!
 quoise","#0060BF":"Summer Sky","#0080FF":"Sky Blue","#40A0FF":"Electric Blue","#80C0FF":"Light Azure","#BFDFFF":"Ice Blue","#1B2C48":"Navy","#385376":"Biscay","#57708F":"Dusty Blue","#00407F":"Sea Blue","#7792AC":"Sky Blue Gray","#A8BED1":"Morning Sky","#DEEBF6":"Vapor","#0000BF":"Deep Blue","#0000FF":"Blue","#4040FF":"Cerulean Blue","#8080FF":"Evening Blue","#BFBFFF":"Light Blue","#212143":"Deep Indigo","#373E68":"Sea Blue","#444F75":"Night Blue","#00007F":"Indigo Blue","#585E82":"Dockside","#8687A4":"Blue Gray","#D2D1E1":"Light Blue Gray","#6000BF":"Neon Violet","#8000FF":"Blue Violet","#A040FF":"Violet Purple","#C080FF":"Violet Dusk","#DFBFFF":"Pale Lavender","#302449":"Cool Shale","#54466F":"Dark Indigo","#655A7F":"Dark Violet","#40007F":"Violet","#726284":"Smoky Violet","#9E8FA9":"Slate Gray","#DCD1DF":"Violet White","#BF00BF":"Royal Violet","#FF00FF":"Fuchsia","#FF40FF":"Magenta","#FF80FF":"Orchid","#FFBFFF":"Pale Magenta","#4A234A":"Dark Purple","#794A72":"Medium Pur!
 ple","#936386":"Cool Granite","#7F007F":"Purple","#9D7292":"Pu!
 rple Moo
n","#C0A0B6":"Pale Purple","#ECDAE5":"Pink Cloud","#BF005F":"Hot Pink","#FF007F":"Deep Pink","#FF409F":"Grape","#FF80BF":"Electric Pink","#FFBFDF":"Pink","#451528":"Purple Red","#823857":"Purple Dino","#A94A76":"Purple Gray","#7F003F":"Rose","#BC6F95":"Antique Mauve","#D8A5BB":"Cool Marble","#F7DDE9":"Pink Granite","#C00000":"Apple","#FF0000":"Fire Truck","#FF4040":"Pale Red","#FF8080":"Salmon","#FFC0C0":"Warm Pink","#441415":"Sepia","#82393C":"Rust","#AA4D4E":"Brick","#800000":"Brick Red","#BC6E6E":"Mauve","#D8A3A4":"Shrimp Pink","#F8DDDD":"Shell Pink","#BF5F00":"Dark Orange","#FF7F00":"Orange","#FF9F40":"Grapefruit","#FFBF80":"Canteloupe","#FFDFBF":"Wax","#482C1B":"Dark Brick","#855A40":"Dirt","#B27C51":"Tan","#7F3F00":"Nutmeg","#C49B71":"Mustard","#E1C4A8":"Pale Tan","#FDEEE0":"Marble"},_colorPicker:null,STR_COLLAPSE:"Collapse Toolbar",STR_SPIN_LABEL:"Spin Button with value {VALUE}. Use Control Shift Up Arrow and Control Shift Down arrow keys to increase or decrease the v!
 alue.",STR_SPIN_UP:"Click to increase the value of this input",STR_SPIN_DOWN:"Click to decrease the value of this input",_titlebar:null,browser:YAHOO.env.ua,_buttonList:null,_buttonGroupList:null,_sep:null,_sepCount:null,_dragHandle:null,_toolbarConfigs:{renderer:true},CLASS_CONTAINER:"yui-toolbar-container",CLASS_DRAGHANDLE:"yui-toolbar-draghandle",CLASS_SEPARATOR:"yui-toolbar-separator",CLASS_DISABLED:"yui-toolbar-disabled",CLASS_PREFIX:"yui-toolbar",init:function(G,F){YAHOO.widget.Toolbar.superclass.init.call(this,G,F);
+},initAttributes:function(F){YAHOO.widget.Toolbar.superclass.initAttributes.call(this,F);this.addClass(this.CLASS_CONTAINER);this.setAttributeConfig("buttonType",{value:F.buttonType||"basic",writeOnce:true,validator:function(G){switch(G){case"advanced":case"basic":return true;}return false;},method:function(G){if(G=="advanced"){if(YAHOO.widget.Button){this.buttonType=YAHOO.widget.ToolbarButtonAdvanced;}else{this.buttonType=YAHOO.widget.ToolbarButton;}}else{this.buttonType=YAHOO.widget.ToolbarButton;}}});this.setAttributeConfig("buttons",{value:[],writeOnce:true,method:function(H){for(var G in H){if(E.hasOwnProperty(H,G)){if(H[G].type=="separator"){this.addSeparator();}else{if(H[G].group!==undefined){this.addButtonGroup(H[G]);}else{this.addButton(H[G]);}}}}}});this.setAttributeConfig("disabled",{value:false,method:function(G){if(this.get("disabled")===G){return false;}if(G){this.addClass(this.CLASS_DISABLED);this.set("draggable",false);this.disableAllButtons();}else{this.rem!
 oveClass(this.CLASS_DISABLED);if(this._configs.draggable._initialConfig.value){this.set("draggable",true);}this.resetAllButtons();}}});this.setAttributeConfig("cont",{value:F.cont,readOnly:true});this.setAttributeConfig("grouplabels",{value:((F.grouplabels===false)?false:true),method:function(G){if(G){C.removeClass(this.get("cont"),(this.CLASS_PREFIX+"-nogrouplabels"));}else{C.addClass(this.get("cont"),(this.CLASS_PREFIX+"-nogrouplabels"));}}});this.setAttributeConfig("titlebar",{value:false,method:function(H){if(H){if(this._titlebar&&this._titlebar.parentNode){this._titlebar.parentNode.removeChild(this._titlebar);}this._titlebar=document.createElement("DIV");this._titlebar.tabIndex="-1";A.on(this._titlebar,"focus",function(){this._handleFocus();},this,true);C.addClass(this._titlebar,this.CLASS_PREFIX+"-titlebar");if(E.isString(H)){var G=document.createElement("h2");G.tabIndex="-1";G.innerHTML='<a href="#" tabIndex="0">'+H+"</a>";this._titlebar.appendChild(G);A.on(G.firstCh!
 ild,"click",function(I){A.stopEvent(I);});A.on([G,G.firstChild!
 ],"focus
",function(){this._handleFocus();},this,true);}if(this.get("firstChild")){this.insertBefore(this._titlebar,this.get("firstChild"));}else{this.appendChild(this._titlebar);}if(this.get("collapse")){this.set("collapse",true);}}else{if(this._titlebar){if(this._titlebar&&this._titlebar.parentNode){this._titlebar.parentNode.removeChild(this._titlebar);}}}}});this.setAttributeConfig("collapse",{value:false,method:function(I){if(this._titlebar){var H=null;var G=C.getElementsByClassName("collapse","span",this._titlebar);if(I){if(G.length>0){return true;}H=document.createElement("SPAN");H.innerHTML="X";H.title=this.STR_COLLAPSE;C.addClass(H,"collapse");this._titlebar.appendChild(H);A.addListener(H,"click",function(){if(C.hasClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed")){this.collapse(false);}else{this.collapse();}},this,true);}else{H=C.getElementsByClassName("collapse","span",this._titlebar);if(H[0]){if(C.hasClass(this.get("cont").parentNode,"yui-toolbar-contain!
 er-collapsed")){this.collapse(false);}H[0].parentNode.removeChild(H[0]);}}}}});this.setAttributeConfig("draggable",{value:(F.draggable||false),method:function(G){if(G&&!this.get("titlebar")){if(!this._dragHandle){this._dragHandle=document.createElement("SPAN");this._dragHandle.innerHTML="|";this._dragHandle.setAttribute("title","Click to drag the toolbar");this._dragHandle.id=this.get("id")+"_draghandle";C.addClass(this._dragHandle,this.CLASS_DRAGHANDLE);if(this.get("cont").hasChildNodes()){this.get("cont").insertBefore(this._dragHandle,this.get("cont").firstChild);}else{this.get("cont").appendChild(this._dragHandle);}this.dd=new YAHOO.util.DD(this.get("id"));this.dd.setHandleElId(this._dragHandle.id);}}else{if(this._dragHandle){this._dragHandle.parentNode.removeChild(this._dragHandle);this._dragHandle=null;this.dd=null;}}if(this._titlebar){if(G){this.dd=new YAHOO.util.DD(this.get("id"));this.dd.setHandleElId(this._titlebar);C.addClass(this._titlebar,"draggable");}else{C.re!
 moveClass(this._titlebar,"draggable");if(this.dd){this.dd.unre!
 g();this
.dd=null;}}}},validator:function(H){var G=true;if(!YAHOO.util.DD){G=false;}return G;}});},addButtonGroup:function(J){if(!this.get("element")){this._queue[this._queue.length]=["addButtonGroup",arguments];return false;}if(!this.hasClass(this.CLASS_PREFIX+"-grouped")){this.addClass(this.CLASS_PREFIX+"-grouped");}var K=document.createElement("DIV");C.addClass(K,this.CLASS_PREFIX+"-group");C.addClass(K,this.CLASS_PREFIX+"-group-"+J.group);if(J.label){var G=document.createElement("h3");G.innerHTML=J.label;K.appendChild(G);}if(!this.get("grouplabels")){C.addClass(this.get("cont"),this.CLASS_PREFIX,"-nogrouplabels");}this.get("cont").appendChild(K);var I=document.createElement("ul");K.appendChild(I);if(!this._buttonGroupList){this._buttonGroupList={};}this._buttonGroupList[J.group]=I;for(var H=0;H<J.buttons.length;H++){var F=document.createElement("li");F.className=this.CLASS_PREFIX+"-groupitem";I.appendChild(F);if((J.buttons[H].type!==undefined)&&J.buttons[H].type=="separator"){thi!
 s.addSeparator(F);}else{J.buttons[H].container=F;this.addButton(J.buttons[H]);}}},addButtonToGroup:function(H,I,J){var G=this._buttonGroupList[I];var F=document.createElement("li");F.className=this.CLASS_PREFIX+"-groupitem";H.container=F;this.addButton(H,J);G.appendChild(F);},addButton:function(K,J){if(!this.get("element")){this._queue[this._queue.length]=["addButton",arguments];return false;}if(!this._buttonList){this._buttonList=[];}if(!K.container){K.container=this.get("cont");}if((K.type=="menu")||(K.type=="split")||(K.type=="select")){if(E.isArray(K.menu)){for(var Q in K.menu){if(E.hasOwnProperty(K.menu,Q)){var W={fn:function(Z,X,Y){if(!K.menucmd){K.menucmd=K.value;}K.value=((Y.value)?Y.value:Y._oText.nodeValue);},scope:this};K.menu[Q].onclick=W;}}}}var R={},O=false;for(var M in K){if(E.hasOwnProperty(K,M)){if(!this._toolbarConfigs[M]){R[M]=K[M];}}}if(K.type=="select"){R.type="menu";}if(K.type=="spin"){R.type="push";
+}if(R.type=="color"){if(YAHOO.widget.Overlay){R=this._makeColorButton(R);}else{O=true;}}if(R.menu){if((YAHOO.widget.Overlay)&&(K.menu instanceof YAHOO.widget.Overlay)){K.menu.showEvent.subscribe(function(){this._button=R;});}else{for(var P=0;P<R.menu.length;P++){if(!R.menu[P].value){R.menu[P].value=R.menu[P].text;}}if(this.browser.webkit){R.focusmenu=false;}}}if(O){K=false;}else{this._configs.buttons.value[this._configs.buttons.value.length]=K;var U=new this.buttonType(R);U.get("element").tabIndex="-1";U.get("element").setAttribute("role","button");U._selected=true;if(!U.buttonType){U.buttonType="rich";U.checkValue=function(Z){var Y=this.getMenu().getItems();if(Y.length===0){this.getMenu()._onBeforeShow();Y=this.getMenu().getItems();}for(var X=0;X<Y.length;X++){Y[X].cfg.setProperty("checked",false);if(Y[X].value==Z){Y[X].cfg.setProperty("checked",true);}}};}if(this.get("disabled")){U.set("disabled",true);}if(!K.id){K.id=U.get("id");}if(J){var G=U.get("element");var N=null;i!
 f(J.get){N=J.get("element").nextSibling;}else{if(J.nextSibling){N=J.nextSibling;}}if(N){N.parentNode.insertBefore(G,N);}}U.addClass(this.CLASS_PREFIX+"-"+U.get("value"));var T=document.createElement("span");T.className=this.CLASS_PREFIX+"-icon";U.get("element").insertBefore(T,U.get("firstChild"));if(U._button.tagName.toLowerCase()=="button"){U.get("element").setAttribute("unselectable","on");var V=document.createElement("a");V.innerHTML=U._button.innerHTML;V.href="#";V.tabIndex="-1";A.on(V,"click",function(X){A.stopEvent(X);});U._button.parentNode.replaceChild(V,U._button);U._button=V;}if(K.type=="select"){if(U._button.tagName.toLowerCase()=="select"){T.parentNode.removeChild(T);var H=U._button;var S=U.get("element");S.parentNode.replaceChild(H,S);}else{U.addClass(this.CLASS_PREFIX+"-select");}}if(K.type=="spin"){if(!E.isArray(K.range)){K.range=[10,100];}this._makeSpinButton(U,K);}U.get("element").setAttribute("title",U.get("label"));if(K.type!="spin"){if((YAHOO.widget.Over!
 lay)&&(R.menu instanceof YAHOO.widget.Overlay)){var I=function!
 (Z){var 
X=true;if(Z.keyCode&&(Z.keyCode==9)){X=false;}if(X){if(this._colorPicker){this._colorPicker._button=K.value;}var Y=U.getMenu().element;if(C.getStyle(Y,"visibility")=="hidden"){U.getMenu().show();}else{U.getMenu().hide();}}YAHOO.util.Event.stopEvent(Z);};U.on("mousedown",I,K,this);U.on("keydown",I,K,this);}else{if((K.type!="menu")&&(K.type!="select")){U.on("keypress",this._buttonClick,K,this);U.on("mousedown",function(X){YAHOO.util.Event.stopEvent(X);this._buttonClick(X,K);},K,this);U.on("click",function(X){});}else{U.on("mousedown",function(X){YAHOO.util.Event.stopEvent(X);});U.on("click",function(X){YAHOO.util.Event.stopEvent(X);});U.on("change",function(X){if(!K.menucmd){K.menucmd=K.value;}K.value=X.value;this._buttonClick(X,K);},this,true);var L=this;if(U.getMenu().mouseDownEvent){U.getMenu().mouseDownEvent.subscribe(function(Z,Y){var X=Y[1];YAHOO.util.Event.stopEvent(Y[0]);U._onMenuClick(Y[0],U);if(!K.menucmd){K.menucmd=K.value;}K.value=((X.value)?X.value:X._oText.nodeVa!
 lue);L._buttonClick.call(L,Y[1],K);U._hideMenu();return false;});U.getMenu().clickEvent.subscribe(function(Y,X){YAHOO.util.Event.stopEvent(X[0]);});U.getMenu().mouseUpEvent.subscribe(function(Y,X){YAHOO.util.Event.stopEvent(X[0]);});}}}}else{U.on("mousedown",function(X){YAHOO.util.Event.stopEvent(X);});U.on("click",function(X){YAHOO.util.Event.stopEvent(X);});}if(this.browser.ie){}if(this.browser.webkit){U.hasFocus=function(){return true;};}this._buttonList[this._buttonList.length]=U;if((K.type=="menu")||(K.type=="split")||(K.type=="select")){if(E.isArray(K.menu)){var F=U.getMenu();if(F.renderEvent){F.renderEvent.subscribe(D,U);if(K.renderer){F.renderEvent.subscribe(K.renderer,U);}}}}}return K;},addSeparator:function(F,I){if(!this.get("element")){this._queue[this._queue.length]=["addSeparator",arguments];return false;}var G=((F)?F:this.get("cont"));if(!this.get("element")){this._queue[this._queue.length]=["addSeparator",arguments];return false;}if(this._sepCount===null){thi!
 s._sepCount=0;}if(!this._sep){this._sep=document.createElement!
 ("SPAN")
;C.addClass(this._sep,this.CLASS_SEPARATOR);this._sep.innerHTML="|";}var H=this._sep.cloneNode(true);this._sepCount++;C.addClass(H,this.CLASS_SEPARATOR+"-"+this._sepCount);if(I){var J=null;if(I.get){J=I.get("element").nextSibling;}else{if(I.nextSibling){J=I.nextSibling;}else{J=I;}}if(J){if(J==I){J.parentNode.appendChild(H);}else{J.parentNode.insertBefore(H,J);}}}else{G.appendChild(H);}return H;},_createColorPicker:function(I){if(C.get(I+"_colors")){C.get(I+"_colors").parentNode.removeChild(C.get(I+"_colors"));}var F=document.createElement("div");F.className="yui-toolbar-colors";F.id=I+"_colors";F.style.display="none";A.on(window,"load",function(){document.body.appendChild(F);},this,true);this._colorPicker=F;var H="";for(var G in this._colorData){if(E.hasOwnProperty(this._colorData,G)){H+='<a style="background-color: '+G+'" href="#">'+G.replace("#","")+"</a>";}}H+="<span><em>X</em><strong></strong></span>";window.setTimeout(function(){F.innerHTML=H;},0);A.on(F,"mouseover",fun!
 ction(N){var L=this._colorPicker;var M=L.getElementsByTagName("em")[0];var K=L.getElementsByTagName("strong")[0];var J=A.getTarget(N);if(J.tagName.toLowerCase()=="a"){M.style.backgroundColor=J.style.backgroundColor;K.innerHTML=this._colorData["#"+J.innerHTML]+"<br>"+J.innerHTML;}},this,true);A.on(F,"focus",function(J){A.stopEvent(J);});A.on(F,"click",function(J){A.stopEvent(J);});A.on(F,"mousedown",function(K){A.stopEvent(K);var J=A.getTarget(K);if(J.tagName.toLowerCase()=="a"){var M=this.fireEvent("colorPickerClicked",{type:"colorPickerClicked",target:this,button:this._colorPicker._button,color:J.innerHTML,colorName:this._colorData["#"+J.innerHTML]});if(M!==false){var L={color:J.innerHTML,colorName:this._colorData["#"+J.innerHTML],value:this._colorPicker._button};this.fireEvent("buttonClick",{type:"buttonClick",target:this.get("element"),button:L});}this.getButtonByValue(this._colorPicker._button).getMenu().hide();
+}},this,true);},_resetColorPicker:function(){var G=this._colorPicker.getElementsByTagName("em")[0];var F=this._colorPicker.getElementsByTagName("strong")[0];G.style.backgroundColor="transparent";F.innerHTML="";},_makeColorButton:function(F){if(!this._colorPicker){this._createColorPicker(this.get("id"));}F.type="color";F.menu=new YAHOO.widget.Overlay(this.get("id")+"_"+F.value+"_menu",{visible:false,position:"absolute",iframe:true});F.menu.setBody("");F.menu.render(this.get("cont"));C.addClass(F.menu.element,"yui-button-menu");C.addClass(F.menu.element,"yui-color-button-menu");F.menu.beforeShowEvent.subscribe(function(){F.menu.cfg.setProperty("zindex",5);F.menu.cfg.setProperty("context",[this.getButtonById(F.id).get("element"),"tl","bl"]);this._resetColorPicker();var G=this._colorPicker;if(G.parentNode){G.parentNode.removeChild(G);}F.menu.setBody("");F.menu.appendToBody(G);this._colorPicker.style.display="block";},this,true);return F;},_makeSpinButton:function(S,M){S.addClas!
 s(this.CLASS_PREFIX+"-spinbutton");var T=this,O=S._button.parentNode.parentNode,J=M.range,I=document.createElement("a"),H=document.createElement("a");I.href="#";H.href="#";I.tabIndex="-1";H.tabIndex="-1";I.className="up";I.title=this.STR_SPIN_UP;I.innerHTML=this.STR_SPIN_UP;H.className="down";H.title=this.STR_SPIN_DOWN;H.innerHTML=this.STR_SPIN_DOWN;O.appendChild(I);O.appendChild(H);var N=YAHOO.lang.substitute(this.STR_SPIN_LABEL,{VALUE:S.get("label")});S.set("title",N);var R=function(U){U=((U<J[0])?J[0]:U);U=((U>J[1])?J[1]:U);return U;};var Q=this.browser;var G=false;var L=this.STR_SPIN_LABEL;if(this._titlebar&&this._titlebar.firstChild){G=this._titlebar.firstChild;}var F=function(V){YAHOO.util.Event.stopEvent(V);if(!S.get("disabled")&&(V.keyCode!=9)){var W=parseInt(S.get("label"),10);W++;W=R(W);S.set("label",""+W);var U=YAHOO.lang.substitute(L,{VALUE:S.get("label")});S.set("title",U);if(!Q.webkit&&G){}T._buttonClick(V,M);}};var P=function(V){YAHOO.util.Event.stopEvent(V);!
 if(!S.get("disabled")&&(V.keyCode!=9)){var W=parseInt(S.get("l!
 abel"),1
0);W--;W=R(W);S.set("label",""+W);var U=YAHOO.lang.substitute(L,{VALUE:S.get("label")});S.set("title",U);if(!Q.webkit&&G){}T._buttonClick(V,M);}};var K=function(U){if(U.keyCode==38){F(U);}else{if(U.keyCode==40){P(U);}else{if(U.keyCode==107&&U.shiftKey){F(U);}else{if(U.keyCode==109&&U.shiftKey){P(U);}}}}};S.on("keydown",K,this,true);A.on(I,"mousedown",function(U){A.stopEvent(U);},this,true);A.on(H,"mousedown",function(U){A.stopEvent(U);},this,true);A.on(I,"click",F,this,true);A.on(H,"click",P,this,true);},_buttonClick:function(M,G){var F=true;if(M&&M.type=="keypress"){if(M.keyCode==9){F=false;}else{if((M.keyCode===13)||(M.keyCode===0)||(M.keyCode===32)){}else{F=false;}}}if(F){var O=true,I=false;if(G.value){I=this.fireEvent(G.value+"Click",{type:G.value+"Click",target:this.get("element"),button:G});if(I===false){O=false;}}if(G.menucmd&&O){I=this.fireEvent(G.menucmd+"Click",{type:G.menucmd+"Click",target:this.get("element"),button:G});if(I===false){O=false;}}if(O){this.fireEven!
 t("buttonClick",{type:"buttonClick",target:this.get("element"),button:G});}if(G.type=="select"){var L=this.getButtonById(G.id);if(L.buttonType=="rich"){var K=G.value;for(var J=0;J<G.menu.length;J++){if(G.menu[J].value==G.value){K=G.menu[J].text;break;}}L.set("label",'<span class="yui-toolbar-'+G.menucmd+"-"+(G.value).replace(/ /g,"-").toLowerCase()+'">'+K+"</span>");var N=L.getMenu().getItems();for(var H=0;H<N.length;H++){if(N[H].value.toLowerCase()==G.value.toLowerCase()){N[H].cfg.setProperty("checked",true);}else{N[H].cfg.setProperty("checked",false);}}}}if(M){A.stopEvent(M);}}},_keyNav:null,_navCounter:null,_navigateButtons:function(G){switch(G.keyCode){case 37:case 39:if(G.keyCode==37){this._navCounter--;}else{this._navCounter++;}if(this._navCounter>(this._buttonList.length-1)){this._navCounter=0;}if(this._navCounter<0){this._navCounter=(this._buttonList.length-1);}var F=this._buttonList[this._navCounter].get("element");if(this.browser.ie){F=this._buttonList[this._navCo!
 unter].get("element").getElementsByTagName("a")[0];}if(this._b!
 uttonLis
t[this._navCounter].get("disabled")){this._navigateButtons(G);}else{F.focus();}break;}},_handleFocus:function(){if(!this._keyNav){var F="keypress";if(this.browser.ie){F="keydown";}A.on(this.get("element"),F,this._navigateButtons,this,true);this._keyNav=true;this._navCounter=-1;}},getButtonById:function(H){var F=this._buttonList.length;for(var G=0;G<F;G++){if(this._buttonList[G].get("id")==H){return this._buttonList[G];}}return false;},getButtonByValue:function(L){var I=this.get("buttons");var G=I.length;for(var J=0;J<G;J++){if(I[J].group!==undefined){for(var F=0;F<I[J].buttons.length;F++){if((I[J].buttons[F].value==L)||(I[J].buttons[F].menucmd==L)){return this.getButtonById(I[J].buttons[F].id);}if(I[J].buttons[F].menu){for(var K=0;K<I[J].buttons[F].menu.length;K++){if(I[J].buttons[F].menu[K].value==L){return this.getButtonById(I[J].buttons[F].id);}}}}}else{if((I[J].value==L)||(I[J].menucmd==L)){return this.getButtonById(I[J].id);}if(I[J].menu){for(var H=0;H<I[J].menu.length;!
 H++){if(I[J].menu[H].value==L){return this.getButtonById(I[J].id);}}}}}return false;},getButtonByIndex:function(F){if(this._buttonList[F]){return this._buttonList[F];}else{return false;}},getButtons:function(){return this._buttonList;},disableButton:function(G){var F=B.call(this,G);if(F){F.set("disabled",true);}else{return false;}},enableButton:function(G){if(this.get("disabled")){return false;}var F=B.call(this,G);if(F){if(F.get("disabled")){F.set("disabled",false);}}else{return false;}},isSelected:function(G){var F=B.call(this,G);if(F){return F._selected;}return false;},selectButton:function(J,H){var G=B.call(this,J);if(G){G.addClass("yui-button-selected");G.addClass("yui-button-"+G.get("value")+"-selected");G._selected=true;if(H){if(G.buttonType=="rich"){var I=G.getMenu().getItems();for(var F=0;F<I.length;F++){if(I[F].value==H){I[F].cfg.setProperty("checked",true);G.set("label",'<span class="yui-toolbar-'+G.get("value")+"-"+(H).replace(/ /g,"-").toLowerCase()+'">'+I[F]._!
 oText.nodeValue+"</span>");
+}else{I[F].cfg.setProperty("checked",false);}}}}}else{return false;}},deselectButton:function(G){var F=B.call(this,G);if(F){F.removeClass("yui-button-selected");F.removeClass("yui-button-"+F.get("value")+"-selected");F.removeClass("yui-button-hover");F._selected=false;}else{return false;}},deselectAllButtons:function(){var F=this._buttonList.length;for(var G=0;G<F;G++){this.deselectButton(this._buttonList[G]);}},disableAllButtons:function(){if(this.get("disabled")){return false;}var F=this._buttonList.length;for(var G=0;G<F;G++){this.disableButton(this._buttonList[G]);}},enableAllButtons:function(){if(this.get("disabled")){return false;}var F=this._buttonList.length;for(var G=0;G<F;G++){this.enableButton(this._buttonList[G]);}},resetAllButtons:function(J){if(!E.isObject(J)){J={};}if(this.get("disabled")){return false;}var F=this._buttonList.length;for(var G=0;G<F;G++){var I=this._buttonList[G];var H=I._configs.disabled._initialConfig.value;if(J[I.get("id")]){this.enableButt!
 on(I);this.selectButton(I);}else{if(H){this.disableButton(I);}else{this.enableButton(I);}this.deselectButton(I);}}},destroyButton:function(J){var H=B.call(this,J);if(H){var I=H.get("id");H.destroy();var F=this._buttonList.length;for(var G=0;G<F;G++){if(this._buttonList[G].get("id")==I){this._buttonList[G]=null;}}}else{return false;}},destroy:function(){this.get("element").innerHTML="";this.get("element").className="";for(var F in this){if(E.hasOwnProperty(this,F)){this[F]=null;}}return true;},collapse:function(G){var F=C.getElementsByClassName("collapse","span",this._titlebar);if(G===false){C.removeClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed");if(F[0]){C.removeClass(F[0],"collapsed");}this.fireEvent("toolbarExpanded",{type:"toolbarExpanded",target:this});}else{if(F[0]){C.addClass(F[0],"collapsed");}C.addClass(this.get("cont").parentNode,"yui-toolbar-container-collapsed");this.fireEvent("toolbarCollapsed",{type:"toolbarCollapsed",target:this});}},toStr!
 ing:function(){return"Toolbar (#"+this.get("element").id+") wi!
 th "+thi
s._buttonList.length+" buttons.";}});})();(function(){var C=YAHOO.util.Dom,A=YAHOO.util.Event,D=YAHOO.lang,B=YAHOO.widget.Toolbar;YAHOO.widget.SimpleEditor=function(I,N){var H={};if(D.isObject(I)&&(!I.tagName)&&!N){D.augmentObject(H,I);I=document.createElement("textarea");this.DOMReady=true;if(H.container){var L=C.get(H.container);L.appendChild(I);}else{document.body.appendChild(I);}}else{D.augmentObject(H,N);}var J={element:null,attributes:H},G=null;if(D.isString(I)){G=I;}else{if(J.attributes.id){G=J.attributes.id;}else{G=C.generateId(I);}}J.element=I;var K=document.createElement("DIV");J.attributes.element_cont=new YAHOO.util.Element(K,{id:G+"_container"});var F=document.createElement("div");C.addClass(F,"first-child");J.attributes.element_cont.appendChild(F);if(!J.attributes.toolbar_cont){J.attributes.toolbar_cont=document.createElement("DIV");J.attributes.toolbar_cont.id=G+"_toolbar";F.appendChild(J.attributes.toolbar_cont);}var M=document.createElement("DIV");F.appendCh!
 ild(M);J.attributes.editor_wrapper=M;YAHOO.widget.SimpleEditor.superclass.constructor.call(this,J.element,J.attributes);};function E(F){return F.replace(/ /g,"-").toLowerCase();}YAHOO.extend(YAHOO.widget.SimpleEditor,YAHOO.util.Element,{_docType:'<!DOCTYPE HTML PUBLIC "-/'+"/W3C/"+"/DTD HTML 4.01/"+'/EN" "http:/'+'/www.w3.org/TR/html4/strict.dtd">',editorDirty:null,_defaultCSS:"html { height: 95%; } body { padding: 7px; background-color: #fff; font:13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a { color: blue; text-decoration: underline; cursor: text; } .warning-localfile { border-bottom: 1px dashed red !important; } .yui-busy { cursor: wait !important; } img.selected { border: 2px dotted #808080; } img { cursor: pointer !important; border: none; }",_defaultToolbar:null,_lastButton:null,_baseHREF:function(){var F=document.location.href;if(F.indexOf("?")!==-1){F=F.substring(0,F.indexOf("?"));}F=F.substring(0,F.lastIndexOf("/"))+"/";return F;}()!
 ,_lastImage:null,_blankImageLoaded:null,_fixNodesTimer:null,_n!
 odeChang
eTimer:null,_lastNodeChangeEvent:null,_lastNodeChange:0,_rendered:null,DOMReady:null,_selection:null,_mask:null,_showingHiddenElements:null,currentWindow:null,currentEvent:null,operaEvent:null,currentFont:null,currentElement:null,dompath:null,beforeElement:null,afterElement:null,invalidHTML:{form:true,input:true,button:true,select:true,link:true,html:true,body:true,iframe:true,script:true,style:true,textarea:true},toolbar:null,_contentTimer:null,_contentTimerCounter:0,_disabled:["createlink","fontname","fontsize","forecolor","backcolor"],_alwaysDisabled:{},_alwaysEnabled:{},_semantic:{"bold":true,"italic":true,"underline":true},_tag2cmd:{"b":"bold","strong":"bold","i":"italic","em":"italic","u":"underline","sup":"superscript","sub":"subscript","img":"insertimage","a":"createlink","ul":"insertunorderedlist","ol":"insertorderedlist"},_createIframe:function(){var J=document.createElement("iframe");J.id=this.get("id")+"_editor";var H={border:"0",frameBorder:"0",marginWidth:"0",m!
 arginHeight:"0",leftMargin:"0",topMargin:"0",allowTransparency:"true",width:"100%"};if(this.get("autoHeight")){H.scrolling="no";}for(var I in H){if(D.hasOwnProperty(H,I)){J.setAttribute(I,H[I]);}}var G="javascript:;";if(this.browser.ie){G="about:blank";}J.setAttribute("src",G);var F=new YAHOO.util.Element(J);return F;},_isElement:function(G,F){if(G&&G.tagName&&(G.tagName.toLowerCase()==F)){return true;}if(G&&G.getAttribute&&(G.getAttribute("tag")==F)){return true;}return false;},_hasParent:function(G,F){if(!G||!G.parentNode){return false;}while(G.parentNode){if(this._isElement(G,F)){return G;}if(G.parentNode){G=G.parentNode;}else{return false;}}return false;},_getDoc:function(){var F=false;if(this.get){if(this.get("iframe")){if(this.get("iframe").get){if(this.get("iframe").get("element")){try{if(this.get("iframe").get("element").contentWindow){if(this.get("iframe").get("element").contentWindow.document){F=this.get("iframe").get("element").contentWindow.document;
+return F;}}}catch(G){}}}}}return false;},_getWindow:function(){return this.get("iframe").get("element").contentWindow;},_focusWindow:function(F){if(this.browser.webkit){if(F){this._getSelection().setBaseAndExtent(this._getDoc().body.firstChild,0,this._getDoc().body.firstChild,1);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(false);}}else{this._getSelection().setBaseAndExtent(this._getDoc().body,1,this._getDoc().body,1);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(false);}}this._getWindow().focus();}else{this._getWindow().focus();}},_hasSelection:function(){var H=this._getSelection();var F=this._getRange();var G=false;if(!H||!F){return G;}if(this.browser.ie||this.browser.opera){if(F.text){G=true;}if(F.html){G=true;}}else{if(this.browser.webkit){if(H+""!==""){G=true;}}else{if(H&&(H.toString()!=="")&&(H!==undefined)){G=true;}}}return G;},_getSelection:function(){var F=n!
 ull;if(this._getDoc()&&this._getWindow()){if(this._getDoc().selection){F=this._getDoc().selection;}else{F=this._getWindow().getSelection();}if(this.browser.webkit){if(F.baseNode){this._selection={};this._selection.baseNode=F.baseNode;this._selection.baseOffset=F.baseOffset;this._selection.extentNode=F.extentNode;this._selection.extentOffset=F.extentOffset;}else{if(this._selection!==null){F=this._getWindow().getSelection();F.setBaseAndExtent(this._selection.baseNode,this._selection.baseOffset,this._selection.extentNode,this._selection.extentOffset);this._selection=null;}}}}return F;},_selectNode:function(G){if(!G){return false;}var H=this._getSelection(),F=null;if(this.browser.ie){try{F=this._getDoc().body.createTextRange();F.moveToElementText(G);F.select();}catch(I){}}else{if(this.browser.webkit){H.setBaseAndExtent(G,0,G,G.innerText.length);}else{if(this.browser.opera){H=this._getWindow().getSelection();F=this._getDoc().createRange();F.selectNode(G);H.removeAllRanges();H.ad!
 dRange(F);}else{F=this._getDoc().createRange();F.selectNodeCon!
 tents(G)
;H.removeAllRanges();H.addRange(F);}}}},_getRange:function(){var F=this._getSelection();if(F===null){return null;}if(this.browser.webkit&&!F.getRangeAt){var H=this._getDoc().createRange();try{H.setStart(F.anchorNode,F.anchorOffset);H.setEnd(F.focusNode,F.focusOffset);}catch(G){H=this._getWindow().getSelection()+"";}return H;}if(this.browser.ie||this.browser.opera){try{return F.createRange();}catch(G){return null;}}if(F.rangeCount>0){return F.getRangeAt(0);}return null;},_setDesignMode:function(F){try{var H=true;if(this.browser.ie&&(F.toLowerCase()=="off")){H=false;}if(H){this._getDoc().designMode=F;}}catch(G){}},_toggleDesignMode:function(){var G=this._getDoc().designMode.toLowerCase(),F="on";if(G=="on"){F="off";}this._setDesignMode(F);return F;},_initEditor:function(){if(this.browser.ie){this._getDoc().body.style.margin="0";}if(!this.get("disabled")){if(this._getDoc().designMode.toLowerCase()!="on"){this._setDesignMode("on");this._contentTimerCounter=0;}}if(!this._getDoc().!
 body){this._contentTimerCounter=0;this._checkLoaded();return false;}this.toolbar.on("buttonClick",this._handleToolbarClick,this,true);A.on(this._getDoc(),"mouseup",this._handleMouseUp,this,true);A.on(this._getDoc(),"mousedown",this._handleMouseDown,this,true);A.on(this._getDoc(),"click",this._handleClick,this,true);A.on(this._getDoc(),"dblclick",this._handleDoubleClick,this,true);A.on(this._getDoc(),"keypress",this._handleKeyPress,this,true);A.on(this._getDoc(),"keyup",this._handleKeyUp,this,true);A.on(this._getDoc(),"keydown",this._handleKeyDown,this,true);if(!this.get("disabled")){this.toolbar.set("disabled",false);}this.fireEvent("editorContentLoaded",{type:"editorLoaded",target:this});if(this.get("dompath")){var F=this;setTimeout(function(){F._writeDomPath.call(F);},150);}this.nodeChange(true);this._setBusy(true);},_checkLoaded:function(){this._contentTimerCounter++;if(this._contentTimer){clearTimeout(this._contentTimer);}if(this._contentTimerCounter>500){return false;}!
 var H=false;try{if(this._getDoc()&&this._getDoc().body){if(thi!
 s.browse
r.ie){if(this._getDoc().body.readyState=="complete"){H=true;}}else{if(this._getDoc().body._rteLoaded===true){H=true;}}}}catch(G){H=false;}if(H===true){this._initEditor();}else{var F=this;this._contentTimer=setTimeout(function(){F._checkLoaded.call(F);},20);}},_setInitialContent:function(){var G=D.substitute(this.get("html"),{TITLE:this.STR_TITLE,CONTENT:this._cleanIncomingHTML(this.get("element").value),CSS:this.get("css"),HIDDEN_CSS:((this.get("hiddencss"))?this.get("hiddencss"):"/* No Hidden CSS */"),EXTRA_CSS:((this.get("extracss"))?this.get("extracss"):"/* No Extra CSS */")}),F=true;if(document.compatMode!="BackCompat"){G=this._docType+"\n"+G;}else{}if(this.browser.ie||this.browser.webkit||this.browser.opera||(navigator.userAgent.indexOf("Firefox/1.5")!=-1)){try{if(this.browser.air){var J=this._getDoc().implementation.createHTMLDocument();var K=this._getDoc();K.open();K.close();J.open();J.write(G);J.close();var H=K.importNode(J.getElementsByTagName("html")[0],true);K.rep!
 laceChild(H,K.getElementsByTagName("html")[0]);K.body._rteLoaded=true;}else{this._getDoc().open();this._getDoc().write(G);this._getDoc().close();}}catch(I){F=false;}}else{this.get("iframe").get("element").src="data:text/html;charset=utf-8,"+encodeURIComponent(G);}if(F){this._checkLoaded();}},_setMarkupType:function(F){switch(this.get("markup")){case"css":this._setEditorStyle(true);break;case"default":this._setEditorStyle(false);break;case"semantic":case"xhtml":if(this._semantic[F]){this._setEditorStyle(false);}else{this._setEditorStyle(true);}break;}},_setEditorStyle:function(G){try{this._getDoc().execCommand("useCSS",false,!G);}catch(F){}},_getSelectedElement:function(){var I=this._getDoc(),F=null,G=null,J=null;if(this.browser.ie){this.currentEvent=this._getWindow().event;F=this._getRange();if(F){J=F.item?F.item(0):F.parentElement();if(J==I.body){J=null;}}if((this.currentEvent!==null)&&(this.currentEvent.keyCode===0)){J=A.getTarget(this.currentEvent);
+}}else{G=this._getSelection();F=this._getRange();if(!G||!F){return null;}if(!this._hasSelection()){if(G.anchorNode&&(G.anchorNode.nodeType==3)){if(G.anchorNode.parentNode){J=G.anchorNode.parentNode;}if(G.anchorNode.nextSibling!=G.focusNode.nextSibling){J=G.anchorNode.nextSibling;}}if(this._isElement(J,"br")){J=null;}if(!J){J=F.commonAncestorContainer;if(!F.collapsed){if(F.startContainer==F.endContainer){if(F.startOffset-F.endOffset<2){if(F.startContainer.hasChildNodes()){J=F.startContainer.childNodes[F.startOffset];}}}}}}}if(this.currentEvent!==null){try{switch(this.currentEvent.type){case"click":case"mousedown":case"mouseup":J=A.getTarget(this.currentEvent);break;default:break;}}catch(H){}}else{if((this.currentElement&&this.currentElement[0])&&(!this.browser.ie)){J=this.currentElement[0];}}if(this.browser.opera||this.browser.webkit){if(this.currentEvent&&!J){J=YAHOO.util.Event.getTarget(this.currentEvent);}}if(!J||!J.tagName){J=I.body;}if(this._isElement(J,"html")){J=I.bod!
 y;}if(this._isElement(J,"body")){J=I.body;}if(J&&!J.parentNode){J=I.body;}if(J===undefined){J=null;}return J;},_getDomPath:function(F){if(!F){F=this._getSelectedElement();}var G=[];while(F!==null){if(F.ownerDocument!=this._getDoc()){F=null;break;}if(F.nodeName&&F.nodeType&&(F.nodeType==1)){G[G.length]=F;}if(this._isElement(F,"body")){break;}F=F.parentNode;}if(G.length===0){if(this._getDoc()&&this._getDoc().body){G[0]=this._getDoc().body;}}return G.reverse();},_writeDomPath:function(){var L=this._getDomPath(),J=[],H="",M="";for(var F=0;F<L.length;F++){var N=L[F].tagName.toLowerCase();if((N=="ol")&&(L[F].type)){N+=":"+L[F].type;}if(C.hasClass(L[F],"yui-tag")){N=L[F].getAttribute("tag");}if((this.get("markup")=="semantic")||(this.get("markup")=="xhtml")){switch(N){case"b":N="strong";break;case"i":N="em";break;}}if(!C.hasClass(L[F],"yui-non")){if(C.hasClass(L[F],"yui-tag")){M=N;}else{H=((L[F].className!=="")?"."+L[F].className.replace(/ /g,"."):"");if((H.indexOf("yui")!=-1)||(H!
 .toLowerCase().indexOf("apple-style-span")!=-1)){H="";}M=N+((L!
 [F].id)?
"#"+L[F].id:"")+H;}switch(N){case"a":if(L[F].getAttribute("href",2)){M+=":"+L[F].getAttribute("href",2).replace("mailto:","").replace("http:/"+"/","").replace("https:/"+"/","");}break;case"img":var G=L[F].height;var K=L[F].width;if(L[F].style.height){G=parseInt(L[F].style.height,10);}if(L[F].style.width){K=parseInt(L[F].style.width,10);}M+="("+G+"x"+K+")";break;}if(M.length>10){M='<span title="'+M+'">'+M.substring(0,10)+"..."+"</span>";}else{M='<span title="'+M+'">'+M+"</span>";}J[J.length]=M;}}var I=J.join(" "+this.SEP_DOMPATH+" ");if(this.dompath.innerHTML!=I){this.dompath.innerHTML=I;}},_fixNodes:function(){var K=this._getDoc(),I=[];for(var F in this.invalidHTML){if(YAHOO.lang.hasOwnProperty(this.invalidHTML,F)){if(F.toLowerCase()!="span"){var G=K.body.getElementsByTagName(F);if(G.length){for(var H=0;H<G.length;H++){I.push(G[H]);}}}}}for(var J=0;J<I.length;J++){if(I[J].parentNode){if(D.isObject(this.invalidHTML[I[J].tagName.toLowerCase()])&&this.invalidHTML[I[J].tagName.t!
 oLowerCase()].keepContents){this._swapEl(I[J],"span",function(M){M.className="yui-non";});}else{I[J].parentNode.removeChild(I[J]);}}}var L=this._getDoc().getElementsByTagName("img");C.addClass(L,"yui-img");},_isNonEditable:function(H){if(this.get("allowNoEdit")){var G=A.getTarget(H);if(this._isElement(G,"html")){G=null;}var J=this._getDomPath(G);for(var F=(J.length-1);F>-1;F--){if(C.hasClass(J[F],this.CLASS_NOEDIT)){try{this._getDoc().execCommand("enableObjectResizing",false,"false");}catch(I){}this.nodeChange();A.stopEvent(H);return true;}}try{this._getDoc().execCommand("enableObjectResizing",false,"true");}catch(I){}}return false;},_setCurrentEvent:function(F){this.currentEvent=F;},_handleClick:function(G){if(this._isNonEditable(G)){return false;}this._setCurrentEvent(G);if(this.currentWindow){this.closeWindow();}if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window!
 .scope);}if(this.browser.webkit){var F=A.getTarget(G);if(this.!
 _isEleme
nt(F,"a")||this._isElement(F.parentNode,"a")){A.stopEvent(G);this.nodeChange();}}else{this.nodeChange();}},_handleMouseUp:function(G){if(this._isNonEditable(G)){return false;}var F=this;if(this.browser.opera){var H=A.getTarget(G);if(this._isElement(H,"img")){this.nodeChange();if(this.operaEvent){clearTimeout(this.operaEvent);this.operaEvent=null;this._handleDoubleClick(G);}else{this.operaEvent=window.setTimeout(function(){F.operaEvent=false;},700);}}}if(this.browser.webkit||this.browser.opera){if(this.browser.webkit){A.stopEvent(G);}}this.nodeChange();this.fireEvent("editorMouseUp",{type:"editorMouseUp",target:this,ev:G});},_handleMouseDown:function(F){if(this._isNonEditable(F)){return false;}this._setCurrentEvent(F);var G=A.getTarget(F);if(this.browser.webkit&&this._hasSelection()){var H=this._getSelection();if(!this.browser.webkit3){H.collapse(true);}else{H.collapseToStart();}}if(this.browser.webkit&&this._lastImage){C.removeClass(this._lastImage,"selected");this._lastImag!
 e=null;}if(this._isElement(G,"img")||this._isElement(G,"a")){if(this.browser.webkit){A.stopEvent(F);if(this._isElement(G,"img")){C.addClass(G,"selected");this._lastImage=G;}}this.nodeChange();}this.fireEvent("editorMouseDown",{type:"editorMouseDown",target:this,ev:F});},_handleDoubleClick:function(F){if(this._isNonEditable(F)){return false;}this._setCurrentEvent(F);var G=A.getTarget(F);if(this._isElement(G,"img")){this.currentElement[0]=G;this.toolbar.fireEvent("insertimageClick",{type:"insertimageClick",target:this.toolbar});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});}else{if(this._hasParent(G,"a")){this.currentElement[0]=this._hasParent(G,"a");this.toolbar.fireEvent("createlinkClick",{type:"createlinkClick",target:this.toolbar});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});}}this.nodeChange();this.editorDirty=false;this.fireEvent("editorDoubleClick",{type:"editorDoubleClick",target:this,ev:F});
+},_handleKeyUp:function(G){if(this._isNonEditable(G)){return false;}this._setCurrentEvent(G);switch(G.keyCode){case 37:case 38:case 39:case 40:case 46:case 8:case 87:if((G.keyCode==87)&&this.currentWindow&&G.shiftKey&&G.ctrlKey){this.closeWindow();}else{if(!this.browser.ie){if(this._nodeChangeTimer){clearTimeout(this._nodeChangeTimer);}var F=this;this._nodeChangeTimer=setTimeout(function(){F._nodeChangeTimer=null;F.nodeChange.call(F);},100);}else{this.nodeChange();}this.editorDirty=true;}break;}this.fireEvent("editorKeyUp",{type:"editorKeyUp",target:this,ev:G});},_handleKeyPress:function(F){if(this.get("allowNoEdit")){if(F&&F.keyCode&&((F.keyCode==46)||F.keyCode==63272)){A.stopEvent(F);}}if(this._isNonEditable(F)){return false;}this._setCurrentEvent(F);if(this.browser.webkit){if(!this.browser.webkit3){if(F.keyCode&&(F.keyCode==122)&&(F.metaKey)){if(this._hasParent(this._getSelectedElement(),"li")){A.stopEvent(F);}}}this._listFix(F);}this.fireEvent("editorKeyPress",{type:"ed!
 itorKeyPress",target:this,ev:F});},_listFix:function(L){var O=null,J=null,F=false,H=null;if(this.browser.webkit){if(L.keyCode&&(L.keyCode==13)){if(this._hasParent(this._getSelectedElement(),"li")){var I=this._hasParent(this._getSelectedElement(),"li");var N=this._getDoc().createElement("li");N.innerHTML='<span class="yui-non"> </span> ';if(I.nextSibling){I.parentNode.insertBefore(N,I.nextSibling);}else{I.parentNode.appendChild(N);}this.currentElement[0]=N;this._selectNode(N.firstChild);if(!this.browser.webkit3){I.parentNode.style.display="list-item";setTimeout(function(){I.parentNode.style.display="block";},1);}A.stopEvent(L);}}}if(L.keyCode&&((!this.browser.webkit3&&(L.keyCode==25))||((this.browser.webkit3||!this.browser.webkit)&&((L.keyCode==9)&&L.shiftKey)))){O=this._getSelectedElement();if(this._hasParent(O,"li")){O=this._hasParent(O,"li");if(this._hasParent(O,"ul")||this._hasParent(O,"ol")){J=this._hasParent(O,"ul");if(!J){J=this._hasParent(O,"ol");}if(this._!
 isElement(J.previousSibling,"li")){J.removeChild(O);J.parentNo!
 de.inser
tBefore(O,J.nextSibling);if(this.browser.ie){H=this._getDoc().body.createTextRange();H.moveToElementText(O);H.collapse(false);H.select();}if(this.browser.webkit){if(!this.browser.webkit3){J.style.display="list-item";J.parentNode.style.display="list-item";setTimeout(function(){J.style.display="block";J.parentNode.style.display="block";},1);}}A.stopEvent(L);}}}}if(L.keyCode&&((L.keyCode==9)&&(!L.shiftKey))){var G=this._getSelectedElement();if(this._hasParent(G,"li")){F=this._hasParent(G,"li").innerHTML;}if(this.browser.webkit){this._getDoc().execCommand("inserttext",false,"\t");}O=this._getSelectedElement();if(this._hasParent(O,"li")){J=this._hasParent(O,"li");var K=this._getDoc().createElement(J.parentNode.tagName.toLowerCase());if(this.browser.webkit){var M=C.getElementsByClassName("Apple-tab-span","span",J);if(M[0]){J.removeChild(M[0]);J.innerHTML=D.trim(J.innerHTML);if(F){J.innerHTML='<span class="yui-non">'+F+"</span> ";}else{J.innerHTML='<span class="yui-non"> !
 </span> ';}}}else{if(F){J.innerHTML=F+" ";}else{J.innerHTML=" ";}}J.parentNode.replaceChild(K,J);K.appendChild(J);if(this.browser.webkit){this._getSelection().setBaseAndExtent(J.firstChild,1,J.firstChild,J.firstChild.innerText.length);if(!this.browser.webkit3){J.parentNode.parentNode.style.display="list-item";setTimeout(function(){J.parentNode.parentNode.style.display="block";},1);}}else{if(this.browser.ie){H=this._getDoc().body.createTextRange();H.moveToElementText(J);H.collapse(false);H.select();}else{this._selectNode(J);}}A.stopEvent(L);}if(this.browser.webkit){A.stopEvent(L);}this.nodeChange();}},_handleKeyDown:function(K){if(this._isNonEditable(K)){return false;}this._setCurrentEvent(K);if(this.currentWindow){this.closeWindow();}if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}var J=false,L=null,H=false;if(K.shiftKey&&K.ctrlKey){J=true!
 ;}switch(K.keyCode){case 84:if(K.shiftKey&&K.ctrlKey){var I=th!
 is.toolb
ar.getElementsByTagName("h2")[0];if(I){I.focus();}A.stopEvent(K);J=false;}break;case 27:if(K.shiftKey){this.afterElement.focus();A.stopEvent(K);H=false;}break;case 76:if(this._hasSelection()){if(K.shiftKey&&K.ctrlKey){var G=true;if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("createlink")){G=false;}}if(G){this.execCommand("createlink","");this.toolbar.fireEvent("createlinkClick",{type:"createlinkClick",target:this.toolbar});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});J=false;}}}break;case 65:if(K.metaKey&&this.browser.webkit){A.stopEvent(K);this._getSelection().setBaseAndExtent(this._getDoc().body,1,this._getDoc().body,this._getDoc().body.innerHTML.length);}break;case 66:L="bold";break;case 73:L="italic";break;case 85:L="underline";break;case 13:if(this.browser.ie){var M=this._getRange();var F=this._getSelectedElement();if(!this._isElement(F,"li")){if(M){M.pasteHTML("<br>");M.collapse(false);M.select();}A.stopEvent(K);}}}if(this.!
 browser.ie){this._listFix(K);}if(J&&L){this.execCommand(L,null);A.stopEvent(K);this.nodeChange();}this.fireEvent("editorKeyDown",{type:"editorKeyDown",target:this,ev:K});},nodeChange:function(G){var H=parseInt(this.get("nodeChangeThreshold"),10);var N=Math.round(new Date().getTime()/1000);if(G===true){this._lastNodeChange=0;}if((this._lastNodeChange+H)<N){var Q=this;if(this._fixNodesTimer===null){this._fixNodesTimer=window.setTimeout(function(){Q._fixNodes.call(Q);Q._fixNodesTimer=null;},0);}}this._lastNodeChange=N;if(this.currentEvent){this._lastNodeChangeEvent=this.currentEvent.type;}var Y=this.fireEvent("beforeNodeChange",{type:"beforeNodeChange",target:this});if(Y===false){return false;}if(this.get("dompath")){this._writeDomPath();}if(!this.get("disabled")){if(this.STOP_NODE_CHANGE){this.STOP_NODE_CHANGE=false;return false;}else{var S=this._getSelection(),P=this._getRange(),F=this._getSelectedElement(),L=this.toolbar.getButtonByValue("fontname"),K=this.toolbar.getButton!
 ByValue("fontsize");
+if(G!==true){this.editorDirty=true;}var M={};if(this._lastButton){M[this._lastButton.id]=true;}if(!this._isElement(F,"body")){if(L){M[L.get("id")]=true;}if(K){M[K.get("id")]=true;}}this.toolbar.resetAllButtons(M);for(var Z=0;Z<this._disabled.length;Z++){var O=this.toolbar.getButtonByValue(this._disabled[Z]);if(O&&O.get){if(this._lastButton&&(O.get("id")===this._lastButton.id)){}else{if(!this._hasSelection()){switch(this._disabled[Z]){case"fontname":case"fontsize":break;default:this.toolbar.disableButton(O);}}else{if(!this._alwaysDisabled[this._disabled[Z]]){this.toolbar.enableButton(O);}}if(!this._alwaysEnabled[this._disabled[Z]]){this.toolbar.deselectButton(O);}}}}var R=this._getDomPath();var a=null,V=null;for(var W=0;W<R.length;W++){a=R[W].tagName.toLowerCase();if(R[W].getAttribute("tag")){a=R[W].getAttribute("tag").toLowerCase();}V=this._tag2cmd[a];if(V===undefined){V=[];}if(!D.isArray(V)){V=[V];}if(R[W].style.fontWeight.toLowerCase()=="bold"){V[V.length]="bold";}if(R[W]!
 .style.fontStyle.toLowerCase()=="italic"){V[V.length]="italic";}if(R[W].style.textDecoration.toLowerCase()=="underline"){V[V.length]="underline";}if(V.length>0){for(var U=0;U<V.length;U++){this.toolbar.selectButton(V[U]);this.toolbar.enableButton(V[U]);}}switch(R[W].style.textAlign.toLowerCase()){case"left":case"right":case"center":case"justify":var T=R[W].style.textAlign.toLowerCase();if(R[W].style.textAlign.toLowerCase()=="justify"){T="full";}this.toolbar.selectButton("justify"+T);this.toolbar.enableButton("justify"+T);break;}}if(L){var X=L._configs.label._initialConfig.value;L.set("label",'<span class="yui-toolbar-fontname-'+E(X)+'">'+X+"</span>");this._updateMenuChecked("fontname",X);}if(K){K.set("label",K._configs.label._initialConfig.value);}var J=this.toolbar.getButtonByValue("heading");if(J){J.set("label",J._configs.label._initialConfig.value);this._updateMenuChecked("heading","none");}var I=this.toolbar.getButtonByValue("insertimage");if(I&&this.currentWindow&&(thi!
 s.currentWindow.name=="insertimage")){this.toolbar.disableButt!
 on(I);}}
}this.fireEvent("afterNodeChange",{type:"afterNodeChange",target:this});},_updateMenuChecked:function(F,G,I){if(!I){I=this.toolbar;}var H=I.getButtonByValue(F);H.checkValue(G);},_handleToolbarClick:function(G){var I="";var J="";var H=G.button.value;if(G.button.menucmd){I=H;H=G.button.menucmd;}this._lastButton=G.button;if(this.STOP_EXEC_COMMAND){this.STOP_EXEC_COMMAND=false;return false;}else{this.execCommand(H,I);if(!this.browser.webkit){var F=this;setTimeout(function(){F._focusWindow.call(F);},5);}}A.stopEvent(G);},_setupAfterElement:function(){if(!this.beforeElement){this.beforeElement=document.createElement("h2");this.beforeElement.className="yui-editor-skipheader";this.beforeElement.tabIndex="-1";this.beforeElement.innerHTML=this.STR_BEFORE_EDITOR;this.get("element_cont").get("firstChild").insertBefore(this.beforeElement,this.toolbar.get("nextSibling"));}if(!this.afterElement){this.afterElement=document.createElement("h2");this.afterElement.className="yui-editor-skiphead!
 er";this.afterElement.tabIndex="-1";this.afterElement.innerHTML=this.STR_LEAVE_EDITOR;this.get("element_cont").get("firstChild").appendChild(this.afterElement);}},_disableEditor:function(G){if(G){if(!this._mask){if(!!this.browser.ie){this._setDesignMode("off");}if(this.toolbar){this.toolbar.set("disabled",true);}this._mask=document.createElement("DIV");C.setStyle(this._mask,"height","100%");C.setStyle(this._mask,"width","100%");C.setStyle(this._mask,"position","absolute");C.setStyle(this._mask,"top","0");C.setStyle(this._mask,"left","0");C.setStyle(this._mask,"opacity",".5");C.addClass(this._mask,"yui-editor-masked");this.get("iframe").get("parentNode").appendChild(this._mask);}}else{if(this._mask){this._mask.parentNode.removeChild(this._mask);this._mask=null;if(this.toolbar){this.toolbar.set("disabled",false);}this._setDesignMode("on");this._focusWindow();var F=this;window.setTimeout(function(){F.nodeChange.call(F);},100);}}},EDITOR_PANEL_ID:"yui-editor-panel",SEP_DOMPATH:!
 "<",STR_LEAVE_EDITOR:"You have left the Rich Text Editor.",STR!
 _BEFORE_
EDITOR:"This text field can contain stylized text and graphics. To cycle through all formatting options, use the keyboard shortcut Control + Shift + T to place focus on the toolbar and navigate between option heading names. <h4>Common formatting keyboard shortcuts:</h4><ul><li>Control Shift B sets text to bold</li> <li>Control Shift I sets text to italic</li> <li>Control Shift U underlines text</li> <li>Control Shift L adds an HTML link</li> <li>To exit this text editor use the keyboard shortcut Control + Shift + ESC.</li></ul>",STR_TITLE:"Rich Text Area.",STR_IMAGE_HERE:"Image Url Here",STR_LINK_URL:"Link URL",STOP_EXEC_COMMAND:false,STOP_NODE_CHANGE:false,CLASS_NOEDIT:"yui-noedit",CLASS_CONTAINER:"yui-editor-container",CLASS_EDITABLE:"yui-editor-editable",CLASS_EDITABLE_CONT:"yui-editor-editable-container",CLASS_PREFIX:"yui-editor",browser:function(){var F=YAHOO.env.ua;if(F.webkit>=420){F.webkit3=F.webkit;}else{F.webkit3=0;}return F;}(),init:function(G,F){if(!this._default!
 Toolbar){this._defaultToolbar={collapse:true,titlebar:"Text Editing Tools",draggable:false,buttons:[{group:"fontstyle",label:"Font Name and Size",buttons:[{type:"select",label:"Arial",value:"fontname",disabled:true,menu:[{text:"Arial",checked:true},{text:"Arial Black"},{text:"Comic Sans MS"},{text:"Courier New"},{text:"Lucida Console"},{text:"Tahoma"},{text:"Times New Roman"},{text:"Trebuchet MS"},{text:"Verdana"}]},{type:"spin",label:"13",value:"fontsize",range:[9,75],disabled:true}]},{type:"separator"},{group:"textstyle",label:"Font Style",buttons:[{type:"push",label:"Bold CTRL + SHIFT + B",value:"bold"},{type:"push",label:"Italic CTRL + SHIFT + I",value:"italic"},{type:"push",label:"Underline CTRL + SHIFT + U",value:"underline"},{type:"separator"},{type:"color",label:"Font Color",value:"forecolor",disabled:true},{type:"color",label:"Background Color",value:"backcolor",disabled:true}]},{type:"separator"},{group:"indentlist",label:"Lists",buttons:[{type:"push",label:"Creat!
 e an Unordered List",value:"insertunorderedlist"},{type:"push"!
 ,label:"
Create an Ordered List",value:"insertorderedlist"}]},{type:"separator"},{group:"insertitem",label:"Insert Item",buttons:[{type:"push",label:"HTML Link CTRL + SHIFT + L",value:"createlink",disabled:true},{type:"push",label:"Insert Image",value:"insertimage"}]}]};
+}YAHOO.widget.SimpleEditor.superclass.init.call(this,G,F);YAHOO.widget.EditorInfo._instances[this.get("id")]=this;this.currentElement=[];this.on("contentReady",function(){this.DOMReady=true;this.fireQueue();},this,true);},initAttributes:function(F){YAHOO.widget.SimpleEditor.superclass.initAttributes.call(this,F);var G=this;this.setAttributeConfig("container",{writeOnce:true,value:F.container||false});this.setAttributeConfig("plainText",{writeOnce:true,value:F.plainText||false});this.setAttributeConfig("iframe",{value:null});this.setAttributeConfig("textarea",{value:null,writeOnce:true});this.setAttributeConfig("container",{readOnly:true,value:null});this.setAttributeConfig("nodeChangeThreshold",{value:F.nodeChangeThreshold||3,validator:YAHOO.lang.isNumber});this.setAttributeConfig("allowNoEdit",{value:F.allowNoEdit||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("limitCommands",{value:F.limitCommands||false,validator:YAHOO.lang.isBoolean});this.setAttributeC!
 onfig("element_cont",{value:F.element_cont});this.setAttributeConfig("editor_wrapper",{value:F.editor_wrapper||null,writeOnce:true});this.setAttributeConfig("height",{value:F.height||C.getStyle(G.get("element"),"height"),method:function(H){if(this._rendered){if(this.get("animate")){var I=new YAHOO.util.Anim(this.get("iframe").get("parentNode"),{height:{to:parseInt(H,10)}},0.5);I.animate();}else{C.setStyle(this.get("iframe").get("parentNode"),"height",H);}}}});this.setAttributeConfig("autoHeight",{value:F.autoHeight||false,method:function(H){if(H){if(this.get("iframe")){this.get("iframe").get("element").setAttribute("scrolling","no");}this.on("afterNodeChange",this._handleAutoHeight,this,true);this.on("editorKeyDown",this._handleAutoHeight,this,true);this.on("editorKeyPress",this._handleAutoHeight,this,true);}else{if(this.get("iframe")){this.get("iframe").get("element").setAttribute("scrolling","auto");}this.unsubscribe("afterNodeChange",this._handleAutoHeight);this.unsubscr!
 ibe("editorKeyDown",this._handleAutoHeight);this.unsubscribe("!
 editorKe
yPress",this._handleAutoHeight);}}});this.setAttributeConfig("width",{value:F.width||C.getStyle(this.get("element"),"width"),method:function(H){if(this._rendered){if(this.get("animate")){var I=new YAHOO.util.Anim(this.get("element_cont").get("element"),{width:{to:parseInt(H,10)}},0.5);I.animate();}else{this.get("element_cont").setStyle("width",H);}}}});this.setAttributeConfig("blankimage",{value:F.blankimage||this._getBlankImage()});this.setAttributeConfig("css",{value:F.css||this._defaultCSS,writeOnce:true});this.setAttributeConfig("html",{value:F.html||'<html><head><title>{TITLE}</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><base href="'+this._baseHREF+'"><style>{CSS}</style><style>{HIDDEN_CSS}</style><style>{EXTRA_CSS}</style></head><body onload="document.body._rteLoaded = true;">{CONTENT}</body></html>',writeOnce:true});this.setAttributeConfig("extracss",{value:F.extracss||"",writeOnce:true});this.setAttributeConfig("handleSubmit",{value:F.!
 handleSubmit||false,method:function(H){if(this.get("element").form){if(!this._formButtons){this._formButtons=[];}if(H){A.on(this.get("element").form,"submit",this._handleFormSubmit,this,true);var I=this.get("element").form.getElementsByTagName("input");for(var K=0;K<I.length;K++){var J=I[K].getAttribute("type");if(J&&(J.toLowerCase()=="submit")){A.on(I[K],"click",this._handleFormButtonClick,this,true);this._formButtons[this._formButtons.length]=I[K];}}}else{A.unsubscribe(this.get("element").form,"submit",this._handleFormSubmit);if(this._formButtons){A.unsubscribe(this._formButtons,"click",this._handleFormButtonClick);}}}}});this.setAttributeConfig("disabled",{value:false,method:function(H){if(this._rendered){this._disableEditor(H);}}});this.setAttributeConfig("toolbar_cont",{value:null,writeOnce:true});this.setAttributeConfig("toolbar",{value:F.toolbar||this._defaultToolbar,writeOnce:true,method:function(H){if(!H.buttonType){H.buttonType=this._defaultToolbar.buttonType;}thi!
 s._defaultToolbar=H;}});this.setAttributeConfig("animate",{val!
 ue:((F.a
nimate)?((YAHOO.util.Anim)?true:false):false),validator:function(I){var H=true;if(!YAHOO.util.Anim){H=false;}return H;}});this.setAttributeConfig("panel",{value:null,writeOnce:true,validator:function(I){var H=true;if(!YAHOO.widget.Overlay){H=false;}return H;}});this.setAttributeConfig("focusAtStart",{value:F.focusAtStart||false,writeOnce:true,method:function(){this.on("editorContentLoaded",function(){var H=this;setTimeout(function(){H._focusWindow.call(H,true);H.editorDirty=false;},400);},this,true);}});this.setAttributeConfig("dompath",{value:F.dompath||false,method:function(H){if(H&&!this.dompath){this.dompath=document.createElement("DIV");this.dompath.id=this.get("id")+"_dompath";C.addClass(this.dompath,"dompath");this.get("element_cont").get("firstChild").appendChild(this.dompath);if(this.get("iframe")){this._writeDomPath();}}else{if(!H&&this.dompath){this.dompath.parentNode.removeChild(this.dompath);this.dompath=null;}}}});this.setAttributeConfig("markup",{value:F.marku!
 p||"semantic",validator:function(H){switch(H.toLowerCase()){case"semantic":case"css":case"default":case"xhtml":return true;}return false;}});this.setAttributeConfig("removeLineBreaks",{value:F.removeLineBreaks||false,validator:YAHOO.lang.isBoolean});this.on("afterRender",function(){this._renderPanel();});},_getBlankImage:function(){if(!this.DOMReady){this._queue[this._queue.length]=["_getBlankImage",arguments];return"";}var F="";if(!this._blankImageLoaded){if(YAHOO.widget.EditorInfo.blankImage){this.set("blankimage",YAHOO.widget.EditorInfo.blankImage);this._blankImageLoaded=true;}else{var G=document.createElement("div");G.style.position="absolute";G.style.top="-9999px";G.style.left="-9999px";G.className=this.CLASS_PREFIX+"-blankimage";document.body.appendChild(G);F=YAHOO.util.Dom.getStyle(G,"background-image");F=F.replace("url(","").replace(")","").replace(/"/g,"");F=F.replace("app:/","");this.set("blankimage",F);
+this._blankImageLoaded=true;YAHOO.widget.EditorInfo.blankImage=F;}}else{F=this.get("blankimage");}return F;},_handleAutoHeight:function(){var J=this._getDoc(),G=J.body,K=J.documentElement;var F=parseInt(C.getStyle(this.get("editor_wrapper"),"height"),10);var H=G.scrollHeight;if(this.browser.webkit){H=K.scrollHeight;}if(H<parseInt(this.get("height"),10)){H=parseInt(this.get("height"),10);}if((F!=H)&&(H>=parseInt(this.get("height"),10))){C.setStyle(this.get("editor_wrapper"),"height",H+"px");if(this.browser.ie){this.get("iframe").setStyle("height","99%");this.get("iframe").setStyle("zoom","1");var I=this;window.setTimeout(function(){I.get("iframe").setStyle("height","100%");},1);}}},_formButtons:null,_formButtonClicked:null,_handleFormButtonClick:function(G){var F=A.getTarget(G);this._formButtonClicked=F;},_handleFormSubmit:function(I){A.stopEvent(I);this.saveHTML();var H=this.get("element").form;var F=this._formButtonClicked||false;var G=this;window.setTimeout(function(){YAH!
 OO.util.Event.removeListener(H,"submit",G._handleFormSubmit);if(YAHOO.env.ua.ie){H.fireEvent("onsubmit");if(F&&!F.disabled){F.click();}}else{if(F&&!F.disabled){F.click();}else{var J=document.createEvent("HTMLEvents");J.initEvent("submit",true,true);H.dispatchEvent(J);if(YAHOO.env.ua.webkit){if(YAHOO.lang.isFunction(H.submit)){H.submit();}}}}},200);},_handleFontSize:function(H){var F=this.toolbar.getButtonById(H.button.id);var G=F.get("label")+"px";this.execCommand("fontsize",G);this.STOP_EXEC_COMMAND=true;},_handleColorPicker:function(H){var G=H.button;var F="#"+H.color;if((G=="forecolor")||(G=="backcolor")){this.execCommand(G,F);}},_handleAlign:function(I){var H=null;for(var F=0;F<I.button.menu.length;F++){if(I.button.menu[F].value==I.button.value){H=I.button.menu[F].value;}}var G=this._getSelection();this.execCommand(H,G);this.STOP_EXEC_COMMAND=true;},_handleAfterNodeChange:function(){var R=this._getDomPath(),M=null,I=null,N=null,G=false;var K=this.toolbar.getButtonByValu!
 e("fontname");var L=this.toolbar.getButtonByValue("fontsize");!
 var F=th
is.toolbar.getButtonByValue("heading");for(var H=0;H<R.length;H++){M=R[H];var Q=M.tagName.toLowerCase();if(M.getAttribute("tag")){Q=M.getAttribute("tag");}I=M.getAttribute("face");if(C.getStyle(M,"font-family")){I=C.getStyle(M,"font-family");I=I.replace(/'/g,"");}if(Q.substring(0,1)=="h"){if(F){for(var J=0;J<F._configs.menu.value.length;J++){if(F._configs.menu.value[J].value.toLowerCase()==Q){F.set("label",F._configs.menu.value[J].text);}}this._updateMenuChecked("heading",Q);}}}if(K){for(var P=0;P<K._configs.menu.value.length;P++){if(I&&K._configs.menu.value[P].text.toLowerCase()==I.toLowerCase()){G=true;I=K._configs.menu.value[P].text;}}if(!G){I=K._configs.label._initialConfig.value;}var O='<span class="yui-toolbar-fontname-'+E(I)+'">'+I+"</span>";if(K.get("label")!=O){K.set("label",O);this._updateMenuChecked("fontname",I);}}if(L){N=parseInt(C.getStyle(M,"fontSize"),10);if((N===null)||isNaN(N)){N=L._configs.label._initialConfig.value;}L.set("label",""+N);}if(!this._isElemen!
 t(M,"body")&&!this._isElement(M,"img")){this.toolbar.enableButton(K);this.toolbar.enableButton(L);this.toolbar.enableButton("forecolor");this.toolbar.enableButton("backcolor");}if(this._isElement(M,"img")){if(YAHOO.widget.Overlay){this.toolbar.enableButton("createlink");}}if(this._isElement(M,"blockquote")){this.toolbar.selectButton("indent");this.toolbar.disableButton("indent");this.toolbar.enableButton("outdent");}if(this._hasParent(M,"ol")||this._hasParent(M,"ul")){this.toolbar.disableButton("indent");}this._lastButton=null;},_setBusy:function(F){},_handleInsertImageClick:function(){if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("insertimage")){return false;}}this.toolbar.set("disabled",true);this.on("afterExecCommand",function(){var F=this.currentElement[0],H="http://";if(!F){F=this._getSelectedElement();}if(F){if(F.getAttribute("src")){H=F.getAttribute("src",2);if(H.indexOf(this.get("blankimage"))!=-1){H=this.STR_IMAGE_HERE;}}}var G=prompt(this.STR_LIN!
 K_URL+": ",H);if((G!=="")&&(G!==null)){F.setAttribute("src",G)!
 ;}else{i
f(G===null){F.parentNode.removeChild(F);this.currentElement=[];this.nodeChange();}}this.closeWindow();this.toolbar.set("disabled",false);},this,true);},_handleInsertImageWindowClose:function(){this.nodeChange();},_isLocalFile:function(F){if((F!=="")&&((F.indexOf("file:/")!=-1)||(F.indexOf(":\\")!=-1))){return true;}return false;},_handleCreateLinkClick:function(){if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue("createlink")){return false;}}this.toolbar.set("disabled",true);this.on("afterExecCommand",function(){var H=this.currentElement[0],G="";if(H){if(H.getAttribute("href",2)!==null){G=H.getAttribute("href",2);}}var J=prompt(this.STR_LINK_URL+": ",G);if((J!=="")&&(J!==null)){var I=J;if((I.indexOf(":/"+"/")==-1)&&(I.substring(0,1)!="/")&&(I.substring(0,6).toLowerCase()!="mailto")){if((I.indexOf("@")!=-1)&&(I.substring(0,6).toLowerCase()!="mailto")){I="mailto:"+I;}else{if(I.substring(0,1)!="#"){I="http:/"+"/"+I;}}}H.setAttribute("href",I);}else{if(J!==null){va!
 r F=this._getDoc().createElement("span");F.innerHTML=H.innerHTML;C.addClass(F,"yui-non");H.parentNode.replaceChild(F,H);}}this.closeWindow();this.toolbar.set("disabled",false);});},_handleCreateLinkWindowClose:function(){this.nodeChange();this.currentElement=[];},render:function(){if(this._rendered){return false;}if(!this.DOMReady){this._queue[this._queue.length]=["render",arguments];return false;}this._rendered=true;var F=this;window.setTimeout(function(){F._render.call(F);},4);},_render:function(){this._setBusy();var F=this;this.set("textarea",this.get("element"));this.get("element_cont").setStyle("display","none");this.get("element_cont").addClass(this.CLASS_CONTAINER);this.set("iframe",this._createIframe());window.setTimeout(function(){F._setInitialContent.call(F);},10);this.get("editor_wrapper").appendChild(this.get("iframe").get("element"));if(this.get("disabled")){this._disableEditor(true);}var G=this.get("toolbar");
+if(G instanceof B){this.toolbar=G;this.toolbar.set("disabled",true);}else{G.disabled=true;this.toolbar=new B(this.get("toolbar_cont"),G);}this.fireEvent("toolbarLoaded",{type:"toolbarLoaded",target:this.toolbar});this.toolbar.on("toolbarCollapsed",function(){if(this.currentWindow){this.moveWindow();}},this,true);this.toolbar.on("toolbarExpanded",function(){if(this.currentWindow){this.moveWindow();}},this,true);this.toolbar.on("fontsizeClick",function(H){this._handleFontSize(H);},this,true);this.toolbar.on("colorPickerClicked",function(H){this._handleColorPicker(H);return false;},this,true);this.toolbar.on("alignClick",function(H){this._handleAlign(H);},this,true);this.on("afterNodeChange",function(){this._handleAfterNodeChange();},this,true);this.toolbar.on("insertimageClick",function(){this._handleInsertImageClick();},this,true);this.on("windowinsertimageClose",function(){this._handleInsertImageWindowClose();},this,true);this.toolbar.on("createlinkClick",function(){this._h!
 andleCreateLinkClick();},this,true);this.on("windowcreatelinkClose",function(){this._handleCreateLinkWindowClose();},this,true);this.get("parentNode").replaceChild(this.get("element_cont").get("element"),this.get("element"));this.setStyle("visibility","hidden");this.setStyle("position","absolute");this.setStyle("top","-9999px");this.setStyle("left","-9999px");this.get("element_cont").appendChild(this.get("element"));this.get("element_cont").setStyle("display","block");C.addClass(this.get("iframe").get("parentNode"),this.CLASS_EDITABLE_CONT);this.get("iframe").addClass(this.CLASS_EDITABLE);this.get("element_cont").setStyle("width",this.get("width"));C.setStyle(this.get("iframe").get("parentNode"),"height",this.get("height"));this.get("iframe").setStyle("width","100%");this.get("iframe").setStyle("height","100%");window.setTimeout(function(){F._setupAfterElement.call(F);},0);this.fireEvent("afterRender",{type:"afterRender",target:this});},execCommand:function(H,G){var K=this.!
 fireEvent("beforeExecCommand",{type:"beforeExecCommand",target!
 :this,ar
gs:arguments});if((K===false)||(this.STOP_EXEC_COMMAND)){this.STOP_EXEC_COMMAND=false;return false;}this._setMarkupType(H);if(this.browser.ie){this._getWindow().focus();}var F=true;if(this.get("limitCommands")){if(!this.toolbar.getButtonByValue(H)){F=false;}}this.editorDirty=true;if((typeof this["cmd_"+H.toLowerCase()]=="function")&&F){var J=this["cmd_"+H.toLowerCase()](G);F=J[0];if(J[1]){H=J[1];}if(J[2]){G=J[2];}}if(F){try{this._getDoc().execCommand(H,false,G);}catch(I){}}else{}this.on("afterExecCommand",function(){this.unsubscribeAll("afterExecCommand");this.nodeChange();});this.fireEvent("afterExecCommand",{type:"afterExecCommand",target:this});},cmd_backcolor:function(I){var F=true,G=this._getSelectedElement(),H="backcolor";if(this.browser.gecko||this.browser.opera){this._setEditorStyle(true);H="hilitecolor";}if(!this._isElement(G,"body")){C.setStyle(G,"background-color",I);this._selectNode(G);F=false;}else{this._createCurrentElement("span",{backgroundColor:I});this._sel!
 ectNode(this.currentElement[0]);F=false;}return[F,H];},cmd_forecolor:function(H){var F=true,G=this._getSelectedElement();if(!this._isElement(G,"body")){C.setStyle(G,"color",H);this._selectNode(G);F=false;}else{this._createCurrentElement("span",{color:H});this._selectNode(this.currentElement[0]);F=false;}return[F];},cmd_unlink:function(F){this._swapEl(this.currentElement[0],"span",function(G){G.className="yui-non";});return[false];},cmd_createlink:function(H){var G=this._getSelectedElement(),F=null;if(this._hasParent(G,"a")){this.currentElement[0]=this._hasParent(G,"a");}else{if(!this._isElement(G,"a")){this._createCurrentElement("a");F=this._swapEl(this.currentElement[0],"a");this.currentElement[0]=F;}else{this.currentElement[0]=G;}}return[false];},cmd_insertimage:function(K){var F=true,G=null,J="insertimage",I=this._getSelectedElement();if(K===""){K=this.get("blankimage");}if(this._isElement(I,"img")){this.currentElement[0]=I;F=false;}else{if(this._getDoc().queryCommandEna!
 bled(J)){this._getDoc().execCommand("insertimage",false,K);var!
  L=this.
_getDoc().getElementsByTagName("img");for(var H=0;H<L.length;H++){if(!YAHOO.util.Dom.hasClass(L[H],"yui-img")){YAHOO.util.Dom.addClass(L[H],"yui-img");this.currentElement[0]=L[H];}}F=false;}else{if(I==this._getDoc().body){G=this._getDoc().createElement("img");G.setAttribute("src",K);YAHOO.util.Dom.addClass(G,"yui-img");this._getDoc().body.appendChild(G);}else{this._createCurrentElement("img");G=this._getDoc().createElement("img");G.setAttribute("src",K);YAHOO.util.Dom.addClass(G,"yui-img");this.currentElement[0].parentNode.replaceChild(G,this.currentElement[0]);}this.currentElement[0]=G;F=false;}}return[F];},cmd_inserthtml:function(I){var F=true,H="inserthtml",G=null,J=null;if(this.browser.webkit&&!this._getDoc().queryCommandEnabled(H)){this._createCurrentElement("img");G=this._getDoc().createElement("span");G.innerHTML=I;this.currentElement[0].parentNode.replaceChild(G,this.currentElement[0]);F=false;}else{if(this.browser.ie){J=this._getRange();if(J.item){J.item(0).outerHTM!
 L=I;}else{J.pasteHTML(I);}F=false;}}return[F];},cmd_list:function(W){var Q=true,T=null,M=0,G=null,P="",U=this._getSelectedElement(),R="insertorderedlist";if(W=="ul"){R="insertunorderedlist";}if((this.browser.webkit&&!this._getDoc().queryCommandEnabled(R))){if(this._isElement(U,"li")&&this._isElement(U.parentNode,W)){G=U.parentNode;T=this._getDoc().createElement("span");YAHOO.util.Dom.addClass(T,"yui-non");P="";var F=G.getElementsByTagName("li");for(M=0;M<F.length;M++){P+="<div>"+F[M].innerHTML+"</div>";}T.innerHTML=P;this.currentElement[0]=G;this.currentElement[0].parentNode.replaceChild(T,this.currentElement[0]);}else{this._createCurrentElement(W.toLowerCase());T=this._getDoc().createElement(W);for(M=0;M<this.currentElement.length;M++){var J=this._getDoc().createElement("li");J.innerHTML=this.currentElement[M].innerHTML+'<span class="yui-non"> </span> ';T.appendChild(J);if(M>0){this.currentElement[M].parentNode.removeChild(this.currentElement[M]);
+}}this.currentElement[0].parentNode.replaceChild(T,this.currentElement[0]);this.currentElement[0]=T;var H=this.currentElement[0].firstChild;H=C.getElementsByClassName("yui-non","span",H)[0];this._getSelection().setBaseAndExtent(H,1,H,H.innerText.length);}Q=false;}else{G=this._getSelectedElement();if(this._isElement(G,"li")&&this._isElement(G.parentNode,W)||(this.browser.ie&&this._isElement(this._getRange().parentElement,"li"))||(this.browser.ie&&this._isElement(G,"ul"))||(this.browser.ie&&this._isElement(G,"ol"))){if(this.browser.ie){if((this.browser.ie&&this._isElement(G,"ul"))||(this.browser.ie&&this._isElement(G,"ol"))){G=G.getElementsByTagName("li")[0];}P="";var I=G.parentNode.getElementsByTagName("li");for(var S=0;S<I.length;S++){P+=I[S].innerHTML+"<br>";}var V=this._getDoc().createElement("span");V.innerHTML=P;G.parentNode.parentNode.replaceChild(V,G.parentNode);}else{this.nodeChange();this._getDoc().execCommand(R,"",G.parentNode);this.nodeChange();}Q=false;}if(this.b!
 rowser.opera){var O=this;window.setTimeout(function(){var X=O._getDoc().getElementsByTagName("li");for(var Y=0;Y<X.length;Y++){if(X[Y].innerHTML.toLowerCase()=="<br>"){X[Y].parentNode.parentNode.removeChild(X[Y].parentNode);}}},30);}if(this.browser.ie&&Q){var K="";if(this._getRange().html){K="<li>"+this._getRange().html+"</li>";}else{var L=this._getRange().text.split("\n");if(L.length>1){K="";for(var N=0;N<L.length;N++){K+="<li>"+L[N]+"</li>";}}else{K="<li>"+this._getRange().text+"</li>";}}this._getRange().pasteHTML("<"+W+">"+K+"</"+W+">");Q=false;}}return Q;},cmd_insertorderedlist:function(F){return[this.cmd_list("ol")];},cmd_insertunorderedlist:function(F){return[this.cmd_list("ul")];},cmd_fontname:function(H){var F=true,G=this._getSelectedElement();this.currentFont=H;if(G&&G.tagName&&!this._hasSelection()){YAHOO.util.Dom.setStyle(G,"font-family",H);F=false;}return[F];},cmd_fontsize:function(G){if(this.currentElement&&(this.currentElement.length>0)&&(!this._hasSelection()!
 )){YAHOO.util.Dom.setStyle(this.currentElement,"fontSize",G);}!
 else{if(
!this._isElement(this._getSelectedElement(),"body")){var F=this._getSelectedElement();YAHOO.util.Dom.setStyle(F,"fontSize",G);this._selectNode(F);}else{this._createCurrentElement("span",{"fontSize":G});this._selectNode(this.currentElement[0]);}}return[false];},_swapEl:function(G,F,I){var H=this._getDoc().createElement(F);H.innerHTML=G.innerHTML;if(typeof I=="function"){I.call(this,H);}G.parentNode.replaceChild(H,G);return H;},_createCurrentElement:function(H,U){H=((H)?H:"a");var b=null,G=[],I=this._getDoc();if(this.currentFont){if(!U){U={};}U.fontFamily=this.currentFont;this.currentFont=null;}this.currentElement=[];var X=function(){var f=null;switch(H){case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":f=I.createElement(H);break;default:f=I.createElement("span");YAHOO.util.Dom.addClass(f,"yui-tag-"+H);YAHOO.util.Dom.addClass(f,"yui-tag");f.setAttribute("tag",H);for(var e in U){if(YAHOO.util.Lang.hasOwnProperty(U,e)){f.style[e]=U[e];}}break;}return f;};if(!this._hasSelecti!
 on()){if(this._getDoc().queryCommandEnabled("insertimage")){this._getDoc().execCommand("insertimage",false,"yui-tmp-img");var W=this._getDoc().getElementsByTagName("img");for(var Z=0;Z<W.length;Z++){if(W[Z].getAttribute("src",2)=="yui-tmp-img"){G=X();W[Z].parentNode.replaceChild(G,W[Z]);this.currentElement[this.currentElement.length]=G;}}}else{if(this.currentEvent){b=YAHOO.util.Event.getTarget(this.currentEvent);}else{b=this._getDoc().body;}}if(b){G=X();if(this._isElement(b,"body")||this._isElement(b,"html")){if(this._isElement(b,"html")){b=this._getDoc().body;}b.appendChild(G);}else{if(b.nextSibling){b.parentNode.insertBefore(G,b.nextSibling);}else{b.parentNode.appendChild(G);}}this.currentElement[this.currentElement.length]=G;this.currentEvent=null;if(this.browser.webkit){this._getSelection().setBaseAndExtent(G,0,G,0);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(true);}}}}else{this._setEditorStyle(true);this._getDoc()!
 .execCommand("fontname",false,"yui-tmp");var F=[];var R=this._!
 getDoc()
.getElementsByTagName("font");var P=this._getDoc().getElementsByTagName(this._getSelectedElement().tagName);var M=this._getDoc().getElementsByTagName("span");var L=this._getDoc().getElementsByTagName("i");var K=this._getDoc().getElementsByTagName("b");var J=this._getDoc().getElementsByTagName(this._getSelectedElement().parentNode.tagName);for(var V=0;V<R.length;V++){F[F.length]=R[V];}for(var N=0;N<J.length;N++){F[F.length]=J[N];}for(var T=0;T<P.length;T++){F[F.length]=P[T];}for(var S=0;S<M.length;S++){F[F.length]=M[S];}for(var Q=0;Q<L.length;Q++){F[F.length]=L[Q];}for(var O=0;O<K.length;O++){F[F.length]=K[O];}for(var a=0;a<F.length;a++){if((YAHOO.util.Dom.getStyle(F[a],"font-family")=="yui-tmp")||(F[a].face&&(F[a].face=="yui-tmp"))){G=X();G.innerHTML=F[a].innerHTML;if(this._isElement(F[a],"ol")||(this._isElement(F[a],"ul"))){var Y=F[a].getElementsByTagName("li")[0];F[a].style.fontFamily="inherit";Y.style.fontFamily="inherit";G.innerHTML=Y.innerHTML;Y.innerHTML="";Y.appendChi!
 ld(G);this.currentElement[this.currentElement.length]=G;}else{if(this._isElement(F[a],"li")){F[a].innerHTML="";F[a].appendChild(G);F[a].style.fontFamily="inherit";this.currentElement[this.currentElement.length]=G;}else{if(F[a].parentNode){F[a].parentNode.replaceChild(G,F[a]);this.currentElement[this.currentElement.length]=G;this.currentEvent=null;if(this.browser.webkit){this._getSelection().setBaseAndExtent(G,0,G,0);if(this.browser.webkit3){this._getSelection().collapseToStart();}else{this._getSelection().collapse(true);}}if(this.browser.ie&&U&&U.fontSize){this._getSelection().empty();}if(this.browser.gecko){this._getSelection().collapseToStart();}}}}}}var c=this.currentElement.length;for(var d=0;d<c;d++){if((d+1)!=c){if(this.currentElement[d]&&this.currentElement[d].nextSibling){if(this._isElement(this.currentElement[d],"br")){this.currentElement[this.currentElement.length]=this.currentElement[d].nextSibling;
+}}}}}},saveHTML:function(){var F=this.cleanHTML();this.get("element").value=F;return F;},setEditorHTML:function(F){F=this._cleanIncomingHTML(F);this._getDoc().body.innerHTML=F;this.nodeChange();},getEditorHTML:function(){var F=this._getDoc().body;if(F===null){return null;}return this._getDoc().body.innerHTML;},show:function(){if(this.browser.gecko){this._setDesignMode("on");this._focusWindow();}if(this.browser.webkit){var F=this;window.setTimeout(function(){F._setInitialContent.call(F);},10);}if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}this.get("iframe").setStyle("position","static");this.get("iframe").setStyle("left","");},hide:function(){if(YAHOO.widget.EditorInfo.window.win&&YAHOO.widget.EditorInfo.window.scope){YAHOO.widget.EditorInfo.window.scope.closeWindow.call(YAHOO.widget.EditorInfo.window.scope);}if(this._fixNodesTimer){clearTimeout(this._f!
 ixNodesTimer);this._fixNodesTimer=null;}if(this._nodeChangeTimer){clearTimeout(this._nodeChangeTimer);this._nodeChangeTimer=null;}this._lastNodeChange=0;this.get("iframe").setStyle("position","absolute");this.get("iframe").setStyle("left","-9999px");},_cleanIncomingHTML:function(F){F=F.replace(/<strong([^>]*)>/gi,"<b$1>");F=F.replace(/<\/strong>/gi,"</b>");F=F.replace(/<embed([^>]*)>/gi,"<YUI_EMBED$1>");F=F.replace(/<\/embed>/gi,"</YUI_EMBED>");F=F.replace(/<em([^>]*)>/gi,"<i$1>");F=F.replace(/<\/em>/gi,"</i>");F=F.replace(/<YUI_EMBED([^>]*)>/gi,"<embed$1>");F=F.replace(/<\/YUI_EMBED>/gi,"</embed>");if(this.get("plainText")){F=F.replace(/\n/g,"<br>").replace(/\r/g,"<br>");F=F.replace(/  /gi,"  ");F=F.replace(/\t/gi,"    ");}F=F.replace(/<script([^>]*)>/gi,"<bad>");F=F.replace(/<\/script([^>]*)>/gi,"</bad>");F=F.replace(/<script([^>]*)>/gi,"<bad>");F=F.replace(/<\/script([^>]*)>/gi,"</bad>");F=F.replace(/\n/g,"<YUI_LF>").replace(/\r/!
 g,"<YUI_LF>");F=F.replace(new RegExp("<bad([^>]*)>(.*?)</bad>"!
 ,"gi"),"
");F=F.replace(/<YUI_LF>/g,"\n");return F;},cleanHTML:function(H){if(!H){H=this.getEditorHTML();}var G=this.get("markup");H=this.pre_filter_linebreaks(H,G);H=H.replace(/<img([^>]*)\/>/gi,"<YUI_IMG$1>");H=H.replace(/<img([^>]*)>/gi,"<YUI_IMG$1>");H=H.replace(/<input([^>]*)\/>/gi,"<YUI_INPUT$1>");H=H.replace(/<input([^>]*)>/gi,"<YUI_INPUT$1>");H=H.replace(/<ul([^>]*)>/gi,"<YUI_UL$1>");H=H.replace(/<\/ul>/gi,"</YUI_UL>");H=H.replace(/<blockquote([^>]*)>/gi,"<YUI_BQ$1>");H=H.replace(/<\/blockquote>/gi,"</YUI_BQ>");H=H.replace(/<embed([^>]*)>/gi,"<YUI_EMBED$1>");H=H.replace(/<\/embed>/gi,"</YUI_EMBED>");if((G=="semantic")||(G=="xhtml")){H=H.replace(/<i(\s+[^>]*)?>/gi,"<em$1>");H=H.replace(/<\/i>/gi,"</em>");H=H.replace(/<b([^>]*)>/gi,"<strong$1>");H=H.replace(/<\/b>/gi,"</strong>");}H=H.replace(/<font/gi,"<font");H=H.replace(/<\/font>/gi,"</font>");H=H.replace(/<span/gi,"<span");H=H.replace(/<\/span>/gi,"</span>");if((G=="semantic")||(G=="xhtml")||(G=="css")){H=H.replace(new RegE!
 xp('<font([^>]*)face="([^>]*)">(.*?)</font>',"gi"),'<span $1 style="font-family: $2;">$3</span>');H=H.replace(/<u/gi,'<span style="text-decoration: underline;"');if(this.browser.webkit){H=H.replace(new RegExp('<span class="Apple-style-span" style="font-weight: bold;">([^>]*)</span>',"gi"),"<strong>$1</strong>");H=H.replace(new RegExp('<span class="Apple-style-span" style="font-style: italic;">([^>]*)</span>',"gi"),"<em>$1</em>");}H=H.replace(/\/u>/gi,"/span>");if(G=="css"){H=H.replace(/<em([^>]*)>/gi,"<i$1>");H=H.replace(/<\/em>/gi,"</i>");H=H.replace(/<strong([^>]*)>/gi,"<b$1>");H=H.replace(/<\/strong>/gi,"</b>");H=H.replace(/<b/gi,'<span style="font-weight: bold;"');H=H.replace(/\/b>/gi,"/span>");H=H.replace(/<i/gi,'<span style="font-style: italic;"');H=H.replace(/\/i>/gi,"/span>");}H=H.replace(/  /gi," ");}else{H=H.replace(/<u/gi,"<u");H=H.replace(/\/u>/gi,"/u>");}H=H.replace(/<ol([^>]*)>/gi,"<ol$1>");H=H.replace(/\/ol>/gi,"/ol>");H=H.replace(/<li/gi,"<li");H=H.replace(/!
 \/li>/gi,"/li>");H=this.filter_safari(H);H=this.filter_interna!
 ls(H);H=
this.filter_all_rgb(H);H=this.post_filter_linebreaks(H,G);if(G=="xhtml"){H=H.replace(/<YUI_IMG([^>]*)>/g,"<img $1 />");H=H.replace(/<YUI_INPUT([^>]*)>/g,"<input $1 />");}else{H=H.replace(/<YUI_IMG([^>]*)>/g,"<img $1>");H=H.replace(/<YUI_INPUT([^>]*)>/g,"<input $1>");}H=H.replace(/<YUI_UL([^>]*)>/g,"<ul$1>");H=H.replace(/<\/YUI_UL>/g,"</ul>");H=this.filter_invalid_lists(H);H=H.replace(/<YUI_BQ([^>]*)>/g,"<blockquote$1>");H=H.replace(/<\/YUI_BQ>/g,"</blockquote>");H=H.replace(/<YUI_EMBED([^>]*)>/g,"<embed$1>");H=H.replace(/<\/YUI_EMBED>/g,"</embed>");H=YAHOO.lang.trim(H);if(this.get("removeLineBreaks")){H=H.replace(/\n/g,"").replace(/\r/g,"");H=H.replace(/  /gi," ");}if(H.substring(0,6).toLowerCase()=="<span>"){H=H.substring(6);if(H.substring(H.length-7,H.length).toLowerCase()=="</span>"){H=H.substring(0,H.length-7);}}for(var F in this.invalidHTML){if(YAHOO.lang.hasOwnProperty(this.invalidHTML,F)){if(D.isObject(F)&&F.keepContents){H=H.replace(new RegExp("<"+F+"([^>]*)>(.*?)</"!
 +F+">","gi"),"$1");}else{H=H.replace(new RegExp("<"+F+"([^>]*)>(.*?)</"+F+">","gi"),"");}}}this.fireEvent("cleanHTML",{type:"cleanHTML",target:this,html:H});return H;},filter_invalid_lists:function(F){F=F.replace(/<\/li>\n/gi,"</li>");F=F.replace(/<\/li><ol>/gi,"</li><li><ol>");F=F.replace(/<\/ol>/gi,"</ol></li>");F=F.replace(/<\/ol><\/li>\n/gi,"</ol>\n");F=F.replace(/<\/li><ul>/gi,"</li><li><ul>");F=F.replace(/<\/ul>/gi,"</ul></li>");F=F.replace(/<\/ul><\/li>\n/gi,"</ul>\n");F=F.replace(/<\/li>/gi,"</li>\n");F=F.replace(/<\/ol>/gi,"</ol>\n");F=F.replace(/<ol>/gi,"<ol>\n");F=F.replace(/<ul>/gi,"<ul>\n");return F;},filter_safari:function(F){if(this.browser.webkit){F=F.replace(/<span class="Apple-tab-span" style="white-space:pre">([^>])<\/span>/gi,"    ");F=F.replace(/Apple-style-span/gi,"");F=F.replace(/style="line-height: normal;"/gi,"");F=F.replace(/<li><\/li>/gi,"");F=F.replace(/<li> <\/li>/gi,"");
+F=F.replace(/<li>  <\/li>/gi,"");F=F.replace(/<div><\/div>/gi,"");F=F.replace(/<div> <\/div>/gi,"");}return F;},filter_internals:function(F){F=F.replace(/\r/g,"");F=F.replace(/<\/?(body|head|html)[^>]*>/gi,"");F=F.replace(/<YUI_BR><\/li>/gi,"</li>");F=F.replace(/yui-tag-span/gi,"");F=F.replace(/yui-tag/gi,"");F=F.replace(/yui-non/gi,"");F=F.replace(/yui-img/gi,"");F=F.replace(/ tag="span"/gi,"");F=F.replace(/ class=""/gi,"");F=F.replace(/ style=""/gi,"");F=F.replace(/ class=" "/gi,"");F=F.replace(/ class="  "/gi,"");F=F.replace(/ target=""/gi,"");F=F.replace(/ title=""/gi,"");if(this.browser.ie){F=F.replace(/ class= /gi,"");F=F.replace(/ class= >/gi,"");F=F.replace(/_height="([^>])"/gi,"");F=F.replace(/_width="([^>])"/gi,"");}return F;},filter_all_rgb:function(J){var I=new RegExp("rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)","gi");var F=J.match(I);if(D.isArray(F)){for(var H=0;H<F.length;H++){var G=this.filter_rgb(F[H]);J=J.replace(F[H].toString(),G);}}r!
 eturn J;},filter_rgb:function(H){if(H.toLowerCase().indexOf("rgb")!=-1){var K=new RegExp("(.*?)rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)(.*?)","gi");var G=H.replace(K,"$1,$2,$3,$4,$5").split(",");if(G.length==5){var J=parseInt(G[1],10).toString(16);var I=parseInt(G[2],10).toString(16);var F=parseInt(G[3],10).toString(16);J=J.length==1?"0"+J:J;I=I.length==1?"0"+I:I;F=F.length==1?"0"+F:F;H="#"+J+I+F;}}return H;},pre_filter_linebreaks:function(G,F){if(this.browser.webkit){G=G.replace(/<br class="khtml-block-placeholder">/gi,"<YUI_BR>");G=G.replace(/<br class="webkit-block-placeholder">/gi,"<YUI_BR>");}G=G.replace(/<br>/gi,"<YUI_BR>");G=G.replace(/<br (.*?)>/gi,"<YUI_BR>");G=G.replace(/<br\/>/gi,"<YUI_BR>");G=G.replace(/<br \/>/gi,"<YUI_BR>");G=G.replace(/<div><YUI_BR><\/div>/gi,"<YUI_BR>");G=G.replace(/<p>( | )<\/p>/g,"<YUI_BR>");G=G.replace(/<p><br> <\/p>/gi,"<YUI_BR>");G=G.replace(/<p> <\/p>/gi,"<YUI_BR>");G=G.replace(/<YUI_BR>$/,""!
 );G=G.replace(/<YUI_BR><\/p>/g,"</p>");return G;},post_filter_!
 linebrea
ks:function(G,F){if(F=="xhtml"){G=G.replace(/<YUI_BR>/g,"<br />");}else{G=G.replace(/<YUI_BR>/g,"<br>");}return G;},clearEditorDoc:function(){this._getDoc().body.innerHTML=" ";},_renderPanel:function(){},openWindow:function(F){},moveWindow:function(){},_closeWindow:function(){},closeWindow:function(){this.unsubscribeAll("afterExecCommand");this.toolbar.resetAllButtons();this._focusWindow();},destroy:function(){this.saveHTML();this.toolbar.destroy();this.setStyle("visibility","hidden");this.setStyle("position","absolute");this.setStyle("top","-9999px");this.setStyle("left","-9999px");var G=this.get("element");this.get("element_cont").get("parentNode").replaceChild(G,this.get("element_cont").get("element"));this.get("element_cont").get("element").innerHTML="";this.set("handleSubmit",false);for(var F in this){if(D.hasOwnProperty(this,F)){this[F]=null;}}return true;},toString:function(){var F="SimpleEditor";if(this.get&&this.get("element_cont")){F="SimpleEditor (#"+this.get!
 ("element_cont").get("id")+")"+((this.get("disabled")?" Disabled":""));}return F;}});YAHOO.widget.EditorInfo={_instances:{},blankImage:"",window:{},panel:null,getEditorById:function(F){if(!YAHOO.lang.isString(F)){F=F.id;}if(this._instances[F]){return this._instances[F];}return false;},toString:function(){var F=0;for(var G in this._instances){F++;}return"Editor Info ("+F+" registered intance"+((F>1)?"s":"")+")";}};})();YAHOO.register("simpleeditor",YAHOO.widget.SimpleEditor,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/editor/simpleeditor-beta.js
===================================================================
--- trunk/root/static/yui/editor/simpleeditor-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/editor/simpleeditor-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 (function() {
     /**
@@ -88,6 +88,7 @@
         oConfig.element.setAttribute('unselectable', 'on');
         oConfig.element.className = 'yui-button yui-' + oConfig.attributes.type + '-button';
         oConfig.element.innerHTML = '<span class="first-child"><a href="#">LABEL</a></span>';
+        oConfig.element.firstChild.firstChild.tabIndex = '-1';
         oConfig.attributes.id = Dom.generateId();
 
         YAHOO.widget.ToolbarButton.superclass.constructor.call(this, oConfig.element, oConfig.attributes);
@@ -285,6 +286,20 @@
             return this.get('menu');
         },
         /** 
+        * @method destroy
+        * @description Destroy the button
+        */        
+        destroy: function() {
+            Event.purgeElement(this.get('element'), true);
+            this.get('element').parentNode.removeChild(this.get('element'));
+            //Brutal Object Destroy
+            for (var i in this) {
+                if (Lang.hasOwnProperty(this, i)) {
+                    this[i] = null;
+                }
+            }       
+        },
+        /** 
         * @method fireEvent
         * @description Overridden fireEvent method to prevent DOM events from firing if the button is disabled.
         */        
@@ -309,7 +324,6 @@
 })();
 /**
  * @description <p>Creates a rich Toolbar widget based on Button. Primarily used with the Rich Text Editor</p>
- * @class Toolbar
  * @namespace YAHOO.widget
  * @requires yahoo, dom, element, event, toolbarbutton
  * @optional container_core, dragdrop
@@ -322,10 +336,29 @@
 var Dom = YAHOO.util.Dom,
     Event = YAHOO.util.Event,
     Lang = YAHOO.lang;
+    
+    var getButton = function(id) {
+        var button = id;
+        if (Lang.isString(id)) {
+            button = this.getButtonById(id);
+        }
+        if (Lang.isNumber(id)) {
+            button = this.getButtonByIndex(id);
+        }
+        if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
+            button = this.getButtonByValue(id);
+        }
+        if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            return button;
+        }
+        return false;
+    };
 
     /**
      * Provides a rich toolbar widget based on the button and menu widgets
      * @constructor
+     * @class Toolbar
+     * @extends YAHOO.util.Element
      * @param {String/HTMLElement} el The element to turn into a toolbar.
      * @param {Object} attrs Object liternal containing configuration parameters.
     */
@@ -363,10 +396,19 @@
             oConfig.element.id = ((Lang.isString(el)) ? el : Dom.generateId());
         }
         
+        var fs = document.createElement('fieldset');
+        var lg = document.createElement('legend');
+        lg.innerHTML = 'Toolbar';
+        fs.appendChild(lg);
+        
         var cont = document.createElement('DIV');
         oConfig.attributes.cont = cont;
         Dom.addClass(cont, 'yui-toolbar-subcont');
-        oConfig.element.appendChild(cont);
+        fs.appendChild(cont);
+        oConfig.element.appendChild(fs);
+
+        oConfig.element.tabIndex = -1;
+
         
         oConfig.attributes.element = oConfig.element;
         oConfig.attributes.id = oConfig.element.id;
@@ -687,6 +729,7 @@
         */
         init: function(p_oElement, p_oAttributes) {
             YAHOO.widget.Toolbar.superclass.init.call(this, p_oElement, p_oAttributes);
+
         },
         /**
         * @method initAttributes
@@ -812,7 +855,7 @@
             * @type Boolean
             */
             this.setAttributeConfig('grouplabels', {
-                value: attr.grouplabels || true,
+                value: ((attr.grouplabels === false) ? false : true),
                 method: function(grouplabels) {
                     if (grouplabels) {
                         Dom.removeClass(this.get('cont'), (this.CLASS_PREFIX + '-nogrouplabels'));
@@ -836,12 +879,22 @@
                             this._titlebar.parentNode.removeChild(this._titlebar);
                         }
                         this._titlebar = document.createElement('DIV');
+                        this._titlebar.tabIndex = '-1';
+                        Event.on(this._titlebar, 'focus', function() {
+                            this._handleFocus();
+                        }, this, true);
                         Dom.addClass(this._titlebar, this.CLASS_PREFIX + '-titlebar');
                         if (Lang.isString(titlebar)) {
                             var h2 = document.createElement('h2');
                             h2.tabIndex = '-1';
-                            h2.innerHTML = titlebar;
+                            h2.innerHTML = '<a href="#" tabIndex="0">' + titlebar + '</a>';
                             this._titlebar.appendChild(h2);
+                            Event.on(h2.firstChild, 'click', function(ev) {
+                                Event.stopEvent(ev);
+                            });
+                            Event.on([h2, h2.firstChild], 'focus', function() {
+                                this._handleFocus();
+                            }, this, true);
                         }
                         if (this.get('firstChild')) {
                             this.insertBefore(this._titlebar, this.get('firstChild'));
@@ -870,34 +923,36 @@
             this.setAttributeConfig('collapse', {
                 value: false,
                 method: function(collapse) {
-                    var collapseEl = null;
-                    var el = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
-                    if (collapse) {
-                        if (el.length > 0) {
-                            //There is already a collapse button
-                            return true;
-                        }
-                        collapseEl = document.createElement('SPAN');
-                        collapseEl.innerHTML = 'X';
-                        collapseEl.title = this.STR_COLLAPSE;
+                    if (this._titlebar) {
+                        var collapseEl = null;
+                        var el = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
+                        if (collapse) {
+                            if (el.length > 0) {
+                                //There is already a collapse button
+                                return true;
+                            }
+                            collapseEl = document.createElement('SPAN');
+                            collapseEl.innerHTML = 'X';
+                            collapseEl.title = this.STR_COLLAPSE;
 
-                        Dom.addClass(collapseEl, 'collapse');
-                        this._titlebar.appendChild(collapseEl);
-                        Event.addListener(collapseEl, 'click', function() {
-                            if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
-                                this.collapse(false); //Expand Toolbar
-                            } else {
-                                this.collapse(); //Collapse Toolbar
+                            Dom.addClass(collapseEl, 'collapse');
+                            this._titlebar.appendChild(collapseEl);
+                            Event.addListener(collapseEl, 'click', function() {
+                                if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
+                                    this.collapse(false); //Expand Toolbar
+                                } else {
+                                    this.collapse(); //Collapse Toolbar
+                                }
+                            }, this, true);
+                        } else {
+                            collapseEl = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
+                            if (collapseEl[0]) {
+                                if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
+                                    //We are closed, reopen the titlebar..
+                                    this.collapse(false); //Expand Toolbar
+                                }
+                                collapseEl[0].parentNode.removeChild(collapseEl[0]);
                             }
-                        }, this, true);
-                    } else {
-                        collapseEl = Dom.getElementsByClassName('collapse', 'span', this._titlebar);
-                        if (collapseEl[0]) {
-                            if (Dom.hasClass(this.get('cont').parentNode, 'yui-toolbar-container-collapsed')) {
-                                //We are closed, reopen the titlebar..
-                                this.collapse(false); //Expand Toolbar
-                            }
-                            collapseEl[0].parentNode.removeChild(collapseEl[0]);
                         }
                     }
                 }
@@ -968,7 +1023,7 @@
         /**
         * @method addButtonGroup
         * @description Add a new button group to the toolbar. (uses addButton)
-        * @param {Object} oGroup Object literal reference to the Groups Config (contains an array of button configs)
+        * @param {Object} oGroup Object literal reference to the Groups Config (contains an array of button configs as well as the group label)
         */
         addButtonGroup: function(oGroup) {
             if (!this.get('element')) {
@@ -982,7 +1037,6 @@
             var div = document.createElement('DIV');
             Dom.addClass(div, this.CLASS_PREFIX + '-group');
             Dom.addClass(div, this.CLASS_PREFIX + '-group-' + oGroup.group);
-            //if (oGroup.label && this.get('grouplabels')) {
             if (oGroup.label) {
                 var label = document.createElement('h3');
                 label.innerHTML = oGroup.label;
@@ -1061,9 +1115,6 @@
                                         oButton.menucmd = oButton.value;
                                     }
                                     oButton.value = ((oMenu.value) ? oMenu.value : oMenu._oText.nodeValue);
-                                    //This line made Opera fire the click event and the mousedown,
-                                    //  so events for menus where firing twice.
-                                    //this._buttonClick('click', oButton);
                                 },
                                 scope: this
                             };
@@ -1114,8 +1165,11 @@
             } else {
                 //Add to .get('buttons') manually
                 this._configs.buttons.value[this._configs.buttons.value.length] = oButton;
-
+                
                 var tmp = new this.buttonType(_oButton);
+                tmp.get('element').tabIndex = '-1';
+                tmp.get('element').setAttribute('role', 'button');
+                tmp._selected = true;
                 if (!tmp.buttonType) {
                     tmp.buttonType = 'rich';
                     tmp.checkValue = function(value) {
@@ -1164,6 +1218,7 @@
                     var a = document.createElement('a');
                     a.innerHTML = tmp._button.innerHTML;
                     a.href = '#';
+                    a.tabIndex = '-1';
                     Event.on(a, 'click', function(ev) {
                         Event.stopEvent(ev);
                     });
@@ -1197,7 +1252,9 @@
                                 exec = false;
                             }
                             if (exec) {
-                                this._colorPicker._button = oButton.value;
+                                if (this._colorPicker) {
+                                    this._colorPicker._button = oButton.value;
+                                }
                                 var menuEL = tmp.getMenu().element;
                                 if (Dom.getStyle(menuEL, 'visibility') == 'hidden') {
                                     tmp.getMenu().show();
@@ -1217,7 +1274,7 @@
                             this._buttonClick(ev, oButton);
                         }, oButton, this);
                         tmp.on('click', function(ev) {
-                            YAHOO.util.Event.stopEvent(ev);
+                            //YAHOO.util.Event.stopEvent(ev);
                         });
                     } else {
                         //Stop the mousedown event so we can trap the selection in the editor!
@@ -1234,6 +1291,7 @@
                             oButton.value = ev.value;
                             this._buttonClick(ev, oButton);
                         }, this, true);
+
                         var self = this;
                         //Hijack the mousedown event in the menu and make it fire a button click..
                         if (tmp.getMenu().mouseDownEvent) {
@@ -1268,6 +1326,7 @@
                     });
                 }
                 if (this.browser.ie) {
+                    /*
                     //Add a couple of new events for IE
                     tmp.DOM_EVENTS.focusin = true;
                     tmp.DOM_EVENTS.focusout = true;
@@ -1283,6 +1342,7 @@
                     tmp.on('click', function(ev) {
                         YAHOO.util.Event.stopEvent(ev);
                     }, oButton, this);
+                    */
                 }
                 if (this.browser.webkit) {
                     //This will keep the document from gaining focus and the editor from loosing it..
@@ -1381,11 +1441,14 @@
                 }
             }
             html += '<span><em>X</em><strong></strong></span>';
-            picker.innerHTML = html;
-            var em = picker.getElementsByTagName('em')[0];
-            var strong = picker.getElementsByTagName('strong')[0];
+            window.setTimeout(function() {
+                picker.innerHTML = html;
+            }, 0);
 
             Event.on(picker, 'mouseover', function(ev) {
+                var picker = this._colorPicker;
+                var em = picker.getElementsByTagName('em')[0];
+                var strong = picker.getElementsByTagName('strong')[0];
                 var tar = Event.getTarget(ev);
                 if (tar.tagName.toLowerCase() == 'a') {
                     em.style.backgroundColor = tar.style.backgroundColor;
@@ -1402,7 +1465,16 @@
                 Event.stopEvent(ev);
                 var tar = Event.getTarget(ev);
                 if (tar.tagName.toLowerCase() == 'a') {
-                    this.fireEvent('colorPickerClicked', { type: 'colorPickerClicked', target: this, button: this._colorPicker._button, color: tar.innerHTML, colorName: this._colorData['#' + tar.innerHTML] } );
+                    var retVal = this.fireEvent('colorPickerClicked', { type: 'colorPickerClicked', target: this, button: this._colorPicker._button, color: tar.innerHTML, colorName: this._colorData['#' + tar.innerHTML] } );
+                    if (retVal !== false) {
+                        var info = {
+                            color: tar.innerHTML,
+                            colorName: this._colorData['#' + tar.innerHTML],
+                            value: this._colorPicker._button 
+                        };
+                    
+                        this.fireEvent('buttonClick', { type: 'buttonClick', target: this.get('element'), button: info });
+                    }
                     this.getButtonByValue(this._colorPicker._button).getMenu().hide();
                 }
             }, this, true);
@@ -1465,6 +1537,8 @@
                 _b2 = document.createElement('a');
                 _b1.href = '#';
                 _b2.href = '#';
+                _b1.tabIndex = '-1';
+                _b2.tabIndex = '-1';
             
             //Setup the up and down arrows
             _b1.className = 'up';
@@ -1615,12 +1689,75 @@
                         }
                     }
                 }
+                if (ev) {
+                    Event.stopEvent(ev);
+                }
             }
-            if (ev) {
-                Event.stopEvent(ev);
+        },
+        /**
+        * @private
+        * @property _keyNav
+        * @description Flag to determine if the arrow nav listeners have been attached
+        * @type Boolean
+        */
+        _keyNav: null,
+        /**
+        * @private
+        * @property _navCounter
+        * @description Internal counter for walking the buttons in the toolbar with the arrow keys
+        * @type Number
+        */
+        _navCounter: null,
+        /**
+        * @private
+        * @method _navigateButtons
+        * @description Handles the navigation/focus of toolbar buttons with the Arrow Keys
+        * @param {Event} ev The Key Event
+        */
+        _navigateButtons: function(ev) {
+            switch (ev.keyCode) {
+                case 37:
+                case 39:
+                    if (ev.keyCode == 37) {
+                        this._navCounter--;
+                    } else {
+                        this._navCounter++;
+                    }
+                    if (this._navCounter > (this._buttonList.length - 1)) {
+                        this._navCounter = 0;
+                    }
+                    if (this._navCounter < 0) {
+                        this._navCounter = (this._buttonList.length - 1);
+                    }
+                    var el = this._buttonList[this._navCounter].get('element');
+                    if (this.browser.ie) {
+                        el = this._buttonList[this._navCounter].get('element').getElementsByTagName('a')[0];
+                    }
+                    if (this._buttonList[this._navCounter].get('disabled')) {
+                        this._navigateButtons(ev);
+                    } else {
+                        el.focus();
+                    }
+                    break;
             }
         },
         /**
+        * @private
+        * @method _handleFocus
+        * @description Sets up the listeners for the arrow key navigation
+        */
+        _handleFocus: function() {
+            if (!this._keyNav) {
+                var ev = 'keypress';
+                if (this.browser.ie) {
+                    ev = 'keydown';
+                }
+                Event.on(this.get('element'), ev, this._navigateButtons, this, true);
+                this._keyNav = true;
+                this._navCounter = -1;
+            }
+        },
+        /**
         * @method getButtonById
         * @description Gets a button instance from the toolbar by is Dom id.
         * @param {String} id The Dom id to query for.
@@ -1701,17 +1838,8 @@
         * @return {Boolean}
         */
         disableButton: function(id) {
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 button.set('disabled', true);
             } else {
                 return false;
@@ -1727,17 +1855,8 @@
             if (this.get('disabled')) {
                 return false;
             }
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 if (button.get('disabled')) {
                     button.set('disabled', false);
                 }
@@ -1746,42 +1865,46 @@
             }
         },
         /**
+        * @method isSelected
+        * @description Tells if a button is selected or not.
+        * @param {String/Number} id A button by it's id, index or value.
+        * @return {Boolean}
+        */
+        isSelected: function(id) {
+            var button = getButton.call(this, id);
+            if (button) {
+                return button._selected;
+            }
+            return false;
+        },
+        /**
         * @method selectButton
         * @description Selects a button in the toolbar.
         * @param {String/Number} id Select a button by it's id, index or value.
+        * @param {String} value If this is a Menu Button, check this item in the menu
         * @return {Boolean}
         */
         selectButton: function(id, value) {
-            var button = id;
-            if (id) {
-                if (Lang.isString(id)) {
-                    button = this.getButtonById(id);
-                }
-                if (Lang.isNumber(id)) {
-                    button = this.getButtonByIndex(id);
-                }
-                if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                    button = this.getButtonByValue(id);
-                }
-                if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
-                    button.addClass('yui-button-selected');
-                    button.addClass('yui-button-' + button.get('value') + '-selected');
-                    if (value) {
-                        if (button.buttonType == 'rich') {
-                            var _items = button.getMenu().getItems();
-                            for (var m = 0; m < _items.length; m++) {
-                                if (_items[m].value == value) {
-                                    _items[m].cfg.setProperty('checked', true);
-                                    button.set('label', '<span class="yui-toolbar-' + button.get('value') + '-' + (value).replace(/ /g, '-').toLowerCase() + '">' + _items[m]._oText.nodeValue + '</span>');
-                                } else {
-                                    _items[m].cfg.setProperty('checked', false);
-                                }
+            var button = getButton.call(this, id);
+            if (button) {
+                button.addClass('yui-button-selected');
+                button.addClass('yui-button-' + button.get('value') + '-selected');
+                button._selected = true;
+                if (value) {
+                    if (button.buttonType == 'rich') {
+                        var _items = button.getMenu().getItems();
+                        for (var m = 0; m < _items.length; m++) {
+                            if (_items[m].value == value) {
+                                _items[m].cfg.setProperty('checked', true);
+                                button.set('label', '<span class="yui-toolbar-' + button.get('value') + '-' + (value).replace(/ /g, '-').toLowerCase() + '">' + _items[m]._oText.nodeValue + '</span>');
+                            } else {
+                                _items[m].cfg.setProperty('checked', false);
                             }
                         }
                     }
-                } else {
-                    return false;
                 }
+            } else {
+                return false;
             }
         },
         /**
@@ -1791,20 +1914,12 @@
         * @return {Boolean}
         */
         deselectButton: function(id) {
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 button.removeClass('yui-button-selected');
                 button.removeClass('yui-button-' + button.get('value') + '-selected');
                 button.removeClass('yui-button-hover');
+                button._selected = false;
             } else {
                 return false;
             }
@@ -1885,17 +2000,8 @@
         * @return {Boolean}
         */
         destroyButton: function(id) {
-            var button = id;
-            if (Lang.isString(id)) {
-                button = this.getButtonById(id);
-            }
-            if (Lang.isNumber(id)) {
-                button = this.getButtonByIndex(id);
-            }
-            if ((!(button instanceof YAHOO.widget.ToolbarButton)) && (!(button instanceof YAHOO.widget.ToolbarButtonAdvanced))) {
-                button = this.getButtonByValue(id);
-            }
-            if ((button instanceof YAHOO.widget.ToolbarButton) || (button instanceof YAHOO.widget.ToolbarButtonAdvanced)) {
+            var button = getButton.call(this, id);
+            if (button) {
                 var thisID = button.get('id');
                 button.destroy();
 
@@ -1908,7 +2014,6 @@
             } else {
                 return false;
             }
-
         },
         /**
         * @method destroy
@@ -2012,16 +2117,35 @@
     */
     
     YAHOO.widget.SimpleEditor = function(el, attrs) {
+        
+        var o = {};
+        if (Lang.isObject(el) && (!el.tagName) && !attrs) {
+            Lang.augmentObject(o, el); //Break the config reference
+            el = document.createElement('textarea');
+            this.DOMReady = true;
+            if (o.container) {
+                var c = Dom.get(o.container);
+                c.appendChild(el);
+            } else {
+                document.body.appendChild(el);
+            }
+        } else {
+            Lang.augmentObject(o, attrs); //Break the config reference
+        }
 
         var oConfig = {
             element: null,
-            attributes: (attrs || {})
+            attributes: o
         }, id = null;
 
         if (Lang.isString(el)) {
             id = el;
         } else {
-            id = el.id;
+            if (oConfig.attributes.id) {
+                id = oConfig.attributes.id;
+            } else {
+                id = Dom.generateId(el);
+            }
         }
         oConfig.element = el;
 
@@ -2050,7 +2174,7 @@
     * @method _cleanClassName
     * @description Makes a useable classname from dynamic data, by dropping it to lowercase and replacing spaces with -'s.
     * @param {String} str The classname to clean up
-    * @returns {String}
+    * @return {String}
     */
     function _cleanClassName(str) {
         return str.replace(/ /g, '-').toLowerCase();
@@ -2069,70 +2193,20 @@
         * @description This flag will be set when certain things in the Editor happen. It is to be used by the developer to check to see if content has changed.
         * @type Boolean
         */
-        editorDirty: false,
+        editorDirty: null,
         /**
         * @property _defaultCSS
         * @description The default CSS used in the config for 'css'. This way you can add to the config like this: { css: YAHOO.widget.SimpleEditor.prototype._defaultCSS + 'ADD MYY CSS HERE' }
         * @type String
         */
-        _defaultCSS: 'html { height: 95%; } body { height: 100%; padding: 7px; background-color: #fff; font:13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a { color: blue; text-decoration: underline; cursor: pointer; } .warning-localfile { border-bottom: 1px dashed red !important; } .yui-busy { cursor: wait !important; } img.selected { border: 2px dotted #808080; } img { cursor: pointer !important; border: none; }',
+        _defaultCSS: 'html { height: 95%; } body { padding: 7px; background-color: #fff; font:13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a { color: blue; text-decoration: underline; cursor: text; } .warning-localfile { border-bottom: 1px dashed red !important; } .yui-busy { cursor: wait !important; } img.selected { border: 2px dotted #808080; } img { cursor: pointer !important; border: none; }',
         /**
         * @property _defaultToolbar
         * @private
         * @description Default toolbar config.
         * @type Object
         */
-        _defaultToolbar: {
-            collapse: true,
-            titlebar: 'Text Editing Tools',
-            draggable: false,
-            buttons: [
-                { group: 'fontstyle', label: 'Font Name and Size',
-                    buttons: [
-                        { type: 'select', label: 'Arial', value: 'fontname', disabled: true,
-                            menu: [
-                                { text: 'Arial', checked: true },
-                                { text: 'Arial Black' },
-                                { text: 'Comic Sans MS' },
-                                { text: 'Courier New' },
-                                { text: 'Lucida Console' },
-                                { text: 'Tahoma' },
-                                { text: 'Times New Roman' },
-                                { text: 'Trebuchet MS' },
-                                { text: 'Verdana' }
-                            ]
-                        },
-                        { type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'textstyle', label: 'Font Style',
-                    buttons: [
-                        { type: 'push', label: 'Bold CTRL + SHIFT + B', value: 'bold' },
-                        { type: 'push', label: 'Italic CTRL + SHIFT + I', value: 'italic' },
-                        { type: 'push', label: 'Underline CTRL + SHIFT + U', value: 'underline' },
-                        { type: 'separator' },
-                        { type: 'color', label: 'Font Color', value: 'forecolor', disabled: true },
-                        { type: 'color', label: 'Background Color', value: 'backcolor', disabled: true }
-                        
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'indentlist', label: 'Lists',
-                    buttons: [
-                        { type: 'push', label: 'Create an Unordered List', value: 'insertunorderedlist' },
-                        { type: 'push', label: 'Create an Ordered List', value: 'insertorderedlist' }
-                    ]
-                },
-                { type: 'separator' },
-                { group: 'insertitem', label: 'Insert Item',
-                    buttons: [
-                        { type: 'push', label: 'HTML Link CTRL + SHIFT + L', value: 'createlink', disabled: true },
-                        { type: 'push', label: 'Insert Image', value: 'insertimage' }
-                    ]
-                }
-            ]
-        },
+        _defaultToolbar: null,
         /**
         * @property _lastButton
         * @private
@@ -2165,9 +2239,9 @@
         * @property _blankImageLoaded
         * @private
         * @description Don't load the blank image more than once..
-        * @type Date
+        * @type Boolean
         */
-        _blankImageLoaded: false,
+        _blankImageLoaded: null,
         /**
         * @property _fixNodesTimer
         * @private
@@ -2202,7 +2276,7 @@
         * @description Flag to determine if editor has been rendered or not
         * @type Boolean
         */
-        _rendered: false,
+        _rendered: null,
         /**
         * @property DOMReady
         * @private
@@ -2261,7 +2335,7 @@
         * @description A reference to the current working element in the editor
         * @type Array
         */
-        currentElement: [],
+        currentElement: null,
         /**
         * @property dompath
         * @description A reference to the dompath container for writing the current working dom path to.
@@ -2293,6 +2367,7 @@
             link: true,
             html: true,
             body: true,
+            iframe: true,
             script: true,
             style: true,
             textarea: true
@@ -2368,7 +2443,7 @@
         * @private _createIframe
         * @description Creates the DOM and YUI Element for the iFrame editor area.
         * @param {String} id The string ID to prefix the iframe with
-        * @returns {Object} iFrame object
+        * @return {Object} iFrame object
         */
         _createIframe: function() {
             var ifrmDom = document.createElement('iframe');
@@ -2383,6 +2458,9 @@
                 allowTransparency: 'true',
                 width: '100%'
             };
+            if (this.get('autoHeight')) {
+                config.scrolling = 'no';
+            }
             for (var i in config) {
                 if (Lang.hasOwnProperty(config, i)) {
                     ifrmDom.setAttribute(i, config[i]);
@@ -2390,9 +2468,7 @@
             }
             var isrc = 'javascript:;';
             if (this.browser.ie) {
-                if (window.location.href.toLowerCase().indexOf("https") !== 0) {
-                    isrc = 'about:blank';
-                }
+                isrc = 'about:blank';
             }
             ifrmDom.setAttribute('src', isrc);
             var ifrm = new YAHOO.util.Element(ifrmDom);
@@ -2404,7 +2480,7 @@
         * @description Checks to see if an Element reference is a valid one and has a certain tag type
         * @param {HTMLElement} el The element to check
         * @param {String} tag The tag that the element needs to be
-        * @returns {Boolean}
+        * @return {Boolean}
         */
         _isElement: function(el, tag) {
             if (el && el.tagName && (el.tagName.toLowerCase() == tag)) {
@@ -2420,7 +2496,7 @@
         * @description Checks to see if an Element reference or one of it's parents is a valid one and has a certain tag type
         * @param {HTMLElement} el The element to check
         * @param {String} tag The tag that the element needs to be
-        * @returns HTMLElement
+        * @return HTMLElement
         */
         _hasParent: function(el, tag) {
             if (!el || !el.parentNode) {
@@ -2512,13 +2588,17 @@
         * @private
         * @method _hasSelection
         * @description Determines if there is a selection in the editor document.
-        * @returns {Boolean}
+        * @return {Boolean}
         */
         _hasSelection: function() {
             var sel = this._getSelection();
             var range = this._getRange();
             var hasSel = false;
 
+            if (!sel || !range) {
+                return hasSel;
+            }
+
             //Internet Explorer
             if (this.browser.ie || this.browser.opera) {
                 if (range.text) {
@@ -2544,7 +2624,7 @@
         * @private
         * @method _getSelection
         * @description Handles the different selection objects across the A-Grade list.
-        * @returns {Object} Selection Object
+        * @return {Object} Selection Object
         */
         _getSelection: function() {
             var _sel = null;
@@ -2614,7 +2694,7 @@
         * @private
         * @method _getRange
         * @description Handles the different range objects across the A-Grade list.
-        * @returns {Object} Range Object
+        * @return {Object} Range Object
         */
         _getRange: function() {
             var sel = this._getSelection();
@@ -2635,7 +2715,11 @@
             }
 
             if (this.browser.ie || this.browser.opera) {
-                return sel.createRange();
+                try {
+                    return sel.createRange();
+                } catch (e) {
+                    return null;
+                }
             }
 
             if (sel.rangeCount > 0) {
@@ -2651,14 +2735,21 @@
         */
         _setDesignMode: function(state) {
             try {
-                this._getDoc().designMode = state;
+                var set = true;
+                //SourceForge Bug #1807057
+                if (this.browser.ie && (state.toLowerCase() == 'off')) {
+                    set = false;
+                }
+                if (set) {
+                    this._getDoc().designMode = state;
+                }
             } catch(e) { }
         },
         /**
         * @private
         * @method _toggleDesignMode
         * @description Toggles the designMode of the iFrame document on and off.
-        * @returns {String} The state that it was set to.
+        * @return {String} The state that it was set to.
         */
         _toggleDesignMode: function() {
             var _dMode = this._getDoc().designMode.toLowerCase(),
@@ -2679,8 +2770,16 @@
                 this._getDoc().body.style.margin = '0';
             }
             if (!this.get('disabled')) {
-                this._setDesignMode('on');
+                if (this._getDoc().designMode.toLowerCase() != 'on') {
+                    this._setDesignMode('on');
+                    this._contentTimerCounter = 0;
+                }
             }
+            if (!this._getDoc().body) {
+                this._contentTimerCounter = 0;
+                this._checkLoaded();
+                return false;
+            }
             
             this.toolbar.on('buttonClick', this._handleToolbarClick, this, true);
             //Setup Listeners on iFrame
@@ -2714,13 +2813,21 @@
             if (this._contentTimer) {
                 clearTimeout(this._contentTimer);
             }
-            if (this._contentTimerCounter > 250) {
+            if (this._contentTimerCounter > 500) {
                 return false;
             }
             var init = false;
             try {
-                if (this._getDoc() && this._getDoc().body && (this._getDoc().body._rteLoaded === true)) {
-                    init = true;
+                if (this._getDoc() && this._getDoc().body) {
+                    if (this.browser.ie) {
+                        if (this._getDoc().body.readyState == 'complete') {
+                            init = true;
+                        }
+                    } else {
+                        if (this._getDoc().body._rteLoaded === true) {
+                            init = true;
+                        }
+                    }
                 }
             } catch (e) {
                 init = false;
@@ -2758,9 +2865,23 @@
             if (this.browser.ie || this.browser.webkit || this.browser.opera || (navigator.userAgent.indexOf('Firefox/1.5') != -1)) {
                 //Firefox 1.5 doesn't like setting designMode on an document created with a data url
                 try {
-                    this._getDoc().open();
-                    this._getDoc().write(html);
-                    this._getDoc().close();
+                    //Adobe AIR Code
+                    if (this.browser.air) {
+                        var doc = this._getDoc().implementation.createHTMLDocument();
+                        var origDoc = this._getDoc();
+                        origDoc.open();
+                        origDoc.close();
+                        doc.open();
+                        doc.write(html);
+                        doc.close();
+                        var node = origDoc.importNode(doc.getElementsByTagName("html")[0], true);
+                        origDoc.replaceChild(node, origDoc.getElementsByTagName("html")[0]);
+                        origDoc.body._rteLoaded = true;
+                    } else {               
+                        this._getDoc().open();
+                        this._getDoc().write(html);
+                        this._getDoc().close();
+                    }
                 } catch (e) {
                     //Safari will only be here if we are hidden
                     check = false;
@@ -2811,7 +2932,7 @@
         * @private
         * @method _getSelectedElement
         * @description This method will attempt to locate the element that was last interacted with, either via selection, location or event.
-        * @returns {HTMLElement} The currently selected element.
+        * @return {HTMLElement} The currently selected element.
         */
         _getSelectedElement: function() {
             var doc = this._getDoc(),
@@ -2878,7 +2999,7 @@
                     }
                 } catch (e) {
                 }
-            } else if (this.currentElement && this.currentElement[0]) {
+            } else if ((this.currentElement && this.currentElement[0]) && (!this.browser.ie)) {
                 elm = this.currentElement[0];
             }
             if (this.browser.opera || this.browser.webkit) {
@@ -2910,7 +3031,7 @@
         * @method _getDomPath
         * @description This method will attempt to build the DOM path from the currently selected element.
         * @param HTMLElement el The element to start with, if not provided _getSelectedElement is used
-        * @returns {Array} An array of node references that will create the DOM Path.
+        * @return {Array} An array of node references that will create the DOM Path.
         */
         _getDomPath: function(el) {
             if (!el) {
@@ -3049,7 +3170,7 @@
         * @description Method is called at the beginning of all event handlers to check if this element or a parent element has the class yui-noedit (this.CLASS_NOEDIT) applied.
         * If it does, then this method will stop the event and return true. The event handlers will then return false and stop the nodeChange from occuring. This method will also
         * disable and enable the Editor's toolbar based on the noedit state.
-        * @returns Boolean
+        * @return Boolean
         */
         _isNonEditable: function(ev) {
             if (this.get('allowNoEdit')) {
@@ -3453,7 +3574,10 @@
             switch (ev.keyCode) {
                 case 84: //Focus Toolbar Header -- Ctrl + Shift + T
                     if (ev.shiftKey && ev.ctrlKey) {
-                        this.toolbar._titlebar.firstChild.focus();
+                        var h = this.toolbar.getElementsByTagName('h2')[0];
+                        if (h) {
+                            h.focus();
+                        }
                         Event.stopEvent(ev);
                         doExec = false;
                     }
@@ -3740,6 +3864,13 @@
         * @description Creates the accessibility h2 header and places it after the iframe in the Dom for navigation.
         */
         _setupAfterElement: function() {
+            if (!this.beforeElement) {
+                this.beforeElement = document.createElement('h2');
+                this.beforeElement.className = 'yui-editor-skipheader';
+                this.beforeElement.tabIndex = '-1';
+                this.beforeElement.innerHTML = this.STR_BEFORE_EDITOR;
+                this.get('element_cont').get('firstChild').insertBefore(this.beforeElement, this.toolbar.get('nextSibling'));
+            }
             if (!this.afterElement) {
                 this.afterElement = document.createElement('h2');
                 this.afterElement.className = 'yui-editor-skipheader';
@@ -3757,7 +3888,9 @@
         _disableEditor: function(disabled) {
             if (disabled) {
                 if (!this._mask) {
-                    this._setDesignMode('off');
+                    if (!!this.browser.ie) {
+                        this._setDesignMode('off');
+                    }
                     if (this.toolbar) {
                         this.toolbar.set('disabled', true);
                     }
@@ -3886,7 +4019,7 @@
         browser: function() {
             var br = YAHOO.env.ua;
             //Check for webkit3
-            if (br.webkit > 420) {
+            if (br.webkit >= 420) {
                 br.webkit3 = br.webkit;
             } else {
                 br.webkit3 = 0;
@@ -3898,9 +4031,66 @@
         * @description The Editor class' initialization method
         */
         init: function(p_oElement, p_oAttributes) {
+
+            if (!this._defaultToolbar) {
+                this._defaultToolbar = {
+                    collapse: true,
+                    titlebar: 'Text Editing Tools',
+                    draggable: false,
+                    buttons: [
+                        { group: 'fontstyle', label: 'Font Name and Size',
+                            buttons: [
+                                { type: 'select', label: 'Arial', value: 'fontname', disabled: true,
+                                    menu: [
+                                        { text: 'Arial', checked: true },
+                                        { text: 'Arial Black' },
+                                        { text: 'Comic Sans MS' },
+                                        { text: 'Courier New' },
+                                        { text: 'Lucida Console' },
+                                        { text: 'Tahoma' },
+                                        { text: 'Times New Roman' },
+                                        { text: 'Trebuchet MS' },
+                                        { text: 'Verdana' }
+                                    ]
+                                },
+                                { type: 'spin', label: '13', value: 'fontsize', range: [ 9, 75 ], disabled: true }
+                            ]
+                        },
+                        { type: 'separator' },
+                        { group: 'textstyle', label: 'Font Style',
+                            buttons: [
+                                { type: 'push', label: 'Bold CTRL + SHIFT + B', value: 'bold' },
+                                { type: 'push', label: 'Italic CTRL + SHIFT + I', value: 'italic' },
+                                { type: 'push', label: 'Underline CTRL + SHIFT + U', value: 'underline' },
+                                { type: 'separator' },
+                                { type: 'color', label: 'Font Color', value: 'forecolor', disabled: true },
+                                { type: 'color', label: 'Background Color', value: 'backcolor', disabled: true }
+                                
+                            ]
+                        },
+                        { type: 'separator' },
+                        { group: 'indentlist', label: 'Lists',
+                            buttons: [
+                                { type: 'push', label: 'Create an Unordered List', value: 'insertunorderedlist' },
+                                { type: 'push', label: 'Create an Ordered List', value: 'insertorderedlist' }
+                            ]
+                        },
+                        { type: 'separator' },
+                        { group: 'insertitem', label: 'Insert Item',
+                            buttons: [
+                                { type: 'push', label: 'HTML Link CTRL + SHIFT + L', value: 'createlink', disabled: true },
+                                { type: 'push', label: 'Insert Image', value: 'insertimage' }
+                            ]
+                        }
+                    ]
+                };
+            }
+
             YAHOO.widget.SimpleEditor.superclass.init.call(this, p_oElement, p_oAttributes);
             YAHOO.widget.EditorInfo._instances[this.get('id')] = this;
 
+
+            this.currentElement = [];
             this.on('contentReady', function() {
                 this.DOMReady = true;
                 this.fireQueue();
@@ -3919,6 +4109,27 @@
             var self = this;
 
             /**
+            * @config container
+            * @description Used when dynamically creating the Editor from Javascript with no default textarea.
+            * We will create one and place it in this container. If no container is passed we will append to document.body.
+            * @default false
+            * @type HTMLElement
+            */
+            this.setAttributeConfig('container', {
+                writeOnce: true,
+                value: attr.container || false
+            });
+            /**
+            * @config plainText
+            * @description Process the inital textarea data as if it was plain text. Accounting for spaces, tabs and line feeds.
+            * @default false
+            * @type Boolean
+            */
+            this.setAttributeConfig('plainText', {
+                writeOnce: true,
+                value: attr.plainText || false
+            });
+            /**
             * @private
             * @config iframe
             * @description Internal config for holding the iframe element.
@@ -3941,6 +4152,17 @@
                 writeOnce: true
             });
             /**
+            * @private
+            * @config container
+            * @description Internal config for holding a reference to the container to append a dynamic editor to.
+            * @default null
+            * @type HTMLElement
+            */
+            this.setAttributeConfig('container', {
+                readOnly: true,
+                value: null
+            });
+            /**
             * @config nodeChangeThreshold
             * @description The number of seconds that need to be in between nodeChange processing
             * @default 3
@@ -4016,6 +4238,32 @@
                 }
             });
             /**
+            * @config autoHeight
+            * @description Remove the scrollbars from the edit area and resize it to fit the content. It will not go any lower than the current config height.
+            * @default false
+            * @type Boolean || Number
+            */
+            this.setAttributeConfig('autoHeight', {
+                value: attr.autoHeight || false,
+                method: function(a) {
+                    if (a) {
+                        if (this.get('iframe')) {
+                            this.get('iframe').get('element').setAttribute('scrolling', 'no');
+                        }
+                        this.on('afterNodeChange', this._handleAutoHeight, this, true);
+                        this.on('editorKeyDown', this._handleAutoHeight, this, true);
+                        this.on('editorKeyPress', this._handleAutoHeight, this, true);
+                    } else {
+                        if (this.get('iframe')) {
+                            this.get('iframe').get('element').setAttribute('scrolling', 'auto');
+                        }
+                        this.unsubscribe('afterNodeChange', this._handleAutoHeight);
+                        this.unsubscribe('editorKeyDown', this._handleAutoHeight);
+                        this.unsubscribe('editorKeyPress', this._handleAutoHeight);
+                    }
+                }
+            });
+            /**
             * @attribute width
             * @description The width of the editor container.
             * @default Best guessed size of the textarea, for best results use CSS to style the width of the textarea or pass it in as an argument
@@ -4126,7 +4374,7 @@
             * @type String
             */            
             this.setAttributeConfig('extracss', {
-                value: attr.css || '',
+                value: attr.extracss || '',
                 writeOnce: true
             });
 
@@ -4139,22 +4387,28 @@
             * @type Boolean
             */            
             this.setAttributeConfig('handleSubmit', {
-                value: false,
-                writeOnce: true,
+                value: attr.handleSubmit || false,
                 method: function(exec) {
-                    if (exec) {
-                        var ta = this.get('element');
-                        if (ta.form) {
-                            var submitForm = function(ev) {
-                                Event.stopEvent(ev);
-                                this.saveHTML();
-                                window.setTimeout(function() {
-                                    YAHOO.util.Event.removeListener(ta.form, 'submit', submitForm);
-                                    ta.form.submit();
-                                }, 200);
-                            };
-                            Event.on(ta.form, 'submit', submitForm, this, true);
+                    if (this.get('element').form) {
+                        if (!this._formButtons) {
+                            this._formButtons = [];
                         }
+                        if (exec) {
+                            Event.on(this.get('element').form, 'submit', this._handleFormSubmit, this, true);
+                            var i = this.get('element').form.getElementsByTagName('input');
+                            for (var s = 0; s < i.length; s++) {
+                                var type = i[s].getAttribute('type');
+                                if (type && (type.toLowerCase() == 'submit')) {
+                                    Event.on(i[s], 'click', this._handleFormButtonClick, this, true);
+                                    this._formButtons[this._formButtons.length] = i[s];
+                                }
+                            }
+                        } else {
+                            Event.unsubscribe(this.get('element').form, 'submit', this._handleFormSubmit);
+                            if (this._formButtons) {
+                                Event.unsubscribe(this._formButtons, 'click', this._handleFormButtonClick);
+                            }
+                        }
                     }
                 }
             });
@@ -4213,7 +4467,7 @@
                         ret = false;
                     }
                     return ret;
-                }               
+                }
             });
             /**
             * @config panel
@@ -4272,7 +4526,6 @@
                         this.dompath.parentNode.removeChild(this.dompath);
                         this.dompath = null;
                     }
-                    this._setupAfterElement();
                 }
             });
             /**
@@ -4314,7 +4567,7 @@
         * @private
         * @method _getBlankImage
         * @description Retrieves the full url of the image to use as the blank image.
-        * @returns {String} The URL to the blank image
+        * @return {String} The URL to the blank image
         */
         _getBlankImage: function() {
             if (!this.DOMReady) {
@@ -4323,16 +4576,24 @@
             }
             var img = '';
             if (!this._blankImageLoaded) {
-                var div = document.createElement('div');
-                div.style.position = 'absolute';
-                div.style.top = '-9999px';
-                div.style.left = '-9999px';
-                div.className = this.CLASS_PREFIX + '-blankimage';
-                document.body.appendChild(div);
-                img = YAHOO.util.Dom.getStyle(div, 'background-image');
-                img = img.replace('url(', '').replace(')', '').replace(/"/g, '');
-                this.set('blankimage', img);
-                this._blankImageLoaded = true;
+                if (YAHOO.widget.EditorInfo.blankImage) {
+                    this.set('blankimage', YAHOO.widget.EditorInfo.blankImage);
+                    this._blankImageLoaded = true;
+                } else {
+                    var div = document.createElement('div');
+                    div.style.position = 'absolute';
+                    div.style.top = '-9999px';
+                    div.style.left = '-9999px';
+                    div.className = this.CLASS_PREFIX + '-blankimage';
+                    document.body.appendChild(div);
+                    img = YAHOO.util.Dom.getStyle(div, 'background-image');
+                    img = img.replace('url(', '').replace(')', '').replace(/"/g, '');
+                    //Adobe AIR Code
+                    img = img.replace('app:/', '');                    
+                    this.set('blankimage', img);
+                    this._blankImageLoaded = true;
+                    YAHOO.widget.EditorInfo.blankImage = img;
+                }
             } else {
                 img = this.get('blankimage');
             }
@@ -4340,6 +4601,81 @@
         },
         /**
         * @private
+        * @method _handleAutoHeight
+        * @description Handles resizing the editor's height based on the content
+        */
+        _handleAutoHeight: function() {
+            var doc = this._getDoc(),
+                body = doc.body,
+                docEl = doc.documentElement;
+
+            var height = parseInt(Dom.getStyle(this.get('editor_wrapper'), 'height'), 10);
+            var newHeight = body.scrollHeight;
+            if (this.browser.webkit) {
+                newHeight = docEl.scrollHeight;
+            }
+            if (newHeight < parseInt(this.get('height'), 10)) {
+                newHeight = parseInt(this.get('height'), 10);
+            }
+            if ((height != newHeight) && (newHeight >= parseInt(this.get('height'), 10))) {   
+                Dom.setStyle(this.get('editor_wrapper'), 'height', newHeight + 'px');
+                if (this.browser.ie) {
+                    //Internet Explorer needs this
+                    this.get('iframe').setStyle('height', '99%');
+                    this.get('iframe').setStyle('zoom', '1');
+                    var self = this;
+                    window.setTimeout(function() {
+                        self.get('iframe').setStyle('height', '100%');
+                    }, 1);
+                }
+            }
+        },
+        _formButtons: null,
+        _formButtonClicked: null,
+        _handleFormButtonClick: function(ev) {
+            var tar = Event.getTarget(ev);
+            this._formButtonClicked = tar;
+        },
+        /**
+        * @private
+        * @method _handleFormSubmit
+        * @description Handles the form submission.
+        * @param {Object} ev The Form Submit Event
+        */
+        _handleFormSubmit: function(ev) {
+            Event.stopEvent(ev);
+            
+            this.saveHTML();
+            var form = this.get('element').form;
+            var tar = this._formButtonClicked || false;
+            var self = this;
+
+            window.setTimeout(function() {
+                YAHOO.util.Event.removeListener(form, 'submit', self._handleFormSubmit);
+                if (YAHOO.env.ua.ie) {
+                    form.fireEvent("onsubmit");
+                    if (tar && !tar.disabled) {
+                        tar.click();
+                    }
+                } else {  // Gecko, Opera, and Safari
+                    if (tar && !tar.disabled) {
+                        tar.click();
+                    } else {
+                        var oEvent = document.createEvent("HTMLEvents");
+                        oEvent.initEvent("submit", true, true);
+                        form.dispatchEvent(oEvent);
+                        if (YAHOO.env.ua.webkit) {
+                            if (YAHOO.lang.isFunction(form.submit)) {
+                                form.submit();
+                            }
+                        }
+                    }
+                }
+            }, 200);
+            
+        },
+        /**
+        * @private
         * @method _handleFontSize
         * @description Handles the font size button in the toolbar.
         * @param {Object} o Object returned from Toolbar's buttonClick Event
@@ -4408,6 +4744,8 @@
                 family = elm.getAttribute('face');
                 if (Dom.getStyle(elm, 'font-family')) {
                     family = Dom.getStyle(elm, 'font-family');
+                    //Adobe AIR Code
+                    family = family.replace(/'/g, '');                    
                 }
 
                 if (tag.substring(0, 1) == 'h') {
@@ -4463,7 +4801,6 @@
                 this.toolbar.disableButton('indent');
                 this.toolbar.enableButton('outdent');
             }
-            //if (this._isElement(elm, 'ol') || this._isElement(elm, 'ul') || this._isElement(elm, 'li')) {
             if (this._hasParent(elm, 'ol') || this._hasParent(elm, 'ul')) {
                 this.toolbar.disableButton('indent');
             }
@@ -4471,6 +4808,7 @@
             
         },
         _setBusy: function(off) {
+            /*
             if (off) {
                 Dom.removeClass(document.body, 'yui-busy');
                 Dom.removeClass(this._getDoc().body, 'yui-busy');
@@ -4478,6 +4816,7 @@
                 Dom.addClass(document.body, 'yui-busy');
                 Dom.addClass(this._getDoc().body, 'yui-busy');
             }
+            */
         },
         /**
         * @private
@@ -4509,9 +4848,10 @@
                 var str = prompt(this.STR_LINK_URL + ': ', src);
                 if ((str !== '') && (str !== null)) {
                     el.setAttribute('src', str);
-                } else if (str !== null) {
+                } else if (str === null) {
                     el.parentNode.removeChild(el);
                     this.currentElement = [];
+                    this.nodeChange();
                 }
                 this.closeWindow();
                 this.toolbar.set('disabled', false);
@@ -4595,7 +4935,7 @@
         },
         /**
         * @method render
-        * @description Causes the toolbar and the editor to render and replace the textarea.
+        * @description Calls the private method _render in a setTimeout to allow for other things on the page to continue to load.
         */
         render: function() {
             if (this._rendered) {
@@ -4605,10 +4945,20 @@
                 this._queue[this._queue.length] = ['render', arguments];
                 return false;
             }
-            this._setBusy();
             this._rendered = true;
             var self = this;
-
+            window.setTimeout(function() {
+                self._render.call(self);
+            }, 4);
+        },
+        /**
+        * @private
+        * @method _render
+        * @description Causes the toolbar and the editor to render and replace the textarea.
+        */
+        _render: function() {
+            this._setBusy();
+            var self = this;
             this.set('textarea', this.get('element'));
 
             this.get('element_cont').setStyle('display', 'none');
@@ -4656,6 +5006,7 @@
             
             this.toolbar.on('colorPickerClicked', function(o) {
                 this._handleColorPicker(o);
+                return false; //Stop the buttonClick event
             }, this, true);
 
             this.toolbar.on('alignClick', function(o) {
@@ -4679,18 +5030,9 @@
             
 
             //Replace Textarea with editable area
-            
             this.get('parentNode').replaceChild(this.get('element_cont').get('element'), this.get('element'));
 
             
-            if (!this.beforeElement) {
-                this.beforeElement = document.createElement('h2');
-                this.beforeElement.className = 'yui-editor-skipheader';
-                this.beforeElement.tabIndex = '-1';
-                this.beforeElement.innerHTML = this.STR_BEFORE_EDITOR;
-                this.get('element_cont').get('firstChild').insertBefore(this.beforeElement, this.toolbar.get('nextSibling'));
-            }
-
             this.setStyle('visibility', 'hidden');
             this.setStyle('position', 'absolute');
             this.setStyle('top', '-9999px');
@@ -4709,9 +5051,9 @@
             this.get('iframe').setStyle('width', '100%'); //WIDTH
             this.get('iframe').setStyle('height', '100%');
 
-            if (this.browser.ie == 7) {
-            }
-
+            window.setTimeout(function() {
+                self._setupAfterElement.call(self);
+            }, 0);
             this.fireEvent('afterRender', { type: 'afterRender', target: this });
         },
         /**
@@ -4997,8 +5339,11 @@
                 exec = false;
             } else {
                 el = this._getSelectedElement();
-                if (this._isElement(el, 'li') && this._isElement(el.parentNode, tag) || (this.browser.ie && this._isElement(this._getRange().parentElement, 'li'))) { //we are in a list..
+                if (this._isElement(el, 'li') && this._isElement(el.parentNode, tag) || (this.browser.ie && this._isElement(this._getRange().parentElement, 'li')) || (this.browser.ie && this._isElement(el, 'ul')) || (this.browser.ie && this._isElement(el, 'ol'))) { //we are in a list..
                     if (this.browser.ie) {
+                        if ((this.browser.ie && this._isElement(el, 'ul')) || (this.browser.ie && this._isElement(el, 'ol'))) {
+                            el = el.getElementsByTagName('li')[0];
+                        }
                         str = '';
                         var lis2 = el.parentNode.getElementsByTagName('li');
                         for (var j = 0; j < lis2.length; j++) {
@@ -5030,7 +5375,15 @@
                     if (this._getRange().html) {
                         html = '<li>' + this._getRange().html+ '</li>';
                     } else {
-                        html = '<li>' + this._getRange().text + '</li>';
+                        var t = this._getRange().text.split('\n');
+                        if (t.length > 1) {
+                            html = '';
+                            for (var ie = 0; ie < t.length; ie++) {
+                                html += '<li>' + t[ie] + '</li>';
+                            }
+                        } else {
+                            html = '<li>' + this._getRange().text + '</li>';
+                        }
                     }
 
                     this._getRange().pasteHTML('<' + tag + '>' + html + '</' + tag + '>');
@@ -5077,7 +5430,7 @@
         * @description This is an execCommand override method. It is called from execCommand when the execCommand('fontsize') is used.
         */
         cmd_fontsize: function(value) {
-            if ((this.currentElement.length > 0) && (!this._hasSelection())) {
+            if (this.currentElement && (this.currentElement.length > 0) && (!this._hasSelection())) {
                 YAHOO.util.Dom.setStyle(this.currentElement, 'fontSize', value);
             } else if (!this._isElement(this._getSelectedElement(), 'body')) {
                 var el = this._getSelectedElement();
@@ -5294,6 +5647,7 @@
         /**
         * @method saveHTML
         * @description Cleans the HTML with the cleanHTML method then places that string back into the textarea.
+        * @return String
         */
         saveHTML: function() {
             var html = this.cleanHTML();
@@ -5315,6 +5669,10 @@
         * @description Gets the unprocessed/unfiltered HTML from the editor
         */
         getEditorHTML: function() {
+            var b = this._getDoc().body;
+            if (b === null) {
+                return null;
+            }
             return this._getDoc().body.innerHTML;
         },
         /**
@@ -5366,20 +5724,45 @@
         * @method _cleanIncomingHTML
         * @param {String} html The unfiltered HTML
         * @description Process the HTML with a few regexes to clean it up and stabilize the input
-        * @returns {String} The filtered HTML
+        * @return {String} The filtered HTML
         */
         _cleanIncomingHTML: function(html) {
             html = html.replace(/<strong([^>]*)>/gi, '<b$1>');
             html = html.replace(/<\/strong>/gi, '</b>');   
+
+            //replace embed before em check
+            html = html.replace(/<embed([^>]*)>/gi, '<YUI_EMBED$1>');
+            html = html.replace(/<\/embed>/gi, '</YUI_EMBED>');
+
             html = html.replace(/<em([^>]*)>/gi, '<i$1>');
             html = html.replace(/<\/em>/gi, '</i>');
+            
+            //Put embed tags back in..
+            html = html.replace(/<YUI_EMBED([^>]*)>/gi, '<embed$1>');
+            html = html.replace(/<\/YUI_EMBED>/gi, '</embed>');
+            if (this.get('plainText')) {
+                html = html.replace(/\n/g, '<br>').replace(/\r/g, '<br>');
+                html = html.replace(/  /gi, '  '); //Replace all double spaces
+                html = html.replace(/\t/gi, '    '); //Replace all tabs
+            }
+            //Removing Script Tags from the Editor
+            html = html.replace(/<script([^>]*)>/gi, '<bad>');
+            html = html.replace(/<\/script([^>]*)>/gi, '</bad>');
+            html = html.replace(/<script([^>]*)>/gi, '<bad>');
+            html = html.replace(/<\/script([^>]*)>/gi, '</bad>');
+            //Replace the line feeds
+            html = html.replace(/\n/g, '<YUI_LF>').replace(/\r/g, '<YUI_LF>');
+            //Remove Bad HTML elements (used to be script nodes)
+            html = html.replace(new RegExp('<bad([^>]*)>(.*?)<\/bad>', 'gi'), '');
+            //Replace the lines feeds
+            html = html.replace(/<YUI_LF>/g, '\n');
             return html;
         },
         /**
         * @method cleanHTML
         * @param {String} html The unfiltered HTML
         * @description Process the HTML with a few regexes to clean it up and stabilize the output
-        * @returns {String} The filtered HTML
+        * @return {String} The filtered HTML
         */
         cleanHTML: function(html) {
             //Start Filtering Output
@@ -5402,9 +5785,12 @@
 		    html = html.replace(/<blockquote([^>]*)>/gi, '<YUI_BQ$1>');
 		    html = html.replace(/<\/blockquote>/gi, '<\/YUI_BQ>');
 
+		    html = html.replace(/<embed([^>]*)>/gi, '<YUI_EMBED$1>');
+		    html = html.replace(/<\/embed>/gi, '<\/YUI_EMBED>');
+
             //Convert b and i tags to strong and em tags
             if ((markup == 'semantic') || (markup == 'xhtml')) {
-                html = html.replace(/<i([^>]*)>/gi, '<em$1>');
+                html = html.replace(/<i(\s+[^>]*)?>/gi, '<em$1>');
                 html = html.replace(/<\/i>/gi, '</em>');
                 html = html.replace(/<b([^>]*)>/gi, '<strong$1>');
                 html = html.replace(/<\/b>/gi, '</strong>');
@@ -5418,6 +5804,10 @@
             if ((markup == 'semantic') || (markup == 'xhtml') || (markup == 'css')) {
                 html = html.replace(new RegExp('<font([^>]*)face="([^>]*)">(.*?)<\/font>', 'gi'), '<span $1 style="font-family: $2;">$3</span>');
                 html = html.replace(/<u/gi, '<span style="text-decoration: underline;"');
+                if (this.browser.webkit) {
+                    html = html.replace(new RegExp('<span class="Apple-style-span" style="font-weight: bold;">([^>]*)<\/span>', 'gi'), '<strong>$1</strong>');
+                    html = html.replace(new RegExp('<span class="Apple-style-span" style="font-style: italic;">([^>]*)<\/span>', 'gi'), '<em>$1</em>');
+                }
                 html = html.replace(/\/u>/gi, '/span>');
                 if (markup == 'css') {
                     html = html.replace(/<em([^>]*)>/gi, '<i$1>');
@@ -5448,8 +5838,8 @@
             html = this.post_filter_linebreaks(html, markup);
 
             if (markup == 'xhtml') {
-		        html = html.replace(/<YUI_IMG([^>]*)>/g, '<img $1/>');
-		        html = html.replace(/<YUI_INPUT([^>]*)>/g, '<input $1/>');
+		        html = html.replace(/<YUI_IMG([^>]*)>/g, '<img $1 />');
+		        html = html.replace(/<YUI_INPUT([^>]*)>/g, '<input $1 />');
             } else {
 		        html = html.replace(/<YUI_IMG([^>]*)>/g, '<img $1>');
 		        html = html.replace(/<YUI_INPUT([^>]*)>/g, '<input $1>');
@@ -5462,6 +5852,9 @@
 		    html = html.replace(/<YUI_BQ([^>]*)>/g, '<blockquote$1>');
 		    html = html.replace(/<\/YUI_BQ>/g, '<\/blockquote>');
 
+		    html = html.replace(/<YUI_EMBED([^>]*)>/g, '<embed$1>');
+		    html = html.replace(/<\/YUI_EMBED>/g, '<\/embed>');
+
             //Trim the output, removing whitespace from the beginning and end
             html = YAHOO.lang.trim(html);
 
@@ -5473,13 +5866,12 @@
             //First empty span
             if (html.substring(0, 6).toLowerCase() == '<span>')  {
                 html = html.substring(6);
+                //Last empty span
+                if (html.substring(html.length - 7, html.length).toLowerCase() == '</span>')  {
+                    html = html.substring(0, html.length - 7);
+                }
             }
-            //Last empty span
-            if (html.substring(html.length - 7, html.length).toLowerCase() == '</span>')  {
-                html = html.substring(0, html.length - 7);
-            }
 
-
             for (var v in this.invalidHTML) {
                 if (YAHOO.lang.hasOwnProperty(this.invalidHTML, v)) {
                     if (Lang.isObject(v) && v.keepContents) {
@@ -5498,7 +5890,6 @@
         * @method filter_invalid_lists
         * @param String html The HTML string to filter
         * @description Filters invalid ol and ul list markup, converts this: <li></li><ol>..</ol> to this: <li></li><li><ol>..</ol></li>
-        * @returns String
         */
         filter_invalid_lists: function(html) {
             html = html.replace(/<\/li>\n/gi, '</li>');
@@ -5521,10 +5912,12 @@
         * @method filter_safari
         * @param String html The HTML string to filter
         * @description Filters strings specific to Safari
-        * @returns String
+        * @return String
         */
         filter_safari: function(html) {
             if (this.browser.webkit) {
+                //<span class="Apple-tab-span" style="white-space:pre">	</span>
+                html = html.replace(/<span class="Apple-tab-span" style="white-space:pre">([^>])<\/span>/gi, '    ');
                 html = html.replace(/Apple-style-span/gi, '');
                 html = html.replace(/style="line-height: normal;"/gi, '');
                 //Remove bogus LI's
@@ -5541,7 +5934,7 @@
         * @method filter_internals
         * @param String html The HTML string to filter
         * @description Filters internal RTE strings and bogus attrs we don't want
-        * @returns String
+        * @return String
         */
         filter_internals: function(html) {
 		    html = html.replace(/\r/g, '');
@@ -5575,7 +5968,7 @@
         * @method filter_all_rgb
         * @param String str The HTML string to filter
         * @description Converts all RGB color strings found in passed string to a hex color, example: style="color: rgb(0, 255, 0)" converts to style="color: #00ff00"
-        * @returns String
+        * @return String
         */
         filter_all_rgb: function(str) {
             var exp = new RegExp("rgb\\s*?\\(\\s*?([0-9]+).*?,\\s*?([0-9]+).*?,\\s*?([0-9]+).*?\\)", "gi");
@@ -5593,7 +5986,7 @@
         * @method filter_rgb
         * @param String css The CSS string containing rgb(#,#,#);
         * @description Converts an RGB color string to a hex color, example: rgb(0, 255, 0) converts to #00ff00
-        * @returns String
+        * @return String
         */
         filter_rgb: function(css) {
             if (css.toLowerCase().indexOf('rgb') != -1) {
@@ -5619,7 +6012,7 @@
         * @param String html The HTML to filter
         * @param String markup The markup type to filter to
         * @description HTML Pre Filter
-        * @returns String
+        * @return String
         */
         pre_filter_linebreaks: function(html, markup) {
             if (this.browser.webkit) {
@@ -5645,11 +6038,11 @@
         * @param String html The HTML to filter
         * @param String markup The markup type to filter to
         * @description HTML Pre Filter
-        * @returns String
+        * @return String
         */
         post_filter_linebreaks: function(html, markup) {
             if (markup == 'xhtml') {
-		        html = html.replace(/<YUI_BR>/g, '<br/>');
+		        html = html.replace(/<YUI_BR>/g, '<br />');
             } else {
 		        html = html.replace(/<YUI_BR>/g, '<br>');
             }
@@ -5712,6 +6105,7 @@
             var textArea = this.get('element');
             this.get('element_cont').get('parentNode').replaceChild(textArea, this.get('element_cont').get('element'));
             this.get('element_cont').get('element').innerHTML = '';
+            this.set('handleSubmit', false); //Remove the submit handler
             //Brutal Object Destroy
             for (var i in this) {
                 if (Lang.hasOwnProperty(this, i)) {
@@ -5826,6 +6220,13 @@
         _instances: {},
         /**
         * @private
+        * @property blankImage
+        * @description A reference to the blankImage url
+        * @type String 
+        */
+        blankImage: '',
+        /**
+        * @private
         * @property window
         * @description A reference to the currently open window object in any editor on the page.
         * @type Object <a href="YAHOO.widget.EditorWindow.html">YAHOO.widget.EditorWindow</a>
@@ -5842,7 +6243,7 @@
         * @method getEditorById
         * @description Returns a reference to the Editor object associated with the given textarea
         * @param {String/HTMLElement} id The id or reference of the textarea to return the Editor instance of
-        * @returns Object <a href="YAHOO.widget.Editor.html">YAHOO.widget.Editor</a>
+        * @return Object <a href="YAHOO.widget.Editor.html">YAHOO.widget.Editor</a>
         */
         getEditorById: function(id) {
             if (!YAHOO.lang.isString(id)) {
@@ -5872,4 +6273,4 @@
 
     
 })();
-YAHOO.register("simpleeditor", YAHOO.widget.SimpleEditor, {version: "2.4.1", build: "742"});
+YAHOO.register("simpleeditor", YAHOO.widget.SimpleEditor, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/element/README
===================================================================
--- trunk/root/static/yui/element/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/element/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,5 +1,11 @@
 Element Release Notes
 
+*** version 2.5.1 ***
+no change
+
+*** version 2.5.0 ***
+* SetAttributes now correctly handles false values
+
 *** version 2.4.0 ***
 no change
 

Modified: trunk/root/static/yui/element/element-beta-debug.js
===================================================================
--- trunk/root/static/yui/element/element-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/element/element-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * Provides Attribute configurations.
@@ -797,7 +797,7 @@
 
         // set based on configOrder
         for (var i = 0, len = this._configOrder.length; i < len; ++i) {
-            if (map[this._configOrder[i]]) {
+            if (map[this._configOrder[i]] !== undefined) {
                 this.set(this._configOrder[i], map[this._configOrder[i]], silent);
             }
         }
@@ -974,8 +974,33 @@
  * @event contentReady
  */
 
+/**
+ * Fires before the Element is appended to another Element.
+ * <p>See: <a href="#addListener">Element.addListener</a></p>
+ * <p><strong>Event fields:</strong><br>
+ * <code><String> type</code> beforeAppendTo<br>
+ * <code><HTMLElement/Element>
+ * target</code> the HTMLElement/Element being appended to 
+ * <p><strong>Usage:</strong><br>
+ * <code>var handler = function(e) {var target = e.target};<br>
+ * myTabs.addListener('beforeAppendTo', handler);</code></p>
+ * @event beforeAppendTo
+ */
 
+/**
+ * Fires after the Element is appended to another Element.
+ * <p>See: <a href="#addListener">Element.addListener</a></p>
+ * <p><strong>Event fields:</strong><br>
+ * <code><String> type</code> appendTo<br>
+ * <code><HTMLElement/Element>
+ * target</code> the HTMLElement/Element being appended to 
+ * <p><strong>Usage:</strong><br>
+ * <code>var handler = function(e) {var target = e.target};<br>
+ * myTabs.addListener('appendTo', handler);</code></p>
+ * @event appendTo
+ */
+
 YAHOO.augment(YAHOO.util.Element, AttributeProvider);
 })();
 
-YAHOO.register("element", YAHOO.util.Element, {version: "2.4.1", build: "742"});
+YAHOO.register("element", YAHOO.util.Element, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/element/element-beta-min.js
===================================================================
--- trunk/root/static/yui/element/element-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/element/element-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 YAHOO.util.Attribute=function(B,A){if(A){this.owner=A;this.configure(B,true);}};YAHOO.util.Attribute.prototype={name:undefined,value:null,owner:null,readOnly:false,writeOnce:false,_initialConfig:null,_written:false,method:null,validator:null,getValue:function(){return this.value;},setValue:function(F,B){var E;var A=this.owner;var C=this.name;var D={type:C,prevValue:this.getValue(),newValue:F};if(this.readOnly||(this.writeOnce&&this._written)){return false;}if(this.validator&&!this.validator.call(A,F)){return false;}if(!B){E=A.fireBeforeChangeEvent(D);if(E===false){return false;}}if(this.method){this.method.call(A,F);}this.value=F;this._written=true;D.type=C;if(!B){this.owner.fireChangeEvent(D);}return true;},configure:function(B,C){B=B||{};this._written=false;this._initialConfig=this._initialConfig||{};for(var A in B){if(A&&YAHOO.lang.hasOwnProperty(B,A)){this[A]=B[A];if(C){this._initialConfig[A]=B[A];}}}},resetValue:function(){return this.setValue(this._initialConfig.value!
 );},resetConfig:function(){this.configure(this._initialConfig);},refresh:function(A){this.setValue(this.value,A);}};(function(){var A=YAHOO.util.Lang;YAHOO.util.AttributeProvider=function(){};YAHOO.util.AttributeProvider.prototype={_configs:null,get:function(C){this._configs=this._configs||{};var B=this._configs[C];if(!B){return undefined;}return B.value;},set:function(D,E,B){this._configs=this._configs||{};var C=this._configs[D];if(!C){return false;}return C.setValue(E,B);},getAttributeKeys:function(){this._configs=this._configs;var D=[];var B;for(var C in this._configs){B=this._configs[C];if(A.hasOwnProperty(this._configs,C)&&!A.isUndefined(B)){D[D.length]=C;}}return D;},setAttributes:function(D,B){for(var C in D){if(A.hasOwnProperty(D,C)){this.set(C,D[C],B);}}},resetValue:function(C,B){this._configs=this._configs||{};if(this._configs[C]){this.set(C,this._configs[C]._initialConfig.value,B);return true;}return false;},refresh:function(E,C){this._configs=this._configs;E=((A!
 .isString(E))?[E]:E)||this.getAttributeKeys();for(var D=0,B=E.!
 length;D
<B;++D){if(this._configs[E[D]]&&!A.isUndefined(this._configs[E[D]].value)&&!A.isNull(this._configs[E[D]].value)){this._configs[E[D]].refresh(C);}}},register:function(B,C){this.setAttributeConfig(B,C);},getAttributeConfig:function(C){this._configs=this._configs||{};var B=this._configs[C]||{};var D={};for(C in B){if(A.hasOwnProperty(B,C)){D[C]=B[C];}}return D;},setAttributeConfig:function(B,C,D){this._configs=this._configs||{};C=C||{};if(!this._configs[B]){C.name=B;this._configs[B]=this.createAttribute(C);}else{this._configs[B].configure(C,D);}},configureAttribute:function(B,C,D){this.setAttributeConfig(B,C,D);},resetAttributeConfig:function(B){this._configs=this._configs||{};this._configs[B].resetConfig();},subscribe:function(B,C){this._events=this._events||{};if(!(B in this._events)){this._events[B]=this.createEvent(B);}YAHOO.util.EventProvider.prototype.subscribe.apply(this,arguments);},on:function(){this.subscribe.apply(this,arguments);},addListener:function(){this.subscri!
 be.apply(this,arguments);},fireBeforeChangeEvent:function(C){var B="before";B+=C.type.charAt(0).toUpperCase()+C.type.substr(1)+"Change";C.type=B;return this.fireEvent(C.type,C);},fireChangeEvent:function(B){B.type+="Change";return this.fireEvent(B.type,B);},createAttribute:function(B){return new YAHOO.util.Attribute(B,this);}};YAHOO.augment(YAHOO.util.AttributeProvider,YAHOO.util.EventProvider);})();(function(){var D=YAHOO.util.Dom,F=YAHOO.util.AttributeProvider;YAHOO.util.Element=function(G,H){if(arguments.length){this.init(G,H);}};YAHOO.util.Element.prototype={DOM_EVENTS:null,appendChild:function(G){G=G.get?G.get("element"):G;this.get("element").appendChild(G);},getElementsByTagName:function(G){return this.get("element").getElementsByTagName(G);},hasChildNodes:function(){return this.get("element").hasChildNodes();},insertBefore:function(G,H){G=G.get?G.get("element"):G;H=(H&&H.get)?H.get("element"):H;this.get("element").insertBefore(G,H);},removeChild:function(G){G=G.get?G!
 .get("element"):G;this.get("element").removeChild(G);return tr!
 ue;},rep
laceChild:function(G,H){G=G.get?G.get("element"):G;H=H.get?H.get("element"):H;return this.get("element").replaceChild(G,H);},initAttributes:function(G){},addListener:function(K,J,L,I){var H=this.get("element");I=I||this;H=this.get("id")||H;var G=this;if(!this._events[K]){if(this.DOM_EVENTS[K]){YAHOO.util.Event.addListener(H,K,function(M){if(M.srcElement&&!M.target){M.target=M.srcElement;}G.fireEvent(K,M);},L,I);}this.createEvent(K,this);}YAHOO.util.EventProvider.prototype.subscribe.apply(this,arguments);},on:function(){this.addListener.apply(this,arguments);},subscribe:function(){this.addListener.apply(this,arguments);},removeListener:function(H,G){this.unsubscribe.apply(this,arguments);},addClass:function(G){D.addClass(this.get("element"),G);},getElementsByClassName:function(H,G){return D.getElementsByClassName(H,G,this.get("element"));},hasClass:function(G){return D.hasClass(this.get("element"),G);},removeClass:function(G){return D.removeClass(this.get("element"),G);},repl!
 aceClass:function(H,G){return D.replaceClass(this.get("element"),H,G);},setStyle:function(I,H){var G=this.get("element");if(!G){return this._queue[this._queue.length]=["setStyle",arguments];}return D.setStyle(G,I,H);},getStyle:function(G){return D.getStyle(this.get("element"),G);},fireQueue:function(){var H=this._queue;for(var I=0,G=H.length;I<G;++I){this[H[I][0]].apply(this,H[I][1]);}},appendTo:function(H,I){H=(H.get)?H.get("element"):D.get(H);this.fireEvent("beforeAppendTo",{type:"beforeAppendTo",target:H});I=(I&&I.get)?I.get("element"):D.get(I);var G=this.get("element");if(!G){return false;}if(!H){return false;}if(G.parent!=H){if(I){H.insertBefore(G,I);}else{H.appendChild(G);}}this.fireEvent("appendTo",{type:"appendTo",target:H});},get:function(G){var I=this._configs||{};var H=I.element;if(H&&!I[G]&&!YAHOO.lang.isUndefined(H.value[G])){return H.value[G];}return F.prototype.get.call(this,G);},setAttributes:function(L,H){var K=this.get("element");
-for(var J in L){if(!this._configs[J]&&!YAHOO.lang.isUndefined(K[J])){this.setAttributeConfig(J);}}for(var I=0,G=this._configOrder.length;I<G;++I){if(L[this._configOrder[I]]){this.set(this._configOrder[I],L[this._configOrder[I]],H);}}},set:function(H,J,G){var I=this.get("element");if(!I){this._queue[this._queue.length]=["set",arguments];if(this._configs[H]){this._configs[H].value=J;}return ;}if(!this._configs[H]&&!YAHOO.lang.isUndefined(I[H])){C.call(this,H);}return F.prototype.set.apply(this,arguments);},setAttributeConfig:function(G,I,J){var H=this.get("element");if(H&&!this._configs[G]&&!YAHOO.lang.isUndefined(H[G])){C.call(this,G,I);}else{F.prototype.setAttributeConfig.apply(this,arguments);}this._configOrder.push(G);},getAttributeKeys:function(){var H=this.get("element");var I=F.prototype.getAttributeKeys.call(this);for(var G in H){if(!this._configs[G]){I[G]=I[G]||H[G];}}return I;},createEvent:function(H,G){this._events[H]=true;F.prototype.createEvent.apply(this,argumen!
 ts);},init:function(H,G){A.apply(this,arguments);}};var A=function(H,G){this._queue=this._queue||[];this._events=this._events||{};this._configs=this._configs||{};this._configOrder=[];G=G||{};G.element=G.element||H||null;this.DOM_EVENTS={"click":true,"dblclick":true,"keydown":true,"keypress":true,"keyup":true,"mousedown":true,"mousemove":true,"mouseout":true,"mouseover":true,"mouseup":true,"focus":true,"blur":true,"submit":true};var I=false;if(YAHOO.lang.isString(H)){C.call(this,"id",{value:G.element});}if(D.get(H)){I=true;E.call(this,G);B.call(this,G);}YAHOO.util.Event.onAvailable(G.element,function(){if(!I){E.call(this,G);}this.fireEvent("available",{type:"available",target:G.element});},this,true);YAHOO.util.Event.onContentReady(G.element,function(){if(!I){B.call(this,G);}this.fireEvent("contentReady",{type:"contentReady",target:G.element});},this,true);};var E=function(G){this.setAttributeConfig("element",{value:D.get(G.element),readOnly:true});};var B=function(G){this.i!
 nitAttributes(G);this.setAttributes(G,true);this.fireQueue();}!
 ;var C=f
unction(G,I){var H=this.get("element");I=I||{};I.name=G;I.method=I.method||function(J){H[G]=J;};I.value=I.value||H[G];this._configs[G]=new YAHOO.util.Attribute(I,this);};YAHOO.augment(YAHOO.util.Element,F);})();YAHOO.register("element",YAHOO.util.Element,{version:"2.4.1",build:"742"});
\ No newline at end of file
+for(var J in L){if(!this._configs[J]&&!YAHOO.lang.isUndefined(K[J])){this.setAttributeConfig(J);}}for(var I=0,G=this._configOrder.length;I<G;++I){if(L[this._configOrder[I]]!==undefined){this.set(this._configOrder[I],L[this._configOrder[I]],H);}}},set:function(H,J,G){var I=this.get("element");if(!I){this._queue[this._queue.length]=["set",arguments];if(this._configs[H]){this._configs[H].value=J;}return ;}if(!this._configs[H]&&!YAHOO.lang.isUndefined(I[H])){C.call(this,H);}return F.prototype.set.apply(this,arguments);},setAttributeConfig:function(G,I,J){var H=this.get("element");if(H&&!this._configs[G]&&!YAHOO.lang.isUndefined(H[G])){C.call(this,G,I);}else{F.prototype.setAttributeConfig.apply(this,arguments);}this._configOrder.push(G);},getAttributeKeys:function(){var H=this.get("element");var I=F.prototype.getAttributeKeys.call(this);for(var G in H){if(!this._configs[G]){I[G]=I[G]||H[G];}}return I;},createEvent:function(H,G){this._events[H]=true;F.prototype.createEvent.apply(!
 this,arguments);},init:function(H,G){A.apply(this,arguments);}};var A=function(H,G){this._queue=this._queue||[];this._events=this._events||{};this._configs=this._configs||{};this._configOrder=[];G=G||{};G.element=G.element||H||null;this.DOM_EVENTS={"click":true,"dblclick":true,"keydown":true,"keypress":true,"keyup":true,"mousedown":true,"mousemove":true,"mouseout":true,"mouseover":true,"mouseup":true,"focus":true,"blur":true,"submit":true};var I=false;if(YAHOO.lang.isString(H)){C.call(this,"id",{value:G.element});}if(D.get(H)){I=true;E.call(this,G);B.call(this,G);}YAHOO.util.Event.onAvailable(G.element,function(){if(!I){E.call(this,G);}this.fireEvent("available",{type:"available",target:G.element});},this,true);YAHOO.util.Event.onContentReady(G.element,function(){if(!I){B.call(this,G);}this.fireEvent("contentReady",{type:"contentReady",target:G.element});},this,true);};var E=function(G){this.setAttributeConfig("element",{value:D.get(G.element),readOnly:true});};var B=functi!
 on(G){this.initAttributes(G);this.setAttributes(G,true);this.f!
 ireQueue
();};var C=function(G,I){var H=this.get("element");I=I||{};I.name=G;I.method=I.method||function(J){H[G]=J;};I.value=I.value||H[G];this._configs[G]=new YAHOO.util.Attribute(I,this);};YAHOO.augment(YAHOO.util.Element,F);})();YAHOO.register("element",YAHOO.util.Element,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/element/element-beta.js
===================================================================
--- trunk/root/static/yui/element/element-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/element/element-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * Provides Attribute configurations.
@@ -783,7 +783,7 @@
 
         // set based on configOrder
         for (var i = 0, len = this._configOrder.length; i < len; ++i) {
-            if (map[this._configOrder[i]]) {
+            if (map[this._configOrder[i]] !== undefined) {
                 this.set(this._configOrder[i], map[this._configOrder[i]], silent);
             }
         }
@@ -960,8 +960,33 @@
  * @event contentReady
  */
 
+/**
+ * Fires before the Element is appended to another Element.
+ * <p>See: <a href="#addListener">Element.addListener</a></p>
+ * <p><strong>Event fields:</strong><br>
+ * <code><String> type</code> beforeAppendTo<br>
+ * <code><HTMLElement/Element>
+ * target</code> the HTMLElement/Element being appended to 
+ * <p><strong>Usage:</strong><br>
+ * <code>var handler = function(e) {var target = e.target};<br>
+ * myTabs.addListener('beforeAppendTo', handler);</code></p>
+ * @event beforeAppendTo
+ */
 
+/**
+ * Fires after the Element is appended to another Element.
+ * <p>See: <a href="#addListener">Element.addListener</a></p>
+ * <p><strong>Event fields:</strong><br>
+ * <code><String> type</code> appendTo<br>
+ * <code><HTMLElement/Element>
+ * target</code> the HTMLElement/Element being appended to 
+ * <p><strong>Usage:</strong><br>
+ * <code>var handler = function(e) {var target = e.target};<br>
+ * myTabs.addListener('appendTo', handler);</code></p>
+ * @event appendTo
+ */
+
 YAHOO.augment(YAHOO.util.Element, AttributeProvider);
 })();
 
-YAHOO.register("element", YAHOO.util.Element, {version: "2.4.1", build: "742"});
+YAHOO.register("element", YAHOO.util.Element, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/event/README
===================================================================
--- trunk/root/static/yui/event/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/event/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,6 +1,21 @@
 
 YUI Library - Event - Release Notes
 
+2.5.1
+  * Arrays are once again resized when a listener is removed.
+  * onAvailable/onContentReady stop polling when there is nothing to look for.
+
+2.5.0
+  * Added try/catch to getTarget to suppress errors when targeting
+    ActiveX controls.
+  * Increased the default poll interval to 20ms, and decreased poll
+    retries to 2000 to reduce IE CPU usage.
+  * onDOMReady now uses the native DOMContentLoaded event for the
+    latest releases of WebKit since it support for it was added.
+  * Restored the code that removes all listeners during the unload event to
+    address issues caused by the way FireFox persists listeners through 
+    page refreshes.
+
 2.4.1
   * Reverted clearAttributes() change to fix IE memory leak on iframes/windows
 

Modified: trunk/root/static/yui/event/event-debug.js
===================================================================
--- trunk/root/static/yui/event/event-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/event/event-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 
 /**
@@ -217,15 +217,12 @@
     fire: function() {
         var len=this.subscribers.length;
         if (!len && this.silent) {
+            //YAHOO.log('DEBUG no subscribers');
             return true;
         }
 
-        var args=[], ret=true, i, rebuild=false;
+        var args=[].slice.call(arguments, 0), ret=true, i, rebuild=false;
 
-        for (i=0; i<arguments.length; ++i) {
-            args.push(arguments[i]);
-        }
-
         if (!this.silent) {
             YAHOO.log( "Firing "       + this  + ", " + 
                        "args: "        + args  + ", " +
@@ -233,14 +230,18 @@
                        "info", "Event"                  );
         }
 
+        // make a copy of the subscribers so that there are
+        // no index problems if one subscriber removes another.
+        var subs = this.subscribers.slice();
+
         for (i=0; i<len; ++i) {
-            var s = this.subscribers[i];
+            var s = subs[i];
             if (!s) {
+                //YAHOO.log('DEBUG rebuilding array');
                 rebuild=true;
             } else {
                 if (!this.silent) {
-                    YAHOO.log( this.type + "->" + (i+1) + ": " +  s, 
-                                "info", "Event" );
+YAHOO.log( this.type + "->" + (i+1) + ": " +  s, "info", "Event" );
                 }
 
                 var scope = s.getScope(this.scope);
@@ -255,22 +256,19 @@
                         ret = s.fn.call(scope, param, s.obj);
                     } catch(e) {
                         this.lastError = e;
-                        YAHOO.log(this + " subscriber exception: " + e,
-                                  "error", "Event");
+YAHOO.log(this + " subscriber exception: " + e, "error", "Event");
                     }
                 } else {
                     try {
                         ret = s.fn.call(scope, this.type, args, s.obj);
                     } catch(ex) {
                         this.lastError = ex;
-                        YAHOO.log(this + " subscriber exception: " + ex,
-                                  "error", "Event");
+YAHOO.log(this + " subscriber exception: " + ex, "error", "Event");
                     }
                 }
                 if (false === ret) {
                     if (!this.silent) {
-                        YAHOO.log("Event cancelled, subscriber " + i + 
-                                  " of " + len, "info", "Event");
+YAHOO.log("Event stopped, sub " + i + " of " + len, "info", "Event");
                     }
 
                     //break;
@@ -279,15 +277,16 @@
             }
         }
 
-        if (rebuild) {
-            var newlist=[],subs=this.subscribers;
-            for (i=0,len=subs.length; i<len; i=i+1) {
-                newlist.push(subs[i]);
-            }
+        
+        // if (rebuild) {
+        //     var newlist=this.,subs=this.subscribers;
+        //     for (i=0,len=subs.length; i<len; i=i+1) {
+        //         // this wasn't doing anything before
+        //         newlist.push(subs[i]);
+        //     }
+        //     this.subscribers=newlist;
+        // }
 
-            this.subscribers=newlist;
-        }
-
         return true;
     },
 
@@ -297,8 +296,8 @@
      * @return {int} The number of listeners unsubscribed
      */
     unsubscribeAll: function() {
-        for (var i=0, len=this.subscribers.length; i<len; ++i) {
-            this._delete(len - 1 - i);
+        for (var i=this.subscribers.length-1; i>-1; i--) {
+            this._delete(i);
         }
 
         this.subscribers=[];
@@ -317,7 +316,8 @@
             delete s.obj;
         }
 
-        this.subscribers[index]=null;
+        // this.subscribers[index]=null;
+        this.subscribers.splice(index, 1);
     },
 
     /**
@@ -545,7 +545,7 @@
             /**
              * The number of times we should look for elements that are not
              * in the DOM at the time the event is requested after the document
-             * has been loaded.  The default is 4000 at amp;10 ms, so it will poll
+             * has been loaded.  The default is 2000 at amp;20 ms, so it will poll
              * for 40 seconds or until all outstanding handlers are bound
              * (whichever comes first).
              * @property POLL_RETRYS
@@ -553,7 +553,7 @@
              * @static
              * @final
              */
-            POLL_RETRYS: 4000,
+            POLL_RETRYS: 2000,
 
             /**
              * The poll interval in milliseconds
@@ -562,7 +562,7 @@
              * @static
              * @final
              */
-            POLL_INTERVAL: 10,
+            POLL_INTERVAL: 20,
 
             /**
              * Element to bind, int constant
@@ -749,7 +749,9 @@
                                        override:   p_override, 
                                        checkReady: checkContent });
                 }
+
                 retryCount = this.POLL_RETRYS;
+
                 this.startInterval();
             },
 
@@ -852,8 +854,7 @@
             addListener: function(el, sType, fn, obj, override) {
 
                 if (!fn || !fn.call) {
-// throw new TypeError(sType + " addListener call failed, callback undefined");
-YAHOO.log(sType + " addListener call failed, invalid callback", "error", "Event");
+YAHOO.log(sType + " addListener failed, invalid callback", "error", "Event");
                     return false;
                 }
 
@@ -987,10 +988,11 @@
              */
             fireLegacyEvent: function(e, legacyIndex) {
                 // this.logger.debug("fireLegacyEvent " + legacyIndex);
-                var ok=true,le,lh,li,scope,ret;
+                var ok=true, le, lh, li, scope, ret;
                 
-                lh = legacyHandlers[legacyIndex];
-                for (var i=0,len=lh.length; i<len; ++i) {
+                lh = legacyHandlers[legacyIndex].slice();
+                for (var i=0, len=lh.length; i<len; ++i) {
+                // for (var i in lh.length) {
                     li = lh[i];
                     if ( li && li[this.WFN] ) {
                         scope = li[this.ADJ_SCOPE];
@@ -1070,7 +1072,7 @@
                 // The el argument can be an array of elements or element ids.
                 } else if ( this._isValidCollection(el)) {
                     var ok = true;
-                    for (i=0,len=el.length; i<len; ++i) {
+                    for (i=el.length-1; i>-1; i--) {
                         ok = ( this.removeListener(el[i], sType, fn) && ok );
                     }
                     return ok;
@@ -1084,14 +1086,14 @@
 
                 if ("unload" == sType) {
 
-                    for (i=0, len=unloadListeners.length; i<len; i++) {
+                    for (i=unloadListeners.length-1; i>-1; i--) {
                         li = unloadListeners[i];
                         if (li && 
                             li[0] == el && 
                             li[1] == sType && 
                             li[2] == fn) {
-                                //unloadListeners.splice(i, 1);
-                                unloadListeners[i]=null;
+                                unloadListeners.splice(i, 1);
+                                // unloadListeners[i]=null;
                                 return true;
                         }
                     }
@@ -1126,13 +1128,14 @@
                     var llist = legacyHandlers[legacyIndex];
                     if (llist) {
                         for (i=0, len=llist.length; i<len; ++i) {
+                        // for (i in llist.length) {
                             li = llist[i];
                             if (li && 
                                 li[this.EL] == el && 
                                 li[this.TYPE] == sType && 
                                 li[this.FN] == fn) {
-                                    //llist.splice(i, 1);
-                                    llist[i]=null;
+                                    llist.splice(i, 1);
+                                    // llist[i]=null;
                                     break;
                             }
                         }
@@ -1150,8 +1153,8 @@
                 // removed the wrapped handler
                 delete listeners[index][this.WFN];
                 delete listeners[index][this.FN];
-                //listeners.splice(index, 1);
-                listeners[index]=null;
+                listeners.splice(index, 1);
+                // listeners[index]=null;
 
                 return true;
 
@@ -1184,12 +1187,14 @@
              * @return {HTMLElement} the normized node
              * @static
              */
-            resolveTextNode: function(node) {
-                if (node && 3 == node.nodeType) {
-                    return node.parentNode;
-                } else {
-                    return node;
-                }
+            resolveTextNode: function(n) {
+                try {
+                    if (n && 3 == n.nodeType) {
+                        return n.parentNode;
+                    }
+                } catch(e) { }
+
+                return n;
             },
 
             /**
@@ -1351,32 +1356,6 @@
                     }
                 }
 
-                // IE events that target non-browser objects (e.g., VML
-                // canvas) will sometimes throw errors when you try to
-                // inspect the properties of the event target.  We try to
-                // detect this condition, and provide a dummy target (the bound
-                // element) to eliminate spurious errors.  
-
-                // the implementation caused unexpected results in some 
-                // implementations, so this has been rolled back for now
-                /* 
-                if (ev && this.isIE) {
-
-                    try {
-
-                        var el = ev.srcElement;
-
-                    } catch(ex) {
-
-                        YAHOO.log("Inspecting the target caused an error, " +
-                            "setting the target to the bound element.", "warn");
-                         
-                        ev.target = boundEl;
-                    }
-
-                }
-                */
-
                 return ev;
             },
 
@@ -1390,7 +1369,7 @@
             getCharCode: function(ev) {
                 var code = ev.keyCode || ev.charCode || 0;
 
-                // webkit normalization
+                // webkit key normalization
                 if (YAHOO.env.ua.webkit && (code in webkitKeymap)) {
                     code = webkitKeymap[code];
                 }
@@ -1405,7 +1384,7 @@
              * @private
              */
             _getCacheIndex: function(el, sType, fn) {
-                for (var i=0,len=listeners.length; i<len; ++i) {
+                for (var i=0, l=listeners.length; i<l; i=i+1) {
                     var li = listeners[i];
                     if ( li                 && 
                          li[this.FN] == fn  && 
@@ -1460,8 +1439,7 @@
                              !o.alert              && // o is not a window
                              typeof o[0] !== "undefined" );
                 } catch(ex) {
-                    YAHOO.log("_isValidCollection error, assuming that " +
-                " this is a cross frame problem and not a collection", "warn");
+                    YAHOO.log("node access error (xframe?)", "warn");
                     return false;
                 }
 
@@ -1525,11 +1503,6 @@
                     // before the window load notification
                     EU._tryPreloadAttach();
 
-                    // Remove the listener to assist with the IE memory issue, but not
-                    // for other browsers because FF 1.0x does not like it.
-                    //if (this.isIE) {
-                        //EU._simpleRemove(window, "load", EU._load);
-                    //}
                 }
             },
 
@@ -1563,18 +1536,24 @@
              */
             _tryPreloadAttach: function() {
 
+                if (onAvailStack.length === 0) {
+                    retryCount = 0;
+                    clearInterval(this._interval);
+                    this._interval = null;
+                    return;
+                }
+
                 if (this.locked) {
-                    return false;
+                    return;
                 }
 
                 if (this.isIE) {
                     // Hold off if DOMReady has not fired and check current
                     // readyState to protect against the IE operation aborted
                     // issue.
-                    //if (!this.DOMReady || "complete" !== document.readyState) {
                     if (!this.DOMReady) {
                         this.startInterval();
-                        return false;
+                        return;
                     }
                 }
 
@@ -1588,7 +1567,7 @@
                 // tested appropriately
                 var tryAgain = !loadComplete;
                 if (!tryAgain) {
-                    tryAgain = (retryCount > 0);
+                    tryAgain = (retryCount > 0 && onAvailStack.length > 0);
                 }
 
                 // onAvailable
@@ -1606,32 +1585,20 @@
                     item.fn.call(scope, item.obj);
                 };
 
-                var i,len,item,el;
+                var i, len, item, el, ready=[];
 
-                // onAvailable
-                for (i=0,len=onAvailStack.length; i<len; ++i) {
+                // onAvailable onContentReady
+                for (i=0, len=onAvailStack.length; i<len; i=i+1) {
                     item = onAvailStack[i];
-                    if (item && !item.checkReady) {
+                    if (item) {
                         el = this.getEl(item.id);
                         if (el) {
-                            executeItem(el, item);
-                            onAvailStack[i] = null;
-                        } else {
-                            notAvail.push(item);
-                        }
-                    }
-                }
-
-                // onContentReady
-                for (i=0,len=onAvailStack.length; i<len; ++i) {
-                    item = onAvailStack[i];
-                    if (item && item.checkReady) {
-                        el = this.getEl(item.id);
-
-                        if (el) {
-                            // The element is available, but not necessarily ready
-                            // @todo should we test parentNode.nextSibling?
-                            if (loadComplete || el.nextSibling) {
+                            if (item.checkReady) {
+                                if (loadComplete || el.nextSibling || !tryAgain) {
+                                    ready.push(item);
+                                    onAvailStack[i] = null;
+                                }
+                            } else {
                                 executeItem(el, item);
                                 onAvailStack[i] = null;
                             }
@@ -1640,11 +1607,24 @@
                         }
                     }
                 }
+                
+                // make sure onContentReady fires after onAvailable
+                for (i=0, len=ready.length; i<len; i=i+1) {
+                    item = ready[i];
+                    executeItem(this.getEl(item.id), item);
+                }
 
-                retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
 
+                retryCount--;
+
                 if (tryAgain) {
-                    // we may need to strip the nulled out items here
+                    for (i=onAvailStack.length-1; i>-1; i--) {
+                        item = onAvailStack[i];
+                        if (!item || !item.id) {
+                            onAvailStack.splice(i, 1);
+                        }
+                    }
+
                     this.startInterval();
                 } else {
                     clearInterval(this._interval);
@@ -1653,8 +1633,6 @@
 
                 this.locked = false;
 
-                return true;
-
             },
 
             /**
@@ -1673,11 +1651,9 @@
                 var oEl = (YAHOO.lang.isString(el)) ? this.getEl(el) : el;
                 var elListeners = this.getListeners(oEl, sType), i, len;
                 if (elListeners) {
-                    for (i=0,len=elListeners.length; i<len ; ++i) {
+                    for (i=elListeners.length-1; i>-1; i--) {
                         var l = elListeners[i];
-                        // can't use the index on the changing collection
-                        this.removeListener(oEl, l.type, l.fn, l.index);
-                        //this.removeListener(oEl, l.type, l.fn);
+                        this.removeListener(oEl, l.type, l.fn);
                     }
                 }
 
@@ -1718,7 +1694,7 @@
 
                 for (var j=0;j<searchLists.length; j=j+1) {
                     var searchList = searchLists[j];
-                    if (searchList && searchList.length > 0) {
+                    if (searchList) {
                         for (var i=0,len=searchList.length; i<len ; ++i) {
                             var l = searchList[i];
                             if ( l  && l[this.EL] === oEl && 
@@ -1748,11 +1724,12 @@
              */
             _unload: function(e) {
 
-                var EU = YAHOO.util.Event, i, j, l, len, index;
+                var EU = YAHOO.util.Event, i, j, l, len, index,
+                         ul = unloadListeners.slice();
 
                 // execute and clear stored unload listeners
                 for (i=0,len=unloadListeners.length; i<len; ++i) {
-                    l = unloadListeners[i];
+                    l = ul[i];
                     if (l) {
                         var scope = window;
                         if (l[EU.ADJ_SCOPE]) {
@@ -1763,7 +1740,7 @@
                             }
                         }
                         l[EU.FN].call(scope, EU.getEvent(e, l[EU.EL]), l[EU.UNLOAD_OBJ] );
-                        unloadListeners[i] = null;
+                        ul[i] = null;
                         l=null;
                         scope=null;
                     }
@@ -1771,54 +1748,23 @@
 
                 unloadListeners = null;
 
-                // call clearAttributes or remove listeners to handle IE memory leaks
-                if (YAHOO.env.ua.ie && listeners && listeners.length > 0) {
-                    j = listeners.length;
-                    while (j) {
-                        index = j-1;
-                        l = listeners[index];
+                // Remove listeners to handle IE memory leaks
+                //if (YAHOO.env.ua.ie && listeners && listeners.length > 0) {
+                
+                // 2.5.0 listeners are removed for all browsers again.  FireFox preserves
+                // at least some listeners between page refreshes, potentially causing
+                // errors during page load (mouseover listeners firing before they
+                // should if the user moves the mouse at the correct moment).
+                if (listeners) {
+                    for (j=listeners.length-1; j>-1; j--) {
+                        l = listeners[j];
                         if (l) {
-                            //try {
-                                //l[EU.EL].clearAttributes(); // errors on window objects
-                            //} catch(ex) {
-                            EU.removeListener(l[EU.EL], l[EU.TYPE], l[EU.FN], index);
-                            //}
+                            EU.removeListener(l[EU.EL], l[EU.TYPE], l[EU.FN], j);
                         } 
-                        j--;
                     }
                     l=null;
                 }
 
-                /*
-                // remove all listeners
-                if (listeners && listeners.length > 0) {
-                    j = listeners.length;
-                    while (j) {
-                        index = j-1;
-                        l = listeners[index];
-                        if (l) {
-                            EU.removeListener(l[EU.EL], l[EU.TYPE], l[EU.FN], index);
-                        } 
-                        j = j - 1;
-                    }
-                    l=null;
-                }
-                */
-
-                /*
-                // kill legacy events
-                for (i=0,len=legacyEvents.length; i<len; ++i) {
-                    // dereference the element
-                    //delete legacyEvents[i][0];
-                    legacyEvents[i][0] = null;
-
-                    // delete the array item
-                    //delete legacyEvents[i];
-                    legacyEvents[i] = null;
-                }
-
-                */
-
                 legacyEvents = null;
 
                 EU._simpleRemove(window, "unload", EU._unload);
@@ -1875,22 +1821,6 @@
                 // does nothing
             },
 
-/*
-            testIEReady: function (){
-                var n = document.createElement('p'), ready = false;
-                try {
-                    // throws an error until the doc is ready
-                    n.doScroll('left'); 
-                    ready = true;
-                } catch(ex){ 
-                    // document is not ready
-                }
-
-                n = null;
-                return ready;
-            },
-*/
-
             /**
              * Adds a DOM event directly without the caching, cleanup, scope adj, etc
              *
@@ -1955,9 +1885,7 @@
          */
         EU.on = EU.addListener;
 
-        /////////////////////////////////////////////////////////////
-        // DOMReady
-        // based on work by: Dean Edwards/John Resig/Matthias Miller 
+/*! DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller */
 
         // Internet Explorer: use the readyState of a defered script.
         // This isolates what appears to be a safe moment to manipulate
@@ -1965,70 +1893,15 @@
         // it is safe to do so.
         if (EU.isIE) {
 
-            // Process onAvailable/onContentReady items when when the 
+            // Process onAvailable/onContentReady items when the 
             // DOM is ready.
             YAHOO.util.Event.onDOMReady(
                     YAHOO.util.Event._tryPreloadAttach,
                     YAHOO.util.Event, true);
-
-            /*
-
-            //YAHOO.log("-" + document.readyState + "-");
-
-            var el, d=document, b=d.body;
-
-            // If the library is being injected after window.onload, it
-            // is not safe to document.write the script tag.  Detecting
-            // this state doesn't appear possible, so we expect a flag
-            // in YAHOO_config to be set if the library is being injected.
-            if (("undefined" !== typeof YAHOO_config) && YAHOO_config.injecting) {
-
-                el = document.createElement("script");
-                var p=d.getElementsByTagName("head")[0] || b;
-                p.insertBefore(el, p.firstChild);
-
-            } else {
-                //YAHOO.log("-dw-");
-    d.write('<scr'+'ipt id="_yui_eu_dr" defer="true" src="//:"><'+'/script>');
-                el=document.getElementById("_yui_eu_dr");
-            }
             
+            var n = document.createElement('p');  
 
-            if (el) {
-                el.onreadystatechange = function() {
-                    //YAHOO.log(";comp-" + this.readyState + ";");
-                    if ("complete" === this.readyState) {
-                        this.parentNode.removeChild(this);
-                        YAHOO.util.Event._ready();
-                    }
-                };
-            } else {
-                // The library was likely injected into the page
-                // rendering onDOMReady unreliable
-                // YAHOO.util.Event._ready();
-            }
-
-            el=null;
-
-            */
-
-/*
-            (function (){
-                var n = document.createElement('p');  
-                try {
-                    // throws an error if doc is not ready
-                    n.doScroll('left');
-                    n = null;
-                    YAHOO.util.Event._ready();
-                } catch (ex){
-                    n = null;
-setTimeout(arguments.callee, YAHOO.util.Event.POLL_INTERVAL);
-                }
-            })();
-*/
-
             EU._dri = setInterval(function() {
-                var n = document.createElement('p');  
                 try {
                     // throws an error if doc is not ready
                     n.doScroll('left');
@@ -2037,15 +1910,13 @@
                     EU._ready();
                     n = null;
                 } catch (ex) { 
-                    n = null;
                 }
             }, EU.POLL_INTERVAL); 
 
         
-        // Safari: The document's readyState in Safari currently will
+        // The document's readyState in Safari currently will
         // change to loaded/complete before images are loaded.
-        //} else if (EU.webkit) {
-        } else if (EU.webkit) {
+        } else if (EU.webkit && EU.webkit < 525) {
 
             EU._dri = setInterval(function() {
                 var rs=document.readyState;
@@ -2057,11 +1928,9 @@
             }, EU.POLL_INTERVAL); 
 
         // FireFox and Opera: These browsers provide a event for this
-        // moment.
+        // moment.  The latest WebKit releases now support this event.
         } else {
 
-            // @todo will this fire when the library is injected?
-
             EU._simpleAdd(document, "DOMContentLoaded", EU._ready);
 
         }
@@ -2522,4 +2391,4 @@
     TAB          : 9,
     UP           : 38
 };
-YAHOO.register("event", YAHOO.util.Event, {version: "2.4.1", build: "742"});
+YAHOO.register("event", YAHOO.util.Event, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/event/event-min.js
===================================================================
--- trunk/root/static/yui/event/event-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/event/event-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +1,11 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-YAHOO.util.CustomEvent=function(D,B,C,A){this.type=D;this.scope=B||window;this.silent=C;this.signature=A||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){}var E="_YUICEOnSubscribe";if(D!==E){this.subscribeEvent=new YAHOO.util.CustomEvent(E,this,true);}this.lastError=null;};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(B,C,A){if(!B){throw new Error("Invalid callback for subscriber to '"+this.type+"'");}if(this.subscribeEvent){this.subscribeEvent.fire(B,C,A);}this.subscribers.push(new YAHOO.util.Subscriber(B,C,A));},unsubscribe:function(D,F){if(!D){return this.unsubscribeAll();}var E=false;for(var B=0,A=this.subscribers.length;B<A;++B){var C=this.subscribers[B];if(C&&C.contains(D,F)){this._delete(B);E=true;}}return E;},fire:function(){var D=this.subscribers.length;if(!D&&this.silent){return true;}var H=[],F=true,C,I=false;for(C=0;C<arguments.length;++C){H.push(arguments[C]);}if(!this.silent){}!
 for(C=0;C<D;++C){var L=this.subscribers[C];if(!L){I=true;}else{if(!this.silent){}var K=L.getScope(this.scope);if(this.signature==YAHOO.util.CustomEvent.FLAT){var A=null;if(H.length>0){A=H[0];}try{F=L.fn.call(K,A,L.obj);}catch(E){this.lastError=E;}}else{try{F=L.fn.call(K,this.type,H,L.obj);}catch(G){this.lastError=G;}}if(false===F){if(!this.silent){}return false;}}}if(I){var J=[],B=this.subscribers;for(C=0,D=B.length;C<D;C=C+1){J.push(B[C]);}this.subscribers=J;}return true;},unsubscribeAll:function(){for(var B=0,A=this.subscribers.length;B<A;++B){this._delete(A-1-B);}this.subscribers=[];return B;},_delete:function(A){var B=this.subscribers[A];if(B){delete B.fn;delete B.obj;}this.subscribers[A]=null;},toString:function(){return"CustomEvent: '"+this.type+"', scope: "+this.scope;}};YAHOO.util.Subscriber=function(B,C,A){this.fn=B;this.obj=YAHOO.lang.isUndefined(C)?null:C;this.override=A;};YAHOO.util.Subscriber.prototype.getScope=function(A){if(this.override){if(this.override===t!
 rue){return this.obj;}else{return this.override;}}return A;};Y!
 AHOO.uti
l.Subscriber.prototype.contains=function(A,B){if(B){return(this.fn==A&&this.obj==B);}else{return(this.fn==A);}};YAHOO.util.Subscriber.prototype.toString=function(){return"Subscriber { obj: "+this.obj+", override: "+(this.override||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var H=false;var I=[];var J=[];var G=[];var E=[];var C=0;var F=[];var B=[];var A=0;var D={63232:38,63233:40,63234:37,63235:39,63276:33,63277:34,25:9};return{POLL_RETRYS:4000,POLL_INTERVAL:10,EL:0,TYPE:1,FN:2,WFN:3,UNLOAD_OBJ:3,ADJ_SCOPE:4,OBJ:5,OVERRIDE:6,lastError:null,isSafari:YAHOO.env.ua.webkit,webkit:YAHOO.env.ua.webkit,isIE:YAHOO.env.ua.ie,_interval:null,_dri:null,DOMReady:false,startInterval:function(){if(!this._interval){var K=this;var L=function(){K._tryPreloadAttach();};this._interval=setInterval(L,this.POLL_INTERVAL);}},onAvailable:function(P,M,Q,O,N){var K=(YAHOO.lang.isString(P))?[P]:P;for(var L=0;L<K.length;L=L+1){F.push({id:K[L],fn:M,obj:Q,override:O,checkReady:N});}C=this!
 .POLL_RETRYS;this.startInterval();},onContentReady:function(M,K,N,L){this.onAvailable(M,K,N,L,true);},onDOMReady:function(K,M,L){if(this.DOMReady){setTimeout(function(){var N=window;if(L){if(L===true){N=M;}else{N=L;}}K.call(N,"DOMReady",[],M);},0);}else{this.DOMReadyEvent.subscribe(K,M,L);}},addListener:function(M,K,V,Q,L){if(!V||!V.call){return false;}if(this._isValidCollection(M)){var W=true;for(var R=0,T=M.length;R<T;++R){W=this.on(M[R],K,V,Q,L)&&W;}return W;}else{if(YAHOO.lang.isString(M)){var P=this.getEl(M);if(P){M=P;}else{this.onAvailable(M,function(){YAHOO.util.Event.on(M,K,V,Q,L);});return true;}}}if(!M){return false;}if("unload"==K&&Q!==this){J[J.length]=[M,K,V,Q,L];return true;}var Y=M;if(L){if(L===true){Y=Q;}else{Y=L;}}var N=function(Z){return V.call(Y,YAHOO.util.Event.getEvent(Z,M),Q);};var X=[M,K,V,N,Y,Q,L];var S=I.length;I[S]=X;if(this.useLegacyEvent(M,K)){var O=this.getLegacyIndex(M,K);if(O==-1||M!=G[O][0]){O=G.length;B[M.id+K]=O;G[O]=[M,K,M["on"+K]];E[O]=[]!
 ;M["on"+K]=function(Z){YAHOO.util.Event.fireLegacyEvent(YAHOO.!
 util.Eve
nt.getEvent(Z),O);};}E[O].push(X);}else{try{this._simpleAdd(M,K,N,false);}catch(U){this.lastError=U;this.removeListener(M,K,V);return false;}}return true;},fireLegacyEvent:function(O,M){var Q=true,K,S,R,T,P;S=E[M];for(var L=0,N=S.length;L<N;++L){R=S[L];if(R&&R[this.WFN]){T=R[this.ADJ_SCOPE];P=R[this.WFN].call(T,O);Q=(Q&&P);}}K=G[M];if(K&&K[2]){K[2](O);}return Q;},getLegacyIndex:function(L,M){var K=this.generateId(L)+M;if(typeof B[K]=="undefined"){return -1;}else{return B[K];}},useLegacyEvent:function(L,M){if(this.webkit&&("click"==M||"dblclick"==M)){var K=parseInt(this.webkit,10);if(!isNaN(K)&&K<418){return true;}}return false;},removeListener:function(L,K,T){var O,R,V;if(typeof L=="string"){L=this.getEl(L);}else{if(this._isValidCollection(L)){var U=true;for(O=0,R=L.length;O<R;++O){U=(this.removeListener(L[O],K,T)&&U);}return U;}}if(!T||!T.call){return this.purgeElement(L,false,K);}if("unload"==K){for(O=0,R=J.length;O<R;O++){V=J[O];if(V&&V[0]==L&&V[1]==K&&V[2]==T){J[O]=null;!
 return true;}}return false;}var P=null;var Q=arguments[3];if("undefined"===typeof Q){Q=this._getCacheIndex(L,K,T);}if(Q>=0){P=I[Q];}if(!L||!P){return false;}if(this.useLegacyEvent(L,K)){var N=this.getLegacyIndex(L,K);var M=E[N];if(M){for(O=0,R=M.length;O<R;++O){V=M[O];if(V&&V[this.EL]==L&&V[this.TYPE]==K&&V[this.FN]==T){M[O]=null;break;}}}}else{try{this._simpleRemove(L,K,P[this.WFN],false);}catch(S){this.lastError=S;return false;}}delete I[Q][this.WFN];delete I[Q][this.FN];I[Q]=null;return true;},getTarget:function(M,L){var K=M.target||M.srcElement;return this.resolveTextNode(K);},resolveTextNode:function(K){if(K&&3==K.nodeType){return K.parentNode;}else{return K;}},getPageX:function(L){var K=L.pageX;if(!K&&0!==K){K=L.clientX||0;if(this.isIE){K+=this._getScrollLeft();}}return K;},getPageY:function(K){var L=K.pageY;if(!L&&0!==L){L=K.clientY||0;if(this.isIE){L+=this._getScrollTop();}}return L;},getXY:function(K){return[this.getPageX(K),this.getPageY(K)];
-},getRelatedTarget:function(L){var K=L.relatedTarget;if(!K){if(L.type=="mouseout"){K=L.toElement;}else{if(L.type=="mouseover"){K=L.fromElement;}}}return this.resolveTextNode(K);},getTime:function(M){if(!M.time){var L=new Date().getTime();try{M.time=L;}catch(K){this.lastError=K;return L;}}return M.time;},stopEvent:function(K){this.stopPropagation(K);this.preventDefault(K);},stopPropagation:function(K){if(K.stopPropagation){K.stopPropagation();}else{K.cancelBubble=true;}},preventDefault:function(K){if(K.preventDefault){K.preventDefault();}else{K.returnValue=false;}},getEvent:function(M,K){var L=M||window.event;if(!L){var N=this.getEvent.caller;while(N){L=N.arguments[0];if(L&&Event==L.constructor){break;}N=N.caller;}}return L;},getCharCode:function(L){var K=L.keyCode||L.charCode||0;if(YAHOO.env.ua.webkit&&(K in D)){K=D[K];}return K;},_getCacheIndex:function(O,P,N){for(var M=0,L=I.length;M<L;++M){var K=I[M];if(K&&K[this.FN]==N&&K[this.EL]==O&&K[this.TYPE]==P){return M;}}return !
 -1;},generateId:function(K){var L=K.id;if(!L){L="yuievtautoid-"+A;++A;K.id=L;}return L;},_isValidCollection:function(L){try{return(L&&typeof L!=="string"&&L.length&&!L.tagName&&!L.alert&&typeof L[0]!=="undefined");}catch(K){return false;}},elCache:{},getEl:function(K){return(typeof K==="string")?document.getElementById(K):K;},clearCache:function(){},DOMReadyEvent:new YAHOO.util.CustomEvent("DOMReady",this),_load:function(L){if(!H){H=true;var K=YAHOO.util.Event;K._ready();K._tryPreloadAttach();}},_ready:function(L){var K=YAHOO.util.Event;if(!K.DOMReady){K.DOMReady=true;K.DOMReadyEvent.fire();K._simpleRemove(document,"DOMContentLoaded",K._ready);}},_tryPreloadAttach:function(){if(this.locked){return false;}if(this.isIE){if(!this.DOMReady){this.startInterval();return false;}}this.locked=true;var P=!H;if(!P){P=(C>0);}var O=[];var Q=function(S,T){var R=S;if(T.override){if(T.override===true){R=T.obj;}else{R=T.override;}}T.fn.call(R,T.obj);};var L,K,N,M;for(L=0,K=F.length;L<K;++L)!
 {N=F[L];if(N&&!N.checkReady){M=this.getEl(N.id);if(M){Q(M,N);F!
 [L]=null
;}else{O.push(N);}}}for(L=0,K=F.length;L<K;++L){N=F[L];if(N&&N.checkReady){M=this.getEl(N.id);if(M){if(H||M.nextSibling){Q(M,N);F[L]=null;}}else{O.push(N);}}}C=(O.length===0)?0:C-1;if(P){this.startInterval();}else{clearInterval(this._interval);this._interval=null;}this.locked=false;return true;},purgeElement:function(O,P,R){var M=(YAHOO.lang.isString(O))?this.getEl(O):O;var Q=this.getListeners(M,R),N,K;if(Q){for(N=0,K=Q.length;N<K;++N){var L=Q[N];this.removeListener(M,L.type,L.fn,L.index);}}if(P&&M&&M.childNodes){for(N=0,K=M.childNodes.length;N<K;++N){this.purgeElement(M.childNodes[N],P,R);}}},getListeners:function(M,K){var P=[],L;if(!K){L=[I,J];}else{if(K==="unload"){L=[J];}else{L=[I];}}var R=(YAHOO.lang.isString(M))?this.getEl(M):M;for(var O=0;O<L.length;O=O+1){var T=L[O];if(T&&T.length>0){for(var Q=0,S=T.length;Q<S;++Q){var N=T[Q];if(N&&N[this.EL]===R&&(!K||K===N[this.TYPE])){P.push({type:N[this.TYPE],fn:N[this.FN],obj:N[this.OBJ],adjust:N[this.OVERRIDE],scope:N[this.ADJ_!
 SCOPE],index:Q});}}}}return(P.length)?P:null;},_unload:function(R){var Q=YAHOO.util.Event,O,N,L,K,M;for(O=0,K=J.length;O<K;++O){L=J[O];if(L){var P=window;if(L[Q.ADJ_SCOPE]){if(L[Q.ADJ_SCOPE]===true){P=L[Q.UNLOAD_OBJ];}else{P=L[Q.ADJ_SCOPE];}}L[Q.FN].call(P,Q.getEvent(R,L[Q.EL]),L[Q.UNLOAD_OBJ]);J[O]=null;L=null;P=null;}}J=null;if(YAHOO.env.ua.ie&&I&&I.length>0){N=I.length;while(N){M=N-1;L=I[M];if(L){Q.removeListener(L[Q.EL],L[Q.TYPE],L[Q.FN],M);}N--;}L=null;}G=null;Q._simpleRemove(window,"unload",Q._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var K=document.documentElement,L=document.body;if(K&&(K.scrollTop||K.scrollLeft)){return[K.scrollTop,K.scrollLeft];}else{if(L){return[L.scrollTop,L.scrollLeft];}else{return[0,0];}}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(M,N,L,K){M.addEventListener(N,L,(K));};}else{if(window.attachEvent){retur!
 n function(M,N,L,K){M.attachEvent("on"+N,L);};}else{return fun!
 ction(){
};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(M,N,L,K){M.removeEventListener(N,L,(K));};}else{if(window.detachEvent){return function(L,M,K){L.detachEvent("on"+M,K);};}else{return function(){};}}}()};}();(function(){var A=YAHOO.util.Event;A.on=A.addListener;if(A.isIE){YAHOO.util.Event.onDOMReady(YAHOO.util.Event._tryPreloadAttach,YAHOO.util.Event,true);A._dri=setInterval(function(){var C=document.createElement("p");try{C.doScroll("left");clearInterval(A._dri);A._dri=null;A._ready();C=null;}catch(B){C=null;}},A.POLL_INTERVAL);}else{if(A.webkit){A._dri=setInterval(function(){var B=document.readyState;if("loaded"==B||"complete"==B){clearInterval(A._dri);A._dri=null;A._ready();}},A.POLL_INTERVAL);}else{A._simpleAdd(document,"DOMContentLoaded",A._ready);}}A._simpleAdd(window,"load",A._load);A._simpleAdd(window,"unload",A._unload);A._tryPreloadAttach();})();}YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null!
 ,__yui_subscribers:null,subscribe:function(A,C,F,E){this.__yui_events=this.__yui_events||{};var D=this.__yui_events[A];if(D){D.subscribe(C,F,E);}else{this.__yui_subscribers=this.__yui_subscribers||{};var B=this.__yui_subscribers;if(!B[A]){B[A]=[];}B[A].push({fn:C,obj:F,override:E});}},unsubscribe:function(C,E,G){this.__yui_events=this.__yui_events||{};var A=this.__yui_events;if(C){var F=A[C];if(F){return F.unsubscribe(E,G);}}else{var B=true;for(var D in A){if(YAHOO.lang.hasOwnProperty(A,D)){B=B&&A[D].unsubscribe(E,G);}}return B;}return false;},unsubscribeAll:function(A){return this.unsubscribe(A);},createEvent:function(G,D){this.__yui_events=this.__yui_events||{};var A=D||{};var I=this.__yui_events;if(I[G]){}else{var H=A.scope||this;var E=(A.silent);var B=new YAHOO.util.CustomEvent(G,H,E,YAHOO.util.CustomEvent.FLAT);I[G]=B;if(A.onSubscribeCallback){B.subscribeEvent.subscribe(A.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};
-var F=this.__yui_subscribers[G];if(F){for(var C=0;C<F.length;++C){B.subscribe(F[C].fn,F[C].obj,F[C].override);}}}return I[G];},fireEvent:function(E,D,A,C){this.__yui_events=this.__yui_events||{};var G=this.__yui_events[E];if(!G){return null;}var B=[];for(var F=1;F<arguments.length;++F){B.push(arguments[F]);}return G.fire.apply(G,B);},hasEvent:function(A){if(this.__yui_events){if(this.__yui_events[A]){return true;}}return false;}};YAHOO.util.KeyListener=function(A,F,B,C){if(!A){}else{if(!F){}else{if(!B){}}}if(!C){C=YAHOO.util.KeyListener.KEYDOWN;}var D=new YAHOO.util.CustomEvent("keyPressed");this.enabledEvent=new YAHOO.util.CustomEvent("enabled");this.disabledEvent=new YAHOO.util.CustomEvent("disabled");if(typeof A=="string"){A=document.getElementById(A);}if(typeof B=="function"){D.subscribe(B);}else{D.subscribe(B.fn,B.scope,B.correctScope);}function E(J,I){if(!F.shift){F.shift=false;}if(!F.alt){F.alt=false;}if(!F.ctrl){F.ctrl=false;}if(J.shiftKey==F.shift&&J.altKey==F.alt&!
 &J.ctrlKey==F.ctrl){var G;if(F.keys instanceof Array){for(var H=0;H<F.keys.length;H++){G=F.keys[H];if(G==J.charCode){D.fire(J.charCode,J);break;}else{if(G==J.keyCode){D.fire(J.keyCode,J);break;}}}}else{G=F.keys;if(G==J.charCode){D.fire(J.charCode,J);}else{if(G==J.keyCode){D.fire(J.keyCode,J);}}}}}this.enable=function(){if(!this.enabled){YAHOO.util.Event.addListener(A,C,E);this.enabledEvent.fire(F);}this.enabled=true;};this.disable=function(){if(this.enabled){YAHOO.util.Event.removeListener(A,C,E);this.disabledEvent.fire(F);}this.enabled=false;};this.toString=function(){return"KeyListener ["+F.keys+"] "+A.tagName+(A.id?"["+A.id+"]":"");};};YAHOO.util.KeyListener.KEYDOWN="keydown";YAHOO.util.KeyListener.KEYUP="keyup";YAHOO.util.KeyListener.KEY={ALT:18,BACK_SPACE:8,CAPS_LOCK:20,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,META:224,NUM_LOCK:144,PAGE_DOWN:34,PAGE_UP:33,PAUSE:19,PRINTSCREEN:44,RIGHT:39,SCROLL_LOCK:145,SHIFT:16,SPACE:32,TAB:9,UP:38};YAHOO!
 .register("event",YAHOO.util.Event,{version:"2.4.1",build:"742!
 "});
\ No newline at end of file
+YAHOO.util.CustomEvent=function(D,B,C,A){this.type=D;this.scope=B||window;this.silent=C;this.signature=A||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){}var E="_YUICEOnSubscribe";if(D!==E){this.subscribeEvent=new YAHOO.util.CustomEvent(E,this,true);}this.lastError=null;};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(B,C,A){if(!B){throw new Error("Invalid callback for subscriber to '"+this.type+"'");}if(this.subscribeEvent){this.subscribeEvent.fire(B,C,A);}this.subscribers.push(new YAHOO.util.Subscriber(B,C,A));},unsubscribe:function(D,F){if(!D){return this.unsubscribeAll();}var E=false;for(var B=0,A=this.subscribers.length;B<A;++B){var C=this.subscribers[B];if(C&&C.contains(D,F)){this._delete(B);E=true;}}return E;},fire:function(){var D=this.subscribers.length;if(!D&&this.silent){return true;}var H=[].slice.call(arguments,0),F=true,C,I=false;if(!this.silent){}var B=this.subscribers.slice()!
 ;for(C=0;C<D;++C){var K=B[C];if(!K){I=true;}else{if(!this.silent){}var J=K.getScope(this.scope);if(this.signature==YAHOO.util.CustomEvent.FLAT){var A=null;if(H.length>0){A=H[0];}try{F=K.fn.call(J,A,K.obj);}catch(E){this.lastError=E;}}else{try{F=K.fn.call(J,this.type,H,K.obj);}catch(G){this.lastError=G;}}if(false===F){if(!this.silent){}return false;}}}return true;},unsubscribeAll:function(){for(var A=this.subscribers.length-1;A>-1;A--){this._delete(A);}this.subscribers=[];return A;},_delete:function(A){var B=this.subscribers[A];if(B){delete B.fn;delete B.obj;}this.subscribers.splice(A,1);},toString:function(){return"CustomEvent: "+"'"+this.type+"', "+"scope: "+this.scope;}};YAHOO.util.Subscriber=function(B,C,A){this.fn=B;this.obj=YAHOO.lang.isUndefined(C)?null:C;this.override=A;};YAHOO.util.Subscriber.prototype.getScope=function(A){if(this.override){if(this.override===true){return this.obj;}else{return this.override;}}return A;};YAHOO.util.Subscriber.prototype.contains=funct!
 ion(A,B){if(B){return(this.fn==A&&this.obj==B);}else{return(th!
 is.fn==A
);}};YAHOO.util.Subscriber.prototype.toString=function(){return"Subscriber { obj: "+this.obj+", override: "+(this.override||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var H=false;var I=[];var J=[];var G=[];var E=[];var C=0;var F=[];var B=[];var A=0;var D={63232:38,63233:40,63234:37,63235:39,63276:33,63277:34,25:9};return{POLL_RETRYS:2000,POLL_INTERVAL:20,EL:0,TYPE:1,FN:2,WFN:3,UNLOAD_OBJ:3,ADJ_SCOPE:4,OBJ:5,OVERRIDE:6,lastError:null,isSafari:YAHOO.env.ua.webkit,webkit:YAHOO.env.ua.webkit,isIE:YAHOO.env.ua.ie,_interval:null,_dri:null,DOMReady:false,startInterval:function(){if(!this._interval){var K=this;var L=function(){K._tryPreloadAttach();};this._interval=setInterval(L,this.POLL_INTERVAL);}},onAvailable:function(P,M,Q,O,N){var K=(YAHOO.lang.isString(P))?[P]:P;for(var L=0;L<K.length;L=L+1){F.push({id:K[L],fn:M,obj:Q,override:O,checkReady:N});}C=this.POLL_RETRYS;this.startInterval();},onContentReady:function(M,K,N,L){this.onAvailable(M,K,N,L,true);},onDOM!
 Ready:function(K,M,L){if(this.DOMReady){setTimeout(function(){var N=window;if(L){if(L===true){N=M;}else{N=L;}}K.call(N,"DOMReady",[],M);},0);}else{this.DOMReadyEvent.subscribe(K,M,L);}},addListener:function(M,K,V,Q,L){if(!V||!V.call){return false;}if(this._isValidCollection(M)){var W=true;for(var R=0,T=M.length;R<T;++R){W=this.on(M[R],K,V,Q,L)&&W;}return W;}else{if(YAHOO.lang.isString(M)){var P=this.getEl(M);if(P){M=P;}else{this.onAvailable(M,function(){YAHOO.util.Event.on(M,K,V,Q,L);});return true;}}}if(!M){return false;}if("unload"==K&&Q!==this){J[J.length]=[M,K,V,Q,L];return true;}var Y=M;if(L){if(L===true){Y=Q;}else{Y=L;}}var N=function(Z){return V.call(Y,YAHOO.util.Event.getEvent(Z,M),Q);};var X=[M,K,V,N,Y,Q,L];var S=I.length;I[S]=X;if(this.useLegacyEvent(M,K)){var O=this.getLegacyIndex(M,K);if(O==-1||M!=G[O][0]){O=G.length;B[M.id+K]=O;G[O]=[M,K,M["on"+K]];E[O]=[];M["on"+K]=function(Z){YAHOO.util.Event.fireLegacyEvent(YAHOO.util.Event.getEvent(Z),O);};}E[O].push(X);}el!
 se{try{this._simpleAdd(M,K,N,false);}catch(U){this.lastError=U!
 ;this.re
moveListener(M,K,V);return false;}}return true;},fireLegacyEvent:function(O,M){var Q=true,K,S,R,T,P;S=E[M].slice();for(var L=0,N=S.length;L<N;++L){R=S[L];if(R&&R[this.WFN]){T=R[this.ADJ_SCOPE];P=R[this.WFN].call(T,O);Q=(Q&&P);}}K=G[M];if(K&&K[2]){K[2](O);}return Q;},getLegacyIndex:function(L,M){var K=this.generateId(L)+M;if(typeof B[K]=="undefined"){return -1;}else{return B[K];}},useLegacyEvent:function(L,M){if(this.webkit&&("click"==M||"dblclick"==M)){var K=parseInt(this.webkit,10);if(!isNaN(K)&&K<418){return true;}}return false;},removeListener:function(L,K,T){var O,R,V;if(typeof L=="string"){L=this.getEl(L);}else{if(this._isValidCollection(L)){var U=true;for(O=L.length-1;O>-1;O--){U=(this.removeListener(L[O],K,T)&&U);}return U;}}if(!T||!T.call){return this.purgeElement(L,false,K);}if("unload"==K){for(O=J.length-1;O>-1;O--){V=J[O];if(V&&V[0]==L&&V[1]==K&&V[2]==T){J.splice(O,1);return true;}}return false;}var P=null;var Q=arguments[3];if("undefined"===typeof Q){Q=this._getC!
 acheIndex(L,K,T);}if(Q>=0){P=I[Q];}if(!L||!P){return false;}if(this.useLegacyEvent(L,K)){var N=this.getLegacyIndex(L,K);var M=E[N];if(M){for(O=0,R=M.length;O<R;++O){V=M[O];if(V&&V[this.EL]==L&&V[this.TYPE]==K&&V[this.FN]==T){M.splice(O,1);break;}}}}else{try{this._simpleRemove(L,K,P[this.WFN],false);}catch(S){this.lastError=S;return false;}}delete I[Q][this.WFN];delete I[Q][this.FN];I.splice(Q,1);return true;},getTarget:function(M,L){var K=M.target||M.srcElement;return this.resolveTextNode(K);},resolveTextNode:function(L){try{if(L&&3==L.nodeType){return L.parentNode;}}catch(K){}return L;},getPageX:function(L){var K=L.pageX;if(!K&&0!==K){K=L.clientX||0;if(this.isIE){K+=this._getScrollLeft();}}return K;},getPageY:function(K){var L=K.pageY;if(!L&&0!==L){L=K.clientY||0;if(this.isIE){L+=this._getScrollTop();}}return L;},getXY:function(K){return[this.getPageX(K),this.getPageY(K)];},getRelatedTarget:function(L){var K=L.relatedTarget;
+if(!K){if(L.type=="mouseout"){K=L.toElement;}else{if(L.type=="mouseover"){K=L.fromElement;}}}return this.resolveTextNode(K);},getTime:function(M){if(!M.time){var L=new Date().getTime();try{M.time=L;}catch(K){this.lastError=K;return L;}}return M.time;},stopEvent:function(K){this.stopPropagation(K);this.preventDefault(K);},stopPropagation:function(K){if(K.stopPropagation){K.stopPropagation();}else{K.cancelBubble=true;}},preventDefault:function(K){if(K.preventDefault){K.preventDefault();}else{K.returnValue=false;}},getEvent:function(M,K){var L=M||window.event;if(!L){var N=this.getEvent.caller;while(N){L=N.arguments[0];if(L&&Event==L.constructor){break;}N=N.caller;}}return L;},getCharCode:function(L){var K=L.keyCode||L.charCode||0;if(YAHOO.env.ua.webkit&&(K in D)){K=D[K];}return K;},_getCacheIndex:function(O,P,N){for(var M=0,L=I.length;M<L;M=M+1){var K=I[M];if(K&&K[this.FN]==N&&K[this.EL]==O&&K[this.TYPE]==P){return M;}}return -1;},generateId:function(K){var L=K.id;if(!L){L="yu!
 ievtautoid-"+A;++A;K.id=L;}return L;},_isValidCollection:function(L){try{return(L&&typeof L!=="string"&&L.length&&!L.tagName&&!L.alert&&typeof L[0]!=="undefined");}catch(K){return false;}},elCache:{},getEl:function(K){return(typeof K==="string")?document.getElementById(K):K;},clearCache:function(){},DOMReadyEvent:new YAHOO.util.CustomEvent("DOMReady",this),_load:function(L){if(!H){H=true;var K=YAHOO.util.Event;K._ready();K._tryPreloadAttach();}},_ready:function(L){var K=YAHOO.util.Event;if(!K.DOMReady){K.DOMReady=true;K.DOMReadyEvent.fire();K._simpleRemove(document,"DOMContentLoaded",K._ready);}},_tryPreloadAttach:function(){if(F.length===0){C=0;clearInterval(this._interval);this._interval=null;return ;}if(this.locked){return ;}if(this.isIE){if(!this.DOMReady){this.startInterval();return ;}}this.locked=true;var Q=!H;if(!Q){Q=(C>0&&F.length>0);}var P=[];var R=function(T,U){var S=T;if(U.override){if(U.override===true){S=U.obj;}else{S=U.override;}}U.fn.call(S,U.obj);};var L,K,!
 O,N,M=[];for(L=0,K=F.length;L<K;L=L+1){O=F[L];if(O){N=this.get!
 El(O.id)
;if(N){if(O.checkReady){if(H||N.nextSibling||!Q){M.push(O);F[L]=null;}}else{R(N,O);F[L]=null;}}else{P.push(O);}}}for(L=0,K=M.length;L<K;L=L+1){O=M[L];R(this.getEl(O.id),O);}C--;if(Q){for(L=F.length-1;L>-1;L--){O=F[L];if(!O||!O.id){F.splice(L,1);}}this.startInterval();}else{clearInterval(this._interval);this._interval=null;}this.locked=false;},purgeElement:function(O,P,R){var M=(YAHOO.lang.isString(O))?this.getEl(O):O;var Q=this.getListeners(M,R),N,K;if(Q){for(N=Q.length-1;N>-1;N--){var L=Q[N];this.removeListener(M,L.type,L.fn);}}if(P&&M&&M.childNodes){for(N=0,K=M.childNodes.length;N<K;++N){this.purgeElement(M.childNodes[N],P,R);}}},getListeners:function(M,K){var P=[],L;if(!K){L=[I,J];}else{if(K==="unload"){L=[J];}else{L=[I];}}var R=(YAHOO.lang.isString(M))?this.getEl(M):M;for(var O=0;O<L.length;O=O+1){var T=L[O];if(T){for(var Q=0,S=T.length;Q<S;++Q){var N=T[Q];if(N&&N[this.EL]===R&&(!K||K===N[this.TYPE])){P.push({type:N[this.TYPE],fn:N[this.FN],obj:N[this.OBJ],adjust:N[this.!
 OVERRIDE],scope:N[this.ADJ_SCOPE],index:Q});}}}}return(P.length)?P:null;},_unload:function(Q){var K=YAHOO.util.Event,N,M,L,P,O,R=J.slice();for(N=0,P=J.length;N<P;++N){L=R[N];if(L){var S=window;if(L[K.ADJ_SCOPE]){if(L[K.ADJ_SCOPE]===true){S=L[K.UNLOAD_OBJ];}else{S=L[K.ADJ_SCOPE];}}L[K.FN].call(S,K.getEvent(Q,L[K.EL]),L[K.UNLOAD_OBJ]);R[N]=null;L=null;S=null;}}J=null;if(I){for(M=I.length-1;M>-1;M--){L=I[M];if(L){K.removeListener(L[K.EL],L[K.TYPE],L[K.FN],M);}}L=null;}G=null;K._simpleRemove(window,"unload",K._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var K=document.documentElement,L=document.body;if(K&&(K.scrollTop||K.scrollLeft)){return[K.scrollTop,K.scrollLeft];}else{if(L){return[L.scrollTop,L.scrollLeft];}else{return[0,0];}}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(M,N,L,K){M.addEventListener(N,L,(K));};}else{if(window.attachEvent!
 ){return function(M,N,L,K){M.attachEvent("on"+N,L);};}else{ret!
 urn func
tion(){};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(M,N,L,K){M.removeEventListener(N,L,(K));};}else{if(window.detachEvent){return function(L,M,K){L.detachEvent("on"+M,K);};}else{return function(){};}}}()};}();(function(){var EU=YAHOO.util.Event;EU.on=EU.addListener;
+/* DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller */
+if(EU.isIE){YAHOO.util.Event.onDOMReady(YAHOO.util.Event._tryPreloadAttach,YAHOO.util.Event,true);var n=document.createElement("p");EU._dri=setInterval(function(){try{n.doScroll("left");clearInterval(EU._dri);EU._dri=null;EU._ready();n=null;}catch(ex){}},EU.POLL_INTERVAL);}else{if(EU.webkit&&EU.webkit<525){EU._dri=setInterval(function(){var rs=document.readyState;if("loaded"==rs||"complete"==rs){clearInterval(EU._dri);EU._dri=null;EU._ready();}},EU.POLL_INTERVAL);}else{EU._simpleAdd(document,"DOMContentLoaded",EU._ready);}}EU._simpleAdd(window,"load",EU._load);EU._simpleAdd(window,"unload",EU._unload);EU._tryPreloadAttach();})();}YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null,__yui_subscribers:null,subscribe:function(A,C,F,E){this.__yui_events=this.__yui_events||{};var D=this.__yui_events[A];if(D){D.subscribe(C,F,E);}else{this.__yui_subscribers=this.__yui_subscribers||{};var B=this.__yui_subscribers;if(!B[A]){B[A]=[];}B[A].push({!
 fn:C,obj:F,override:E});}},unsubscribe:function(C,E,G){this.__yui_events=this.__yui_events||{};var A=this.__yui_events;if(C){var F=A[C];if(F){return F.unsubscribe(E,G);}}else{var B=true;for(var D in A){if(YAHOO.lang.hasOwnProperty(A,D)){B=B&&A[D].unsubscribe(E,G);}}return B;}return false;},unsubscribeAll:function(A){return this.unsubscribe(A);},createEvent:function(G,D){this.__yui_events=this.__yui_events||{};var A=D||{};var I=this.__yui_events;if(I[G]){}else{var H=A.scope||this;var E=(A.silent);var B=new YAHOO.util.CustomEvent(G,H,E,YAHOO.util.CustomEvent.FLAT);
+I[G]=B;if(A.onSubscribeCallback){B.subscribeEvent.subscribe(A.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};var F=this.__yui_subscribers[G];if(F){for(var C=0;C<F.length;++C){B.subscribe(F[C].fn,F[C].obj,F[C].override);}}}return I[G];},fireEvent:function(E,D,A,C){this.__yui_events=this.__yui_events||{};var G=this.__yui_events[E];if(!G){return null;}var B=[];for(var F=1;F<arguments.length;++F){B.push(arguments[F]);}return G.fire.apply(G,B);},hasEvent:function(A){if(this.__yui_events){if(this.__yui_events[A]){return true;}}return false;}};YAHOO.util.KeyListener=function(A,F,B,C){if(!A){}else{if(!F){}else{if(!B){}}}if(!C){C=YAHOO.util.KeyListener.KEYDOWN;}var D=new YAHOO.util.CustomEvent("keyPressed");this.enabledEvent=new YAHOO.util.CustomEvent("enabled");this.disabledEvent=new YAHOO.util.CustomEvent("disabled");if(typeof A=="string"){A=document.getElementById(A);}if(typeof B=="function"){D.subscribe(B);}else{D.subscribe(B.fn,B.scope,B.correctScope);}!
 function E(J,I){if(!F.shift){F.shift=false;}if(!F.alt){F.alt=false;}if(!F.ctrl){F.ctrl=false;}if(J.shiftKey==F.shift&&J.altKey==F.alt&&J.ctrlKey==F.ctrl){var G;if(F.keys instanceof Array){for(var H=0;H<F.keys.length;H++){G=F.keys[H];if(G==J.charCode){D.fire(J.charCode,J);break;}else{if(G==J.keyCode){D.fire(J.keyCode,J);break;}}}}else{G=F.keys;if(G==J.charCode){D.fire(J.charCode,J);}else{if(G==J.keyCode){D.fire(J.keyCode,J);}}}}}this.enable=function(){if(!this.enabled){YAHOO.util.Event.addListener(A,C,E);this.enabledEvent.fire(F);}this.enabled=true;};this.disable=function(){if(this.enabled){YAHOO.util.Event.removeListener(A,C,E);this.disabledEvent.fire(F);}this.enabled=false;};this.toString=function(){return"KeyListener ["+F.keys+"] "+A.tagName+(A.id?"["+A.id+"]":"");};};YAHOO.util.KeyListener.KEYDOWN="keydown";YAHOO.util.KeyListener.KEYUP="keyup";YAHOO.util.KeyListener.KEY={ALT:18,BACK_SPACE:8,CAPS_LOCK:20,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:!
 37,META:224,NUM_LOCK:144,PAGE_DOWN:34,PAGE_UP:33,PAUSE:19,PRIN!
 TSCREEN:
44,RIGHT:39,SCROLL_LOCK:145,SHIFT:16,SPACE:32,TAB:9,UP:38};YAHOO.register("event",YAHOO.util.Event,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/event/event.js
===================================================================
--- trunk/root/static/yui/event/event.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/event/event.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 
 /**
@@ -219,17 +219,17 @@
             return true;
         }
 
-        var args=[], ret=true, i, rebuild=false;
+        var args=[].slice.call(arguments, 0), ret=true, i, rebuild=false;
 
-        for (i=0; i<arguments.length; ++i) {
-            args.push(arguments[i]);
-        }
-
         if (!this.silent) {
         }
 
+        // make a copy of the subscribers so that there are
+        // no index problems if one subscriber removes another.
+        var subs = this.subscribers.slice();
+
         for (i=0; i<len; ++i) {
-            var s = this.subscribers[i];
+            var s = subs[i];
             if (!s) {
                 rebuild=true;
             } else {
@@ -266,15 +266,16 @@
             }
         }
 
-        if (rebuild) {
-            var newlist=[],subs=this.subscribers;
-            for (i=0,len=subs.length; i<len; i=i+1) {
-                newlist.push(subs[i]);
-            }
+        
+        // if (rebuild) {
+        //     var newlist=this.,subs=this.subscribers;
+        //     for (i=0,len=subs.length; i<len; i=i+1) {
+        //         // this wasn't doing anything before
+        //         newlist.push(subs[i]);
+        //     }
+        //     this.subscribers=newlist;
+        // }
 
-            this.subscribers=newlist;
-        }
-
         return true;
     },
 
@@ -284,8 +285,8 @@
      * @return {int} The number of listeners unsubscribed
      */
     unsubscribeAll: function() {
-        for (var i=0, len=this.subscribers.length; i<len; ++i) {
-            this._delete(len - 1 - i);
+        for (var i=this.subscribers.length-1; i>-1; i--) {
+            this._delete(i);
         }
 
         this.subscribers=[];
@@ -304,7 +305,8 @@
             delete s.obj;
         }
 
-        this.subscribers[index]=null;
+        // this.subscribers[index]=null;
+        this.subscribers.splice(index, 1);
     },
 
     /**
@@ -532,7 +534,7 @@
             /**
              * The number of times we should look for elements that are not
              * in the DOM at the time the event is requested after the document
-             * has been loaded.  The default is 4000 at amp;10 ms, so it will poll
+             * has been loaded.  The default is 2000 at amp;20 ms, so it will poll
              * for 40 seconds or until all outstanding handlers are bound
              * (whichever comes first).
              * @property POLL_RETRYS
@@ -540,7 +542,7 @@
              * @static
              * @final
              */
-            POLL_RETRYS: 4000,
+            POLL_RETRYS: 2000,
 
             /**
              * The poll interval in milliseconds
@@ -549,7 +551,7 @@
              * @static
              * @final
              */
-            POLL_INTERVAL: 10,
+            POLL_INTERVAL: 20,
 
             /**
              * Element to bind, int constant
@@ -736,7 +738,9 @@
                                        override:   p_override, 
                                        checkReady: checkContent });
                 }
+
                 retryCount = this.POLL_RETRYS;
+
                 this.startInterval();
             },
 
@@ -839,7 +843,6 @@
             addListener: function(el, sType, fn, obj, override) {
 
                 if (!fn || !fn.call) {
-// throw new TypeError(sType + " addListener call failed, callback undefined");
                     return false;
                 }
 
@@ -970,10 +973,11 @@
              * @private
              */
             fireLegacyEvent: function(e, legacyIndex) {
-                var ok=true,le,lh,li,scope,ret;
+                var ok=true, le, lh, li, scope, ret;
                 
-                lh = legacyHandlers[legacyIndex];
-                for (var i=0,len=lh.length; i<len; ++i) {
+                lh = legacyHandlers[legacyIndex].slice();
+                for (var i=0, len=lh.length; i<len; ++i) {
+                // for (var i in lh.length) {
                     li = lh[i];
                     if ( li && li[this.WFN] ) {
                         scope = li[this.ADJ_SCOPE];
@@ -1053,7 +1057,7 @@
                 // The el argument can be an array of elements or element ids.
                 } else if ( this._isValidCollection(el)) {
                     var ok = true;
-                    for (i=0,len=el.length; i<len; ++i) {
+                    for (i=el.length-1; i>-1; i--) {
                         ok = ( this.removeListener(el[i], sType, fn) && ok );
                     }
                     return ok;
@@ -1066,14 +1070,14 @@
 
                 if ("unload" == sType) {
 
-                    for (i=0, len=unloadListeners.length; i<len; i++) {
+                    for (i=unloadListeners.length-1; i>-1; i--) {
                         li = unloadListeners[i];
                         if (li && 
                             li[0] == el && 
                             li[1] == sType && 
                             li[2] == fn) {
-                                //unloadListeners.splice(i, 1);
-                                unloadListeners[i]=null;
+                                unloadListeners.splice(i, 1);
+                                // unloadListeners[i]=null;
                                 return true;
                         }
                     }
@@ -1106,13 +1110,14 @@
                     var llist = legacyHandlers[legacyIndex];
                     if (llist) {
                         for (i=0, len=llist.length; i<len; ++i) {
+                        // for (i in llist.length) {
                             li = llist[i];
                             if (li && 
                                 li[this.EL] == el && 
                                 li[this.TYPE] == sType && 
                                 li[this.FN] == fn) {
-                                    //llist.splice(i, 1);
-                                    llist[i]=null;
+                                    llist.splice(i, 1);
+                                    // llist[i]=null;
                                     break;
                             }
                         }
@@ -1130,8 +1135,8 @@
                 // removed the wrapped handler
                 delete listeners[index][this.WFN];
                 delete listeners[index][this.FN];
-                //listeners.splice(index, 1);
-                listeners[index]=null;
+                listeners.splice(index, 1);
+                // listeners[index]=null;
 
                 return true;
 
@@ -1164,12 +1169,14 @@
              * @return {HTMLElement} the normized node
              * @static
              */
-            resolveTextNode: function(node) {
-                if (node && 3 == node.nodeType) {
-                    return node.parentNode;
-                } else {
-                    return node;
-                }
+            resolveTextNode: function(n) {
+                try {
+                    if (n && 3 == n.nodeType) {
+                        return n.parentNode;
+                    }
+                } catch(e) { }
+
+                return n;
             },
 
             /**
@@ -1331,30 +1338,6 @@
                     }
                 }
 
-                // IE events that target non-browser objects (e.g., VML
-                // canvas) will sometimes throw errors when you try to
-                // inspect the properties of the event target.  We try to
-                // detect this condition, and provide a dummy target (the bound
-                // element) to eliminate spurious errors.  
-
-                // the implementation caused unexpected results in some 
-                // implementations, so this has been rolled back for now
-                /* 
-                if (ev && this.isIE) {
-
-                    try {
-
-                        var el = ev.srcElement;
-
-                    } catch(ex) {
-
-                         
-                        ev.target = boundEl;
-                    }
-
-                }
-                */
-
                 return ev;
             },
 
@@ -1368,7 +1351,7 @@
             getCharCode: function(ev) {
                 var code = ev.keyCode || ev.charCode || 0;
 
-                // webkit normalization
+                // webkit key normalization
                 if (YAHOO.env.ua.webkit && (code in webkitKeymap)) {
                     code = webkitKeymap[code];
                 }
@@ -1383,7 +1366,7 @@
              * @private
              */
             _getCacheIndex: function(el, sType, fn) {
-                for (var i=0,len=listeners.length; i<len; ++i) {
+                for (var i=0, l=listeners.length; i<l; i=i+1) {
                     var li = listeners[i];
                     if ( li                 && 
                          li[this.FN] == fn  && 
@@ -1501,11 +1484,6 @@
                     // before the window load notification
                     EU._tryPreloadAttach();
 
-                    // Remove the listener to assist with the IE memory issue, but not
-                    // for other browsers because FF 1.0x does not like it.
-                    //if (this.isIE) {
-                        //EU._simpleRemove(window, "load", EU._load);
-                    //}
                 }
             },
 
@@ -1539,18 +1517,24 @@
              */
             _tryPreloadAttach: function() {
 
+                if (onAvailStack.length === 0) {
+                    retryCount = 0;
+                    clearInterval(this._interval);
+                    this._interval = null;
+                    return;
+                }
+
                 if (this.locked) {
-                    return false;
+                    return;
                 }
 
                 if (this.isIE) {
                     // Hold off if DOMReady has not fired and check current
                     // readyState to protect against the IE operation aborted
                     // issue.
-                    //if (!this.DOMReady || "complete" !== document.readyState) {
                     if (!this.DOMReady) {
                         this.startInterval();
-                        return false;
+                        return;
                     }
                 }
 
@@ -1563,7 +1547,7 @@
                 // tested appropriately
                 var tryAgain = !loadComplete;
                 if (!tryAgain) {
-                    tryAgain = (retryCount > 0);
+                    tryAgain = (retryCount > 0 && onAvailStack.length > 0);
                 }
 
                 // onAvailable
@@ -1581,32 +1565,20 @@
                     item.fn.call(scope, item.obj);
                 };
 
-                var i,len,item,el;
+                var i, len, item, el, ready=[];
 
-                // onAvailable
-                for (i=0,len=onAvailStack.length; i<len; ++i) {
+                // onAvailable onContentReady
+                for (i=0, len=onAvailStack.length; i<len; i=i+1) {
                     item = onAvailStack[i];
-                    if (item && !item.checkReady) {
+                    if (item) {
                         el = this.getEl(item.id);
                         if (el) {
-                            executeItem(el, item);
-                            onAvailStack[i] = null;
-                        } else {
-                            notAvail.push(item);
-                        }
-                    }
-                }
-
-                // onContentReady
-                for (i=0,len=onAvailStack.length; i<len; ++i) {
-                    item = onAvailStack[i];
-                    if (item && item.checkReady) {
-                        el = this.getEl(item.id);
-
-                        if (el) {
-                            // The element is available, but not necessarily ready
-                            // @todo should we test parentNode.nextSibling?
-                            if (loadComplete || el.nextSibling) {
+                            if (item.checkReady) {
+                                if (loadComplete || el.nextSibling || !tryAgain) {
+                                    ready.push(item);
+                                    onAvailStack[i] = null;
+                                }
+                            } else {
                                 executeItem(el, item);
                                 onAvailStack[i] = null;
                             }
@@ -1615,11 +1587,24 @@
                         }
                     }
                 }
+                
+                // make sure onContentReady fires after onAvailable
+                for (i=0, len=ready.length; i<len; i=i+1) {
+                    item = ready[i];
+                    executeItem(this.getEl(item.id), item);
+                }
 
-                retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
 
+                retryCount--;
+
                 if (tryAgain) {
-                    // we may need to strip the nulled out items here
+                    for (i=onAvailStack.length-1; i>-1; i--) {
+                        item = onAvailStack[i];
+                        if (!item || !item.id) {
+                            onAvailStack.splice(i, 1);
+                        }
+                    }
+
                     this.startInterval();
                 } else {
                     clearInterval(this._interval);
@@ -1628,8 +1613,6 @@
 
                 this.locked = false;
 
-                return true;
-
             },
 
             /**
@@ -1648,11 +1631,9 @@
                 var oEl = (YAHOO.lang.isString(el)) ? this.getEl(el) : el;
                 var elListeners = this.getListeners(oEl, sType), i, len;
                 if (elListeners) {
-                    for (i=0,len=elListeners.length; i<len ; ++i) {
+                    for (i=elListeners.length-1; i>-1; i--) {
                         var l = elListeners[i];
-                        // can't use the index on the changing collection
-                        this.removeListener(oEl, l.type, l.fn, l.index);
-                        //this.removeListener(oEl, l.type, l.fn);
+                        this.removeListener(oEl, l.type, l.fn);
                     }
                 }
 
@@ -1693,7 +1674,7 @@
 
                 for (var j=0;j<searchLists.length; j=j+1) {
                     var searchList = searchLists[j];
-                    if (searchList && searchList.length > 0) {
+                    if (searchList) {
                         for (var i=0,len=searchList.length; i<len ; ++i) {
                             var l = searchList[i];
                             if ( l  && l[this.EL] === oEl && 
@@ -1723,11 +1704,12 @@
              */
             _unload: function(e) {
 
-                var EU = YAHOO.util.Event, i, j, l, len, index;
+                var EU = YAHOO.util.Event, i, j, l, len, index,
+                         ul = unloadListeners.slice();
 
                 // execute and clear stored unload listeners
                 for (i=0,len=unloadListeners.length; i<len; ++i) {
-                    l = unloadListeners[i];
+                    l = ul[i];
                     if (l) {
                         var scope = window;
                         if (l[EU.ADJ_SCOPE]) {
@@ -1738,7 +1720,7 @@
                             }
                         }
                         l[EU.FN].call(scope, EU.getEvent(e, l[EU.EL]), l[EU.UNLOAD_OBJ] );
-                        unloadListeners[i] = null;
+                        ul[i] = null;
                         l=null;
                         scope=null;
                     }
@@ -1746,54 +1728,23 @@
 
                 unloadListeners = null;
 
-                // call clearAttributes or remove listeners to handle IE memory leaks
-                if (YAHOO.env.ua.ie && listeners && listeners.length > 0) {
-                    j = listeners.length;
-                    while (j) {
-                        index = j-1;
-                        l = listeners[index];
+                // Remove listeners to handle IE memory leaks
+                //if (YAHOO.env.ua.ie && listeners && listeners.length > 0) {
+                
+                // 2.5.0 listeners are removed for all browsers again.  FireFox preserves
+                // at least some listeners between page refreshes, potentially causing
+                // errors during page load (mouseover listeners firing before they
+                // should if the user moves the mouse at the correct moment).
+                if (listeners) {
+                    for (j=listeners.length-1; j>-1; j--) {
+                        l = listeners[j];
                         if (l) {
-                            //try {
-                                //l[EU.EL].clearAttributes(); // errors on window objects
-                            //} catch(ex) {
-                            EU.removeListener(l[EU.EL], l[EU.TYPE], l[EU.FN], index);
-                            //}
+                            EU.removeListener(l[EU.EL], l[EU.TYPE], l[EU.FN], j);
                         } 
-                        j--;
                     }
                     l=null;
                 }
 
-                /*
-                // remove all listeners
-                if (listeners && listeners.length > 0) {
-                    j = listeners.length;
-                    while (j) {
-                        index = j-1;
-                        l = listeners[index];
-                        if (l) {
-                            EU.removeListener(l[EU.EL], l[EU.TYPE], l[EU.FN], index);
-                        } 
-                        j = j - 1;
-                    }
-                    l=null;
-                }
-                */
-
-                /*
-                // kill legacy events
-                for (i=0,len=legacyEvents.length; i<len; ++i) {
-                    // dereference the element
-                    //delete legacyEvents[i][0];
-                    legacyEvents[i][0] = null;
-
-                    // delete the array item
-                    //delete legacyEvents[i];
-                    legacyEvents[i] = null;
-                }
-
-                */
-
                 legacyEvents = null;
 
                 EU._simpleRemove(window, "unload", EU._unload);
@@ -1850,22 +1801,6 @@
                 // does nothing
             },
 
-/*
-            testIEReady: function (){
-                var n = document.createElement('p'), ready = false;
-                try {
-                    // throws an error until the doc is ready
-                    n.doScroll('left'); 
-                    ready = true;
-                } catch(ex){ 
-                    // document is not ready
-                }
-
-                n = null;
-                return ready;
-            },
-*/
-
             /**
              * Adds a DOM event directly without the caching, cleanup, scope adj, etc
              *
@@ -1930,9 +1865,7 @@
          */
         EU.on = EU.addListener;
 
-        /////////////////////////////////////////////////////////////
-        // DOMReady
-        // based on work by: Dean Edwards/John Resig/Matthias Miller 
+/*! DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller */
 
         // Internet Explorer: use the readyState of a defered script.
         // This isolates what appears to be a safe moment to manipulate
@@ -1940,67 +1873,15 @@
         // it is safe to do so.
         if (EU.isIE) {
 
-            // Process onAvailable/onContentReady items when when the 
+            // Process onAvailable/onContentReady items when the 
             // DOM is ready.
             YAHOO.util.Event.onDOMReady(
                     YAHOO.util.Event._tryPreloadAttach,
                     YAHOO.util.Event, true);
-
-            /*
-
-
-            var el, d=document, b=d.body;
-
-            // If the library is being injected after window.onload, it
-            // is not safe to document.write the script tag.  Detecting
-            // this state doesn't appear possible, so we expect a flag
-            // in YAHOO_config to be set if the library is being injected.
-            if (("undefined" !== typeof YAHOO_config) && YAHOO_config.injecting) {
-
-                el = document.createElement("script");
-                var p=d.getElementsByTagName("head")[0] || b;
-                p.insertBefore(el, p.firstChild);
-
-            } else {
-    d.write('<scr'+'ipt id="_yui_eu_dr" defer="true" src="//:"><'+'/script>');
-                el=document.getElementById("_yui_eu_dr");
-            }
             
+            var n = document.createElement('p');  
 
-            if (el) {
-                el.onreadystatechange = function() {
-                    if ("complete" === this.readyState) {
-                        this.parentNode.removeChild(this);
-                        YAHOO.util.Event._ready();
-                    }
-                };
-            } else {
-                // The library was likely injected into the page
-                // rendering onDOMReady unreliable
-                // YAHOO.util.Event._ready();
-            }
-
-            el=null;
-
-            */
-
-/*
-            (function (){
-                var n = document.createElement('p');  
-                try {
-                    // throws an error if doc is not ready
-                    n.doScroll('left');
-                    n = null;
-                    YAHOO.util.Event._ready();
-                } catch (ex){
-                    n = null;
-setTimeout(arguments.callee, YAHOO.util.Event.POLL_INTERVAL);
-                }
-            })();
-*/
-
             EU._dri = setInterval(function() {
-                var n = document.createElement('p');  
                 try {
                     // throws an error if doc is not ready
                     n.doScroll('left');
@@ -2009,15 +1890,13 @@
                     EU._ready();
                     n = null;
                 } catch (ex) { 
-                    n = null;
                 }
             }, EU.POLL_INTERVAL); 
 
         
-        // Safari: The document's readyState in Safari currently will
+        // The document's readyState in Safari currently will
         // change to loaded/complete before images are loaded.
-        //} else if (EU.webkit) {
-        } else if (EU.webkit) {
+        } else if (EU.webkit && EU.webkit < 525) {
 
             EU._dri = setInterval(function() {
                 var rs=document.readyState;
@@ -2029,11 +1908,9 @@
             }, EU.POLL_INTERVAL); 
 
         // FireFox and Opera: These browsers provide a event for this
-        // moment.
+        // moment.  The latest WebKit releases now support this event.
         } else {
 
-            // @todo will this fire when the library is injected?
-
             EU._simpleAdd(document, "DOMContentLoaded", EU._ready);
 
         }
@@ -2489,4 +2366,4 @@
     TAB          : 9,
     UP           : 38
 };
-YAHOO.register("event", YAHOO.util.Event, {version: "2.4.1", build: "742"});
+YAHOO.register("event", YAHOO.util.Event, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/fonts/README
===================================================================
--- trunk/root/static/yui/fonts/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/fonts/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,13 @@
 YUI Library - Fonts - Release Notes
 
-Version 2.4.1
-No change
+Version 2.5.1
 
+  * No changes.
+
+Version 2.5.0
+
+  * No changes.
+
 Version 2.4.0
 
   * Rechanged core line-height from 1.22 to 1.231, sans units.

Modified: trunk/root/static/yui/fonts/fonts-min.css
===================================================================
--- trunk/root/static/yui/fonts/fonts-min.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/fonts/fonts-min.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 body {font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}

Modified: trunk/root/static/yui/fonts/fonts.css
===================================================================
--- trunk/root/static/yui/fonts/fonts.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/fonts/fonts.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * Percents could work for IE, but for backCompat purposes, we are using keywords.

Modified: trunk/root/static/yui/get/README
===================================================================
--- trunk/root/static/yui/get/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/get/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,18 @@
 get - Release Notes
 
+2.5.1
+    * onFailure callback receives a second parameter containing an error message.
+    * Added 'charset' configuration option for inserted nodes.  Default is utf-8.
+    * Added 'insertBefore' configuration to specify a node or node id to insert before.
+      This can be used to position CSS nodes before any overriding styles.
+
+2.5.0
+    * autopurge no longer attempts to remove nodes that have been
+      removed previously.
+    * Fixed Safari 2.x external script insert.
+
 2.4.1
+   * No change
 
-No change
-
 2.4.0
    * Inital release

Deleted: trunk/root/static/yui/get/get-beta-debug.js
===================================================================
--- trunk/root/static/yui/get/get-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/get/get-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,643 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-/**
- * Provides a mechanism to fetch remote resources and
- * insert them into a document
- * @module get
- * @requires yahoo
- */
-
-/**
- * Fetches and inserts one or more script or link nodes into the document 
- * @namespace YAHOO.util
- * @class YAHOO.util.Get
- */
-YAHOO.util.Get = function() {
-
-    /**
-     * hash of queues to manage multiple requests
-     * @property queues
-     * @private
-     */
-    var queues={}, 
-        
-    /**
-     * queue index used to generate transaction ids
-     * @property qidx
-     * @type int
-     * @private
-     */
-        qidx=0, 
-        
-    /**
-     * node index used to generate unique node ids
-     * @property nidx
-     * @type int
-     * @private
-     */
-        nidx=0, 
-
-        // ridx=0,
-
-        // sandboxFrame=null,
-
-    /**
-     * interal property used to prevent multiple simultaneous purge 
-     * processes
-     * @property purging
-     * @type boolean
-     * @private
-     */
-        purging=false,
-
-        ua=YAHOO.env.ua, 
-        
-        lang=YAHOO.lang;
-    
-    /** 
-     * Generates an HTML element, this is not appended to a document
-     * @method _node
-     * @param type {string} the type of element
-     * @param attr {string} the attributes
-     * @param win {Window} optional window to create the element in
-     * @return {HTMLElement} the generated node
-     * @private
-     */
-    var _node = function(type, attr, win) {
-        var w = win || window, d=w.document, n=d.createElement(type);
-
-        for (var i in attr) {
-            if (attr[i] && YAHOO.lang.hasOwnProperty(attr, i)) {
-                n.setAttribute(i, attr[i]);
-            }
-        }
-
-        return n;
-    };
-
-    /**
-     * Generates a link node
-     * @method _linkNode
-     * @param url {string} the url for the css file
-     * @param win {Window} optional window to create the node in
-     * @return {HTMLElement} the generated node
-     * @private
-     */
-    var _linkNode = function(url, win) {
-        return _node("link", {
-                "id": "yui__dyn_" + (nidx++),
-                "type": "text/css",
-                "rel": "stylesheet",
-                "href": url
-            }, win);
-    };
-
-    /**
-     * Generates a script node
-     * @method _scriptNode
-     * @param url {string} the url for the script file
-     * @param win {Window} optional window to create the node in
-     * @return {HTMLElement} the generated node
-     * @private
-     */
-    var _scriptNode = function(url, win) {
-        return _node("script", {
-                "id": "yui__dyn_" + (nidx++),
-                "type": "text/javascript",
-                "src": url
-            }, win);
-    };
-
-    /**
-     * Returns the data payload for callback functions
-     * @method _returnData
-     * @private
-     */
-    var _returnData = function(q) {
-        return {
-                tId: q.tId,
-                win: q.win,
-                data: q.data,
-                nodes: q.nodes,
-                purge: function() {
-                    _purge(this.tId);
-                }
-            };
-    };
-
-    /*
-     * The request failed, execute fail handler with whatever
-     * was accomplished.  There isn't a failure case at the
-     * moment unless you count aborted transactions
-     * @method _fail
-     * @param id {string} the id of the request
-     * @private
-     */
-    var _fail = function(id) {
-        var q = queues[id];
-        // execute failure callback
-        if (q.onFailure) {
-            var sc=q.scope || q.win;
-            q.onFailure.call(sc, _returnData(q));
-        }
-    };
-
-    /**
-     * The request is complete, so executing the requester's callback
-     * @method _finish
-     * @param id {string} the id of the request
-     * @private
-     */
-    var _finish = function(id) {
-        YAHOO.log("Finishing transaction " + id);
-        var q = queues[id];
-        q.finished = true;
-
-        if (q.aborted) {
-            YAHOO.log("transaction " + id + " was aborted", "info", "Get");
-            _fail(id);
-            return;
-        }
-
-        // execute success callback
-        if (q.onSuccess) {
-            var sc=q.scope || q.win;
-            q.onSuccess.call(sc, _returnData(q));
-        }
-    };
-
-    /**
-     * Loads the next item for a given request
-     * @method _next
-     * @param id {string} the id of the request
-     * @param loaded {string} the url that was just loaded, if any
-     * @private
-     */
-    var _next = function(id, loaded) {
-        YAHOO.log("_next: " + id + ", loaded: " + loaded, "info", "Get");
-        var q = queues[id];
-
-        if (q.aborted) {
-            YAHOO.log("transaction " + id + " was aborted", "info", "Get");
-            _fail(id);
-            return;
-        }
-
-        if (loaded) {
-            q.url.shift(); 
-            if (q.varName) {
-                q.varName.shift(); 
-            }
-        } else {
-            // This is the first pass: make sure the url is an array
-            q.url = (lang.isString(q.url)) ? [q.url] : q.url;
-            if (q.varName) {
-                q.varName = (lang.isString(q.varName)) ? [q.varName] : q.varName;
-            }
-        }
-
-        var w=q.win, d=w.document, h=d.getElementsByTagName("head")[0], n;
-
-        if (q.url.length === 0) {
-            // Safari 2.x workaround - There is no way to know when 
-            // a script is ready in versions of Safari prior to 3.x.
-            // Adding an extra node reduces the problem, but doesn't
-            // eliminate it completely because the browser executes
-            // them asynchronously. 
-            if (q.type === "script" && ua.webkit && ua.webkit < 420 && 
-                    !q.finalpass && !q.varName) {
-                // Add another script node.  This does not guarantee that the
-                // scripts will execute in order, but it does appear to fix the
-                // problem on fast connections more effectively than using an
-                // arbitrary timeout.  It is possible that the browser does
-                // block subsequent script execution in this case for a limited
-                // time.
-                var extra = _scriptNode(null, q.win);
-                extra.innerHTML='YAHOO.util.Get._finalize("' + id + '");';
-                q.nodes.push(extra); h.appendChild(extra);
-
-            } else {
-                _finish(id);
-            }
-
-            return;
-        } 
-
-
-        var url = q.url[0];
-        YAHOO.log("attempting to load " + url, "info", "Get");
-
-        if (q.type === "script") {
-            n = _scriptNode(url, w);
-        } else {
-            n = _linkNode(url, w);
-        }
-
-        // track this node's load progress
-        _track(q.type, n, id, url, w, q.url.length);
-
-        // add the node to the queue so we can return it to the user supplied callback
-        q.nodes.push(n);
-
-        // add it to the head
-        h.appendChild(n);
-        
-        YAHOO.log("Appending node: " + url, "info", "Get");
-
-        // FireFox does not support the onload event for link nodes, so there is
-        // no way to make the css requests synchronous. This means that the css 
-        // rules in multiple files could be applied out of order in this browser
-        // if a later request returns before an earlier one.  Safari too.
-        if ((ua.webkit || ua.gecko) && q.type === "css") {
-            _next(id, url);
-        }
-    };
-
-    /**
-     * Removes processed queues and corresponding nodes
-     * @method _autoPurge
-     * @private
-     */
-    var _autoPurge = function() {
-
-        if (purging) {
-            return;
-        }
-
-        purging = true;
-        for (var i in queues) {
-            var q = queues[i];
-            if (q.autopurge && q.finished) {
-                _purge(q.tId);
-            }
-        }
-
-        purging = false;
-    };
-
-    /**
-     * Removes the nodes for the specified queue
-     * @method _purge
-     * @private
-     */
-    var _purge = function(tId) {
-        var q=queues[tId];
-        if (q) {
-            var n=q.nodes, l=n.length, d=q.win.document, 
-                h=d.getElementsByTagName("head")[0];
-            for (var i=0; i<l; i=i+1) {
-                h.removeChild(n[i]);
-            }
-        }
-    };
-
-    /**
-     * Saves the state for the request and begins loading
-     * the requested urls
-     * @method queue
-     * @param type {string} the type of node to insert
-     * @param url {string} the url to load
-     * @param opts the hash of options for this request
-     * @private
-     */
-    var _queue = function(type, url, opts) {
-
-        var id = "q" + (qidx++);
-        opts = opts || {};
-
-        if (qidx % YAHOO.util.Get.PURGE_THRESH === 0) {
-            _autoPurge();
-        }
-
-        queues[id] = lang.merge(opts, {
-            tId: id,
-            type: type,
-            url: url,
-            finished: false,
-            nodes: []
-        });
-
-        var q = queues[id];
-        q.win = q.win || window;
-        q.scope = q.scope || q.win;
-        q.autopurge = ("autopurge" in q) ? q.autopurge : 
-                      (type === "script") ? true : false;
-
-        lang.later(0, q, _next, id);
-
-        return {
-            tId: id
-        };
-    };
-
-    /**
-     * Detects when a node has been loaded.  In the case of
-     * script nodes, this does not guarantee that contained
-     * script is ready to use.
-     * @method _track
-     * @param type {string} the type of node to track
-     * @param n {HTMLElement} the node to track
-     * @param id {string} the id of the request
-     * @param url {string} the url that is being loaded
-     * @param win {Window} the targeted window
-     * @param qlength the number of remaining items in the queue,
-     * including this one
-     * @param trackfn {Function} function to execute when finished
-     * the default is _next
-     * @private
-     */
-    var _track = function(type, n, id, url, win, qlength, trackfn) {
-        var f = trackfn || _next;
-
-        // IE supports the readystatechange event for script and css nodes
-        if (ua.ie) {
-            n.onreadystatechange = function() {
-                var rs = this.readyState;
-                if ("loaded" === rs || "complete" === rs) {
-                    YAHOO.log(id + " onload " + url, "info", "Get");
-                    f(id, url);
-                }
-            };
-
-        // webkit prior to 3.x is problemmatic
-        } else if (ua.webkit) {
-
-            if (type === "script") {
-
-                // Safari 3.x supports the load event for script nodes (DOM2)
-                if (ua.webkit > 419) {
-
-                    n.addEventListener("load", function() {
-                        YAHOO.log(id + " DOM2 onload " + url, "info", "Get");
-                        f(id, url);
-                    });
-
-                // Nothing can be done with Safari < 3.x except to pause and hope
-                // for the best, particularly after last script is inserted. The
-                // scripts will always execute in the order they arrive, not
-                // necessarily the order in which they were inserted.  To support
-                // script nodes with complete reliability in these browsers, script
-                // nodes either need to invoke a function in the window once they
-                // are loaded or the implementer needs to provide a well-known
-                // property that the utility can poll for.
-                } else {
-                    // Poll for the existence of the named variable, if it
-                    // was supplied.
-                    var q = queues[id];
-                    if (q.varName) {
-                        var freq=YAHOO.util.Get.POLL_FREQ;
-                        YAHOO.log("Polling for " + q.varName[0]);
-                        q.maxattempts = YAHOO.util.Get.TIMEOUT/freq;
-                        q.attempts = 0;
-                        q._cache = q.varName[0].split(".");
-                        q.timer = lang.later(freq, q, function(o) {
-                            var a=this._cache, l=a.length, w=this.win, i;
-                            for (i=0; i<l; i=i+1) {
-                                w = w[a[i]];
-                                if (!w) {
-                                    // if we have exausted our attempts, give up
-                                    this.attempts++;
-                                    if (this.attempts++ > this.maxattempts) {
-                                        YAHOO.log("Over retry limit, giving up");
-                                        q.timer.cancel();
-                                        _fail(id);
-                                    } else {
-                                        YAHOO.log(a[i] + " failed, retrying");
-                                    }
-                                    return;
-                                }
-                            }
-                            
-                            YAHOO.log("Safari poll complete");
-
-                            q.timer.cancel();
-                            f(id, url);
-
-                        }, null, true);
-                    } else {
-                        lang.later(YAHOO.util.Get.POLL_FREQ, null, f, [id, url]);
-                    }
-                }
-            } 
-
-        // FireFox and Opera support onload (but not DOM2 in FF) handlers for
-        // script nodes.  Opera, but not FF, supports the onload event for link
-        // nodes.
-        } else { 
-            n.onload = function() {
-                YAHOO.log(id + " onload " + url, "info", "Get");
-                f(id, url);
-            };
-        }
-    };
-
-    return {
-
-        /**
-         * The default poll freqency in ms, when needed
-         * @property POLL_FREQ
-         * @static
-         * @type int
-         * @default 10
-         */
-        POLL_FREQ: 10,
-
-        /**
-         * The number of request required before an automatic purge.
-         * property PURGE_THRESH
-         * @static
-         * @type int
-         * @default 20
-         */
-        PURGE_THRESH: 20,
-
-        /**
-         * The length time to poll for varName when loading a script in
-         * Safari 2.x before the transaction fails.
-         * property TIMEOUT
-         * @static
-         * @type int
-         * @default 2000
-         */
-        TIMEOUT: 2000,
-        
-        /**
-         * Called by the the helper for detecting script load in Safari
-         * @method _finalize
-         * @param id {string} the transaction id
-         * @private
-         */
-        _finalize: function(id) {
-            YAHOO.log(id + " finalized ", "info", "Get");
-            lang.later(0, null, _finish, id);
-        },
-
-        /**
-         * Abort a transaction
-         * @method abort
-         * @param {string|object} either the tId or the object returned from
-         * script() or css()
-         */
-        abort: function(o) {
-            var id = (lang.isString(o)) ? o : o.tId;
-            var q = queues[id];
-            if (q) {
-                YAHOO.log("Aborting " + id, "info", "Get");
-                q.aborted = true;
-            }
-        }, 
-
-        /**
-         * Fetches and inserts one or more script nodes into the head
-         * of the current document or the document in a specified window.
-         *
-         * @method script
-         * @static
-         * @param url {string|string[]} the url or urls to the script(s)
-         * @param opts {object} Options: 
-         * <dl>
-         * <dt>onSuccess</dt>
-         * <dd>
-         * callback to execute when the script(s) are finished loading
-         * The callback receives an object back with the following
-         * data:
-         * <dl>
-         * <dt>win</dt>
-         * <dd>the window the script(s) were inserted into</dd>
-         * <dt>data</dt>
-         * <dd>the data object passed in when the request was made</dd>
-         * <dt>nodes</dt>
-         * <dd>An array containing references to the nodes that were
-         * inserted</dd>
-         * <dt>purge</dt>
-         * <dd>A function that, when executed, will remove the nodes
-         * that were inserted</dd>
-         * <dt>
-         * </dl>
-         * </dd>
-         * <dt>onFailure</dt>
-         * <dd>
-         * callback to execute when the script load operation fails
-         * The callback receives an object back with the following
-         * data:
-         * <dl>
-         * <dt>win</dt>
-         * <dd>the window the script(s) were inserted into</dd>
-         * <dt>data</dt>
-         * <dd>the data object passed in when the request was made</dd>
-         * <dt>nodes</dt>
-         * <dd>An array containing references to the nodes that were
-         * inserted successfully</dd>
-         * <dt>purge</dt>
-         * <dd>A function that, when executed, will remove any nodes
-         * that were inserted</dd>
-         * <dt>
-         * </dl>
-         * </dd>
-         * <dt>scope</dt>
-         * <dd>the execution context for the callbacks</dd>
-         * <dt>win</dt>
-         * <dd>a window other than the one the utility occupies</dd>
-         * <dt>autopurge</dt>
-         * <dd>
-         * setting to true will let the utilities cleanup routine purge 
-         * the script once loaded
-         * </dd>
-         * <dt>data</dt>
-         * <dd>
-         * data that is supplied to the callback when the script(s) are
-         * loaded.
-         * </dd>
-         * <dt>varName</dt>
-         * <dd>
-         * variable that should be available when a script is finished
-         * loading.  Used to help Safari 2.x and below with script load 
-         * detection.  The type of this property should match what was
-         * passed into the url parameter: if loading a single url, a
-         * string can be supplied.  If loading multiple scripts, you
-         * must supply an array that contains the variable name for
-         * each script.
-         * </dd>
-         * </dl>
-         * <pre>
-         * // assumes yahoo, dom, and event are already on the page
-         *   YAHOO.util.Get.script(
-         *   ["http://yui.yahooapis.com/2.3.1/build/dragdrop/dragdrop-min.js",
-         *    "http://yui.yahooapis.com/2.3.1/build/animation/animation-min.js"], {
-         *     onSuccess: function(o) {
-         *       YAHOO.log(o.data); // foo
-         *       new YAHOO.util.DDProxy("dd1"); // also new o.reference("dd1"); would work
-         *       this.log("won't cause error because YAHOO is the scope");
-         *       this.log(o.nodes.length === 2) // true
-         *       // o.purge(); // optionally remove the script nodes immediately
-         *     },
-         *     onFailure: function(o) {
-         *       YAHOO.log("transaction failed");
-         *     },
-         *     data: "foo",
-         *     scope: YAHOO,
-         *     // win: otherframe // target another window/frame
-         *     autopurge: true // allow the utility to choose when to remove the nodes
-         *   });
-         * </pre>
-         * @return {tId: string} an object containing info about the transaction
-         */
-        script: function(url, opts) { return _queue("script", url, opts); },
-
-        /**
-         * Fetches and inserts one or more css link nodes into the 
-         * head of the current document or the document in a specified
-         * window.
-         * @method css
-         * @static
-         * @param url {string} the url or urls to the css file(s)
-         * @param opts Options: 
-         * <dl>
-         * <dt>onSuccess</dt>
-         * <dd>
-         * callback to execute when the css file(s) are finished loading
-         * The callback receives an object back with the following
-         * data:
-         * <dl>win</dl>
-         * <dd>the window the link nodes(s) were inserted into</dd>
-         * <dt>data</dt>
-         * <dd>the data object passed in when the request was made</dd>
-         * <dt>nodes</dt>
-         * <dd>An array containing references to the nodes that were
-         * inserted</dd>
-         * <dt>purge</dt>
-         * <dd>A function that, when executed, will remove the nodes
-         * that were inserted</dd>
-         * <dt>
-         * </dl>
-         * </dd>
-         * <dt>scope</dt>
-         * <dd>the execution context for the callbacks</dd>
-         * <dt>win</dt>
-         * <dd>a window other than the one the utility occupies</dd>
-         * <dt>data</dt>
-         * <dd>
-         * data that is supplied to the callbacks when the nodes(s) are
-         * loaded.
-         * </dd>
-         * </dl>
-         * <pre>
-         *      YAHOO.util.Get.css("http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css");
-         * </pre>
-         * <pre>
-         *      YAHOO.util.Get.css(["http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css",
-         *                          "http://yui.yahooapis.com/2.3.1/build/logger/assets/skins/sam/logger.css"]);
-         * </pre>
-         * @return {tId: string} an object containing info about the transaction
-         */
-        css: function(url, opts) {
-            return _queue("css", url, opts); 
-        }
-    };
-}();
-
-YAHOO.register("get", YAHOO.util.Get, {version: "2.4.1", build: "742"});

Deleted: trunk/root/static/yui/get/get-beta-min.js
===================================================================
--- trunk/root/static/yui/get/get-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/get/get-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-YAHOO.util.Get=function(){var I={},H=0,B=0,O=false,A=YAHOO.env.ua,D=YAHOO.lang;var Q=function(U,R,V){var S=V||window,W=S.document,X=W.createElement(U);for(var T in R){if(R[T]&&YAHOO.lang.hasOwnProperty(R,T)){X.setAttribute(T,R[T]);}}return X;};var N=function(R,S){return Q("link",{"id":"yui__dyn_"+(B++),"type":"text/css","rel":"stylesheet","href":R},S);};var M=function(R,S){return Q("script",{"id":"yui__dyn_"+(B++),"type":"text/javascript","src":R},S);};var K=function(R){return{tId:R.tId,win:R.win,data:R.data,nodes:R.nodes,purge:function(){J(this.tId);}};};var P=function(T){var R=I[T];if(R.onFailure){var S=R.scope||R.win;R.onFailure.call(S,K(R));}};var F=function(T){var R=I[T];R.finished=true;if(R.aborted){P(T);return ;}if(R.onSuccess){var S=R.scope||R.win;R.onSuccess.call(S,K(R));}};var E=function(T,W){var S=I[T];if(S.aborted){P(T);return ;}if(W){S.url.shift();if(S.varName){S.varName.shift();}}else{S.url=(D.isString(S.url))?[S.url]:S.url;if(S.varName){S.varName=(D.isString(!
 S.varName))?[S.varName]:S.varName;}}var Z=S.win,Y=Z.document,X=Y.getElementsByTagName("head")[0],U;if(S.url.length===0){if(S.type==="script"&&A.webkit&&A.webkit<420&&!S.finalpass&&!S.varName){var V=M(null,S.win);V.innerHTML="YAHOO.util.Get._finalize(\""+T+"\");";S.nodes.push(V);X.appendChild(V);}else{F(T);}return ;}var R=S.url[0];if(S.type==="script"){U=M(R,Z);}else{U=N(R,Z);}G(S.type,U,T,R,Z,S.url.length);S.nodes.push(U);X.appendChild(U);if((A.webkit||A.gecko)&&S.type==="css"){E(T,R);}};var C=function(){if(O){return ;}O=true;for(var R in I){var S=I[R];if(S.autopurge&&S.finished){J(S.tId);}}O=false;};var J=function(X){var U=I[X];if(U){var W=U.nodes,R=W.length,V=U.win.document,T=V.getElementsByTagName("head")[0];for(var S=0;S<R;S=S+1){T.removeChild(W[S]);}}};var L=function(S,R,T){var V="q"+(H++);T=T||{};if(H%YAHOO.util.Get.PURGE_THRESH===0){C();}I[V]=D.merge(T,{tId:V,type:S,url:R,finished:false,nodes:[]});var U=I[V];U.win=U.win||window;U.scope=U.scope||U.win;U.autopurge=("au!
 topurge" in U)?U.autopurge:(S==="script")?true:false;D.later(0!
 ,U,E,V);
return{tId:V};};var G=function(a,V,U,S,W,X,Z){var Y=Z||E;if(A.ie){V.onreadystatechange=function(){var b=this.readyState;if("loaded"===b||"complete"===b){Y(U,S);}};}else{if(A.webkit){if(a==="script"){if(A.webkit>419){V.addEventListener("load",function(){Y(U,S);});}else{var R=I[U];if(R.varName){var T=YAHOO.util.Get.POLL_FREQ;R.maxattempts=YAHOO.util.Get.TIMEOUT/T;R.attempts=0;R._cache=R.varName[0].split(".");R.timer=D.later(T,R,function(f){var d=this._cache,c=d.length,b=this.win,e;for(e=0;e<c;e=e+1){b=b[d[e]];if(!b){this.attempts++;if(this.attempts++>this.maxattempts){R.timer.cancel();P(U);}else{}return ;}}R.timer.cancel();Y(U,S);},null,true);}else{D.later(YAHOO.util.Get.POLL_FREQ,null,Y,[U,S]);}}}}else{V.onload=function(){Y(U,S);};}}};return{POLL_FREQ:10,PURGE_THRESH:20,TIMEOUT:2000,_finalize:function(R){D.later(0,null,F,R);},abort:function(S){var T=(D.isString(S))?S:S.tId;var R=I[T];if(R){R.aborted=true;}},script:function(R,S){return L("script",R,S);},css:function(R,S){retur!
 n L("css",R,S);}};}();YAHOO.register("get",YAHOO.util.Get,{version:"2.4.1",build:"742"});
\ No newline at end of file

Deleted: trunk/root/static/yui/get/get-beta.js
===================================================================
--- trunk/root/static/yui/get/get-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/get/get-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,625 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-/**
- * Provides a mechanism to fetch remote resources and
- * insert them into a document
- * @module get
- * @requires yahoo
- */
-
-/**
- * Fetches and inserts one or more script or link nodes into the document 
- * @namespace YAHOO.util
- * @class YAHOO.util.Get
- */
-YAHOO.util.Get = function() {
-
-    /**
-     * hash of queues to manage multiple requests
-     * @property queues
-     * @private
-     */
-    var queues={}, 
-        
-    /**
-     * queue index used to generate transaction ids
-     * @property qidx
-     * @type int
-     * @private
-     */
-        qidx=0, 
-        
-    /**
-     * node index used to generate unique node ids
-     * @property nidx
-     * @type int
-     * @private
-     */
-        nidx=0, 
-
-        // ridx=0,
-
-        // sandboxFrame=null,
-
-    /**
-     * interal property used to prevent multiple simultaneous purge 
-     * processes
-     * @property purging
-     * @type boolean
-     * @private
-     */
-        purging=false,
-
-        ua=YAHOO.env.ua, 
-        
-        lang=YAHOO.lang;
-    
-    /** 
-     * Generates an HTML element, this is not appended to a document
-     * @method _node
-     * @param type {string} the type of element
-     * @param attr {string} the attributes
-     * @param win {Window} optional window to create the element in
-     * @return {HTMLElement} the generated node
-     * @private
-     */
-    var _node = function(type, attr, win) {
-        var w = win || window, d=w.document, n=d.createElement(type);
-
-        for (var i in attr) {
-            if (attr[i] && YAHOO.lang.hasOwnProperty(attr, i)) {
-                n.setAttribute(i, attr[i]);
-            }
-        }
-
-        return n;
-    };
-
-    /**
-     * Generates a link node
-     * @method _linkNode
-     * @param url {string} the url for the css file
-     * @param win {Window} optional window to create the node in
-     * @return {HTMLElement} the generated node
-     * @private
-     */
-    var _linkNode = function(url, win) {
-        return _node("link", {
-                "id": "yui__dyn_" + (nidx++),
-                "type": "text/css",
-                "rel": "stylesheet",
-                "href": url
-            }, win);
-    };
-
-    /**
-     * Generates a script node
-     * @method _scriptNode
-     * @param url {string} the url for the script file
-     * @param win {Window} optional window to create the node in
-     * @return {HTMLElement} the generated node
-     * @private
-     */
-    var _scriptNode = function(url, win) {
-        return _node("script", {
-                "id": "yui__dyn_" + (nidx++),
-                "type": "text/javascript",
-                "src": url
-            }, win);
-    };
-
-    /**
-     * Returns the data payload for callback functions
-     * @method _returnData
-     * @private
-     */
-    var _returnData = function(q) {
-        return {
-                tId: q.tId,
-                win: q.win,
-                data: q.data,
-                nodes: q.nodes,
-                purge: function() {
-                    _purge(this.tId);
-                }
-            };
-    };
-
-    /*
-     * The request failed, execute fail handler with whatever
-     * was accomplished.  There isn't a failure case at the
-     * moment unless you count aborted transactions
-     * @method _fail
-     * @param id {string} the id of the request
-     * @private
-     */
-    var _fail = function(id) {
-        var q = queues[id];
-        // execute failure callback
-        if (q.onFailure) {
-            var sc=q.scope || q.win;
-            q.onFailure.call(sc, _returnData(q));
-        }
-    };
-
-    /**
-     * The request is complete, so executing the requester's callback
-     * @method _finish
-     * @param id {string} the id of the request
-     * @private
-     */
-    var _finish = function(id) {
-        var q = queues[id];
-        q.finished = true;
-
-        if (q.aborted) {
-            _fail(id);
-            return;
-        }
-
-        // execute success callback
-        if (q.onSuccess) {
-            var sc=q.scope || q.win;
-            q.onSuccess.call(sc, _returnData(q));
-        }
-    };
-
-    /**
-     * Loads the next item for a given request
-     * @method _next
-     * @param id {string} the id of the request
-     * @param loaded {string} the url that was just loaded, if any
-     * @private
-     */
-    var _next = function(id, loaded) {
-        var q = queues[id];
-
-        if (q.aborted) {
-            _fail(id);
-            return;
-        }
-
-        if (loaded) {
-            q.url.shift(); 
-            if (q.varName) {
-                q.varName.shift(); 
-            }
-        } else {
-            // This is the first pass: make sure the url is an array
-            q.url = (lang.isString(q.url)) ? [q.url] : q.url;
-            if (q.varName) {
-                q.varName = (lang.isString(q.varName)) ? [q.varName] : q.varName;
-            }
-        }
-
-        var w=q.win, d=w.document, h=d.getElementsByTagName("head")[0], n;
-
-        if (q.url.length === 0) {
-            // Safari 2.x workaround - There is no way to know when 
-            // a script is ready in versions of Safari prior to 3.x.
-            // Adding an extra node reduces the problem, but doesn't
-            // eliminate it completely because the browser executes
-            // them asynchronously. 
-            if (q.type === "script" && ua.webkit && ua.webkit < 420 && 
-                    !q.finalpass && !q.varName) {
-                // Add another script node.  This does not guarantee that the
-                // scripts will execute in order, but it does appear to fix the
-                // problem on fast connections more effectively than using an
-                // arbitrary timeout.  It is possible that the browser does
-                // block subsequent script execution in this case for a limited
-                // time.
-                var extra = _scriptNode(null, q.win);
-                extra.innerHTML='YAHOO.util.Get._finalize("' + id + '");';
-                q.nodes.push(extra); h.appendChild(extra);
-
-            } else {
-                _finish(id);
-            }
-
-            return;
-        } 
-
-
-        var url = q.url[0];
-
-        if (q.type === "script") {
-            n = _scriptNode(url, w);
-        } else {
-            n = _linkNode(url, w);
-        }
-
-        // track this node's load progress
-        _track(q.type, n, id, url, w, q.url.length);
-
-        // add the node to the queue so we can return it to the user supplied callback
-        q.nodes.push(n);
-
-        // add it to the head
-        h.appendChild(n);
-        
-
-        // FireFox does not support the onload event for link nodes, so there is
-        // no way to make the css requests synchronous. This means that the css 
-        // rules in multiple files could be applied out of order in this browser
-        // if a later request returns before an earlier one.  Safari too.
-        if ((ua.webkit || ua.gecko) && q.type === "css") {
-            _next(id, url);
-        }
-    };
-
-    /**
-     * Removes processed queues and corresponding nodes
-     * @method _autoPurge
-     * @private
-     */
-    var _autoPurge = function() {
-
-        if (purging) {
-            return;
-        }
-
-        purging = true;
-        for (var i in queues) {
-            var q = queues[i];
-            if (q.autopurge && q.finished) {
-                _purge(q.tId);
-            }
-        }
-
-        purging = false;
-    };
-
-    /**
-     * Removes the nodes for the specified queue
-     * @method _purge
-     * @private
-     */
-    var _purge = function(tId) {
-        var q=queues[tId];
-        if (q) {
-            var n=q.nodes, l=n.length, d=q.win.document, 
-                h=d.getElementsByTagName("head")[0];
-            for (var i=0; i<l; i=i+1) {
-                h.removeChild(n[i]);
-            }
-        }
-    };
-
-    /**
-     * Saves the state for the request and begins loading
-     * the requested urls
-     * @method queue
-     * @param type {string} the type of node to insert
-     * @param url {string} the url to load
-     * @param opts the hash of options for this request
-     * @private
-     */
-    var _queue = function(type, url, opts) {
-
-        var id = "q" + (qidx++);
-        opts = opts || {};
-
-        if (qidx % YAHOO.util.Get.PURGE_THRESH === 0) {
-            _autoPurge();
-        }
-
-        queues[id] = lang.merge(opts, {
-            tId: id,
-            type: type,
-            url: url,
-            finished: false,
-            nodes: []
-        });
-
-        var q = queues[id];
-        q.win = q.win || window;
-        q.scope = q.scope || q.win;
-        q.autopurge = ("autopurge" in q) ? q.autopurge : 
-                      (type === "script") ? true : false;
-
-        lang.later(0, q, _next, id);
-
-        return {
-            tId: id
-        };
-    };
-
-    /**
-     * Detects when a node has been loaded.  In the case of
-     * script nodes, this does not guarantee that contained
-     * script is ready to use.
-     * @method _track
-     * @param type {string} the type of node to track
-     * @param n {HTMLElement} the node to track
-     * @param id {string} the id of the request
-     * @param url {string} the url that is being loaded
-     * @param win {Window} the targeted window
-     * @param qlength the number of remaining items in the queue,
-     * including this one
-     * @param trackfn {Function} function to execute when finished
-     * the default is _next
-     * @private
-     */
-    var _track = function(type, n, id, url, win, qlength, trackfn) {
-        var f = trackfn || _next;
-
-        // IE supports the readystatechange event for script and css nodes
-        if (ua.ie) {
-            n.onreadystatechange = function() {
-                var rs = this.readyState;
-                if ("loaded" === rs || "complete" === rs) {
-                    f(id, url);
-                }
-            };
-
-        // webkit prior to 3.x is problemmatic
-        } else if (ua.webkit) {
-
-            if (type === "script") {
-
-                // Safari 3.x supports the load event for script nodes (DOM2)
-                if (ua.webkit > 419) {
-
-                    n.addEventListener("load", function() {
-                        f(id, url);
-                    });
-
-                // Nothing can be done with Safari < 3.x except to pause and hope
-                // for the best, particularly after last script is inserted. The
-                // scripts will always execute in the order they arrive, not
-                // necessarily the order in which they were inserted.  To support
-                // script nodes with complete reliability in these browsers, script
-                // nodes either need to invoke a function in the window once they
-                // are loaded or the implementer needs to provide a well-known
-                // property that the utility can poll for.
-                } else {
-                    // Poll for the existence of the named variable, if it
-                    // was supplied.
-                    var q = queues[id];
-                    if (q.varName) {
-                        var freq=YAHOO.util.Get.POLL_FREQ;
-                        q.maxattempts = YAHOO.util.Get.TIMEOUT/freq;
-                        q.attempts = 0;
-                        q._cache = q.varName[0].split(".");
-                        q.timer = lang.later(freq, q, function(o) {
-                            var a=this._cache, l=a.length, w=this.win, i;
-                            for (i=0; i<l; i=i+1) {
-                                w = w[a[i]];
-                                if (!w) {
-                                    // if we have exausted our attempts, give up
-                                    this.attempts++;
-                                    if (this.attempts++ > this.maxattempts) {
-                                        q.timer.cancel();
-                                        _fail(id);
-                                    } else {
-                                    }
-                                    return;
-                                }
-                            }
-                            
-
-                            q.timer.cancel();
-                            f(id, url);
-
-                        }, null, true);
-                    } else {
-                        lang.later(YAHOO.util.Get.POLL_FREQ, null, f, [id, url]);
-                    }
-                }
-            } 
-
-        // FireFox and Opera support onload (but not DOM2 in FF) handlers for
-        // script nodes.  Opera, but not FF, supports the onload event for link
-        // nodes.
-        } else { 
-            n.onload = function() {
-                f(id, url);
-            };
-        }
-    };
-
-    return {
-
-        /**
-         * The default poll freqency in ms, when needed
-         * @property POLL_FREQ
-         * @static
-         * @type int
-         * @default 10
-         */
-        POLL_FREQ: 10,
-
-        /**
-         * The number of request required before an automatic purge.
-         * property PURGE_THRESH
-         * @static
-         * @type int
-         * @default 20
-         */
-        PURGE_THRESH: 20,
-
-        /**
-         * The length time to poll for varName when loading a script in
-         * Safari 2.x before the transaction fails.
-         * property TIMEOUT
-         * @static
-         * @type int
-         * @default 2000
-         */
-        TIMEOUT: 2000,
-        
-        /**
-         * Called by the the helper for detecting script load in Safari
-         * @method _finalize
-         * @param id {string} the transaction id
-         * @private
-         */
-        _finalize: function(id) {
-            lang.later(0, null, _finish, id);
-        },
-
-        /**
-         * Abort a transaction
-         * @method abort
-         * @param {string|object} either the tId or the object returned from
-         * script() or css()
-         */
-        abort: function(o) {
-            var id = (lang.isString(o)) ? o : o.tId;
-            var q = queues[id];
-            if (q) {
-                q.aborted = true;
-            }
-        }, 
-
-        /**
-         * Fetches and inserts one or more script nodes into the head
-         * of the current document or the document in a specified window.
-         *
-         * @method script
-         * @static
-         * @param url {string|string[]} the url or urls to the script(s)
-         * @param opts {object} Options: 
-         * <dl>
-         * <dt>onSuccess</dt>
-         * <dd>
-         * callback to execute when the script(s) are finished loading
-         * The callback receives an object back with the following
-         * data:
-         * <dl>
-         * <dt>win</dt>
-         * <dd>the window the script(s) were inserted into</dd>
-         * <dt>data</dt>
-         * <dd>the data object passed in when the request was made</dd>
-         * <dt>nodes</dt>
-         * <dd>An array containing references to the nodes that were
-         * inserted</dd>
-         * <dt>purge</dt>
-         * <dd>A function that, when executed, will remove the nodes
-         * that were inserted</dd>
-         * <dt>
-         * </dl>
-         * </dd>
-         * <dt>onFailure</dt>
-         * <dd>
-         * callback to execute when the script load operation fails
-         * The callback receives an object back with the following
-         * data:
-         * <dl>
-         * <dt>win</dt>
-         * <dd>the window the script(s) were inserted into</dd>
-         * <dt>data</dt>
-         * <dd>the data object passed in when the request was made</dd>
-         * <dt>nodes</dt>
-         * <dd>An array containing references to the nodes that were
-         * inserted successfully</dd>
-         * <dt>purge</dt>
-         * <dd>A function that, when executed, will remove any nodes
-         * that were inserted</dd>
-         * <dt>
-         * </dl>
-         * </dd>
-         * <dt>scope</dt>
-         * <dd>the execution context for the callbacks</dd>
-         * <dt>win</dt>
-         * <dd>a window other than the one the utility occupies</dd>
-         * <dt>autopurge</dt>
-         * <dd>
-         * setting to true will let the utilities cleanup routine purge 
-         * the script once loaded
-         * </dd>
-         * <dt>data</dt>
-         * <dd>
-         * data that is supplied to the callback when the script(s) are
-         * loaded.
-         * </dd>
-         * <dt>varName</dt>
-         * <dd>
-         * variable that should be available when a script is finished
-         * loading.  Used to help Safari 2.x and below with script load 
-         * detection.  The type of this property should match what was
-         * passed into the url parameter: if loading a single url, a
-         * string can be supplied.  If loading multiple scripts, you
-         * must supply an array that contains the variable name for
-         * each script.
-         * </dd>
-         * </dl>
-         * <pre>
-         * // assumes yahoo, dom, and event are already on the page
-         *   YAHOO.util.Get.script(
-         *   ["http://yui.yahooapis.com/2.3.1/build/dragdrop/dragdrop-min.js",
-         *    "http://yui.yahooapis.com/2.3.1/build/animation/animation-min.js"], {
-         *     onSuccess: function(o) {
-         *       new YAHOO.util.DDProxy("dd1"); // also new o.reference("dd1"); would work
-         *       this.log("won't cause error because YAHOO is the scope");
-         *       this.log(o.nodes.length === 2) // true
-         *       // o.purge(); // optionally remove the script nodes immediately
-         *     },
-         *     onFailure: function(o) {
-         *     },
-         *     data: "foo",
-         *     scope: YAHOO,
-         *     // win: otherframe // target another window/frame
-         *     autopurge: true // allow the utility to choose when to remove the nodes
-         *   });
-         * </pre>
-         * @return {tId: string} an object containing info about the transaction
-         */
-        script: function(url, opts) { return _queue("script", url, opts); },
-
-        /**
-         * Fetches and inserts one or more css link nodes into the 
-         * head of the current document or the document in a specified
-         * window.
-         * @method css
-         * @static
-         * @param url {string} the url or urls to the css file(s)
-         * @param opts Options: 
-         * <dl>
-         * <dt>onSuccess</dt>
-         * <dd>
-         * callback to execute when the css file(s) are finished loading
-         * The callback receives an object back with the following
-         * data:
-         * <dl>win</dl>
-         * <dd>the window the link nodes(s) were inserted into</dd>
-         * <dt>data</dt>
-         * <dd>the data object passed in when the request was made</dd>
-         * <dt>nodes</dt>
-         * <dd>An array containing references to the nodes that were
-         * inserted</dd>
-         * <dt>purge</dt>
-         * <dd>A function that, when executed, will remove the nodes
-         * that were inserted</dd>
-         * <dt>
-         * </dl>
-         * </dd>
-         * <dt>scope</dt>
-         * <dd>the execution context for the callbacks</dd>
-         * <dt>win</dt>
-         * <dd>a window other than the one the utility occupies</dd>
-         * <dt>data</dt>
-         * <dd>
-         * data that is supplied to the callbacks when the nodes(s) are
-         * loaded.
-         * </dd>
-         * </dl>
-         * <pre>
-         *      YAHOO.util.Get.css("http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css");
-         * </pre>
-         * <pre>
-         *      YAHOO.util.Get.css(["http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css",
-         * </pre>
-         * @return {tId: string} an object containing info about the transaction
-         */
-        css: function(url, opts) {
-            return _queue("css", url, opts); 
-        }
-    };
-}();
-
-YAHOO.register("get", YAHOO.util.Get, {version: "2.4.1", build: "742"});

Added: trunk/root/static/yui/get/get-debug.js
===================================================================
--- trunk/root/static/yui/get/get-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/get/get-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,684 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * Provides a mechanism to fetch remote resources and
+ * insert them into a document
+ * @module get
+ * @requires yahoo
+ */
+
+/**
+ * Fetches and inserts one or more script or link nodes into the document 
+ * @namespace YAHOO.util
+ * @class YAHOO.util.Get
+ */
+YAHOO.util.Get = function() {
+
+    /**
+     * hash of queues to manage multiple requests
+     * @property queues
+     * @private
+     */
+    var queues={}, 
+        
+    /**
+     * queue index used to generate transaction ids
+     * @property qidx
+     * @type int
+     * @private
+     */
+        qidx=0, 
+        
+    /**
+     * node index used to generate unique node ids
+     * @property nidx
+     * @type int
+     * @private
+     */
+        nidx=0, 
+
+        // ridx=0,
+
+        // sandboxFrame=null,
+
+    /**
+     * interal property used to prevent multiple simultaneous purge 
+     * processes
+     * @property purging
+     * @type boolean
+     * @private
+     */
+        purging=false,
+
+        ua=YAHOO.env.ua, 
+        
+        lang=YAHOO.lang;
+    
+    /** 
+     * Generates an HTML element, this is not appended to a document
+     * @method _node
+     * @param type {string} the type of element
+     * @param attr {string} the attributes
+     * @param win {Window} optional window to create the element in
+     * @return {HTMLElement} the generated node
+     * @private
+     */
+    var _node = function(type, attr, win) {
+        var w = win || window, d=w.document, n=d.createElement(type);
+
+        for (var i in attr) {
+            if (attr[i] && YAHOO.lang.hasOwnProperty(attr, i)) {
+                n.setAttribute(i, attr[i]);
+            }
+        }
+
+        return n;
+    };
+
+    /**
+     * Generates a link node
+     * @method _linkNode
+     * @param url {string} the url for the css file
+     * @param win {Window} optional window to create the node in
+     * @return {HTMLElement} the generated node
+     * @private
+     */
+    var _linkNode = function(url, win, charset) {
+        var c = charset || "utf-8";
+        return _node("link", {
+                "id":      "yui__dyn_" + (nidx++),
+                "type":    "text/css",
+                "charset": c,
+                "rel":     "stylesheet",
+                "href":    url
+            }, win);
+    };
+
+    /**
+     * Generates a script node
+     * @method _scriptNode
+     * @param url {string} the url for the script file
+     * @param win {Window} optional window to create the node in
+     * @return {HTMLElement} the generated node
+     * @private
+     */
+    var _scriptNode = function(url, win, charset) {
+        var c = charset || "utf-8";
+        return _node("script", {
+                "id":      "yui__dyn_" + (nidx++),
+                "type":    "text/javascript",
+                "charset": c,
+                "src":     url
+            }, win);
+    };
+
+    /**
+     * Returns the data payload for callback functions
+     * @method _returnData
+     * @private
+     */
+    var _returnData = function(q, msg) {
+        return {
+                tId: q.tId,
+                win: q.win,
+                data: q.data,
+                nodes: q.nodes,
+                msg: msg,
+                purge: function() {
+                    _purge(this.tId);
+                }
+            };
+    };
+
+    var _get = function(nId, tId) {
+        var q = queues[tId],
+            n = (lang.isString(nId)) ? q.win.document.getElementById(nId) : nId;
+        if (!n) {
+            _fail(tId, "target node not found: " + nId);
+        }
+
+        return n;
+    };
+
+    /*
+     * The request failed, execute fail handler with whatever
+     * was accomplished.  There isn't a failure case at the
+     * moment unless you count aborted transactions
+     * @method _fail
+     * @param id {string} the id of the request
+     * @private
+     */
+    var _fail = function(id, msg) {
+        YAHOO.log("get failure: " + msg, "warn", "Get");
+        var q = queues[id];
+        // execute failure callback
+        if (q.onFailure) {
+            var sc=q.scope || q.win;
+            q.onFailure.call(sc, _returnData(q, msg));
+        }
+    };
+
+    /**
+     * The request is complete, so executing the requester's callback
+     * @method _finish
+     * @param id {string} the id of the request
+     * @private
+     */
+    var _finish = function(id) {
+        YAHOO.log("Finishing transaction " + id);
+        var q = queues[id];
+        q.finished = true;
+
+        if (q.aborted) {
+            var msg = "transaction " + id + " was aborted";
+            _fail(id, msg);
+            return;
+        }
+
+        // execute success callback
+        if (q.onSuccess) {
+            var sc=q.scope || q.win;
+            q.onSuccess.call(sc, _returnData(q));
+        }
+    };
+
+    /**
+     * Loads the next item for a given request
+     * @method _next
+     * @param id {string} the id of the request
+     * @param loaded {string} the url that was just loaded, if any
+     * @private
+     */
+    var _next = function(id, loaded) {
+        YAHOO.log("_next: " + id + ", loaded: " + loaded, "info", "Get");
+        var q = queues[id];
+
+        if (q.aborted) {
+            var msg = "transaction " + id + " was aborted";
+            _fail(id, msg);
+            return;
+        }
+
+        if (loaded) {
+            q.url.shift(); 
+            if (q.varName) {
+                q.varName.shift(); 
+            }
+        } else {
+            // This is the first pass: make sure the url is an array
+            q.url = (lang.isString(q.url)) ? [q.url] : q.url;
+            if (q.varName) {
+                q.varName = (lang.isString(q.varName)) ? [q.varName] : q.varName;
+            }
+        }
+
+        var w=q.win, d=w.document, h=d.getElementsByTagName("head")[0], n;
+
+        if (q.url.length === 0) {
+            // Safari 2.x workaround - There is no way to know when 
+            // a script is ready in versions of Safari prior to 3.x.
+            // Adding an extra node reduces the problem, but doesn't
+            // eliminate it completely because the browser executes
+            // them asynchronously. 
+            if (q.type === "script" && ua.webkit && ua.webkit < 420 && 
+                    !q.finalpass && !q.varName) {
+                // Add another script node.  This does not guarantee that the
+                // scripts will execute in order, but it does appear to fix the
+                // problem on fast connections more effectively than using an
+                // arbitrary timeout.  It is possible that the browser does
+                // block subsequent script execution in this case for a limited
+                // time.
+                var extra = _scriptNode(null, q.win, q.charset);
+                extra.innerHTML='YAHOO.util.Get._finalize("' + id + '");';
+                q.nodes.push(extra); h.appendChild(extra);
+
+            } else {
+                _finish(id);
+            }
+
+            return;
+        } 
+
+
+        var url = q.url[0];
+        YAHOO.log("attempting to load " + url, "info", "Get");
+
+        if (q.type === "script") {
+            n = _scriptNode(url, w, q.charset);
+        } else {
+            n = _linkNode(url, w, q.charset);
+        }
+
+        // track this node's load progress
+        _track(q.type, n, id, url, w, q.url.length);
+
+        // add the node to the queue so we can return it to the user supplied callback
+        q.nodes.push(n);
+
+        // add it to the head or insert it before 'insertBefore'
+        if (q.insertBefore) {
+            var s = _get(q.insertBefore, id);
+            if (s) {
+                s.parentNode.insertBefore(n, s);
+            }
+        } else {
+            h.appendChild(n);
+        }
+        
+        YAHOO.log("Appending node: " + url, "info", "Get");
+
+        // FireFox does not support the onload event for link nodes, so there is
+        // no way to make the css requests synchronous. This means that the css 
+        // rules in multiple files could be applied out of order in this browser
+        // if a later request returns before an earlier one.  Safari too.
+        if ((ua.webkit || ua.gecko) && q.type === "css") {
+            _next(id, url);
+        }
+    };
+
+    /**
+     * Removes processed queues and corresponding nodes
+     * @method _autoPurge
+     * @private
+     */
+    var _autoPurge = function() {
+
+        if (purging) {
+            return;
+        }
+
+        purging = true;
+        for (var i in queues) {
+            var q = queues[i];
+            if (q.autopurge && q.finished) {
+                _purge(q.tId);
+                delete queues[i];
+            }
+        }
+
+        purging = false;
+    };
+
+    /**
+     * Removes the nodes for the specified queue
+     * @method _purge
+     * @private
+     */
+    var _purge = function(tId) {
+        var q=queues[tId];
+        if (q) {
+            var n=q.nodes, l=n.length, d=q.win.document, 
+                h=d.getElementsByTagName("head")[0];
+
+            if (q.insertBefore) {
+                var s = _get(q.insertBefore, tId);
+                if (s) {
+                    h = s.parentNode;
+                }
+            }
+
+            for (var i=0; i<l; i=i+1) {
+                h.removeChild(n[i]);
+            }
+        }
+        q.nodes = [];
+    };
+
+    /**
+     * Saves the state for the request and begins loading
+     * the requested urls
+     * @method queue
+     * @param type {string} the type of node to insert
+     * @param url {string} the url to load
+     * @param opts the hash of options for this request
+     * @private
+     */
+    var _queue = function(type, url, opts) {
+
+        var id = "q" + (qidx++);
+        opts = opts || {};
+
+        if (qidx % YAHOO.util.Get.PURGE_THRESH === 0) {
+            _autoPurge();
+        }
+
+        queues[id] = lang.merge(opts, {
+            tId: id,
+            type: type,
+            url: url,
+            finished: false,
+            nodes: []
+        });
+
+        var q = queues[id];
+        q.win = q.win || window;
+        q.scope = q.scope || q.win;
+        q.autopurge = ("autopurge" in q) ? q.autopurge : 
+                      (type === "script") ? true : false;
+
+        lang.later(0, q, _next, id);
+
+        return {
+            tId: id
+        };
+    };
+
+    /**
+     * Detects when a node has been loaded.  In the case of
+     * script nodes, this does not guarantee that contained
+     * script is ready to use.
+     * @method _track
+     * @param type {string} the type of node to track
+     * @param n {HTMLElement} the node to track
+     * @param id {string} the id of the request
+     * @param url {string} the url that is being loaded
+     * @param win {Window} the targeted window
+     * @param qlength the number of remaining items in the queue,
+     * including this one
+     * @param trackfn {Function} function to execute when finished
+     * the default is _next
+     * @private
+     */
+    var _track = function(type, n, id, url, win, qlength, trackfn) {
+        var f = trackfn || _next;
+
+        // IE supports the readystatechange event for script and css nodes
+        if (ua.ie) {
+            n.onreadystatechange = function() {
+                var rs = this.readyState;
+                if ("loaded" === rs || "complete" === rs) {
+                    YAHOO.log(id + " onload " + url, "info", "Get");
+                    f(id, url);
+                }
+            };
+
+        // webkit prior to 3.x is problemmatic
+        } else if (ua.webkit) {
+
+            if (type === "script") {
+
+                // Safari 3.x supports the load event for script nodes (DOM2)
+                if (ua.webkit >= 420) {
+
+                    n.addEventListener("load", function() {
+                        YAHOO.log(id + " DOM2 onload " + url, "info", "Get");
+                        f(id, url);
+                    });
+
+                // Nothing can be done with Safari < 3.x except to pause and hope
+                // for the best, particularly after last script is inserted. The
+                // scripts will always execute in the order they arrive, not
+                // necessarily the order in which they were inserted.  To support
+                // script nodes with complete reliability in these browsers, script
+                // nodes either need to invoke a function in the window once they
+                // are loaded or the implementer needs to provide a well-known
+                // property that the utility can poll for.
+                } else {
+                    // Poll for the existence of the named variable, if it
+                    // was supplied.
+                    var q = queues[id];
+                    if (q.varName) {
+                        var freq=YAHOO.util.Get.POLL_FREQ;
+                        YAHOO.log("Polling for " + q.varName[0]);
+                        q.maxattempts = YAHOO.util.Get.TIMEOUT/freq;
+                        q.attempts = 0;
+                        q._cache = q.varName[0].split(".");
+                        q.timer = lang.later(freq, q, function(o) {
+                            var a=this._cache, l=a.length, w=this.win, i;
+                            for (i=0; i<l; i=i+1) {
+                                w = w[a[i]];
+                                if (!w) {
+                                    // if we have exausted our attempts, give up
+                                    this.attempts++;
+                                    if (this.attempts++ > this.maxattempts) {
+                                        var msg = "Over retry limit, giving up";
+                                        q.timer.cancel();
+                                        _fail(id, msg);
+                                    } else {
+                                        YAHOO.log(a[i] + " failed, retrying");
+                                    }
+                                    return;
+                                }
+                            }
+                            
+                            YAHOO.log("Safari poll complete");
+
+                            q.timer.cancel();
+                            f(id, url);
+
+                        }, null, true);
+                    } else {
+                        lang.later(YAHOO.util.Get.POLL_FREQ, null, f, [id, url]);
+                    }
+                }
+            } 
+
+        // FireFox and Opera support onload (but not DOM2 in FF) handlers for
+        // script nodes.  Opera, but not FF, supports the onload event for link
+        // nodes.
+        } else { 
+            n.onload = function() {
+                YAHOO.log(id + " onload " + url, "info", "Get");
+                f(id, url);
+            };
+        }
+    };
+
+    return {
+
+        /**
+         * The default poll freqency in ms, when needed
+         * @property POLL_FREQ
+         * @static
+         * @type int
+         * @default 10
+         */
+        POLL_FREQ: 10,
+
+        /**
+         * The number of request required before an automatic purge.
+         * property PURGE_THRESH
+         * @static
+         * @type int
+         * @default 20
+         */
+        PURGE_THRESH: 20,
+
+        /**
+         * The length time to poll for varName when loading a script in
+         * Safari 2.x before the transaction fails.
+         * property TIMEOUT
+         * @static
+         * @type int
+         * @default 2000
+         */
+        TIMEOUT: 2000,
+        
+        /**
+         * Called by the the helper for detecting script load in Safari
+         * @method _finalize
+         * @param id {string} the transaction id
+         * @private
+         */
+        _finalize: function(id) {
+            YAHOO.log(id + " finalized ", "info", "Get");
+            lang.later(0, null, _finish, id);
+        },
+
+        /**
+         * Abort a transaction
+         * @method abort
+         * @param {string|object} either the tId or the object returned from
+         * script() or css()
+         */
+        abort: function(o) {
+            var id = (lang.isString(o)) ? o : o.tId;
+            var q = queues[id];
+            if (q) {
+                YAHOO.log("Aborting " + id, "info", "Get");
+                q.aborted = true;
+            }
+        }, 
+
+        /**
+         * Fetches and inserts one or more script nodes into the head
+         * of the current document or the document in a specified window.
+         *
+         * @method script
+         * @static
+         * @param url {string|string[]} the url or urls to the script(s)
+         * @param opts {object} Options: 
+         * <dl>
+         * <dt>onSuccess</dt>
+         * <dd>
+         * callback to execute when the script(s) are finished loading
+         * The callback receives an object back with the following
+         * data:
+         * <dl>
+         * <dt>win</dt>
+         * <dd>the window the script(s) were inserted into</dd>
+         * <dt>data</dt>
+         * <dd>the data object passed in when the request was made</dd>
+         * <dt>nodes</dt>
+         * <dd>An array containing references to the nodes that were
+         * inserted</dd>
+         * <dt>purge</dt>
+         * <dd>A function that, when executed, will remove the nodes
+         * that were inserted</dd>
+         * <dt>
+         * </dl>
+         * </dd>
+         * <dt>onFailure</dt>
+         * <dd>
+         * callback to execute when the script load operation fails
+         * The callback receives an object back with the following
+         * data:
+         * <dl>
+         * <dt>win</dt>
+         * <dd>the window the script(s) were inserted into</dd>
+         * <dt>data</dt>
+         * <dd>the data object passed in when the request was made</dd>
+         * <dt>nodes</dt>
+         * <dd>An array containing references to the nodes that were
+         * inserted successfully</dd>
+         * <dt>purge</dt>
+         * <dd>A function that, when executed, will remove any nodes
+         * that were inserted</dd>
+         * <dt>
+         * </dl>
+         * </dd>
+         * <dt>scope</dt>
+         * <dd>the execution context for the callbacks</dd>
+         * <dt>win</dt>
+         * <dd>a window other than the one the utility occupies</dd>
+         * <dt>autopurge</dt>
+         * <dd>
+         * setting to true will let the utilities cleanup routine purge 
+         * the script once loaded
+         * </dd>
+         * <dt>data</dt>
+         * <dd>
+         * data that is supplied to the callback when the script(s) are
+         * loaded.
+         * </dd>
+         * <dt>varName</dt>
+         * <dd>
+         * variable that should be available when a script is finished
+         * loading.  Used to help Safari 2.x and below with script load 
+         * detection.  The type of this property should match what was
+         * passed into the url parameter: if loading a single url, a
+         * string can be supplied.  If loading multiple scripts, you
+         * must supply an array that contains the variable name for
+         * each script.
+         * </dd>
+         * <dt>insertBefore</dt>
+         * <dd>node or node id that will become the new node's nextSibling</dd>
+         * </dl>
+         * <dt>charset</dt>
+         * <dd>Node charset, default utf-8</dd>
+         * <pre>
+         * // assumes yahoo, dom, and event are already on the page
+         *   YAHOO.util.Get.script(
+         *   ["http://yui.yahooapis.com/2.3.1/build/dragdrop/dragdrop-min.js",
+         *    "http://yui.yahooapis.com/2.3.1/build/animation/animation-min.js"], {
+         *     onSuccess: function(o) {
+         *       YAHOO.log(o.data); // foo
+         *       new YAHOO.util.DDProxy("dd1"); // also new o.reference("dd1"); would work
+         *       this.log("won't cause error because YAHOO is the scope");
+         *       this.log(o.nodes.length === 2) // true
+         *       // o.purge(); // optionally remove the script nodes immediately
+         *     },
+         *     onFailure: function(o) {
+         *       YAHOO.log("transaction failed");
+         *     },
+         *     data: "foo",
+         *     scope: YAHOO,
+         *     // win: otherframe // target another window/frame
+         *     autopurge: true // allow the utility to choose when to remove the nodes
+         *   });
+         * </pre>
+         * @return {tId: string} an object containing info about the transaction
+         */
+        script: function(url, opts) { return _queue("script", url, opts); },
+
+        /**
+         * Fetches and inserts one or more css link nodes into the 
+         * head of the current document or the document in a specified
+         * window.
+         * @method css
+         * @static
+         * @param url {string} the url or urls to the css file(s)
+         * @param opts Options: 
+         * <dl>
+         * <dt>onSuccess</dt>
+         * <dd>
+         * callback to execute when the css file(s) are finished loading
+         * The callback receives an object back with the following
+         * data:
+         * <dl>win</dl>
+         * <dd>the window the link nodes(s) were inserted into</dd>
+         * <dt>data</dt>
+         * <dd>the data object passed in when the request was made</dd>
+         * <dt>nodes</dt>
+         * <dd>An array containing references to the nodes that were
+         * inserted</dd>
+         * <dt>purge</dt>
+         * <dd>A function that, when executed, will remove the nodes
+         * that were inserted</dd>
+         * <dt>
+         * </dl>
+         * </dd>
+         * <dt>scope</dt>
+         * <dd>the execution context for the callbacks</dd>
+         * <dt>win</dt>
+         * <dd>a window other than the one the utility occupies</dd>
+         * <dt>data</dt>
+         * <dd>
+         * data that is supplied to the callbacks when the nodes(s) are
+         * loaded.
+         * </dd>
+         * <dt>insertBefore</dt>
+         * <dd>node or node id that will become the new node's nextSibling</dd>
+         * <dt>charset</dt>
+         * <dd>Node charset, default utf-8</dd>
+         * </dl>
+         * <pre>
+         *      YAHOO.util.Get.css("http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css");
+         * </pre>
+         * <pre>
+         *      YAHOO.util.Get.css(["http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css",
+         *                          "http://yui.yahooapis.com/2.3.1/build/logger/assets/skins/sam/logger.css"]);
+         * </pre>
+         * @return {tId: string} an object containing info about the transaction
+         */
+        css: function(url, opts) {
+            return _queue("css", url, opts); 
+        }
+    };
+}();
+
+YAHOO.register("get", YAHOO.util.Get, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/get/get-min.js
===================================================================
--- trunk/root/static/yui/get/get-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/get/get-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+YAHOO.util.Get=function(){var M={},L=0,Q=0,E=false,N=YAHOO.env.ua,R=YAHOO.lang;var J=function(V,S,W){var T=W||window,X=T.document,Y=X.createElement(V);for(var U in S){if(S[U]&&YAHOO.lang.hasOwnProperty(S,U)){Y.setAttribute(U,S[U]);}}return Y;};var H=function(S,T,V){var U=V||"utf-8";return J("link",{"id":"yui__dyn_"+(Q++),"type":"text/css","charset":U,"rel":"stylesheet","href":S},T);};var O=function(S,T,V){var U=V||"utf-8";return J("script",{"id":"yui__dyn_"+(Q++),"type":"text/javascript","charset":U,"src":S},T);};var A=function(S,T){return{tId:S.tId,win:S.win,data:S.data,nodes:S.nodes,msg:T,purge:function(){D(this.tId);}};};var B=function(S,V){var T=M[V],U=(R.isString(S))?T.win.document.getElementById(S):S;if(!U){P(V,"target node not found: "+S);}return U;};var P=function(V,U){var S=M[V];if(S.onFailure){var T=S.scope||S.win;S.onFailure.call(T,A(S,U));}};var C=function(V){var S=M[V];S.finished=true;if(S.aborted){var U="transaction "+V+" was aborted";P(V,U);return ;}if(S.onSu!
 ccess){var T=S.scope||S.win;S.onSuccess.call(T,A(S));}};var G=function(U,Y){var T=M[U];if(T.aborted){var W="transaction "+U+" was aborted";P(U,W);return ;}if(Y){T.url.shift();if(T.varName){T.varName.shift();}}else{T.url=(R.isString(T.url))?[T.url]:T.url;if(T.varName){T.varName=(R.isString(T.varName))?[T.varName]:T.varName;}}var b=T.win,a=b.document,Z=a.getElementsByTagName("head")[0],V;if(T.url.length===0){if(T.type==="script"&&N.webkit&&N.webkit<420&&!T.finalpass&&!T.varName){var X=O(null,T.win,T.charset);X.innerHTML='YAHOO.util.Get._finalize("'+U+'");';T.nodes.push(X);Z.appendChild(X);}else{C(U);}return ;}var S=T.url[0];if(T.type==="script"){V=O(S,b,T.charset);}else{V=H(S,b,T.charset);}F(T.type,V,U,S,b,T.url.length);T.nodes.push(V);if(T.insertBefore){var c=B(T.insertBefore,U);if(c){c.parentNode.insertBefore(V,c);}}else{Z.appendChild(V);}if((N.webkit||N.gecko)&&T.type==="css"){G(U,S);}};var K=function(){if(E){return ;}E=true;for(var S in M){var T=M[S];if(T.autopurge&&T.fin!
 ished){D(T.tId);delete M[S];}}E=false;};var D=function(Z){var !
 W=M[Z];i
f(W){var Y=W.nodes,S=Y.length,X=W.win.document,V=X.getElementsByTagName("head")[0];if(W.insertBefore){var U=B(W.insertBefore,Z);if(U){V=U.parentNode;}}for(var T=0;T<S;T=T+1){V.removeChild(Y[T]);}}W.nodes=[];};var I=function(T,S,U){var W="q"+(L++);U=U||{};if(L%YAHOO.util.Get.PURGE_THRESH===0){K();}M[W]=R.merge(U,{tId:W,type:T,url:S,finished:false,nodes:[]});var V=M[W];V.win=V.win||window;V.scope=V.scope||V.win;V.autopurge=("autopurge" in V)?V.autopurge:(T==="script")?true:false;R.later(0,V,G,W);return{tId:W};};var F=function(b,W,V,T,X,Y,a){var Z=a||G;if(N.ie){W.onreadystatechange=function(){var c=this.readyState;if("loaded"===c||"complete"===c){Z(V,T);}};}else{if(N.webkit){if(b==="script"){if(N.webkit>=420){W.addEventListener("load",function(){Z(V,T);});}else{var S=M[V];if(S.varName){var U=YAHOO.util.Get.POLL_FREQ;S.maxattempts=YAHOO.util.Get.TIMEOUT/U;S.attempts=0;S._cache=S.varName[0].split(".");S.timer=R.later(U,S,function(h){var e=this._cache,d=e.length,c=this.win,f;for(f!
 =0;f<d;f=f+1){c=c[e[f]];if(!c){this.attempts++;if(this.attempts++>this.maxattempts){var g="Over retry limit, giving up";S.timer.cancel();P(V,g);}else{}return ;}}S.timer.cancel();Z(V,T);},null,true);}else{R.later(YAHOO.util.Get.POLL_FREQ,null,Z,[V,T]);}}}}else{W.onload=function(){Z(V,T);};}}};return{POLL_FREQ:10,PURGE_THRESH:20,TIMEOUT:2000,_finalize:function(S){R.later(0,null,C,S);},abort:function(T){var U=(R.isString(T))?T:T.tId;var S=M[U];if(S){S.aborted=true;}},script:function(S,T){return I("script",S,T);},css:function(S,T){return I("css",S,T);}};}();YAHOO.register("get",YAHOO.util.Get,{version:"2.5.1",build:"984"});
\ No newline at end of file

Added: trunk/root/static/yui/get/get.js
===================================================================
--- trunk/root/static/yui/get/get.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/get/get.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,668 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * Provides a mechanism to fetch remote resources and
+ * insert them into a document
+ * @module get
+ * @requires yahoo
+ */
+
+/**
+ * Fetches and inserts one or more script or link nodes into the document 
+ * @namespace YAHOO.util
+ * @class YAHOO.util.Get
+ */
+YAHOO.util.Get = function() {
+
+    /**
+     * hash of queues to manage multiple requests
+     * @property queues
+     * @private
+     */
+    var queues={}, 
+        
+    /**
+     * queue index used to generate transaction ids
+     * @property qidx
+     * @type int
+     * @private
+     */
+        qidx=0, 
+        
+    /**
+     * node index used to generate unique node ids
+     * @property nidx
+     * @type int
+     * @private
+     */
+        nidx=0, 
+
+        // ridx=0,
+
+        // sandboxFrame=null,
+
+    /**
+     * interal property used to prevent multiple simultaneous purge 
+     * processes
+     * @property purging
+     * @type boolean
+     * @private
+     */
+        purging=false,
+
+        ua=YAHOO.env.ua, 
+        
+        lang=YAHOO.lang;
+    
+    /** 
+     * Generates an HTML element, this is not appended to a document
+     * @method _node
+     * @param type {string} the type of element
+     * @param attr {string} the attributes
+     * @param win {Window} optional window to create the element in
+     * @return {HTMLElement} the generated node
+     * @private
+     */
+    var _node = function(type, attr, win) {
+        var w = win || window, d=w.document, n=d.createElement(type);
+
+        for (var i in attr) {
+            if (attr[i] && YAHOO.lang.hasOwnProperty(attr, i)) {
+                n.setAttribute(i, attr[i]);
+            }
+        }
+
+        return n;
+    };
+
+    /**
+     * Generates a link node
+     * @method _linkNode
+     * @param url {string} the url for the css file
+     * @param win {Window} optional window to create the node in
+     * @return {HTMLElement} the generated node
+     * @private
+     */
+    var _linkNode = function(url, win, charset) {
+        var c = charset || "utf-8";
+        return _node("link", {
+                "id":      "yui__dyn_" + (nidx++),
+                "type":    "text/css",
+                "charset": c,
+                "rel":     "stylesheet",
+                "href":    url
+            }, win);
+    };
+
+    /**
+     * Generates a script node
+     * @method _scriptNode
+     * @param url {string} the url for the script file
+     * @param win {Window} optional window to create the node in
+     * @return {HTMLElement} the generated node
+     * @private
+     */
+    var _scriptNode = function(url, win, charset) {
+        var c = charset || "utf-8";
+        return _node("script", {
+                "id":      "yui__dyn_" + (nidx++),
+                "type":    "text/javascript",
+                "charset": c,
+                "src":     url
+            }, win);
+    };
+
+    /**
+     * Returns the data payload for callback functions
+     * @method _returnData
+     * @private
+     */
+    var _returnData = function(q, msg) {
+        return {
+                tId: q.tId,
+                win: q.win,
+                data: q.data,
+                nodes: q.nodes,
+                msg: msg,
+                purge: function() {
+                    _purge(this.tId);
+                }
+            };
+    };
+
+    var _get = function(nId, tId) {
+        var q = queues[tId],
+            n = (lang.isString(nId)) ? q.win.document.getElementById(nId) : nId;
+        if (!n) {
+            _fail(tId, "target node not found: " + nId);
+        }
+
+        return n;
+    };
+
+    /*
+     * The request failed, execute fail handler with whatever
+     * was accomplished.  There isn't a failure case at the
+     * moment unless you count aborted transactions
+     * @method _fail
+     * @param id {string} the id of the request
+     * @private
+     */
+    var _fail = function(id, msg) {
+        var q = queues[id];
+        // execute failure callback
+        if (q.onFailure) {
+            var sc=q.scope || q.win;
+            q.onFailure.call(sc, _returnData(q, msg));
+        }
+    };
+
+    /**
+     * The request is complete, so executing the requester's callback
+     * @method _finish
+     * @param id {string} the id of the request
+     * @private
+     */
+    var _finish = function(id) {
+        var q = queues[id];
+        q.finished = true;
+
+        if (q.aborted) {
+            var msg = "transaction " + id + " was aborted";
+            _fail(id, msg);
+            return;
+        }
+
+        // execute success callback
+        if (q.onSuccess) {
+            var sc=q.scope || q.win;
+            q.onSuccess.call(sc, _returnData(q));
+        }
+    };
+
+    /**
+     * Loads the next item for a given request
+     * @method _next
+     * @param id {string} the id of the request
+     * @param loaded {string} the url that was just loaded, if any
+     * @private
+     */
+    var _next = function(id, loaded) {
+        var q = queues[id];
+
+        if (q.aborted) {
+            var msg = "transaction " + id + " was aborted";
+            _fail(id, msg);
+            return;
+        }
+
+        if (loaded) {
+            q.url.shift(); 
+            if (q.varName) {
+                q.varName.shift(); 
+            }
+        } else {
+            // This is the first pass: make sure the url is an array
+            q.url = (lang.isString(q.url)) ? [q.url] : q.url;
+            if (q.varName) {
+                q.varName = (lang.isString(q.varName)) ? [q.varName] : q.varName;
+            }
+        }
+
+        var w=q.win, d=w.document, h=d.getElementsByTagName("head")[0], n;
+
+        if (q.url.length === 0) {
+            // Safari 2.x workaround - There is no way to know when 
+            // a script is ready in versions of Safari prior to 3.x.
+            // Adding an extra node reduces the problem, but doesn't
+            // eliminate it completely because the browser executes
+            // them asynchronously. 
+            if (q.type === "script" && ua.webkit && ua.webkit < 420 && 
+                    !q.finalpass && !q.varName) {
+                // Add another script node.  This does not guarantee that the
+                // scripts will execute in order, but it does appear to fix the
+                // problem on fast connections more effectively than using an
+                // arbitrary timeout.  It is possible that the browser does
+                // block subsequent script execution in this case for a limited
+                // time.
+                var extra = _scriptNode(null, q.win, q.charset);
+                extra.innerHTML='YAHOO.util.Get._finalize("' + id + '");';
+                q.nodes.push(extra); h.appendChild(extra);
+
+            } else {
+                _finish(id);
+            }
+
+            return;
+        } 
+
+
+        var url = q.url[0];
+
+        if (q.type === "script") {
+            n = _scriptNode(url, w, q.charset);
+        } else {
+            n = _linkNode(url, w, q.charset);
+        }
+
+        // track this node's load progress
+        _track(q.type, n, id, url, w, q.url.length);
+
+        // add the node to the queue so we can return it to the user supplied callback
+        q.nodes.push(n);
+
+        // add it to the head or insert it before 'insertBefore'
+        if (q.insertBefore) {
+            var s = _get(q.insertBefore, id);
+            if (s) {
+                s.parentNode.insertBefore(n, s);
+            }
+        } else {
+            h.appendChild(n);
+        }
+        
+
+        // FireFox does not support the onload event for link nodes, so there is
+        // no way to make the css requests synchronous. This means that the css 
+        // rules in multiple files could be applied out of order in this browser
+        // if a later request returns before an earlier one.  Safari too.
+        if ((ua.webkit || ua.gecko) && q.type === "css") {
+            _next(id, url);
+        }
+    };
+
+    /**
+     * Removes processed queues and corresponding nodes
+     * @method _autoPurge
+     * @private
+     */
+    var _autoPurge = function() {
+
+        if (purging) {
+            return;
+        }
+
+        purging = true;
+        for (var i in queues) {
+            var q = queues[i];
+            if (q.autopurge && q.finished) {
+                _purge(q.tId);
+                delete queues[i];
+            }
+        }
+
+        purging = false;
+    };
+
+    /**
+     * Removes the nodes for the specified queue
+     * @method _purge
+     * @private
+     */
+    var _purge = function(tId) {
+        var q=queues[tId];
+        if (q) {
+            var n=q.nodes, l=n.length, d=q.win.document, 
+                h=d.getElementsByTagName("head")[0];
+
+            if (q.insertBefore) {
+                var s = _get(q.insertBefore, tId);
+                if (s) {
+                    h = s.parentNode;
+                }
+            }
+
+            for (var i=0; i<l; i=i+1) {
+                h.removeChild(n[i]);
+            }
+        }
+        q.nodes = [];
+    };
+
+    /**
+     * Saves the state for the request and begins loading
+     * the requested urls
+     * @method queue
+     * @param type {string} the type of node to insert
+     * @param url {string} the url to load
+     * @param opts the hash of options for this request
+     * @private
+     */
+    var _queue = function(type, url, opts) {
+
+        var id = "q" + (qidx++);
+        opts = opts || {};
+
+        if (qidx % YAHOO.util.Get.PURGE_THRESH === 0) {
+            _autoPurge();
+        }
+
+        queues[id] = lang.merge(opts, {
+            tId: id,
+            type: type,
+            url: url,
+            finished: false,
+            nodes: []
+        });
+
+        var q = queues[id];
+        q.win = q.win || window;
+        q.scope = q.scope || q.win;
+        q.autopurge = ("autopurge" in q) ? q.autopurge : 
+                      (type === "script") ? true : false;
+
+        lang.later(0, q, _next, id);
+
+        return {
+            tId: id
+        };
+    };
+
+    /**
+     * Detects when a node has been loaded.  In the case of
+     * script nodes, this does not guarantee that contained
+     * script is ready to use.
+     * @method _track
+     * @param type {string} the type of node to track
+     * @param n {HTMLElement} the node to track
+     * @param id {string} the id of the request
+     * @param url {string} the url that is being loaded
+     * @param win {Window} the targeted window
+     * @param qlength the number of remaining items in the queue,
+     * including this one
+     * @param trackfn {Function} function to execute when finished
+     * the default is _next
+     * @private
+     */
+    var _track = function(type, n, id, url, win, qlength, trackfn) {
+        var f = trackfn || _next;
+
+        // IE supports the readystatechange event for script and css nodes
+        if (ua.ie) {
+            n.onreadystatechange = function() {
+                var rs = this.readyState;
+                if ("loaded" === rs || "complete" === rs) {
+                    f(id, url);
+                }
+            };
+
+        // webkit prior to 3.x is problemmatic
+        } else if (ua.webkit) {
+
+            if (type === "script") {
+
+                // Safari 3.x supports the load event for script nodes (DOM2)
+                if (ua.webkit >= 420) {
+
+                    n.addEventListener("load", function() {
+                        f(id, url);
+                    });
+
+                // Nothing can be done with Safari < 3.x except to pause and hope
+                // for the best, particularly after last script is inserted. The
+                // scripts will always execute in the order they arrive, not
+                // necessarily the order in which they were inserted.  To support
+                // script nodes with complete reliability in these browsers, script
+                // nodes either need to invoke a function in the window once they
+                // are loaded or the implementer needs to provide a well-known
+                // property that the utility can poll for.
+                } else {
+                    // Poll for the existence of the named variable, if it
+                    // was supplied.
+                    var q = queues[id];
+                    if (q.varName) {
+                        var freq=YAHOO.util.Get.POLL_FREQ;
+                        q.maxattempts = YAHOO.util.Get.TIMEOUT/freq;
+                        q.attempts = 0;
+                        q._cache = q.varName[0].split(".");
+                        q.timer = lang.later(freq, q, function(o) {
+                            var a=this._cache, l=a.length, w=this.win, i;
+                            for (i=0; i<l; i=i+1) {
+                                w = w[a[i]];
+                                if (!w) {
+                                    // if we have exausted our attempts, give up
+                                    this.attempts++;
+                                    if (this.attempts++ > this.maxattempts) {
+                                        var msg = "Over retry limit, giving up";
+                                        q.timer.cancel();
+                                        _fail(id, msg);
+                                    } else {
+                                    }
+                                    return;
+                                }
+                            }
+                            
+
+                            q.timer.cancel();
+                            f(id, url);
+
+                        }, null, true);
+                    } else {
+                        lang.later(YAHOO.util.Get.POLL_FREQ, null, f, [id, url]);
+                    }
+                }
+            } 
+
+        // FireFox and Opera support onload (but not DOM2 in FF) handlers for
+        // script nodes.  Opera, but not FF, supports the onload event for link
+        // nodes.
+        } else { 
+            n.onload = function() {
+                f(id, url);
+            };
+        }
+    };
+
+    return {
+
+        /**
+         * The default poll freqency in ms, when needed
+         * @property POLL_FREQ
+         * @static
+         * @type int
+         * @default 10
+         */
+        POLL_FREQ: 10,
+
+        /**
+         * The number of request required before an automatic purge.
+         * property PURGE_THRESH
+         * @static
+         * @type int
+         * @default 20
+         */
+        PURGE_THRESH: 20,
+
+        /**
+         * The length time to poll for varName when loading a script in
+         * Safari 2.x before the transaction fails.
+         * property TIMEOUT
+         * @static
+         * @type int
+         * @default 2000
+         */
+        TIMEOUT: 2000,
+        
+        /**
+         * Called by the the helper for detecting script load in Safari
+         * @method _finalize
+         * @param id {string} the transaction id
+         * @private
+         */
+        _finalize: function(id) {
+            lang.later(0, null, _finish, id);
+        },
+
+        /**
+         * Abort a transaction
+         * @method abort
+         * @param {string|object} either the tId or the object returned from
+         * script() or css()
+         */
+        abort: function(o) {
+            var id = (lang.isString(o)) ? o : o.tId;
+            var q = queues[id];
+            if (q) {
+                q.aborted = true;
+            }
+        }, 
+
+        /**
+         * Fetches and inserts one or more script nodes into the head
+         * of the current document or the document in a specified window.
+         *
+         * @method script
+         * @static
+         * @param url {string|string[]} the url or urls to the script(s)
+         * @param opts {object} Options: 
+         * <dl>
+         * <dt>onSuccess</dt>
+         * <dd>
+         * callback to execute when the script(s) are finished loading
+         * The callback receives an object back with the following
+         * data:
+         * <dl>
+         * <dt>win</dt>
+         * <dd>the window the script(s) were inserted into</dd>
+         * <dt>data</dt>
+         * <dd>the data object passed in when the request was made</dd>
+         * <dt>nodes</dt>
+         * <dd>An array containing references to the nodes that were
+         * inserted</dd>
+         * <dt>purge</dt>
+         * <dd>A function that, when executed, will remove the nodes
+         * that were inserted</dd>
+         * <dt>
+         * </dl>
+         * </dd>
+         * <dt>onFailure</dt>
+         * <dd>
+         * callback to execute when the script load operation fails
+         * The callback receives an object back with the following
+         * data:
+         * <dl>
+         * <dt>win</dt>
+         * <dd>the window the script(s) were inserted into</dd>
+         * <dt>data</dt>
+         * <dd>the data object passed in when the request was made</dd>
+         * <dt>nodes</dt>
+         * <dd>An array containing references to the nodes that were
+         * inserted successfully</dd>
+         * <dt>purge</dt>
+         * <dd>A function that, when executed, will remove any nodes
+         * that were inserted</dd>
+         * <dt>
+         * </dl>
+         * </dd>
+         * <dt>scope</dt>
+         * <dd>the execution context for the callbacks</dd>
+         * <dt>win</dt>
+         * <dd>a window other than the one the utility occupies</dd>
+         * <dt>autopurge</dt>
+         * <dd>
+         * setting to true will let the utilities cleanup routine purge 
+         * the script once loaded
+         * </dd>
+         * <dt>data</dt>
+         * <dd>
+         * data that is supplied to the callback when the script(s) are
+         * loaded.
+         * </dd>
+         * <dt>varName</dt>
+         * <dd>
+         * variable that should be available when a script is finished
+         * loading.  Used to help Safari 2.x and below with script load 
+         * detection.  The type of this property should match what was
+         * passed into the url parameter: if loading a single url, a
+         * string can be supplied.  If loading multiple scripts, you
+         * must supply an array that contains the variable name for
+         * each script.
+         * </dd>
+         * <dt>insertBefore</dt>
+         * <dd>node or node id that will become the new node's nextSibling</dd>
+         * </dl>
+         * <dt>charset</dt>
+         * <dd>Node charset, default utf-8</dd>
+         * <pre>
+         * // assumes yahoo, dom, and event are already on the page
+         *   YAHOO.util.Get.script(
+         *   ["http://yui.yahooapis.com/2.3.1/build/dragdrop/dragdrop-min.js",
+         *    "http://yui.yahooapis.com/2.3.1/build/animation/animation-min.js"], {
+         *     onSuccess: function(o) {
+         *       new YAHOO.util.DDProxy("dd1"); // also new o.reference("dd1"); would work
+         *       this.log("won't cause error because YAHOO is the scope");
+         *       this.log(o.nodes.length === 2) // true
+         *       // o.purge(); // optionally remove the script nodes immediately
+         *     },
+         *     onFailure: function(o) {
+         *     },
+         *     data: "foo",
+         *     scope: YAHOO,
+         *     // win: otherframe // target another window/frame
+         *     autopurge: true // allow the utility to choose when to remove the nodes
+         *   });
+         * </pre>
+         * @return {tId: string} an object containing info about the transaction
+         */
+        script: function(url, opts) { return _queue("script", url, opts); },
+
+        /**
+         * Fetches and inserts one or more css link nodes into the 
+         * head of the current document or the document in a specified
+         * window.
+         * @method css
+         * @static
+         * @param url {string} the url or urls to the css file(s)
+         * @param opts Options: 
+         * <dl>
+         * <dt>onSuccess</dt>
+         * <dd>
+         * callback to execute when the css file(s) are finished loading
+         * The callback receives an object back with the following
+         * data:
+         * <dl>win</dl>
+         * <dd>the window the link nodes(s) were inserted into</dd>
+         * <dt>data</dt>
+         * <dd>the data object passed in when the request was made</dd>
+         * <dt>nodes</dt>
+         * <dd>An array containing references to the nodes that were
+         * inserted</dd>
+         * <dt>purge</dt>
+         * <dd>A function that, when executed, will remove the nodes
+         * that were inserted</dd>
+         * <dt>
+         * </dl>
+         * </dd>
+         * <dt>scope</dt>
+         * <dd>the execution context for the callbacks</dd>
+         * <dt>win</dt>
+         * <dd>a window other than the one the utility occupies</dd>
+         * <dt>data</dt>
+         * <dd>
+         * data that is supplied to the callbacks when the nodes(s) are
+         * loaded.
+         * </dd>
+         * <dt>insertBefore</dt>
+         * <dd>node or node id that will become the new node's nextSibling</dd>
+         * <dt>charset</dt>
+         * <dd>Node charset, default utf-8</dd>
+         * </dl>
+         * <pre>
+         *      YAHOO.util.Get.css("http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css");
+         * </pre>
+         * <pre>
+         *      YAHOO.util.Get.css(["http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css",
+         * </pre>
+         * @return {tId: string} an object containing info about the transaction
+         */
+        css: function(url, opts) {
+            return _queue("css", url, opts); 
+        }
+    };
+}();
+
+YAHOO.register("get", YAHOO.util.Get, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/grids/README
===================================================================
--- trunk/root/static/yui/grids/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/grids/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,10 +1,19 @@
 YUI Library - Grids - Release Notes
 
-Version 2.4.1
+Version 2.5.1
 
-No change
+  * Added more specific selectors to allow nesting on "yui-gd" grids 
+    within "yui-ge" for Bugzilla #1779582, Sourceforge #1897741 
+  * Modified Page Width and Template Preset values for IE
+  * Reordered several rules; formatted file and added more comments
+  * Modified width and margin values for "thirds" nesting grid
+  * Combined and optimized several selectors and rules
 
+Version 2.5.0
 
+  * Tweaked em widths for "template presets" .yui-t1-6
+  * Pruned two redundant lines
+
 Version 2.4.0
 
   * No changes.
@@ -67,4 +76,4 @@
   
 Version 0.10.0
 
-  * Initial release.
+  * Initial release.
\ No newline at end of file

Modified: trunk/root/static/yui/grids/grids-min.css
===================================================================
--- trunk/root/static/yui/grids/grids-min.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/grids/grids-min.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-body{text-align:center;}#ft{clear:both;}#doc,#doc2,#doc3,#doc4,.yui-t1,.yui-t2,.yui-t3,.yui-t4,.yui-t5,.yui-t6,.yui-t7{margin:auto;text-align:left;width:57.69em;*width:56.301em;min-width:750px;}#doc2{width:73.074em;*width:71.313em;}#doc3{margin:auto 10px;width:auto;}#doc4{width:74.923em;*width:73.117em;}.yui-b{position:relative;}.yui-b{_position:static;}#yui-main .yui-b{position:static;}#yui-main{width:100%;}.yui-t1 #yui-main,.yui-t2 #yui-main,.yui-t3 #yui-main{float:right;margin-left:-25em;}.yui-t4 #yui-main,.yui-t5 #yui-main,.yui-t6 #yui-main{float:left;margin-right:-25em;}.yui-t1 .yui-b{float:left;width:12.3207em;*width:12.0106em;}.yui-t1 #yui-main .yui-b{margin-left:13.3207em;*margin-left:13.0106em;}.yui-t2 .yui-b{float:left;width:13.8456em;*width:13.512em;}.yui-t2 #yui-main .yui-b{margin-left:14.8456em;*margin-left:14.512em;}.yui-t3 .yui-b{float:left;width:23.0759em;*width:22.52em;}.yui-t3 #yui-main .yui-b{margin-left:24.0759em;*margin-left:23.52em;}.yui-t4 .yui-b{floa!
 t:right;width:13.8456em;*width:13.512em;}.yui-t4 #yui-main .yui-b{margin-right:14.8456em;*margin-right:14.512em;}.yui-t5 .yui-b{float:right;width:18.4608em;*width:18.016em;}.yui-t5 #yui-main .yui-b{margin-right:19.4608em;*margin-right:19.016em;}.yui-t6 .yui-b{float:right;width:23.0759em;*width:22.52em;}.yui-t6 #yui-main .yui-b{margin-right:24.0759em;*margin-right:23.52em;}.yui-t7 #yui-main .yui-b{display:block;margin:0 0 1em 0;}#yui-main .yui-b{float:none;width:auto;}.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gb .yui-u,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{float:left;margin-left:2%;width:32%;}.yui-gb .yui-gb .yui-u,.yui-gb .yui-gc .yui-u{*margin-left:1.8%;_margin-left:4%;}.yui-g .yui-gb .yui-u{_margin-left:.8%;}.yui-gb .yui-u{float:right;}.yui-gb div.first{margin-left:0;float:left;}.yui-g .yui-gb div.first,.yui-gb .yui-gb div.first{*margin-right:0;*width:32%;_width:31.7%;}.yui-gb .yui-gc d!
 iv.first,.yui-gb .yui-gd div.first{*margin-right:0;}.yui-gb .y!
 ui-gd .y
ui-u{*width:66%;_width:61.2%;}.yui-gb .yui-gd div.first{*width:31%;_width:29.5%;}.yui-g .yui-gc .yui-u,.yui-gb .yui-gc .yui-u{width:32%;_float:right;margin-right:0;_margin-left:0;}.yui-gb .yui-gc div.first{width:66%;*float:left;*margin-left:0;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf .yui-u{margin:0;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf,.yui-gc .yui-u,.yui-gd .yui-g,.yui-g .yui-gc .yui-u,.yui-ge .yui-u,.yui-ge .yui-g,.yui-gf .yui-g,.yui-gf .yui-u{float:right;}.yui-g .yui-gc div.first,.yui-g .yui-ge div.first,.yui-g div.first,.yui-gc div.first,.yui-gc div.first div.first,.yui-gd div.first,.yui-ge div.first,.yui-gf div.first{float:left;}.yui-g .yui-g .yui-u,.yui-gb .yui-g .yui-u,.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u,.yui-ge .yui-g .yui-u,.yui-gf .yui-g .yui-u{width:49%;*width:48.1%;*margin-left:0;}.yui-g .yui-g div.first{*margin:0;}.yui-gb .yui-g div.first{*margin-right:4%;_margin-right:1.3%;}.yui-gb .yui-gb!
  .yui-u{_margin-left:.7%;}.yui-gb .yui-g div.first,.yui-gb .yui-gb div.first{*margin-left:0;}.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u{*width:48.1%;*margin-left:0;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf{width:49.1%;}.yui-g .yui-gb div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first{margin-left:0;}.yui-g .yui-gc div.first,.yui-gc div.first,.yui-gd .yui-g,.yui-gd .yui-u{width:66%;}.yui-gd div.first,.yui-gb .yui-gd div.first{width:32%;}.yui-g .yui-gd div.first{_width:29.9%;}.yui-ge .yui-u,.yui-ge .yui-g,.yui-gf div.first{width:24%;}.yui-gb .yui-ge div.yui-u,.yui-gb .yui-gf div.yui-u{float:right;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf div.first {float:left;}.yui-ge div.first,.yui-gf .yui-g,.yui-gf .yui-u{width:74.2%;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf div.first{*width:24%;_width:20%;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf .yui-u{*width:73.5%;_width:65.5%;}#bd:after,.yui-g:after,.yui-gb:after!
 ,.yui-gc:after,.yui-gd:after,.yui-ge:after,.yui-gf:after{conte!
 nt:".";d
isplay:block;height:0;clear:both;visibility:hidden;}#bd,.yui-g,.yui-gb,.yui-gc,.yui-gd,.yui-ge,.yui-gf{zoom:1;}.yui-gb .yui-u{float:left;}
\ No newline at end of file
+body{text-align:center;}#ft{clear:both;}#doc,#doc2,#doc3,#doc4,.yui-t1,.yui-t2,.yui-t3,.yui-t4,.yui-t5,.yui-t6,.yui-t7{margin:auto;text-align:left;width:57.69em;*width:56.25em;min-width:750px;}#doc2{width:73.076em;*width:71.25em;}#doc3{margin:auto 10px;width:auto;}#doc4{width:74.923em;*width:73.05em;}.yui-b{position:relative;}.yui-b{_position:static;}#yui-main .yui-b{position:static;}#yui-main{width:100%;}.yui-t1 #yui-main,.yui-t2 #yui-main,.yui-t3 #yui-main{float:right;margin-left:-25em;}.yui-t4 #yui-main,.yui-t5 #yui-main,.yui-t6 #yui-main{float:left;margin-right:-25em;}.yui-t1 .yui-b{float:left;width:12.30769em;*width:12.00em;}.yui-t1 #yui-main .yui-b{margin-left:13.30769em;*margin-left:13.05em;}.yui-t2 .yui-b{float:left;width:13.8461em;*width:13.50em;}.yui-t2 #yui-main .yui-b{margin-left:14.8461em;*margin-left:14.55em;}.yui-t3 .yui-b{float:left;width:23.0769em;*width:22.50em;}.yui-t3 #yui-main .yui-b{margin-left:24.0769em;*margin-left:23.62em;}.yui-t4 .yui-b{float:right!
 ;width:13.8456em;*width:13.50em;}.yui-t4 #yui-main .yui-b{margin-right:14.8456em;*margin-right:14.55em;}.yui-t5 .yui-b{float:right;width:18.4615em;*width:18.00em;}.yui-t5 #yui-main .yui-b{margin-right:19.4615em;*margin-right:19.125em;}.yui-t6 .yui-b{float:right;width:23.0769em;*width:22.50em;}.yui-t6 #yui-main .yui-b{margin-right:24.0769em;*margin-right:23.62em;}.yui-t7 #yui-main .yui-b{display:block;margin:0 0 1em 0;}#yui-main .yui-b{float:none;width:auto;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf,.yui-gc .yui-u,.yui-gd .yui-g,.yui-g .yui-gc .yui-u,.yui-ge .yui-u,.yui-ge .yui-g,.yui-gf .yui-g,.yui-gf .yui-u{float:right;}.yui-g div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first,.yui-ge div.first,.yui-gf div.first,.y!
 ui-g .yui-gc div.first,.yui-g .yui-ge div.first,.yui-gc div.fi!
 rst div.
first{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf{width:49.1%;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{width:32%;margin-left:1.99%;}.yui-gb .yui-u{*margin-left:1.9%;*width:31.9%;}.yui-gc div.first,.yui-gd .yui-u{width:66%;}.yui-gd div.first{width:32%;}.yui-ge div.first,.yui-gf .yui-u{width:74.2%;}.yui-ge .yui-u,.yui-gf div.first{width:24%;}.yui-g .yui-gb div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first{margin-left:0;}.yui-g .yui-g .yui-u,.yui-gb .yui-g .yui-u,.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u,.yui-ge .yui-g .yui-u,.yui-gf .yui-g .yui-u{width:49%;*width:48.1%;*margin-left:0;}.yui-g .yui-gb div.first,.yui-gb .yui-gb div.first{*margin-right:0;*width:32%;_width:31.7%;}.yui-g .yui-gc div.first,.yui-gd .yui-g{width:66%;}.yui-gb .yui-g div.first{*margin!
 -right:4%;_margin-right:1.3%;}.yui-gb .yui-gc div.first,.yui-gb .yui-gd div.first{*margin-right:0;}.yui-gb .yui-gb .yui-u,.yui-gb .yui-gc .yui-u{*margin-left:1.8%;_margin-left:4%;}.yui-g .yui-gb .yui-u{_margin-left:1.0%;}.yui-gb .yui-gd .yui-u{*width:66%;_width:61.2%;}.yui-gb .yui-gd div.first{*width:31%;_width:29.5%;}.yui-g .yui-gc .yui-u,.yui-gb .yui-gc .yui-u{width:32%;_float:right;margin-right:0;_margin-left:0;}.yui-gb .yui-gc div.first{width:66%;*float:left;*margin-left:0;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf .yui-u{margin:0;}.yui-gb .yui-gb .yui-u{_margin-left:.7%;}.yui-gb .yui-g div.first,.yui-gb .yui-gb div.first{*margin-left:0;}.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u{*width:48.1%;*margin-left:0;}s .yui-gb .yui-gd div.first{width:32%;}.yui-g .yui-gd div.first{_width:29.9%;}.yui-ge .yui-g{width:24%;}.yui-gf .yui-g{width:74.2%;}.yui-gb .yui-ge div.yui-u,.yui-gb .yui-gf div.yui-u{float:right;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf div.first{float:left;}.yui-gb!
  .yui-ge .yui-u,.yui-gb .yui-gf div.first{*width:24%;_width:20!
 %;}.yui-
gb .yui-ge div.first,.yui-gb .yui-gf .yui-u{*width:73.5%;_width:65.5%;}.yui-ge div.first .yui-gd .yui-u{width:65%;}.yui-ge div.first .yui-gd div.first{width:32%;}#bd:after,.yui-g:after,.yui-gb:after,.yui-gc:after,.yui-gd:after,.yui-ge:after,.yui-gf:after{content:".";display:block;height:0;clear:both;visibility:hidden;}#bd,.yui-g,.yui-gb,.yui-gc,.yui-gd,.yui-ge,.yui-gf{zoom:1;}
\ No newline at end of file

Modified: trunk/root/static/yui/grids/grids.css
===================================================================
--- trunk/root/static/yui/grids/grids.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/grids/grids.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,76 +1,136 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-/* for all templates and grids */
-body{text-align:center;}
-#ft{clear:both;}
-/* 750 centered, and backward compatibility */ 
-#doc,#doc2,#doc3,#doc4,.yui-t1,.yui-t2,.yui-t3,.yui-t4,.yui-t5,.yui-t6,.yui-t7 {
-	margin:auto;text-align:left;
-	width:57.69em;*width:56.301em;min-width:750px;}
-/* 950 centered */ 
-#doc2 {
-	width:73.074em;*width:71.313em;}
-/* 100% with 10px viewport side matting */ 
-#doc3 {
-	margin:auto 10px; /* not for structure, but so content doesn't bleed to edge */
-	width:auto;}
-/* 974 centered */
-#doc4 {
-	width:74.923em;*width:73.117em;}	
-/* below required for all fluid grids; adjust widths and margins above accordingly */
+/*
+	Note: Throughout this file, the *property filter is used to 
+	      give a value to IE that other browsers do not see.	
+*/
+
+/*
+	Section: General Rules
+*/
+
+	body {
+		text-align:center;
+	}
+	
+	#ft {
+		clear:both;
+	}
+
+/*
+	Section: Page Width Rules (#doc, #doc2, #doc3, #doc4)
+*/
+
+	/* 
+		Subsection: General 
+	*/ 	
+
+	#doc,#doc2,#doc3,#doc4,.yui-t1,.yui-t2,.yui-t3,.yui-t4,.yui-t5,.yui-t6,.yui-t7 {
+		margin:auto;
+		text-align:left;
+		width:57.69em;*width:56.25em;
+		min-width:750px;
+	}
+	/* 
+		Subsection: 950 Centered (doc2) 
+	*/
+	#doc2 {
+		width:73.076em;*width:71.25em;
+	}
+
+	/* 
+		Subsection: 100% (doc3) 
+	*/
+	#doc3 {
+		/* Left and Right margins are not a structural part of Grids. Without them Grids
+		   works fine, but content bleeds to the very edge of the document, which often
+		   impairs readability and usability. They are 
+		   provided because they prevent the content from "bleeding" into the browser's chrome.*/
+		margin:auto 10px; 
+		width:auto;
+	}
+	
+	/* 
+		Subsection: 974 Centered (doc4) 
+	*/
+	#doc4 {
+		width:74.923em;*width:73.05em;
+	}	
+	
+/*
+	Section: Preset Template Rules (.yui-t[1-6])
+*/
+	
+	/* 
+		Subsection: General
+	*/
+
 	/* to preserve source-order independence for Gecko */
 	.yui-b{position:relative;}
-	.yui-b{_position:static;} /* for IE < 7 */
-	#yui-main .yui-b{position:static;} 
-#yui-main {width:100%;}
-.yui-t1 #yui-main,.yui-t2 #yui-main,.yui-t3 #yui-main{float:right;margin-left:-25em;/* IE: preserve layout at narrow widths */}
-.yui-t4 #yui-main,.yui-t5 #yui-main,.yui-t6 #yui-main{float:left;margin-right:-25em;/* IE: preserve layout at narrow widths */}
-.yui-t1 .yui-b {float:left;width:12.3207em;*width:12.0106em;}
-.yui-t1 #yui-main .yui-b{margin-left:13.3207em;*margin-left:13.0106em;}
-.yui-t2 .yui-b {float:left;width:13.8456em;*width:13.512em;}
-.yui-t2 #yui-main .yui-b {margin-left:14.8456em;*margin-left:14.512em;}
-.yui-t3 .yui-b {float:left;width:23.0759em;*width:22.52em;}
-.yui-t3 #yui-main .yui-b {margin-left:24.0759em;*margin-left:23.52em;}
-.yui-t4 .yui-b {float:right;width:13.8456em;*width:13.512em;}
-.yui-t4 #yui-main .yui-b {margin-right:14.8456em;*margin-right:14.512em;}
-.yui-t5 .yui-b {float:right;width:18.4608em;*width:18.016em;}
-.yui-t5 #yui-main .yui-b {margin-right:19.4608em;*margin-right:19.016em;}
-.yui-t6 .yui-b {float:right;width:23.0759em;*width:22.52em;}
-.yui-t6 #yui-main .yui-b {margin-right:24.0759em;*margin-right:23.52em;}
-.yui-t7 #yui-main .yui-b {display:block;margin:0 0 1em 0;}
-#yui-main .yui-b {float:none;width:auto;}
-.yui-g .yui-gb .yui-u,
-.yui-gb .yui-g,
-.yui-gb .yui-gb,
-.yui-gb .yui-gc,
-.yui-gb .yui-gd,
-.yui-gb .yui-ge,
-.yui-gb .yui-gf,
-.yui-gb .yui-u, 
-.yui-gc .yui-u, 
-.yui-gc .yui-g,
-.yui-gd .yui-u{float:left;margin-left:2%;width:32%;}
-.yui-gb .yui-gb .yui-u,
-.yui-gb .yui-gc .yui-u {*margin-left:1.8%;_margin-left:4%;}
-.yui-g .yui-gb .yui-u {_margin-left:.8%;}
-.yui-gb .yui-u {float:right;} 
-.yui-gb div.first {margin-left:0;float:left;}
-.yui-g .yui-gb div.first,
-.yui-gb .yui-gb div.first {*margin-right:0;*width:32%;_width:31.7%;} 
-.yui-gb .yui-gc div.first,
-.yui-gb .yui-gd div.first
-	 {*margin-right:0;}
-.yui-gb .yui-gd .yui-u {*width:66%;_width:61.2%;} 
-.yui-gb .yui-gd div.first {*width:31%;_width:29.5%;}
-.yui-g .yui-gc .yui-u, 
-.yui-gb .yui-gc .yui-u {width:32%;_float:right;margin-right:0;_margin-left:0;}
-.yui-gb .yui-gc div.first {width:66%;*float:left;*margin-left:0;}
-.yui-gb .yui-ge .yui-u, 
-.yui-gb .yui-gf .yui-u {margin:0;}
+	.yui-b{_position:static;}
+	#yui-main .yui-b{position:static;}
+
+	#yui-main {width:100%;}
+		
+	.yui-t1 #yui-main,
+	.yui-t2 #yui-main,
+	.yui-t3 #yui-main{float:right;margin-left:-25em;/* IE: preserve layout at narrow widths */}
+
+	.yui-t4 #yui-main,
+	.yui-t5 #yui-main,
+	.yui-t6 #yui-main{float:left;margin-right:-25em;/* IE: preserve layout at narrow widths */}
+
+	/* 
+		Subsection: For Specific Template Presets
+	*/
+
+	.yui-t1 .yui-b {float:left;width:12.30769em;*width:12.00em;}
+	.yui-t1 #yui-main .yui-b{margin-left:13.30769em;*margin-left:13.05em;}
+
+	.yui-t2 .yui-b {float:left;width:13.8461em;*width:13.50em;}
+	.yui-t2 #yui-main .yui-b {margin-left:14.8461em;*margin-left:14.55em;}
+
+	.yui-t3 .yui-b {float:left;width:23.0769em;*width:22.50em;}
+	.yui-t3 #yui-main .yui-b {margin-left:24.0769em;*margin-left:23.62em;}
+
+	.yui-t4 .yui-b {float:right;width:13.8456em;*width:13.50em;}
+	.yui-t4 #yui-main .yui-b {margin-right:14.8456em;*margin-right:14.55em;}
+
+	.yui-t5 .yui-b {float:right;width:18.4615em;*width:18.00em;}
+	.yui-t5 #yui-main .yui-b {margin-right:19.4615em;*margin-right:19.125em;}
+
+	.yui-t6 .yui-b {float:right;width:23.0769em;*width:22.50em;}
+	.yui-t6 #yui-main .yui-b {margin-right:24.0769em;*margin-right:23.62em;}
+
+	.yui-t7 #yui-main .yui-b {
+		display:block;margin:0 0 1em 0;
+	}
+	#yui-main .yui-b {float:none;width:auto;}
+
+/*
+	Section: Grids and Nesting Grids
+*/
+
+	/*
+		Subsection: Children generally take half the available space
+	*/
+
+	.yui-gb .yui-u,
+	.yui-g .yui-gb .yui-u,
+	.yui-gb .yui-g,
+	.yui-gb .yui-gb,
+	.yui-gb .yui-gc,
+	.yui-gb .yui-gd,
+	.yui-gb .yui-ge,
+	.yui-gb .yui-gf,
+	.yui-gc .yui-u, 
+	.yui-gc .yui-g,
+	.yui-gd .yui-u {float:left;}
+
 	/*Float units (and sub grids) to the right */
 	.yui-g .yui-u,
 	.yui-g .yui-g,
@@ -86,63 +146,127 @@
 	.yui-ge .yui-g, 
 	.yui-gf .yui-g,
 	.yui-gf .yui-u{float:right;}
+
 	/*Float units (and sub grids) to the left */
-	.yui-g .yui-gc div.first,
-	.yui-g .yui-ge div.first,
 	.yui-g div.first, 
+	.yui-gb div.first,
 	.yui-gc div.first,
-	.yui-gc div.first div.first,
 	.yui-gd div.first, 
 	.yui-ge div.first, 
-	.yui-gf div.first{float:left;}
-.yui-g .yui-g .yui-u,
-.yui-gb .yui-g .yui-u,
-.yui-gc .yui-g .yui-u,
-.yui-gd .yui-g .yui-u,
-.yui-ge .yui-g .yui-u,
-.yui-gf .yui-g .yui-u {width:49%;*width:48.1%;*margin-left:0;}
-.yui-g .yui-g div.first {*margin:0;}
-.yui-gb .yui-g div.first {*margin-right:4%;_margin-right:1.3%;}
-.yui-gb .yui-gb .yui-u {_margin-left:.7%;}
-.yui-gb .yui-g div.first,
-.yui-gb .yui-gb div.first {*margin-left:0;}
-.yui-gc .yui-g .yui-u,
-.yui-gd .yui-g .yui-u {*width:48.1%;*margin-left:0;}
-.yui-g .yui-u,
-.yui-g .yui-g,
-.yui-g .yui-gb,
-.yui-g .yui-gc,
-.yui-g .yui-gd,
-.yui-g .yui-ge,
-.yui-g .yui-gf {width:49.1%;}
-.yui-g .yui-gb div.first,
-       .yui-gb div.first, 
-       .yui-gc div.first, 
-       .yui-gd div.first {margin-left:0;}
-.yui-g .yui-gc div.first, 
-.yui-gc div.first, 
-.yui-gd .yui-g, /* for 056, 057 */
-.yui-gd .yui-u {width:66%;}
-.yui-gd div.first,
-.yui-gb .yui-gd div.first {width:32%;}
-.yui-g .yui-gd div.first {_width:29.9%;}
-.yui-ge .yui-u,
-.yui-ge .yui-g,
-.yui-gf div.first {width:24%;}
-.yui-gb .yui-ge div.yui-u,
-.yui-gb .yui-gf div.yui-u {float:right;}
-.yui-gb .yui-ge div.first,
-.yui-gb .yui-gf div.first  {float:left;}
-.yui-ge div.first, 
-.yui-gf .yui-g,
-.yui-gf .yui-u{width:74.2%;}
-/* narrower width in nexted contexts */
-.yui-gb .yui-ge .yui-u,
-.yui-gb .yui-gf div.first {*width:24%;_width:20%;}
-/* narrower width in nexted contexts */
-.yui-gb .yui-ge div.first, 
-.yui-gb .yui-gf .yui-u{*width:73.5%;_width:65.5%;}
-/* clearing */
+	.yui-gf div.first,
+	.yui-g .yui-gc div.first,
+	.yui-g .yui-ge div.first,
+	.yui-gc div.first div.first {float:left;}
+
+	.yui-g .yui-u,
+	.yui-g .yui-g,
+	.yui-g .yui-gb,
+	.yui-g .yui-gc,
+	.yui-g .yui-gd,
+	.yui-g .yui-ge,
+	.yui-g .yui-gf {width:49.1%;}
+
+	.yui-gb .yui-u,
+	.yui-g .yui-gb .yui-u,
+	.yui-gb .yui-g,
+	.yui-gb .yui-gb,
+	.yui-gb .yui-gc,
+	.yui-gb .yui-gd,
+	.yui-gb .yui-ge,
+	.yui-gb .yui-gf,
+	.yui-gc .yui-u, 
+	.yui-gc .yui-g,
+	.yui-gd .yui-u {width:32%;margin-left:1.99%;}
+
+		/* Give IE some extra breathing room for 1/3-based rounding issues */
+		.yui-gb .yui-u {*margin-left:1.9%;*width:31.9%;}
+
+	.yui-gc div.first, 
+	.yui-gd .yui-u {width:66%;}
+	.yui-gd div.first {width:32%;}
+
+	.yui-ge div.first, 
+	.yui-gf .yui-u{width:74.2%;}
+
+	.yui-ge .yui-u,
+	.yui-gf div.first {width:24%;}
+
+	.yui-g .yui-gb div.first,
+	.yui-gb div.first, 
+	.yui-gc div.first, 
+	.yui-gd div.first {margin-left:0;}
+	   
+	/*
+		Section: Deep Nesting 
+	*/
+	.yui-g .yui-g .yui-u,
+	.yui-gb .yui-g .yui-u,
+	.yui-gc .yui-g .yui-u,
+	.yui-gd .yui-g .yui-u,
+	.yui-ge .yui-g .yui-u,
+	.yui-gf .yui-g .yui-u {width:49%;*width:48.1%;*margin-left:0;}
+
+	.yui-g .yui-gb div.first,
+	.yui-gb .yui-gb div.first {*margin-right:0;*width:32%;_width:31.7%;}
+
+	.yui-g .yui-gc div.first, 
+	.yui-gd .yui-g  {width:66%;}
+
+	.yui-gb .yui-g div.first {*margin-right:4%;_margin-right:1.3%;}
+
+	.yui-gb .yui-gc div.first, 
+	.yui-gb .yui-gd div.first  {*margin-right:0;}
+
+	.yui-gb .yui-gb .yui-u,
+	.yui-gb .yui-gc .yui-u {*margin-left:1.8%;_margin-left:4%;}
+
+	.yui-g .yui-gb .yui-u {_margin-left:1.0%;}
+
+	.yui-gb .yui-gd .yui-u {*width:66%;_width:61.2%;} 
+	.yui-gb .yui-gd div.first {*width:31%;_width:29.5%;}
+
+	.yui-g .yui-gc .yui-u, 
+	.yui-gb .yui-gc .yui-u {width:32%;_float:right;margin-right:0;_margin-left:0;}
+	.yui-gb .yui-gc div.first {width:66%;*float:left;*margin-left:0;}
+
+	.yui-gb .yui-ge .yui-u, 
+	.yui-gb .yui-gf .yui-u {margin:0;}
+
+	.yui-gb .yui-gb .yui-u {_margin-left:.7%;}
+
+	.yui-gb .yui-g div.first, 
+	.yui-gb .yui-gb div.first {*margin-left:0;}
+
+	.yui-gc .yui-g .yui-u,
+	.yui-gd .yui-g .yui-u {*width:48.1%;*margin-left:0;}s
+
+	.yui-gb .yui-gd div.first {width:32%;}
+	.yui-g .yui-gd div.first {_width:29.9%;}
+
+	.yui-ge .yui-g {width:24%;}
+	.yui-gf .yui-g {width:74.2%;}
+
+	.yui-gb .yui-ge div.yui-u,
+	.yui-gb .yui-gf div.yui-u {float:right;}
+	.yui-gb .yui-ge div.first,
+	.yui-gb .yui-gf div.first  {float:left;}
+
+	/* Width Accommodation for Nested Contexts */
+	.yui-gb .yui-ge .yui-u,
+	.yui-gb .yui-gf div.first {*width:24%;_width:20%;}
+
+	/* Width Accommodation for Nested Contexts */
+	.yui-gb .yui-ge div.first, 
+	.yui-gb .yui-gf .yui-u{*width:73.5%;_width:65.5%;}
+
+	/* Patch for GD within GE */
+	.yui-ge div.first .yui-gd .yui-u {width:65%;}
+	.yui-ge div.first .yui-gd div.first {width:32%;}
+
+/*
+	Section: Clearing 
+*/
+
 #bd:after,
 .yui-g:after, 
 .yui-gb:after, 
@@ -157,4 +281,3 @@
 .yui-gd, 
 .yui-ge, 
 .yui-gf{zoom:1;}
-.yui-gb .yui-u {float:left;}
\ No newline at end of file

Modified: trunk/root/static/yui/history/README
===================================================================
--- trunk/root/static/yui/history/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/history/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,19 @@
 YUI Library - History - Release Notes
 
-2.4.1
-No change
+2.5.1
 
+  * While BHM still does not work with current versions of Opera, we
+    are no longer throwing an exception in Opera -- which, if uncaught,
+    causes execution to stop.  Instead, we're messaging the unsupported
+    browser issue via YAHOO.log.  This will allow other aspects of a BHM-
+    managed script to continue executing in Opera.
+  * Fixed issue with case-sensitive tagName comparisons
+    (SourceForge bug 1868730).
+
+2.5.0
+
+  * No changes.
+
 2.4.0
 
   * Added onReady method (similar to the Event utility's DOMReady method)
@@ -48,4 +59,4 @@
     are not considered appropriate for implementation in mission-
     critical applications. Please see the YUI FAQ at
     http://developer.yahoo.com/yui/articles/faq/#experimental
-    for more information about the "experimental" designation.
+    for more information about the "experimental" designation.
\ No newline at end of file

Modified: trunk/root/static/yui/history/history-debug.js
===================================================================
--- trunk/root/static/yui/history/history-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/history/history-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The Browser History Manager provides the ability to use the back/forward
@@ -11,8 +11,8 @@
  *
  * This library requires the following static markup:
  *
- * <iframe id="yui-history-iframe" src="path-to-real-asset-in-same-domain"></iframe>
- * <input id="yui-history-field" type="hidden">
+ * <iframe id="yui-history-iframe" src="path-to-real-asset-in-same-domain"></iframe>
+ * <input id="yui-history-field" type="hidden">
  *
  * @module history
  * @requires yahoo,event
@@ -538,7 +538,7 @@
                 // As a consequence, the best thing we can do is to throw an
                 // exception. The application should catch it, and degrade
                 // gracefully. This is the sad state of history management.
-                throw new Error("Unsupported browser");
+                YAHOO.log("Unsupported browser.", "error", this.toString());
             }
 
             if (typeof stateField === "string") {
@@ -546,8 +546,8 @@
             }
 
             if (!stateField ||
-                stateField.tagName !== "TEXTAREA" &&
-                (stateField.tagName !== "INPUT" ||
+                stateField.tagName.toUpperCase() !== "TEXTAREA" &&
+                (stateField.tagName.toUpperCase() !== "INPUT" ||
                  stateField.type !== "hidden" &&
                  stateField.type !== "text")) {
                 throw new Error("Missing or invalid argument");
@@ -561,7 +561,7 @@
                     histFrame = document.getElementById(histFrame);
                 }
 
-                if (!histFrame || histFrame.tagName !== "IFRAME") {
+                if (!histFrame || histFrame.tagName.toUpperCase() !== "IFRAME") {
                     throw new Error("Missing or invalid argument");
                 }
 
@@ -631,9 +631,9 @@
                 if (YAHOO.lang.hasOwnProperty(_modules, moduleName)) {
                     moduleObj = _modules[moduleName];
                     if (YAHOO.lang.hasOwnProperty(states, moduleName)) {
-                        currentState = states[moduleName];
+                        currentState = states[unescape(moduleName)];
                     } else {
-                        currentState = moduleObj.currentState;
+                        currentState = unescape(moduleObj.currentState);
                     }
 
                     // Make sure the strings passed in do not contain our separators "," and "|"
@@ -786,4 +786,4 @@
     };
 
 })();
-YAHOO.register("history", YAHOO.util.History, {version: "2.4.1", build: "742"});
+YAHOO.register("history", YAHOO.util.History, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/history/history-min.js
===================================================================
--- trunk/root/static/yui/history/history-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/history/history-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-YAHOO.util.History=(function(){var C=null;var K=null;var F=false;var D=[];var B=[];function I(){var M,L;L=top.location.href;M=L.indexOf("#");return M>=0?L.substr(M+1):null;}function A(){var M,N,O=[],L=[];for(M in D){if(YAHOO.lang.hasOwnProperty(D,M)){N=D[M];O.push(M+"="+N.initialState);L.push(M+"="+N.currentState);}}K.value=O.join("&")+"|"+L.join("&");if(YAHOO.env.ua.webkit){K.value+="|"+B.join(",");}}function H(L){var Q,R,M,O,P,T,S,N;if(!L){for(M in D){if(YAHOO.lang.hasOwnProperty(D,M)){O=D[M];O.currentState=O.initialState;O.onStateChange(unescape(O.currentState));}}return ;}P=[];T=L.split("&");for(Q=0,R=T.length;Q<R;Q++){S=T[Q].split("=");if(S.length===2){M=S[0];N=S[1];P[M]=N;}}for(M in D){if(YAHOO.lang.hasOwnProperty(D,M)){O=D[M];N=P[M];if(!N||O.currentState!==N){O.currentState=N||O.initialState;O.onStateChange(unescape(O.currentState));}}}}function J(O){var L,N;L="<html><body><div id=\"state\">"+O+"</div></body></html>";try{N=C.contentWindow.document;N.open();N.write(L)!
 ;N.close();return true;}catch(M){return false;}}function G(){var O,L,N,M;if(!C.contentWindow||!C.contentWindow.document){setTimeout(G,10);return ;}O=C.contentWindow.document;L=O.getElementById("state");N=L?L.innerText:null;M=I();setInterval(function(){var U,Q,R,S,T,P;O=C.contentWindow.document;L=O.getElementById("state");U=L?L.innerText:null;T=I();if(U!==N){N=U;H(N);if(!N){Q=[];for(R in D){if(YAHOO.lang.hasOwnProperty(D,R)){S=D[R];Q.push(R+"="+S.initialState);}}T=Q.join("&");}else{T=N;}top.location.hash=T;M=T;A();}else{if(T!==M){M=T;J(T);}}},50);F=true;YAHOO.util.History.onLoadEvent.fire();}function E(){var S,U,Q,W,M,O,V,P,T,N,L,R;Q=K.value.split("|");if(Q.length>1){V=Q[0].split("&");for(S=0,U=V.length;S<U;S++){W=V[S].split("=");if(W.length===2){M=W[0];P=W[1];O=D[M];if(O){O.initialState=P;}}}T=Q[1].split("&");for(S=0,U=T.length;S<U;S++){W=T[S].split("=");if(W.length>=2){M=W[0];N=W[1];O=D[M];if(O){O.currentState=N;}}}}if(Q.length>2){B=Q[2].split(",");}if(YAHOO.env.ua.ie){G()!
 ;}else{L=history.length;R=I();setInterval(function(){var Z,X,Y!
 ;X=I();Y
=history.length;if(X!==R){R=X;L=Y;H(R);A();}else{if(Y!==L&&YAHOO.env.ua.webkit){R=X;L=Y;Z=B[L-1];H(Z);A();}}},50);F=true;YAHOO.util.History.onLoadEvent.fire();}}return{onLoadEvent:new YAHOO.util.CustomEvent("onLoad"),onReady:function(M,N,L){if(F){setTimeout(function(){var O=window;if(L){if(L===true){O=N;}else{O=L;}}M.call(O,"onLoad",[],N);},0);}else{YAHOO.util.History.onLoadEvent.subscribe(M,N,L);}},register:function(O,L,Q,R,N){var P,M;if(typeof O!=="string"||YAHOO.lang.trim(O)===""||typeof L!=="string"||typeof Q!=="function"){throw new Error("Missing or invalid argument");}if(D[O]){return ;}if(F){throw new Error("All modules must be registered before calling YAHOO.util.History.initialize");}O=escape(O);L=escape(L);P=null;if(N===true){P=R;}else{P=N;}M=function(S){return Q.call(P,S,R);};D[O]={name:O,initialState:L,currentState:L,onStateChange:M};},initialize:function(L,M){if(F){return ;}if(YAHOO.env.ua.opera){throw new Error("Unsupported browser");}if(typeof L==="string"){L=d!
 ocument.getElementById(L);}if(!L||L.tagName!=="TEXTAREA"&&(L.tagName!=="INPUT"||L.type!=="hidden"&&L.type!=="text")){throw new Error("Missing or invalid argument");}K=L;if(YAHOO.env.ua.ie){if(typeof M==="string"){M=document.getElementById(M);}if(!M||M.tagName!=="IFRAME"){throw new Error("Missing or invalid argument");}C=M;}YAHOO.util.Event.onDOMReady(E);},navigate:function(M,N){var L;if(typeof M!=="string"||typeof N!=="string"){throw new Error("Missing or invalid argument");}L={};L[M]=N;return YAHOO.util.History.multiNavigate(L);},multiNavigate:function(M){var L,N,P,O,Q;if(typeof M!=="object"){throw new Error("Missing or invalid argument");}if(!F){throw new Error("The Browser History Manager is not initialized");}for(N in M){if(!D[N]){throw new Error("The following module has not been registered: "+N);}}L=[];for(N in D){if(YAHOO.lang.hasOwnProperty(D,N)){P=D[N];if(YAHOO.lang.hasOwnProperty(M,N)){O=M[N];}else{O=P.currentState;}N=escape(N);O=escape(O);L.push(N+"="+O);}}Q=L.jo!
 in("&");if(YAHOO.env.ua.ie){return J(Q);}else{top.location.has!
 h=Q;if(Y
AHOO.env.ua.webkit){B[history.length]=Q;A();}return true;}},getCurrentState:function(L){var M;if(typeof L!=="string"){throw new Error("Missing or invalid argument");}if(!F){throw new Error("The Browser History Manager is not initialized");}M=D[L];if(!M){throw new Error("No such registered module: "+L);}return unescape(M.currentState);},getBookmarkedState:function(Q){var P,M,L,S,N,R,O;if(typeof Q!=="string"){throw new Error("Missing or invalid argument");}L=top.location.href.indexOf("#");S=L>=0?top.location.href.substr(L+1):top.location.href;N=S.split("&");for(P=0,M=N.length;P<M;P++){R=N[P].split("=");if(R.length===2){O=R[0];if(O===Q){return unescape(R[1]);}}}return null;},getQueryStringParameter:function(Q,N){var O,M,L,S,R,P;N=N||top.location.href;L=N.indexOf("?");S=L>=0?N.substr(L+1):N;L=S.lastIndexOf("#");S=L>=0?S.substr(0,L):S;R=S.split("&");for(O=0,M=R.length;O<M;O++){P=R[O].split("=");if(P.length>=2){if(P[0]===Q){return unescape(P[1]);}}}return null;}};})();YAHOO.regist!
 er("history",YAHOO.util.History,{version:"2.4.1",build:"742"});
\ No newline at end of file
+YAHOO.util.History=(function(){var C=null;var K=null;var F=false;var D=[];var B=[];function I(){var M,L;L=top.location.href;M=L.indexOf("#");return M>=0?L.substr(M+1):null;}function A(){var M,N,O=[],L=[];for(M in D){if(YAHOO.lang.hasOwnProperty(D,M)){N=D[M];O.push(M+"="+N.initialState);L.push(M+"="+N.currentState);}}K.value=O.join("&")+"|"+L.join("&");if(YAHOO.env.ua.webkit){K.value+="|"+B.join(",");}}function H(L){var Q,R,M,O,P,T,S,N;if(!L){for(M in D){if(YAHOO.lang.hasOwnProperty(D,M)){O=D[M];O.currentState=O.initialState;O.onStateChange(unescape(O.currentState));}}return ;}P=[];T=L.split("&");for(Q=0,R=T.length;Q<R;Q++){S=T[Q].split("=");if(S.length===2){M=S[0];N=S[1];P[M]=N;}}for(M in D){if(YAHOO.lang.hasOwnProperty(D,M)){O=D[M];N=P[M];if(!N||O.currentState!==N){O.currentState=N||O.initialState;O.onStateChange(unescape(O.currentState));}}}}function J(O){var L,N;L='<html><body><div id="state">'+O+"</div></body></html>";try{N=C.contentWindow.document;N.open();N.write(L);N!
 .close();return true;}catch(M){return false;}}function G(){var O,L,N,M;if(!C.contentWindow||!C.contentWindow.document){setTimeout(G,10);return ;}O=C.contentWindow.document;L=O.getElementById("state");N=L?L.innerText:null;M=I();setInterval(function(){var U,Q,R,S,T,P;O=C.contentWindow.document;L=O.getElementById("state");U=L?L.innerText:null;T=I();if(U!==N){N=U;H(N);if(!N){Q=[];for(R in D){if(YAHOO.lang.hasOwnProperty(D,R)){S=D[R];Q.push(R+"="+S.initialState);}}T=Q.join("&");}else{T=N;}top.location.hash=T;M=T;A();}else{if(T!==M){M=T;J(T);}}},50);F=true;YAHOO.util.History.onLoadEvent.fire();}function E(){var S,U,Q,W,M,O,V,P,T,N,L,R;Q=K.value.split("|");if(Q.length>1){V=Q[0].split("&");for(S=0,U=V.length;S<U;S++){W=V[S].split("=");if(W.length===2){M=W[0];P=W[1];O=D[M];if(O){O.initialState=P;}}}T=Q[1].split("&");for(S=0,U=T.length;S<U;S++){W=T[S].split("=");if(W.length>=2){M=W[0];N=W[1];O=D[M];if(O){O.currentState=N;}}}}if(Q.length>2){B=Q[2].split(",");}if(YAHOO.env.ua.ie){G();}!
 else{L=history.length;R=I();setInterval(function(){var Z,X,Y;X!
 =I();Y=h
istory.length;if(X!==R){R=X;L=Y;H(R);A();}else{if(Y!==L&&YAHOO.env.ua.webkit){R=X;L=Y;Z=B[L-1];H(Z);A();}}},50);F=true;YAHOO.util.History.onLoadEvent.fire();}}return{onLoadEvent:new YAHOO.util.CustomEvent("onLoad"),onReady:function(M,N,L){if(F){setTimeout(function(){var O=window;if(L){if(L===true){O=N;}else{O=L;}}M.call(O,"onLoad",[],N);},0);}else{YAHOO.util.History.onLoadEvent.subscribe(M,N,L);}},register:function(O,L,Q,R,N){var P,M;if(typeof O!=="string"||YAHOO.lang.trim(O)===""||typeof L!=="string"||typeof Q!=="function"){throw new Error("Missing or invalid argument");}if(D[O]){return ;}if(F){throw new Error("All modules must be registered before calling YAHOO.util.History.initialize");}O=escape(O);L=escape(L);P=null;if(N===true){P=R;}else{P=N;}M=function(S){return Q.call(P,S,R);};D[O]={name:O,initialState:L,currentState:L,onStateChange:M};},initialize:function(L,M){if(F){return ;}if(YAHOO.env.ua.opera){}if(typeof L==="string"){L=document.getElementById(L);}if(!L||L.tagNa!
 me.toUpperCase()!=="TEXTAREA"&&(L.tagName.toUpperCase()!=="INPUT"||L.type!=="hidden"&&L.type!=="text")){throw new Error("Missing or invalid argument");}K=L;if(YAHOO.env.ua.ie){if(typeof M==="string"){M=document.getElementById(M);}if(!M||M.tagName.toUpperCase()!=="IFRAME"){throw new Error("Missing or invalid argument");}C=M;}YAHOO.util.Event.onDOMReady(E);},navigate:function(M,N){var L;if(typeof M!=="string"||typeof N!=="string"){throw new Error("Missing or invalid argument");}L={};L[M]=N;return YAHOO.util.History.multiNavigate(L);},multiNavigate:function(M){var L,N,P,O,Q;if(typeof M!=="object"){throw new Error("Missing or invalid argument");}if(!F){throw new Error("The Browser History Manager is not initialized");}for(N in M){if(!D[N]){throw new Error("The following module has not been registered: "+N);}}L=[];for(N in D){if(YAHOO.lang.hasOwnProperty(D,N)){P=D[N];if(YAHOO.lang.hasOwnProperty(M,N)){O=M[unescape(N)];}else{O=unescape(P.currentState);}N=escape(N);O=escape(O);L.p!
 ush(N+"="+O);}}Q=L.join("&");if(YAHOO.env.ua.ie){return J(Q);}!
 else{top
.location.hash=Q;if(YAHOO.env.ua.webkit){B[history.length]=Q;A();}return true;}},getCurrentState:function(L){var M;if(typeof L!=="string"){throw new Error("Missing or invalid argument");}if(!F){throw new Error("The Browser History Manager is not initialized");}M=D[L];if(!M){throw new Error("No such registered module: "+L);}return unescape(M.currentState);},getBookmarkedState:function(Q){var P,M,L,S,N,R,O;if(typeof Q!=="string"){throw new Error("Missing or invalid argument");}L=top.location.href.indexOf("#");S=L>=0?top.location.href.substr(L+1):top.location.href;N=S.split("&");for(P=0,M=N.length;P<M;P++){R=N[P].split("=");if(R.length===2){O=R[0];if(O===Q){return unescape(R[1]);}}}return null;},getQueryStringParameter:function(Q,N){var O,M,L,S,R,P;N=N||top.location.href;L=N.indexOf("?");S=L>=0?N.substr(L+1):N;L=S.lastIndexOf("#");S=L>=0?S.substr(0,L):S;R=S.split("&");for(O=0,M=R.length;O<M;O++){P=R[O].split("=");if(P.length>=2){if(P[0]===Q){return unescape(P[1]);}}}return null!
 ;}};})();YAHOO.register("history",YAHOO.util.History,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/history/history.js
===================================================================
--- trunk/root/static/yui/history/history.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/history/history.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The Browser History Manager provides the ability to use the back/forward
@@ -11,8 +11,8 @@
  *
  * This library requires the following static markup:
  *
- * <iframe id="yui-history-iframe" src="path-to-real-asset-in-same-domain"></iframe>
- * <input id="yui-history-field" type="hidden">
+ * <iframe id="yui-history-iframe" src="path-to-real-asset-in-same-domain"></iframe>
+ * <input id="yui-history-field" type="hidden">
  *
  * @module history
  * @requires yahoo,event
@@ -538,7 +538,6 @@
                 // As a consequence, the best thing we can do is to throw an
                 // exception. The application should catch it, and degrade
                 // gracefully. This is the sad state of history management.
-                throw new Error("Unsupported browser");
             }
 
             if (typeof stateField === "string") {
@@ -546,8 +545,8 @@
             }
 
             if (!stateField ||
-                stateField.tagName !== "TEXTAREA" &&
-                (stateField.tagName !== "INPUT" ||
+                stateField.tagName.toUpperCase() !== "TEXTAREA" &&
+                (stateField.tagName.toUpperCase() !== "INPUT" ||
                  stateField.type !== "hidden" &&
                  stateField.type !== "text")) {
                 throw new Error("Missing or invalid argument");
@@ -561,7 +560,7 @@
                     histFrame = document.getElementById(histFrame);
                 }
 
-                if (!histFrame || histFrame.tagName !== "IFRAME") {
+                if (!histFrame || histFrame.tagName.toUpperCase() !== "IFRAME") {
                     throw new Error("Missing or invalid argument");
                 }
 
@@ -631,9 +630,9 @@
                 if (YAHOO.lang.hasOwnProperty(_modules, moduleName)) {
                     moduleObj = _modules[moduleName];
                     if (YAHOO.lang.hasOwnProperty(states, moduleName)) {
-                        currentState = states[moduleName];
+                        currentState = states[unescape(moduleName)];
                     } else {
-                        currentState = moduleObj.currentState;
+                        currentState = unescape(moduleObj.currentState);
                     }
 
                     // Make sure the strings passed in do not contain our separators "," and "|"
@@ -786,4 +785,4 @@
     };
 
 })();
-YAHOO.register("history", YAHOO.util.History, {version: "2.4.1", build: "742"});
+YAHOO.register("history", YAHOO.util.History, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/imagecropper/README
===================================================================
--- trunk/root/static/yui/imagecropper/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imagecropper/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,12 @@
+**** version 2.5.1 ***
+    Fixed Issues dealing with mask resize and keeping crop interface inside of crop region
+
+    Bug Fixes:
+        * 1770394 - [SF 1900953 ] Ratio doesn't work
+        * 1776164 - [SF 1903193 ] Several issues with the crop window
+        * 1779430 - [SF 1904258 ] Initial CSS size isn't checked
+    
+
+**** version 2.5.0 ***
+
+Initial Release

Added: trunk/root/static/yui/imagecropper/assets/imagecropper-core.css
===================================================================
--- trunk/root/static/yui/imagecropper/assets/imagecropper-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imagecropper/assets/imagecropper-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,32 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+.yui-crop {
+    position: relative;
+}
+.yui-crop .yui-crop-mask {
+    position: absolute;
+    top: 0;
+    left: 0;
+    height: 100%;
+    width: 100%;
+}
+
+.yui-crop .yui-resize {
+    position: absolute;
+    top: 10px;
+    left: 10px;
+}
+
+.yui-crop .yui-crop-resize-mask {
+    position: absolute;
+    top: 0;
+    left: 0;
+    height: 100%;
+    width: 100%;
+    background-position: -10px -10px;
+    overflow: hidden;
+}

Added: trunk/root/static/yui/imagecropper/assets/skins/sam/imagecropper-skin.css
===================================================================
--- trunk/root/static/yui/imagecropper/assets/skins/sam/imagecropper-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imagecropper/assets/skins/sam/imagecropper-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,16 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+.yui-skin-sam .yui-crop .yui-crop-mask {
+    background-color: #000;
+    opacity: .5;
+    filter: alpha(opacity=50);
+}
+
+.yui-skin-sam .yui-crop .yui-resize {
+    border: 1px dashed #fff;   
+}
+

Added: trunk/root/static/yui/imagecropper/assets/skins/sam/imagecropper.css
===================================================================
--- trunk/root/static/yui/imagecropper/assets/skins/sam/imagecropper.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imagecropper/assets/skins/sam/imagecropper.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+.yui-crop{position:relative;}.yui-crop .yui-crop-mask{position:absolute;top:0;left:0;height:100%;width:100%;}.yui-crop .yui-resize{position:absolute;top:10px;left:10px;}.yui-crop .yui-crop-resize-mask{position:absolute;top:0;left:0;height:100%;width:100%;background-position:-10px -10px;overflow:hidden;}.yui-skin-sam .yui-crop .yui-crop-mask{background-color:#000;opacity:.5;filter:alpha(opacity=50);}.yui-skin-sam .yui-crop .yui-resize{border:1px dashed #fff;}

Added: trunk/root/static/yui/imagecropper/imagecropper-beta-debug.js
===================================================================
--- trunk/root/static/yui/imagecropper/imagecropper-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imagecropper/imagecropper-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,894 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * @description <p>Creates a Image Cropper control.</p>
+ * @namespace YAHOO.widget
+ * @requires yahoo, dom, dragdrop, element, event, resize
+ * @module imagecropper
+ * @beta
+ */
+(function() {
+var Dom = YAHOO.util.Dom,
+    Event = YAHOO.util.Event,
+    Lang = YAHOO.lang;
+
+    /**
+     * @constructor
+     * @class ImageCropper
+     * @description <p>Creates a Image Cropper control.</p>
+     * @extends YAHOO.util.Element
+     * @param {String/HTMLElement} el The image element to make croppable.
+     * @param {Object} attrs Object liternal containing configuration parameters.
+    */
+    var Crop = function(el, config) {
+        YAHOO.log('Initializing', 'log', 'ImageCropper');
+        var oConfig = {
+            element: el,
+            attributes: config || {}
+        };
+
+        Crop.superclass.constructor.call(this, oConfig.element, oConfig.attributes);    
+    };
+
+    /**
+    * @private
+    * @static
+    * @property _instances
+    * @description Internal hash table for all ImageCropper instances
+    * @type Object
+    */ 
+    Crop._instances = {};
+    /**
+    * @static
+    * @method getCropperById 
+    * @description Get's an ImageCropper object by the HTML id of the image associated with the ImageCropper object.
+    * @return {Object} The ImageCropper Object
+    */ 
+    Crop.getCropperById = function(id) {
+        if (Crop._instances[id]) {
+            return Crop._instances[id];
+        }
+        return false;
+    };
+
+    YAHOO.extend(Crop, YAHOO.util.Element, {
+        /**
+        * @private
+        * @property CSS_MAIN
+        * @description The CSS class used to wrap the element 
+        * @type String
+        */
+        CSS_MAIN: 'yui-crop',
+        /**
+        * @private
+        * @property CSS_MASK
+        * @description The CSS class for the mask element
+        * @type String
+        */
+        CSS_MASK: 'yui-crop-mask',
+        /**
+        * @private
+        * @property CSS_RESIZE_MASK
+        * @description The CSS class for the mask inside the resize element
+        * @type String
+        */
+        CSS_RESIZE_MASK: 'yui-crop-resize-mask',
+
+        /**
+        * @private
+        * @property _image
+        * @description The url of the image we are cropping
+        * @type String
+        */
+        _image: null,
+        /**
+        * @private
+        * @property _active
+        * @description Flag to determine if the crop region is active
+        * @type Boolean
+        */
+        _active: null,
+        /**
+        * @private
+        * @property _resize
+        * @description A reference to the Resize Utility used in this Cropper Instance
+        * @type Object
+        */
+        _resize: null,
+        /**
+        * @private
+        * @property _resizeEl
+        * @description The HTML Element used to create the Resize Oject
+        * @type HTMLElement
+        */
+        _resizeEl: null,
+        /**
+        * @private
+        * @property _resizeMaskEl
+        * @description The HTML Element used to create the Resize mask
+        * @type HTMLElement
+        */
+        _resizeMaskEl: null,
+        /**
+        * @private
+        * @property _wrap
+        * @description The HTML Element created to wrap the image
+        * @type HTMLElement
+        */
+        _wrap: null,
+        /**
+        * @private
+        * @property _mask
+        * @description The HTML Element created to "mask" the image being cropped
+        * @type HTMLElement
+        */
+        _mask: null,
+        /**
+        * @private
+        * @method _createWrap
+        * @description Creates the wrapper element used to wrap the image
+        */
+        _createWrap: function() {
+            YAHOO.log('Creating the wrap element', 'log', 'ImageCropper');
+            this._wrap = document.createElement('div');
+            this._wrap.id = this.get('element').id + '_wrap';
+            this._wrap.className = this.CSS_MAIN;
+            var el = this.get('element');
+            this._wrap.style.width = el.width ? el.width + 'px' : Dom.getStyle(el, 'width');
+            this._wrap.style.height = el.height ? el.height + 'px' : Dom.getStyle(el, 'height');
+            
+            var par = this.get('element').parentNode;
+            par.replaceChild(this._wrap, this.get('element'));
+            this._wrap.appendChild(this.get('element'));
+
+            Event.on(this._wrap, 'mouseover', this._handleMouseOver, this, true);
+            Event.on(this._wrap, 'mouseout', this._handleMouseOut, this, true);
+
+            Event.on(this._wrap, 'click', function(ev) { Event.stopEvent(ev); }, this, true);
+        },
+
+        /**
+        * @private
+        * @method _createMask
+        * @description Creates the mask element used to mask the image
+        */
+        _createMask: function() {
+            YAHOO.log('Creating the Mask', 'log', 'ImageCropper');
+            this._mask = document.createElement('div');
+            this._mask.className = this.CSS_MASK;
+            this._wrap.appendChild(this._mask);
+        },
+
+        /**
+        * @private
+        * @method _createResize
+        * @description Creates the resize element and the instance of the Resize Utility
+        */
+        _createResize: function() {
+            YAHOO.log('Creating the Resize element', 'log', 'ImageCropper');
+            this._resizeEl = document.createElement('div');
+            this._resizeEl.className = YAHOO.util.Resize.prototype.CSS_RESIZE;
+            this._resizeEl.style.position = 'absolute';
+            
+            this._resizeEl.innerHTML = '<div class="' + this.CSS_RESIZE_MASK + '"></div>';
+            this._resizeMaskEl = this._resizeEl.firstChild;
+            this._wrap.appendChild(this._resizeEl);
+            this._resizeEl.style.top = this.get('initialXY')[1] + 'px';
+            this._resizeEl.style.left = this.get('initialXY')[0] + 'px';
+            this._resizeMaskEl.style.height = Math.floor(this.get('initHeight')) + 'px';
+            this._resizeMaskEl.style.width = Math.floor(this.get('initWidth')) + 'px';
+
+            this._resize = new YAHOO.util.Resize(this._resizeEl, {
+                knobHandles: true,
+                handles: 'all',
+                draggable: true,
+                status: this.get('status'),
+                minWidth: this.get('minWidth'),
+                minHeight: this.get('minHeight'),
+                ratio: this.get('ratio'),
+                autoRatio: this.get('autoRatio'),
+                height: this.get('initHeight'),
+                width: this.get('initWidth')
+            });
+
+            this._setBackgroundImage(this.get('element').getAttribute('src', 2));
+            this._setBackgroundPosition(-(this.get('initialXY')[0]),  -(this.get('initialXY')[1]));
+
+            this._resize.on('startResize', this._handleStartResizeEvent, this, true);
+            this._resize.on('dragEvent', this._handleDragEvent, this, true);
+            this._resize.on('beforeResize', this._handleBeforeResizeEvent, this, true);
+            this._resize.on('resize', this._handleResizeEvent, this, true);
+            this._resize.dd.on('b4StartDragEvent', this._handleB4DragEvent, this, true);
+        },
+
+        /**
+        * @private
+        * @method _handleMouseOver
+        * @description Handles the mouseover event
+        */
+        _handleMouseOver: function(ev) {
+            var evType = 'keydown';
+            if (YAHOO.env.ua.gecko || YAHOO.env.ua.opera) {
+                evType = 'keypress';
+            }
+            if (!this._active) {
+                this._active = true;
+                if (this.get('useKeys')) {
+                    Event.on(document, evType, this._handleKeyPress, this, true);
+                }
+            }
+        },
+        /**
+        * @private
+        * @method _handleMouseOut
+        * @description Handles the mouseout event
+        */
+        _handleMouseOut: function(ev) {
+            var evType = 'keydown';
+            if (YAHOO.env.ua.gecko || YAHOO.env.ua.opera) {
+                evType = 'keypress';
+            }
+            this._active = false;
+            if (this.get('useKeys')) {
+                Event.removeListener(document, evType, this._handleKeyPress);
+            }
+        },
+
+        /**
+        * @private
+        * @method _moveEl
+        * @description Moves the resize element based on the arrow keys
+        */
+        _moveEl: function(dir, inc) {
+            YAHOO.log('Moving the element', 'log', 'ImageCropper');
+            var t = 0, l = 0,
+                region = this._setConstraints(),
+                resize = true;
+
+            switch (dir) {
+                case 'down':
+                    t = -(inc);
+                    if ((region.bottom - inc) < 0) {
+                        resize = false;
+                        this._resizeEl.style.top = (region.top + region.bottom) + 'px';
+                    }
+                    break;
+                case 'up':
+                    t = (inc);
+                    if ((region.top - inc) < 0) {
+                        resize = false;
+                        this._resizeEl.style.top = '0px';
+                    }
+                    break;
+                case 'right':
+                    l = -(inc);
+                    if ((region.right - inc) < 0) {
+                        resize = false;
+                        this._resizeEl.style.left = (region.left + region.right) + 'px';
+                    }
+                    break;
+                case 'left':
+                    l = inc;
+                    if ((region.left - inc) < 0) {
+                        resize = false;
+                        this._resizeEl.style.left = '0px';
+                    }
+                    break;
+            }
+
+            if (resize) {
+                YAHOO.log('Moving via Key Listener: ' + dir, 'log', 'ImageCropper');
+                this._resizeEl.style.left = (parseInt(this._resizeEl.style.left, 10) - l) + 'px';
+                this._resizeEl.style.top = (parseInt(this._resizeEl.style.top, 10) - t) + 'px';
+                this.fireEvent('moveEvent', { target: 'keypress' });
+            } else {
+                this._setConstraints();
+            }
+            this._syncBackgroundPosition();
+        },
+
+        /**
+        * @private
+        * @method _handleKeyPress
+        * @description Handles the keypress event
+        */
+        _handleKeyPress: function(ev) {
+            var kc = Event.getCharCode(ev),
+                stopEvent = false,
+                inc = ((ev.shiftKey) ? this.get('shiftKeyTick') : this.get('keyTick'));
+
+            switch (kc) {
+                case 0x25: // left
+                    this._moveEl('left', inc);
+                    stopEvent = true;
+                    break;
+                case 0x26: // up
+                    this._moveEl('up', inc);
+                    stopEvent = true;
+                    break;
+                case 0x27: // right
+                    this._moveEl('right', inc);
+                    stopEvent = true;
+                    break;
+                case 0x28: // down
+                    this._moveEl('down', inc);
+                    stopEvent = true;
+                    break;
+                default:
+            }
+            if (stopEvent) {
+                Event.preventDefault(ev);
+            }
+        },
+
+        /**
+        * @private
+        * @method _handleB4DragEvent
+        * @description Handles the DragDrop b4DragEvent event
+        */
+        _handleB4DragEvent: function() {
+            this._setConstraints();
+        },
+
+        /**
+        * @private
+        * @method _handleDragEvent
+        * @description Handles the DragDrop DragEvent event
+        */
+        _handleDragEvent: function() {
+            this._syncBackgroundPosition();
+            this.fireEvent('dragEvent', arguments);
+            this.fireEvent('moveEvent', { target: 'dragevent' });
+        },
+
+        /**
+        * @private
+        * @method _handleBeforeResizeEvent
+        * @description Handles the Resize Utilitys beforeResize event
+        */
+        _handleBeforeResizeEvent: function(args) {
+            var region = Dom.getRegion(this.get('element')),
+                c = this._resize._cache,
+                ch = this._resize._currentHandle, h = 0, w = 0;
+
+            if (args.top && (args.top < region.top)) {
+                h = (c.height + c.top) - region.top;
+                Dom.setY(this._resize.getWrapEl(), region.top);
+                this._resize.getWrapEl().style.height = h + 'px';
+                this._resize._cache.height = h;
+                this._resize._cache.top = region.top;
+                this._syncBackgroundPosition();
+                return false;
+            }
+            if (args.left && (args.left < region.left)) {
+                w = (c.width + c.left) - region.left;
+                Dom.setX(this._resize.getWrapEl(), region.left);
+                this._resize._cache.left = region.left;
+                this._resize.getWrapEl().style.width = w + 'px';
+                this._resize._cache.width = w;
+                this._syncBackgroundPosition();
+                return false;
+            }
+            if (ch != 'tl' && ch != 'l' && ch != 'bl') {
+                if (c.left && args.width && ((c.left + args.width) > region.right)) {
+                    w = (region.right - c.left);
+                    Dom.setX(this._resize.getWrapEl(), (region.right - w));
+                    this._resize.getWrapEl().style.width = w + 'px';
+                    this._resize._cache.left = (region.right - w);
+                    this._resize._cache.width = w;
+                    this._syncBackgroundPosition();
+                    return false;
+                }
+            }
+            if (ch != 't' && ch != 'tr' && ch != 'tl') {
+                if (c.top && args.height && ((c.top + args.height) > region.bottom)) {
+                    h = (region.bottom - c.top);
+                    Dom.setY(this._resize.getWrapEl(), (region.bottom - h));
+                    this._resize.getWrapEl().style.height = h + 'px';
+                    this._resize._cache.height = h;
+                    this._resize._cache.top = (region.bottom - h);
+                    this._syncBackgroundPosition();
+                    return false;
+                }
+            }
+        },
+        /**
+        * @private
+        * @method _handleResizeMaskEl
+        * @description Resizes the inner mask element
+        */
+        _handleResizeMaskEl: function() {
+            var a = this._resize._cache;
+            this._resizeMaskEl.style.height = Math.floor(a.height) + 'px';
+            this._resizeMaskEl.style.width = Math.floor(a.width) + 'px';
+        },
+        /**
+        * @private
+        * @method _handleResizeEvent
+        * @param Event ev The Resize Utilitys resize event.
+        * @description Handles the Resize Utilitys Resize event
+        */
+        _handleResizeEvent: function(ev) {
+            this._setConstraints(true);
+            this._syncBackgroundPosition();
+            this.fireEvent('resizeEvent', arguments);
+            this.fireEvent('moveEvent', { target: 'resizeevent' });
+        },
+
+        /**
+        * @private
+        * @method _syncBackgroundPosition
+        * @description Syncs the packground position of the resize element with the resize elements top and left style position
+        */
+        _syncBackgroundPosition: function() {
+            this._handleResizeMaskEl();
+            this._setBackgroundPosition(-(parseInt(this._resizeEl.style.left, 10)), -(parseInt(this._resizeEl.style.top, 10)));
+        },
+
+        /**
+        * @private
+        * @method _setBackgroundPosition
+        * @param Number l The left position
+        * @param Number t The top position
+        * @description Sets the background image position to the top and left position
+        */
+        _setBackgroundPosition: function(l, t) {
+            //YAHOO.log('Setting the image background position of the mask to: (' + l + ', ' + t + ')', 'log', 'ImageCropper');
+            var bl = parseInt(Dom.getStyle(this._resize.get('element'), 'borderLeftWidth'), 10);
+            var bt = parseInt(Dom.getStyle(this._resize.get('element'), 'borderTopWidth'), 10);
+            var mask = this._resize.getWrapEl().firstChild;
+            var pos = (l - bl) + 'px ' + (t - bt) + 'px';
+            this._resizeMaskEl.style.backgroundPosition = pos;
+        },
+
+        /**
+        * @private
+        * @method _setBackgroundImage
+        * @param String url The url of the image
+        * @description Sets the background image of the resize element
+        */
+        _setBackgroundImage: function(url) {
+            YAHOO.log('Setting the background image', 'log', 'ImageCropper');
+            var mask = this._resize.getWrapEl().firstChild;
+            this._image = url;
+            mask.style.backgroundImage = 'url(' + url + '#)';
+        },
+        
+        /**
+        * @private
+        * @method _handleStartResizeEvent
+        * @description Handles the Resize Utilitys startResizeEvent event
+        */
+        _handleStartResizeEvent: function() {
+            this._setConstraints(true);
+
+            var h = this._resize._cache.height,
+                 w = this._resize._cache.width,
+                 t = parseInt(this._resize.getWrapEl().style.top, 10),
+                 l = parseInt(this._resize.getWrapEl().style.left, 10),
+                 maxH = 0, maxW = 0;
+ 
+            switch (this._resize._currentHandle) {
+                case 'b':
+                    maxH = (h + this._resize.dd.bottomConstraint);
+                    break;
+                case 'l':
+                    maxW = (w + this._resize.dd.leftConstraint);
+                    break;
+                case 'r':
+                    maxH = (h + t);
+                    maxW = (w + this._resize.dd.rightConstraint);
+                    break;
+                 case 'br':
+                     maxH = (h + this._resize.dd.bottomConstraint);
+                     maxW = (w + this._resize.dd.rightConstraint);
+                     break;
+                 case 'tr':
+                     maxH = (h + t);
+                     maxW = (w + this._resize.dd.rightConstraint);
+                     break;
+
+             }
+            
+             if (maxH) {
+                YAHOO.log('Setting the maxHeight on the resize object to: ' + maxH, 'log', 'ImageCropper');
+                 //this._resize.set('maxHeight', maxH);
+             }
+             if (maxW) {
+                YAHOO.log('Setting the maxWidth on the resize object to: ' + maxW, 'log', 'ImageCropper');
+                 //this._resize.set('maxWidth', maxW);
+             }
+
+            this.fireEvent('startResizeEvent', arguments);
+        },
+        
+        /**
+        * @private
+        * @method _setConstraints
+        * @param Boolean inside Used when called from inside a resize event, false by default (dragging)
+        * @description Set the DragDrop constraints to keep the element inside the crop area.
+        * @return {Object} Object containing Top, Right, Bottom and Left constraints
+        */
+        _setConstraints: function(inside) {
+            YAHOO.log('Setting Contraints', 'log', 'ImageCropper');
+            var resize = this._resize;
+            resize.dd.resetConstraints();
+            var height = parseInt(resize.get('height'), 10),
+                width = parseInt(resize.get('width'), 10);
+
+            if (inside) {
+                //Called from inside the resize callback
+                height = resize._cache.height;
+                width = resize._cache.width;
+            }
+
+            //Get the top, right, bottom and left positions
+            var region = Dom.getRegion(this.get('element'));
+            //Get the element we are working on
+            var el = resize.getWrapEl();
+
+            //Get the xy position of it
+            var xy = Dom.getXY(el);
+
+            //Set left to x minus left
+            var left = xy[0] - region.left;
+
+            //Set right to right minus x minus width
+            var right = region.right - xy[0] - width;
+
+            //Set top to y minus top
+            var top = xy[1] - region.top;
+
+            //Set bottom to bottom minus y minus height
+            var bottom = region.bottom - xy[1] - height;
+
+            if (top < 0) {
+                top = 0;
+            }
+            
+            resize.dd.setXConstraint(left, right); 
+            resize.dd.setYConstraint(top, bottom);
+
+            YAHOO.log('Constraints: ' + top + ',' + right + ',' + bottom + ',' + left, 'log', 'ImageCropper');
+
+            return {
+                top: top,
+                right: right,
+                bottom: bottom,
+                left: left
+            };
+
+            
+            
+        },
+        /**
+        * @method getCropCoords
+        * @description Returns the coordinates needed to crop the image
+        * @return {Object} The top, left, height, width and image url of the image being cropped
+        */
+        getCropCoords: function() {
+            var coords = {
+                top: parseInt(this._resize.getWrapEl().style.top, 10),
+                left: parseInt(this._resize.getWrapEl().style.left, 10),
+                height: this._resize._cache.height,
+                width: this._resize._cache.width,
+                image: this._image
+            };
+            YAHOO.log('Getting the crop coordinates: ' + Lang.dump(coords), 'log', 'ImageCropper');
+            return coords;
+        },
+        /**
+        * @method reset
+        * @description Resets the crop element back to it's original position
+        * @return {<a href="YAHOO.widget.ImageCropper.html">YAHOO.widget.ImageCropper</a>} The ImageCropper instance
+        */
+        reset: function() {
+            YAHOO.log('Resetting the control', 'log', 'ImageCropper');
+            this._resize.resize(null, this.get('initHeight'), this.get('initWidth'), 0, 0, true);
+            this._resizeEl.style.top = this.get('initialXY')[1] + 'px';
+            this._resizeEl.style.left = this.get('initialXY')[0] + 'px';
+            this._syncBackgroundPosition();
+            return this;
+        },
+
+        /**
+        * @method getEl
+        * @description Get the HTML reference for the image element.
+        * @return {HTMLElement} The image element
+        */      
+        getEl: function() {
+            return this.get('element');
+        },
+        /**
+        * @method getResizeEl
+        * @description Get the HTML reference for the resize element.
+        * @return {HTMLElement} The resize element
+        */      
+        getResizeEl: function() {
+            return this._resizeEl;
+        },
+        /**
+        * @method getWrapEl
+        * @description Get the HTML reference for the wrap element.
+        * @return {HTMLElement} The wrap element
+        */      
+        getWrapEl: function() {
+            return this._wrap;
+        },
+
+        /**
+        * @method getMaskEl
+        * @description Get the HTML reference for the mask element.
+        * @return {HTMLElement} The mask element
+        */      
+        getMaskEl: function() {
+            return this._mask;
+        },
+
+        /**
+        * @method getResizeMaskEl
+        * @description Get the HTML reference for the resizable object's mask element.
+        * @return {HTMLElement} The resize objects mask element.
+        */      
+        getResizeMaskEl: function() {
+            return this._resizeMaskEl;
+        },
+
+        /**
+        * @method getResizeObject
+        * @description Get the Resize Utility object.
+        * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
+        */      
+        getResizeObject: function() {
+            return this._resize;
+        },
+
+        /** 
+        * @private
+        * @method init
+        * @description The ImageCropper class's initialization method
+        */        
+        init: function(p_oElement, p_oAttributes) {
+            YAHOO.log('init', 'info', 'ImageCropper');
+            Crop.superclass.init.call(this, p_oElement, p_oAttributes);
+
+            var id = p_oElement;
+
+            if (!Lang.isString(id)) {
+                if (id.tagName && (id.tagName.toLowerCase() == 'img')) {
+                    id = Dom.generateId(id);                    
+                } else {
+                    YAHOO.log('Element is not an image.', 'error', 'ImageCropper');
+                    return false;
+                }
+            } else {
+                var el = Dom.get(id);
+                if (el.tagName && el.tagName.toLowerCase() == 'img') {
+                    //All good
+                } else {
+                    YAHOO.log('Element is not an image.', 'error', 'ImageCropper');
+                    return false;
+                }
+            }
+            
+
+
+            Crop._instances[id] = this;
+            this._createWrap();
+            this._createMask();
+            this._createResize();
+            this._setConstraints();
+
+        },
+        /**
+        * @private
+        * @method initAttributes
+        * @description Initializes all of the configuration attributes used to create a croppable element.
+        * @param {Object} attr Object literal specifying a set of 
+        * configuration attributes used to create the widget.
+        */      
+
+        initAttributes: function(attr) {
+            Crop.superclass.initAttributes.call(this, attr);
+
+            /**
+            * @attribute initialXY
+            * @description Array of the XY position that we need to set the crop element to when we build it. Defaults to [10, 10]
+            * @type Array
+            */
+            this.setAttributeConfig('initialXY', {
+                writeOnce: true,
+                validator: YAHOO.lang.isArray,
+                value: attr.initialXY || [10, 10]
+            });
+            /**
+            * @attribute keyTick
+            * @description The pixel tick for the arrow keys, defaults to 1
+            * @type Number
+            */
+            this.setAttributeConfig('keyTick', {
+                validator: YAHOO.lang.isNumber,
+                value: attr.keyTick || 1
+            });
+
+            /**
+            * @attribute shiftKeyTick
+            * @description The pixel tick for shift + the arrow keys, defaults to 10
+            * @type Number
+            */
+            this.setAttributeConfig('shiftKeyTick', {
+                validator: YAHOO.lang.isNumber,
+                value: attr.shiftKeyTick || 10
+            });
+
+            /**
+            * @attribute useKeys
+            * @description Should we use the Arrow keys to position the crop element, defaults to true
+            * @type Boolean
+            */
+            this.setAttributeConfig('useKeys', {
+                validator: YAHOO.lang.isBoolean,
+                value: ((attr.useKeys === false) ? false : true)
+            });
+
+            /**
+            * @attribute status
+            * @description Show the Resize Utility status, defaults to true
+            * @type Boolean
+            */
+            this.setAttributeConfig('status', {
+                validator: YAHOO.lang.isBoolean,
+                value: ((attr.status === false) ? false : true),
+                method: function(status) {
+                    if (this._resize) {
+                        this._resize.set('status', status);
+                    }
+                }
+            });
+
+            /**
+            * @attribute minHeight
+            * @description MinHeight of the crop area, default 50
+            * @type Number
+            */
+            this.setAttributeConfig('minHeight', {
+                validator: YAHOO.lang.isNumber,
+                value: attr.minHeight || 50,
+                method: function(h) {
+                    if (this._resize) {
+                        this._resize.set('minHeight', h);
+                    }
+                }
+            });
+
+            /**
+            * @attribute minWidth
+            * @description MinWidth of the crop area, default 50.
+            * @type Number
+            */
+            this.setAttributeConfig('minWidth', {
+                validator: YAHOO.lang.isNumber,
+                value: attr.minWidth || 50,
+                method: function(w) {
+                    if (this._resize) {
+                        this._resize.set('minWidth', w);
+                    }
+                }
+            });
+
+            /**
+            * @attribute ratio
+            * @description Set the ratio config option of the Resize Utlility, default false
+            * @type Boolean
+            */
+            this.setAttributeConfig('ratio', {
+                validator: YAHOO.lang.isBoolean,
+                value: attr.ratio || false,
+                method: function(r) {
+                    if (this._resize) {
+                        this._resize.set('ratio', r);
+                    }
+                }
+            });
+
+            /**
+            * @attribute ratio
+            * @description Set the autoRatio config option of the Resize Utlility, default true
+            * @type Boolean
+            */
+            this.setAttributeConfig('autoRatio', {
+                validator: YAHOO.lang.isBoolean,
+                value: ((attr.autoRatio === false) ? false : true),
+                method: function(a) {
+                    if (this._resize) {
+                        this._resize.set('autoRatio', a);
+                    }
+                }
+            });
+
+            /**
+            * @attribute initHeight
+            * @description Set the initlal height of the crop area, defaults to 1/4 of the image height
+            * @type Number
+            */
+            this.setAttributeConfig('initHeight', {
+                writeOnce: true,
+                validator: YAHOO.lang.isNumber,
+                value: attr.initHeight || (this.get('element').height / 4)
+            });
+
+            /**
+            * @attribute initWidth
+            * @description Set the initlal width of the crop area, defaults to 1/4 of the image width
+            * @type Number
+            */
+            this.setAttributeConfig('initWidth', {
+                validator: YAHOO.lang.isNumber,
+                writeOnce: true,
+                value: attr.initWidth || (this.get('element').width / 4)
+            });
+
+        },
+        /**
+        * @method destroy
+        * @description Destroys the ImageCropper object and all of it's elements & listeners.
+        */        
+        destroy: function() {
+            YAHOO.log('Destroying the ImageCropper', 'info', 'ImageCropper');
+            this._resize.destroy();
+            this._resizeEl.parentNode.removeChild(this._resizeEl);
+            this._mask.parentNode.removeChild(this._mask);
+            Event.purgeElement(this._wrap);
+            this._wrap.parentNode.replaceChild(this.get('element'), this._wrap);
+            
+            //Brutal Object Destroy
+            for (var i in this) {
+                if (Lang.hasOwnProperty(this, i)) {
+                    this[i] = null;
+                }
+            }
+                       
+        },
+        /**
+        * @method toString
+        * @description Returns a string representing the ImageCropper Object.
+        * @return {String}
+        */        
+        toString: function() {
+            if (this.get) {
+                return 'ImageCropper (#' + this.get('id') + ')';
+            }
+            return 'Image Cropper';
+        }
+    });
+
+    YAHOO.widget.ImageCropper = Crop;
+
+/**
+* @event dragEvent
+* @description Fires when the DragDrop dragEvent
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event startResizeEvent
+* @description Fires when when a resize action is started.
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event resizeEvent
+* @description Fires on every element resize.
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event moveEvent
+* @description Fires on every element move. Inside these methods: _handleKeyPress, _handleDragEvent, _handleResizeEvent
+* @type YAHOO.util.CustomEvent
+*/
+
+})();
+
+YAHOO.register("imagecropper", YAHOO.widget.ImageCropper, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/imagecropper/imagecropper-beta-min.js
===================================================================
--- trunk/root/static/yui/imagecropper/imagecropper-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imagecropper/imagecropper-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+(function(){var C=YAHOO.util.Dom,A=YAHOO.util.Event,D=YAHOO.lang;var B=function(F,E){var G={element:F,attributes:E||{}};B.superclass.constructor.call(this,G.element,G.attributes);};B._instances={};B.getCropperById=function(E){if(B._instances[E]){return B._instances[E];}return false;};YAHOO.extend(B,YAHOO.util.Element,{CSS_MAIN:"yui-crop",CSS_MASK:"yui-crop-mask",CSS_RESIZE_MASK:"yui-crop-resize-mask",_image:null,_active:null,_resize:null,_resizeEl:null,_resizeMaskEl:null,_wrap:null,_mask:null,_createWrap:function(){this._wrap=document.createElement("div");this._wrap.id=this.get("element").id+"_wrap";this._wrap.className=this.CSS_MAIN;var F=this.get("element");this._wrap.style.width=F.width?F.width+"px":C.getStyle(F,"width");this._wrap.style.height=F.height?F.height+"px":C.getStyle(F,"height");var E=this.get("element").parentNode;E.replaceChild(this._wrap,this.get("element"));this._wrap.appendChild(this.get("element"));A.on(this._wrap,"mouseover",this._handleMouseOver,this,t!
 rue);A.on(this._wrap,"mouseout",this._handleMouseOut,this,true);A.on(this._wrap,"click",function(G){A.stopEvent(G);},this,true);},_createMask:function(){this._mask=document.createElement("div");this._mask.className=this.CSS_MASK;this._wrap.appendChild(this._mask);},_createResize:function(){this._resizeEl=document.createElement("div");this._resizeEl.className=YAHOO.util.Resize.prototype.CSS_RESIZE;this._resizeEl.style.position="absolute";this._resizeEl.innerHTML='<div class="'+this.CSS_RESIZE_MASK+'"></div>';this._resizeMaskEl=this._resizeEl.firstChild;this._wrap.appendChild(this._resizeEl);this._resizeEl.style.top=this.get("initialXY")[1]+"px";this._resizeEl.style.left=this.get("initialXY")[0]+"px";this._resizeMaskEl.style.height=Math.floor(this.get("initHeight"))+"px";this._resizeMaskEl.style.width=Math.floor(this.get("initWidth"))+"px";this._resize=new YAHOO.util.Resize(this._resizeEl,{knobHandles:true,handles:"all",draggable:true,status:this.get("status"),minWidth:this.g!
 et("minWidth"),minHeight:this.get("minHeight"),ratio:this.get(!
 "ratio")
,autoRatio:this.get("autoRatio"),height:this.get("initHeight"),width:this.get("initWidth")});this._setBackgroundImage(this.get("element").getAttribute("src",2));this._setBackgroundPosition(-(this.get("initialXY")[0]),-(this.get("initialXY")[1]));this._resize.on("startResize",this._handleStartResizeEvent,this,true);this._resize.on("dragEvent",this._handleDragEvent,this,true);this._resize.on("beforeResize",this._handleBeforeResizeEvent,this,true);this._resize.on("resize",this._handleResizeEvent,this,true);this._resize.dd.on("b4StartDragEvent",this._handleB4DragEvent,this,true);},_handleMouseOver:function(F){var E="keydown";if(YAHOO.env.ua.gecko||YAHOO.env.ua.opera){E="keypress";}if(!this._active){this._active=true;if(this.get("useKeys")){A.on(document,E,this._handleKeyPress,this,true);}}},_handleMouseOut:function(F){var E="keydown";if(YAHOO.env.ua.gecko||YAHOO.env.ua.opera){E="keypress";}this._active=false;if(this.get("useKeys")){A.removeListener(document,E,this._handleKeyPres!
 s);}},_moveEl:function(G,J){var H=0,E=0,I=this._setConstraints(),F=true;switch(G){case"down":H=-(J);if((I.bottom-J)<0){F=false;this._resizeEl.style.top=(I.top+I.bottom)+"px";}break;case"up":H=(J);if((I.top-J)<0){F=false;this._resizeEl.style.top="0px";}break;case"right":E=-(J);if((I.right-J)<0){F=false;this._resizeEl.style.left=(I.left+I.right)+"px";}break;case"left":E=J;if((I.left-J)<0){F=false;this._resizeEl.style.left="0px";}break;}if(F){this._resizeEl.style.left=(parseInt(this._resizeEl.style.left,10)-E)+"px";this._resizeEl.style.top=(parseInt(this._resizeEl.style.top,10)-H)+"px";this.fireEvent("moveEvent",{target:"keypress"});}else{this._setConstraints();}this._syncBackgroundPosition();},_handleKeyPress:function(G){var E=A.getCharCode(G),F=false,H=((G.shiftKey)?this.get("shiftKeyTick"):this.get("keyTick"));switch(E){case 37:this._moveEl("left",H);F=true;break;case 38:this._moveEl("up",H);F=true;break;case 39:this._moveEl("right",H);F=true;break;case 40:this._moveEl("dow!
 n",H);F=true;break;default:}if(F){A.preventDefault(G);}},_hand!
 leB4Drag
Event:function(){this._setConstraints();},_handleDragEvent:function(){this._syncBackgroundPosition();this.fireEvent("dragEvent",arguments);this.fireEvent("moveEvent",{target:"dragevent"});},_handleBeforeResizeEvent:function(F){var I=C.getRegion(this.get("element")),J=this._resize._cache,H=this._resize._currentHandle,G=0,E=0;if(F.top&&(F.top<I.top)){G=(J.height+J.top)-I.top;C.setY(this._resize.getWrapEl(),I.top);this._resize.getWrapEl().style.height=G+"px";this._resize._cache.height=G;this._resize._cache.top=I.top;this._syncBackgroundPosition();return false;}if(F.left&&(F.left<I.left)){E=(J.width+J.left)-I.left;C.setX(this._resize.getWrapEl(),I.left);this._resize._cache.left=I.left;this._resize.getWrapEl().style.width=E+"px";this._resize._cache.width=E;this._syncBackgroundPosition();return false;}if(H!="tl"&&H!="l"&&H!="bl"){if(J.left&&F.width&&((J.left+F.width)>I.right)){E=(I.right-J.left);C.setX(this._resize.getWrapEl(),(I.right-E));this._resize.getWrapEl().style.width=E+"p!
 x";this._resize._cache.left=(I.right-E);this._resize._cache.width=E;this._syncBackgroundPosition();return false;}}if(H!="t"&&H!="tr"&&H!="tl"){if(J.top&&F.height&&((J.top+F.height)>I.bottom)){G=(I.bottom-J.top);C.setY(this._resize.getWrapEl(),(I.bottom-G));this._resize.getWrapEl().style.height=G+"px";this._resize._cache.height=G;this._resize._cache.top=(I.bottom-G);this._syncBackgroundPosition();return false;}}},_handleResizeMaskEl:function(){var E=this._resize._cache;this._resizeMaskEl.style.height=Math.floor(E.height)+"px";this._resizeMaskEl.style.width=Math.floor(E.width)+"px";},_handleResizeEvent:function(E){this._setConstraints(true);this._syncBackgroundPosition();this.fireEvent("resizeEvent",arguments);this.fireEvent("moveEvent",{target:"resizeevent"});},_syncBackgroundPosition:function(){this._handleResizeMaskEl();this._setBackgroundPosition(-(parseInt(this._resizeEl.style.left,10)),-(parseInt(this._resizeEl.style.top,10)));
+},_setBackgroundPosition:function(F,H){var J=parseInt(C.getStyle(this._resize.get("element"),"borderLeftWidth"),10);var G=parseInt(C.getStyle(this._resize.get("element"),"borderTopWidth"),10);var E=this._resize.getWrapEl().firstChild;var I=(F-J)+"px "+(H-G)+"px";this._resizeMaskEl.style.backgroundPosition=I;},_setBackgroundImage:function(F){var E=this._resize.getWrapEl().firstChild;this._image=F;E.style.backgroundImage="url("+F+"#)";},_handleStartResizeEvent:function(){this._setConstraints(true);var I=this._resize._cache.height,F=this._resize._cache.width,H=parseInt(this._resize.getWrapEl().style.top,10),E=parseInt(this._resize.getWrapEl().style.left,10),G=0,J=0;switch(this._resize._currentHandle){case"b":G=(I+this._resize.dd.bottomConstraint);break;case"l":J=(F+this._resize.dd.leftConstraint);break;case"r":G=(I+H);J=(F+this._resize.dd.rightConstraint);break;case"br":G=(I+this._resize.dd.bottomConstraint);J=(F+this._resize.dd.rightConstraint);break;case"tr":G=(I+H);J=(F+thi!
 s._resize.dd.rightConstraint);break;}if(G){}if(J){}this.fireEvent("startResizeEvent",arguments);},_setConstraints:function(J){var H=this._resize;H.dd.resetConstraints();var N=parseInt(H.get("height"),10),F=parseInt(H.get("width"),10);if(J){N=H._cache.height;F=H._cache.width;}var L=C.getRegion(this.get("element"));var G=H.getWrapEl();var O=C.getXY(G);var I=O[0]-L.left;var M=L.right-O[0]-F;var K=O[1]-L.top;var E=L.bottom-O[1]-N;if(K<0){K=0;}H.dd.setXConstraint(I,M);H.dd.setYConstraint(K,E);return{top:K,right:M,bottom:E,left:I};},getCropCoords:function(){var E={top:parseInt(this._resize.getWrapEl().style.top,10),left:parseInt(this._resize.getWrapEl().style.left,10),height:this._resize._cache.height,width:this._resize._cache.width,image:this._image};return E;},reset:function(){this._resize.resize(null,this.get("initHeight"),this.get("initWidth"),0,0,true);this._resizeEl.style.top=this.get("initialXY")[1]+"px";this._resizeEl.style.left=this.get("initialXY")[0]+"px";this._syncBac!
 kgroundPosition();return this;},getEl:function(){return this.g!
 et("elem
ent");},getResizeEl:function(){return this._resizeEl;},getWrapEl:function(){return this._wrap;},getMaskEl:function(){return this._mask;},getResizeMaskEl:function(){return this._resizeMaskEl;},getResizeObject:function(){return this._resize;},init:function(G,E){B.superclass.init.call(this,G,E);var H=G;if(!D.isString(H)){if(H.tagName&&(H.tagName.toLowerCase()=="img")){H=C.generateId(H);}else{return false;}}else{var F=C.get(H);if(F.tagName&&F.tagName.toLowerCase()=="img"){}else{return false;}}B._instances[H]=this;this._createWrap();this._createMask();this._createResize();this._setConstraints();},initAttributes:function(E){B.superclass.initAttributes.call(this,E);this.setAttributeConfig("initialXY",{writeOnce:true,validator:YAHOO.lang.isArray,value:E.initialXY||[10,10]});this.setAttributeConfig("keyTick",{validator:YAHOO.lang.isNumber,value:E.keyTick||1});this.setAttributeConfig("shiftKeyTick",{validator:YAHOO.lang.isNumber,value:E.shiftKeyTick||10});this.setAttributeConfig("useK!
 eys",{validator:YAHOO.lang.isBoolean,value:((E.useKeys===false)?false:true)});this.setAttributeConfig("status",{validator:YAHOO.lang.isBoolean,value:((E.status===false)?false:true),method:function(F){if(this._resize){this._resize.set("status",F);}}});this.setAttributeConfig("minHeight",{validator:YAHOO.lang.isNumber,value:E.minHeight||50,method:function(F){if(this._resize){this._resize.set("minHeight",F);}}});this.setAttributeConfig("minWidth",{validator:YAHOO.lang.isNumber,value:E.minWidth||50,method:function(F){if(this._resize){this._resize.set("minWidth",F);}}});this.setAttributeConfig("ratio",{validator:YAHOO.lang.isBoolean,value:E.ratio||false,method:function(F){if(this._resize){this._resize.set("ratio",F);}}});this.setAttributeConfig("autoRatio",{validator:YAHOO.lang.isBoolean,value:((E.autoRatio===false)?false:true),method:function(F){if(this._resize){this._resize.set("autoRatio",F);}}});this.setAttributeConfig("initHeight",{writeOnce:true,validator:YAHOO.lang.isNumb!
 er,value:E.initHeight||(this.get("element").height/4)});this.s!
 etAttrib
uteConfig("initWidth",{validator:YAHOO.lang.isNumber,writeOnce:true,value:E.initWidth||(this.get("element").width/4)});},destroy:function(){this._resize.destroy();this._resizeEl.parentNode.removeChild(this._resizeEl);this._mask.parentNode.removeChild(this._mask);A.purgeElement(this._wrap);this._wrap.parentNode.replaceChild(this.get("element"),this._wrap);for(var E in this){if(D.hasOwnProperty(this,E)){this[E]=null;}}},toString:function(){if(this.get){return"ImageCropper (#"+this.get("id")+")";}return"Image Cropper";}});YAHOO.widget.ImageCropper=B;})();YAHOO.register("imagecropper",YAHOO.widget.ImageCropper,{version:"2.5.1",build:"984"});
\ No newline at end of file

Added: trunk/root/static/yui/imagecropper/imagecropper-beta.js
===================================================================
--- trunk/root/static/yui/imagecropper/imagecropper-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imagecropper/imagecropper-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,876 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * @description <p>Creates a Image Cropper control.</p>
+ * @namespace YAHOO.widget
+ * @requires yahoo, dom, dragdrop, element, event, resize
+ * @module imagecropper
+ * @beta
+ */
+(function() {
+var Dom = YAHOO.util.Dom,
+    Event = YAHOO.util.Event,
+    Lang = YAHOO.lang;
+
+    /**
+     * @constructor
+     * @class ImageCropper
+     * @description <p>Creates a Image Cropper control.</p>
+     * @extends YAHOO.util.Element
+     * @param {String/HTMLElement} el The image element to make croppable.
+     * @param {Object} attrs Object liternal containing configuration parameters.
+    */
+    var Crop = function(el, config) {
+        var oConfig = {
+            element: el,
+            attributes: config || {}
+        };
+
+        Crop.superclass.constructor.call(this, oConfig.element, oConfig.attributes);    
+    };
+
+    /**
+    * @private
+    * @static
+    * @property _instances
+    * @description Internal hash table for all ImageCropper instances
+    * @type Object
+    */ 
+    Crop._instances = {};
+    /**
+    * @static
+    * @method getCropperById 
+    * @description Get's an ImageCropper object by the HTML id of the image associated with the ImageCropper object.
+    * @return {Object} The ImageCropper Object
+    */ 
+    Crop.getCropperById = function(id) {
+        if (Crop._instances[id]) {
+            return Crop._instances[id];
+        }
+        return false;
+    };
+
+    YAHOO.extend(Crop, YAHOO.util.Element, {
+        /**
+        * @private
+        * @property CSS_MAIN
+        * @description The CSS class used to wrap the element 
+        * @type String
+        */
+        CSS_MAIN: 'yui-crop',
+        /**
+        * @private
+        * @property CSS_MASK
+        * @description The CSS class for the mask element
+        * @type String
+        */
+        CSS_MASK: 'yui-crop-mask',
+        /**
+        * @private
+        * @property CSS_RESIZE_MASK
+        * @description The CSS class for the mask inside the resize element
+        * @type String
+        */
+        CSS_RESIZE_MASK: 'yui-crop-resize-mask',
+
+        /**
+        * @private
+        * @property _image
+        * @description The url of the image we are cropping
+        * @type String
+        */
+        _image: null,
+        /**
+        * @private
+        * @property _active
+        * @description Flag to determine if the crop region is active
+        * @type Boolean
+        */
+        _active: null,
+        /**
+        * @private
+        * @property _resize
+        * @description A reference to the Resize Utility used in this Cropper Instance
+        * @type Object
+        */
+        _resize: null,
+        /**
+        * @private
+        * @property _resizeEl
+        * @description The HTML Element used to create the Resize Oject
+        * @type HTMLElement
+        */
+        _resizeEl: null,
+        /**
+        * @private
+        * @property _resizeMaskEl
+        * @description The HTML Element used to create the Resize mask
+        * @type HTMLElement
+        */
+        _resizeMaskEl: null,
+        /**
+        * @private
+        * @property _wrap
+        * @description The HTML Element created to wrap the image
+        * @type HTMLElement
+        */
+        _wrap: null,
+        /**
+        * @private
+        * @property _mask
+        * @description The HTML Element created to "mask" the image being cropped
+        * @type HTMLElement
+        */
+        _mask: null,
+        /**
+        * @private
+        * @method _createWrap
+        * @description Creates the wrapper element used to wrap the image
+        */
+        _createWrap: function() {
+            this._wrap = document.createElement('div');
+            this._wrap.id = this.get('element').id + '_wrap';
+            this._wrap.className = this.CSS_MAIN;
+            var el = this.get('element');
+            this._wrap.style.width = el.width ? el.width + 'px' : Dom.getStyle(el, 'width');
+            this._wrap.style.height = el.height ? el.height + 'px' : Dom.getStyle(el, 'height');
+            
+            var par = this.get('element').parentNode;
+            par.replaceChild(this._wrap, this.get('element'));
+            this._wrap.appendChild(this.get('element'));
+
+            Event.on(this._wrap, 'mouseover', this._handleMouseOver, this, true);
+            Event.on(this._wrap, 'mouseout', this._handleMouseOut, this, true);
+
+            Event.on(this._wrap, 'click', function(ev) { Event.stopEvent(ev); }, this, true);
+        },
+
+        /**
+        * @private
+        * @method _createMask
+        * @description Creates the mask element used to mask the image
+        */
+        _createMask: function() {
+            this._mask = document.createElement('div');
+            this._mask.className = this.CSS_MASK;
+            this._wrap.appendChild(this._mask);
+        },
+
+        /**
+        * @private
+        * @method _createResize
+        * @description Creates the resize element and the instance of the Resize Utility
+        */
+        _createResize: function() {
+            this._resizeEl = document.createElement('div');
+            this._resizeEl.className = YAHOO.util.Resize.prototype.CSS_RESIZE;
+            this._resizeEl.style.position = 'absolute';
+            
+            this._resizeEl.innerHTML = '<div class="' + this.CSS_RESIZE_MASK + '"></div>';
+            this._resizeMaskEl = this._resizeEl.firstChild;
+            this._wrap.appendChild(this._resizeEl);
+            this._resizeEl.style.top = this.get('initialXY')[1] + 'px';
+            this._resizeEl.style.left = this.get('initialXY')[0] + 'px';
+            this._resizeMaskEl.style.height = Math.floor(this.get('initHeight')) + 'px';
+            this._resizeMaskEl.style.width = Math.floor(this.get('initWidth')) + 'px';
+
+            this._resize = new YAHOO.util.Resize(this._resizeEl, {
+                knobHandles: true,
+                handles: 'all',
+                draggable: true,
+                status: this.get('status'),
+                minWidth: this.get('minWidth'),
+                minHeight: this.get('minHeight'),
+                ratio: this.get('ratio'),
+                autoRatio: this.get('autoRatio'),
+                height: this.get('initHeight'),
+                width: this.get('initWidth')
+            });
+
+            this._setBackgroundImage(this.get('element').getAttribute('src', 2));
+            this._setBackgroundPosition(-(this.get('initialXY')[0]),  -(this.get('initialXY')[1]));
+
+            this._resize.on('startResize', this._handleStartResizeEvent, this, true);
+            this._resize.on('dragEvent', this._handleDragEvent, this, true);
+            this._resize.on('beforeResize', this._handleBeforeResizeEvent, this, true);
+            this._resize.on('resize', this._handleResizeEvent, this, true);
+            this._resize.dd.on('b4StartDragEvent', this._handleB4DragEvent, this, true);
+        },
+
+        /**
+        * @private
+        * @method _handleMouseOver
+        * @description Handles the mouseover event
+        */
+        _handleMouseOver: function(ev) {
+            var evType = 'keydown';
+            if (YAHOO.env.ua.gecko || YAHOO.env.ua.opera) {
+                evType = 'keypress';
+            }
+            if (!this._active) {
+                this._active = true;
+                if (this.get('useKeys')) {
+                    Event.on(document, evType, this._handleKeyPress, this, true);
+                }
+            }
+        },
+        /**
+        * @private
+        * @method _handleMouseOut
+        * @description Handles the mouseout event
+        */
+        _handleMouseOut: function(ev) {
+            var evType = 'keydown';
+            if (YAHOO.env.ua.gecko || YAHOO.env.ua.opera) {
+                evType = 'keypress';
+            }
+            this._active = false;
+            if (this.get('useKeys')) {
+                Event.removeListener(document, evType, this._handleKeyPress);
+            }
+        },
+
+        /**
+        * @private
+        * @method _moveEl
+        * @description Moves the resize element based on the arrow keys
+        */
+        _moveEl: function(dir, inc) {
+            var t = 0, l = 0,
+                region = this._setConstraints(),
+                resize = true;
+
+            switch (dir) {
+                case 'down':
+                    t = -(inc);
+                    if ((region.bottom - inc) < 0) {
+                        resize = false;
+                        this._resizeEl.style.top = (region.top + region.bottom) + 'px';
+                    }
+                    break;
+                case 'up':
+                    t = (inc);
+                    if ((region.top - inc) < 0) {
+                        resize = false;
+                        this._resizeEl.style.top = '0px';
+                    }
+                    break;
+                case 'right':
+                    l = -(inc);
+                    if ((region.right - inc) < 0) {
+                        resize = false;
+                        this._resizeEl.style.left = (region.left + region.right) + 'px';
+                    }
+                    break;
+                case 'left':
+                    l = inc;
+                    if ((region.left - inc) < 0) {
+                        resize = false;
+                        this._resizeEl.style.left = '0px';
+                    }
+                    break;
+            }
+
+            if (resize) {
+                this._resizeEl.style.left = (parseInt(this._resizeEl.style.left, 10) - l) + 'px';
+                this._resizeEl.style.top = (parseInt(this._resizeEl.style.top, 10) - t) + 'px';
+                this.fireEvent('moveEvent', { target: 'keypress' });
+            } else {
+                this._setConstraints();
+            }
+            this._syncBackgroundPosition();
+        },
+
+        /**
+        * @private
+        * @method _handleKeyPress
+        * @description Handles the keypress event
+        */
+        _handleKeyPress: function(ev) {
+            var kc = Event.getCharCode(ev),
+                stopEvent = false,
+                inc = ((ev.shiftKey) ? this.get('shiftKeyTick') : this.get('keyTick'));
+
+            switch (kc) {
+                case 0x25: // left
+                    this._moveEl('left', inc);
+                    stopEvent = true;
+                    break;
+                case 0x26: // up
+                    this._moveEl('up', inc);
+                    stopEvent = true;
+                    break;
+                case 0x27: // right
+                    this._moveEl('right', inc);
+                    stopEvent = true;
+                    break;
+                case 0x28: // down
+                    this._moveEl('down', inc);
+                    stopEvent = true;
+                    break;
+                default:
+            }
+            if (stopEvent) {
+                Event.preventDefault(ev);
+            }
+        },
+
+        /**
+        * @private
+        * @method _handleB4DragEvent
+        * @description Handles the DragDrop b4DragEvent event
+        */
+        _handleB4DragEvent: function() {
+            this._setConstraints();
+        },
+
+        /**
+        * @private
+        * @method _handleDragEvent
+        * @description Handles the DragDrop DragEvent event
+        */
+        _handleDragEvent: function() {
+            this._syncBackgroundPosition();
+            this.fireEvent('dragEvent', arguments);
+            this.fireEvent('moveEvent', { target: 'dragevent' });
+        },
+
+        /**
+        * @private
+        * @method _handleBeforeResizeEvent
+        * @description Handles the Resize Utilitys beforeResize event
+        */
+        _handleBeforeResizeEvent: function(args) {
+            var region = Dom.getRegion(this.get('element')),
+                c = this._resize._cache,
+                ch = this._resize._currentHandle, h = 0, w = 0;
+
+            if (args.top && (args.top < region.top)) {
+                h = (c.height + c.top) - region.top;
+                Dom.setY(this._resize.getWrapEl(), region.top);
+                this._resize.getWrapEl().style.height = h + 'px';
+                this._resize._cache.height = h;
+                this._resize._cache.top = region.top;
+                this._syncBackgroundPosition();
+                return false;
+            }
+            if (args.left && (args.left < region.left)) {
+                w = (c.width + c.left) - region.left;
+                Dom.setX(this._resize.getWrapEl(), region.left);
+                this._resize._cache.left = region.left;
+                this._resize.getWrapEl().style.width = w + 'px';
+                this._resize._cache.width = w;
+                this._syncBackgroundPosition();
+                return false;
+            }
+            if (ch != 'tl' && ch != 'l' && ch != 'bl') {
+                if (c.left && args.width && ((c.left + args.width) > region.right)) {
+                    w = (region.right - c.left);
+                    Dom.setX(this._resize.getWrapEl(), (region.right - w));
+                    this._resize.getWrapEl().style.width = w + 'px';
+                    this._resize._cache.left = (region.right - w);
+                    this._resize._cache.width = w;
+                    this._syncBackgroundPosition();
+                    return false;
+                }
+            }
+            if (ch != 't' && ch != 'tr' && ch != 'tl') {
+                if (c.top && args.height && ((c.top + args.height) > region.bottom)) {
+                    h = (region.bottom - c.top);
+                    Dom.setY(this._resize.getWrapEl(), (region.bottom - h));
+                    this._resize.getWrapEl().style.height = h + 'px';
+                    this._resize._cache.height = h;
+                    this._resize._cache.top = (region.bottom - h);
+                    this._syncBackgroundPosition();
+                    return false;
+                }
+            }
+        },
+        /**
+        * @private
+        * @method _handleResizeMaskEl
+        * @description Resizes the inner mask element
+        */
+        _handleResizeMaskEl: function() {
+            var a = this._resize._cache;
+            this._resizeMaskEl.style.height = Math.floor(a.height) + 'px';
+            this._resizeMaskEl.style.width = Math.floor(a.width) + 'px';
+        },
+        /**
+        * @private
+        * @method _handleResizeEvent
+        * @param Event ev The Resize Utilitys resize event.
+        * @description Handles the Resize Utilitys Resize event
+        */
+        _handleResizeEvent: function(ev) {
+            this._setConstraints(true);
+            this._syncBackgroundPosition();
+            this.fireEvent('resizeEvent', arguments);
+            this.fireEvent('moveEvent', { target: 'resizeevent' });
+        },
+
+        /**
+        * @private
+        * @method _syncBackgroundPosition
+        * @description Syncs the packground position of the resize element with the resize elements top and left style position
+        */
+        _syncBackgroundPosition: function() {
+            this._handleResizeMaskEl();
+            this._setBackgroundPosition(-(parseInt(this._resizeEl.style.left, 10)), -(parseInt(this._resizeEl.style.top, 10)));
+        },
+
+        /**
+        * @private
+        * @method _setBackgroundPosition
+        * @param Number l The left position
+        * @param Number t The top position
+        * @description Sets the background image position to the top and left position
+        */
+        _setBackgroundPosition: function(l, t) {
+            var bl = parseInt(Dom.getStyle(this._resize.get('element'), 'borderLeftWidth'), 10);
+            var bt = parseInt(Dom.getStyle(this._resize.get('element'), 'borderTopWidth'), 10);
+            var mask = this._resize.getWrapEl().firstChild;
+            var pos = (l - bl) + 'px ' + (t - bt) + 'px';
+            this._resizeMaskEl.style.backgroundPosition = pos;
+        },
+
+        /**
+        * @private
+        * @method _setBackgroundImage
+        * @param String url The url of the image
+        * @description Sets the background image of the resize element
+        */
+        _setBackgroundImage: function(url) {
+            var mask = this._resize.getWrapEl().firstChild;
+            this._image = url;
+            mask.style.backgroundImage = 'url(' + url + '#)';
+        },
+        
+        /**
+        * @private
+        * @method _handleStartResizeEvent
+        * @description Handles the Resize Utilitys startResizeEvent event
+        */
+        _handleStartResizeEvent: function() {
+            this._setConstraints(true);
+
+            var h = this._resize._cache.height,
+                 w = this._resize._cache.width,
+                 t = parseInt(this._resize.getWrapEl().style.top, 10),
+                 l = parseInt(this._resize.getWrapEl().style.left, 10),
+                 maxH = 0, maxW = 0;
+ 
+            switch (this._resize._currentHandle) {
+                case 'b':
+                    maxH = (h + this._resize.dd.bottomConstraint);
+                    break;
+                case 'l':
+                    maxW = (w + this._resize.dd.leftConstraint);
+                    break;
+                case 'r':
+                    maxH = (h + t);
+                    maxW = (w + this._resize.dd.rightConstraint);
+                    break;
+                 case 'br':
+                     maxH = (h + this._resize.dd.bottomConstraint);
+                     maxW = (w + this._resize.dd.rightConstraint);
+                     break;
+                 case 'tr':
+                     maxH = (h + t);
+                     maxW = (w + this._resize.dd.rightConstraint);
+                     break;
+
+             }
+            
+             if (maxH) {
+                 //this._resize.set('maxHeight', maxH);
+             }
+             if (maxW) {
+                 //this._resize.set('maxWidth', maxW);
+             }
+
+            this.fireEvent('startResizeEvent', arguments);
+        },
+        
+        /**
+        * @private
+        * @method _setConstraints
+        * @param Boolean inside Used when called from inside a resize event, false by default (dragging)
+        * @description Set the DragDrop constraints to keep the element inside the crop area.
+        * @return {Object} Object containing Top, Right, Bottom and Left constraints
+        */
+        _setConstraints: function(inside) {
+            var resize = this._resize;
+            resize.dd.resetConstraints();
+            var height = parseInt(resize.get('height'), 10),
+                width = parseInt(resize.get('width'), 10);
+
+            if (inside) {
+                //Called from inside the resize callback
+                height = resize._cache.height;
+                width = resize._cache.width;
+            }
+
+            //Get the top, right, bottom and left positions
+            var region = Dom.getRegion(this.get('element'));
+            //Get the element we are working on
+            var el = resize.getWrapEl();
+
+            //Get the xy position of it
+            var xy = Dom.getXY(el);
+
+            //Set left to x minus left
+            var left = xy[0] - region.left;
+
+            //Set right to right minus x minus width
+            var right = region.right - xy[0] - width;
+
+            //Set top to y minus top
+            var top = xy[1] - region.top;
+
+            //Set bottom to bottom minus y minus height
+            var bottom = region.bottom - xy[1] - height;
+
+            if (top < 0) {
+                top = 0;
+            }
+            
+            resize.dd.setXConstraint(left, right); 
+            resize.dd.setYConstraint(top, bottom);
+
+
+            return {
+                top: top,
+                right: right,
+                bottom: bottom,
+                left: left
+            };
+
+            
+            
+        },
+        /**
+        * @method getCropCoords
+        * @description Returns the coordinates needed to crop the image
+        * @return {Object} The top, left, height, width and image url of the image being cropped
+        */
+        getCropCoords: function() {
+            var coords = {
+                top: parseInt(this._resize.getWrapEl().style.top, 10),
+                left: parseInt(this._resize.getWrapEl().style.left, 10),
+                height: this._resize._cache.height,
+                width: this._resize._cache.width,
+                image: this._image
+            };
+            return coords;
+        },
+        /**
+        * @method reset
+        * @description Resets the crop element back to it's original position
+        * @return {<a href="YAHOO.widget.ImageCropper.html">YAHOO.widget.ImageCropper</a>} The ImageCropper instance
+        */
+        reset: function() {
+            this._resize.resize(null, this.get('initHeight'), this.get('initWidth'), 0, 0, true);
+            this._resizeEl.style.top = this.get('initialXY')[1] + 'px';
+            this._resizeEl.style.left = this.get('initialXY')[0] + 'px';
+            this._syncBackgroundPosition();
+            return this;
+        },
+
+        /**
+        * @method getEl
+        * @description Get the HTML reference for the image element.
+        * @return {HTMLElement} The image element
+        */      
+        getEl: function() {
+            return this.get('element');
+        },
+        /**
+        * @method getResizeEl
+        * @description Get the HTML reference for the resize element.
+        * @return {HTMLElement} The resize element
+        */      
+        getResizeEl: function() {
+            return this._resizeEl;
+        },
+        /**
+        * @method getWrapEl
+        * @description Get the HTML reference for the wrap element.
+        * @return {HTMLElement} The wrap element
+        */      
+        getWrapEl: function() {
+            return this._wrap;
+        },
+
+        /**
+        * @method getMaskEl
+        * @description Get the HTML reference for the mask element.
+        * @return {HTMLElement} The mask element
+        */      
+        getMaskEl: function() {
+            return this._mask;
+        },
+
+        /**
+        * @method getResizeMaskEl
+        * @description Get the HTML reference for the resizable object's mask element.
+        * @return {HTMLElement} The resize objects mask element.
+        */      
+        getResizeMaskEl: function() {
+            return this._resizeMaskEl;
+        },
+
+        /**
+        * @method getResizeObject
+        * @description Get the Resize Utility object.
+        * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
+        */      
+        getResizeObject: function() {
+            return this._resize;
+        },
+
+        /** 
+        * @private
+        * @method init
+        * @description The ImageCropper class's initialization method
+        */        
+        init: function(p_oElement, p_oAttributes) {
+            Crop.superclass.init.call(this, p_oElement, p_oAttributes);
+
+            var id = p_oElement;
+
+            if (!Lang.isString(id)) {
+                if (id.tagName && (id.tagName.toLowerCase() == 'img')) {
+                    id = Dom.generateId(id);                    
+                } else {
+                    return false;
+                }
+            } else {
+                var el = Dom.get(id);
+                if (el.tagName && el.tagName.toLowerCase() == 'img') {
+                    //All good
+                } else {
+                    return false;
+                }
+            }
+            
+
+
+            Crop._instances[id] = this;
+            this._createWrap();
+            this._createMask();
+            this._createResize();
+            this._setConstraints();
+
+        },
+        /**
+        * @private
+        * @method initAttributes
+        * @description Initializes all of the configuration attributes used to create a croppable element.
+        * @param {Object} attr Object literal specifying a set of 
+        * configuration attributes used to create the widget.
+        */      
+
+        initAttributes: function(attr) {
+            Crop.superclass.initAttributes.call(this, attr);
+
+            /**
+            * @attribute initialXY
+            * @description Array of the XY position that we need to set the crop element to when we build it. Defaults to [10, 10]
+            * @type Array
+            */
+            this.setAttributeConfig('initialXY', {
+                writeOnce: true,
+                validator: YAHOO.lang.isArray,
+                value: attr.initialXY || [10, 10]
+            });
+            /**
+            * @attribute keyTick
+            * @description The pixel tick for the arrow keys, defaults to 1
+            * @type Number
+            */
+            this.setAttributeConfig('keyTick', {
+                validator: YAHOO.lang.isNumber,
+                value: attr.keyTick || 1
+            });
+
+            /**
+            * @attribute shiftKeyTick
+            * @description The pixel tick for shift + the arrow keys, defaults to 10
+            * @type Number
+            */
+            this.setAttributeConfig('shiftKeyTick', {
+                validator: YAHOO.lang.isNumber,
+                value: attr.shiftKeyTick || 10
+            });
+
+            /**
+            * @attribute useKeys
+            * @description Should we use the Arrow keys to position the crop element, defaults to true
+            * @type Boolean
+            */
+            this.setAttributeConfig('useKeys', {
+                validator: YAHOO.lang.isBoolean,
+                value: ((attr.useKeys === false) ? false : true)
+            });
+
+            /**
+            * @attribute status
+            * @description Show the Resize Utility status, defaults to true
+            * @type Boolean
+            */
+            this.setAttributeConfig('status', {
+                validator: YAHOO.lang.isBoolean,
+                value: ((attr.status === false) ? false : true),
+                method: function(status) {
+                    if (this._resize) {
+                        this._resize.set('status', status);
+                    }
+                }
+            });
+
+            /**
+            * @attribute minHeight
+            * @description MinHeight of the crop area, default 50
+            * @type Number
+            */
+            this.setAttributeConfig('minHeight', {
+                validator: YAHOO.lang.isNumber,
+                value: attr.minHeight || 50,
+                method: function(h) {
+                    if (this._resize) {
+                        this._resize.set('minHeight', h);
+                    }
+                }
+            });
+
+            /**
+            * @attribute minWidth
+            * @description MinWidth of the crop area, default 50.
+            * @type Number
+            */
+            this.setAttributeConfig('minWidth', {
+                validator: YAHOO.lang.isNumber,
+                value: attr.minWidth || 50,
+                method: function(w) {
+                    if (this._resize) {
+                        this._resize.set('minWidth', w);
+                    }
+                }
+            });
+
+            /**
+            * @attribute ratio
+            * @description Set the ratio config option of the Resize Utlility, default false
+            * @type Boolean
+            */
+            this.setAttributeConfig('ratio', {
+                validator: YAHOO.lang.isBoolean,
+                value: attr.ratio || false,
+                method: function(r) {
+                    if (this._resize) {
+                        this._resize.set('ratio', r);
+                    }
+                }
+            });
+
+            /**
+            * @attribute ratio
+            * @description Set the autoRatio config option of the Resize Utlility, default true
+            * @type Boolean
+            */
+            this.setAttributeConfig('autoRatio', {
+                validator: YAHOO.lang.isBoolean,
+                value: ((attr.autoRatio === false) ? false : true),
+                method: function(a) {
+                    if (this._resize) {
+                        this._resize.set('autoRatio', a);
+                    }
+                }
+            });
+
+            /**
+            * @attribute initHeight
+            * @description Set the initlal height of the crop area, defaults to 1/4 of the image height
+            * @type Number
+            */
+            this.setAttributeConfig('initHeight', {
+                writeOnce: true,
+                validator: YAHOO.lang.isNumber,
+                value: attr.initHeight || (this.get('element').height / 4)
+            });
+
+            /**
+            * @attribute initWidth
+            * @description Set the initlal width of the crop area, defaults to 1/4 of the image width
+            * @type Number
+            */
+            this.setAttributeConfig('initWidth', {
+                validator: YAHOO.lang.isNumber,
+                writeOnce: true,
+                value: attr.initWidth || (this.get('element').width / 4)
+            });
+
+        },
+        /**
+        * @method destroy
+        * @description Destroys the ImageCropper object and all of it's elements & listeners.
+        */        
+        destroy: function() {
+            this._resize.destroy();
+            this._resizeEl.parentNode.removeChild(this._resizeEl);
+            this._mask.parentNode.removeChild(this._mask);
+            Event.purgeElement(this._wrap);
+            this._wrap.parentNode.replaceChild(this.get('element'), this._wrap);
+            
+            //Brutal Object Destroy
+            for (var i in this) {
+                if (Lang.hasOwnProperty(this, i)) {
+                    this[i] = null;
+                }
+            }
+                       
+        },
+        /**
+        * @method toString
+        * @description Returns a string representing the ImageCropper Object.
+        * @return {String}
+        */        
+        toString: function() {
+            if (this.get) {
+                return 'ImageCropper (#' + this.get('id') + ')';
+            }
+            return 'Image Cropper';
+        }
+    });
+
+    YAHOO.widget.ImageCropper = Crop;
+
+/**
+* @event dragEvent
+* @description Fires when the DragDrop dragEvent
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event startResizeEvent
+* @description Fires when when a resize action is started.
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event resizeEvent
+* @description Fires on every element resize.
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event moveEvent
+* @description Fires on every element move. Inside these methods: _handleKeyPress, _handleDragEvent, _handleResizeEvent
+* @type YAHOO.util.CustomEvent
+*/
+
+})();
+
+YAHOO.register("imagecropper", YAHOO.widget.ImageCropper, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/imageloader/README
===================================================================
--- trunk/root/static/yui/imageloader/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imageloader/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,12 @@
 ImageLoader - Release Notes
 
-2.4.1
+2.5.1
    * No Change
 
+2.5.0
+   * Group object has an addCustomTrigger() function for adding custom event triggers
+   * PNG background images now support custom properties for AlphaImageLoader
+
 2.4.0
    * No Change
 

Deleted: trunk/root/static/yui/imageloader/imageloader-beta-debug.js
===================================================================
--- trunk/root/static/yui/imageloader/imageloader-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imageloader/imageloader-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,442 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-/**
- * The image loader is a framework to dynamically load images
- * according to certain triggers, enabling faster load times
- * and a more responsive UI.
- *
- * @module imageloader
- * @namespace YAHOO.util
- * @experimental
- */
-
-if (typeof(YAHOO.util.ImageLoader) == 'undefined') {
-	YAHOO.util.ImageLoader = {};
-}
-
-/**
- * A group for images. A group can have one time limit and a series of triggers. Thus the images belonging to this group must share these constraints.
- * @class YAHOO.util.ImageLoader.group
- * @requires YAHOO.util.Dom
- * @requires YAHOO.util.Event
- * @constructor
- * @param {String|HTMLElement}	trigEl	The HTML element id or reference to assign the trigger event to. Can be null for no trigger
- * @param {String}	trigAct The type of event to assign to trigEl. Can be null for no trigger
- * @param {Number}	timeout	Timeout (time limit) length, in seconds. Can be undefined, or <= 0, for no time limit
- */
-YAHOO.util.ImageLoader.group = function(trigEl, trigAct, timeout) {
-	/**
-	 * Name for the group. Only used to identify the group in logging statements
-	 * @property name
-	 * @type String
-	 */
-	this.name = 'unnamed';
-	
-	/**
-	 * Collection of images registered with this group
-	 * @property _imgObjs
-	 * @private
-	 * @type Object
-	 */
-	this._imgObjs = {};
-	
-	/**
-	 * Timeout (time limit) length, in seconds
-	 * @property timeoutLen
-	 * @type Number
-	 */
-	this.timeoutLen = timeout;
-	
-	/**
-	 * Timeout object to keep a handle on the time limit
-	 * @property _timeout
-	 * @private
-	 * @type Object
-	 */
-	this._timeout = null;
-	
-	/**
-	 * Collection of triggers for this group.
-	 * Keeps track of each trigger's element, event, and event-listener-callback "fetch" function
-	 * @property _triggers
-	 * @private
-	 * @type Array
-	 */
-	this._triggers = [];
-
-	/**
-	 * Flag to check if images are above the fold. If foldConditional is true, the group will check each of its image locations at page load. If any part of the image is within the client viewport, the image is displayed immediately
-	 * @property foldConditional
-	 * @type Boolean
-	 */
-	this.foldConditional = false;
-
-	/**
-	 * Class name that will identify images belonging to the group. This class name will be removed from each element in order to fetch images.
-	 * This class should have, in its CSS style definition, "background:none !important;"
-	 * @property className
-	 * @type String
-	 */
-	this.className = null;
-
-	/**
-	 * HTML elements having the class name that is associated with this group
-	 * Elements are stored during the _foldCheck function and reused later during the fetch function. Gives a slight performance improvement when className and foldConditional are both used
-	 * @property _classImageEls
-	 * @private
-	 * @type Array
-	 */
-	this._classImageEls = null;
-
-	// add a listener to set the time limit in the onload
-	YAHOO.util.Event.addListener(window, 'load', this._onloadTasks, this, true);
-	// add the trigger
-	this.addTrigger(trigEl, trigAct);
-
-};
-
-/**
- * Adds a trigger to the group. Call this with the same style as YAHOO.util.Event.addListener
- * @method addTrigger
- * @param {String|HTMLElement} trigEl  The HTML element id or reference to assign the trigger event to
- * @param {String} trigAct The type of event to assign to trigEl
- */
-YAHOO.util.ImageLoader.group.prototype.addTrigger = function(trigEl, trigAct) {
-	if (! trigEl || ! trigAct) {
-		return;
-	}
-	/* Need to wrap the fetch function. Event Util can't distinguish prototyped functions of different instantiations
-	 *   Leads to this scenario: groupA and groupZ both have window-scroll triggers. groupZ also has a 2-sec timeout (groupA has no timeout).
-	 *   groupZ's timeout fires; we remove the triggers. The removeListener call finds the first window-scroll event with Y.u.IL.p.fetch, which is groupA's. 
-	 *   groupA's trigger is removed and never fires, leaving images unfetched
-	 */
-	var wrappedFetch = function() {
-		this.fetch();
-	};
-	this._triggers.push([trigEl, trigAct, wrappedFetch]);
-	YAHOO.util.Event.addListener(trigEl, trigAct, wrappedFetch, this, true);
-};
-
-/**
- * Setup to do in the window's onload
- * Initiates time limit for group; executes the fold check for the images
- * @method _onloadTasks
- * @private
- */
-YAHOO.util.ImageLoader.group.prototype._onloadTasks = function() {
-	if (this.timeoutLen && typeof(this.timeoutLen) == 'number' && this.timeoutLen > 0) {
-		this._timeout = setTimeout(this._getFetchTimeout(), this.timeoutLen * 1000);
-	}
-
-	if (this.foldConditional) {
-		this._foldCheck();
-	}
-};
-
-/**
- * Returns the group's fetch method, with the proper closure, for use with setTimeout
- * @method _getFetchTimeout
- * @return {Function}  group's fetch method
- * @private
- */
-YAHOO.util.ImageLoader.group.prototype._getFetchTimeout = function() {
-	var self = this;
-	return function() { self.fetch(); };
-};
-
-/**
- * Registers a background image with the group
- * @method registerBgImage
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- * @return {Object}	bgImgObj that was registered, for modifying any attributes in the object
- */
-YAHOO.util.ImageLoader.group.prototype.registerBgImage = function(domId, url) {
-	this._imgObjs[domId] = new YAHOO.util.ImageLoader.bgImgObj(domId, url);
-	return this._imgObjs[domId];
-};
-/**
- * Registers a src image with the group
- * @method registerSrcImage
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- * @param {Int}	width	pixel width of the image - defaults to image's natural size
- * @param {Int}	height	pixel height of the image - defaults to image's natural size
- * @return {Object}	srcImgObj that was registered, for modifying any attributes in the object
- */
-YAHOO.util.ImageLoader.group.prototype.registerSrcImage = function(domId, url, width, height) {
-	this._imgObjs[domId] = new YAHOO.util.ImageLoader.srcImgObj(domId, url, width, height);
-	return this._imgObjs[domId];
-};
-/**
- * Registers an alpha-channel-type png background image with the group
- * @method registerPngBgImage
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- * @return {Object}	pngBgImgObj that was registered, for modifying any attributes in the object
- */
-YAHOO.util.ImageLoader.group.prototype.registerPngBgImage = function(domId, url) {
-	this._imgObjs[domId] = new YAHOO.util.ImageLoader.pngBgImgObj(domId, url);
-	return this._imgObjs[domId];
-};
-
-/**
- * Displays the images in the group
- * @method fetch
- */
-YAHOO.util.ImageLoader.group.prototype.fetch = function() {
-	YAHOO.log('Fetching images in group: "' + this.name + '".', 'info', 'imageloader');
-
-	clearTimeout(this._timeout);
-	// remove all listeners
-	for (var i=0; i < this._triggers.length; i++) {
-		YAHOO.util.Event.removeListener(this._triggers[i][0], this._triggers[i][1], this._triggers[i][2]);
-	}
-
-	// fetch whatever we need to by className
-	this._fetchByClass();
-
-	// fetch registered images
-	for (var id in this._imgObjs) {
-		if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
-			this._imgObjs[id].fetch();
-		}
-	}
-};
-
-/**
- * Checks the position of each image in the group. If any part of the image is within the client viewport, shows the image immediately.
- * @method _foldCheck
- * @private
- */
-YAHOO.util.ImageLoader.group.prototype._foldCheck = function() {
-	YAHOO.log('Checking for images above the fold in group: "' + this.name + '"', 'info', 'imageloader');
-	var scrollTop = (document.compatMode != 'CSS1Compat') ? document.body.scrollTop : document.documentElement.scrollTop;
-	var viewHeight = YAHOO.util.Dom.getViewportHeight();
-	var hLimit = scrollTop + viewHeight;
-	var scrollLeft = (document.compatMode != 'CSS1Compat') ? document.body.scrollLeft : document.documentElement.scrollLeft;
-	var viewWidth = YAHOO.util.Dom.getViewportWidth();
-	var wLimit = scrollLeft + viewWidth;
-	for (var id in this._imgObjs) {
-		if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
-			var elPos = YAHOO.util.Dom.getXY(this._imgObjs[id].domId);
-			if (elPos[1] < hLimit && elPos[0] < wLimit) {
-				YAHOO.log('Image with id "' + this._imgObjs[id].domId + '" is above the fold. Fetching image.', 'info', 'imageloader');
-				this._imgObjs[id].fetch();
-			}
-		}
-	}
-	// and by class
-	if (this.className) {
-		this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
-		for (var i=0; i < this._classImageEls.length; i++) {
-			var elPos = YAHOO.util.Dom.getXY(this._classImageEls[i]);
-			if (elPos[1] < hLimit && elPos[0] < wLimit) {
-				YAHOO.log('Image with id "' + this._classImageEls[i].id + '" is above the fold. Fetching image. (Image registered by class name with the group - may not have an id.)', 'info', 'imageloader');
-				YAHOO.util.Dom.removeClass(this._classImageEls[i], this.className);
-			}
-		}
-	}
-};
-
-/**
- * Finds all elements in the Dom with the class name specified in the group. Removes the class from the element in order to let the style definitions trigger the image fetching
- * @method _fetchByClass
- * @private
- */
-YAHOO.util.ImageLoader.group.prototype._fetchByClass = function() {
-	if (! this.className) {
-		return;
-	}
-
-	YAHOO.log('Fetching all images with class "' + this.className + '" in group "' + this.name + '".', 'info', 'imageloader');
-	// this._classImageEls may have been set during _foldCheck
-	if (this._classImageEls === null) {
-		this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
-	}
-	YAHOO.util.Dom.removeClass(this._classImageEls, this.className);
-};
-
-
-/**
- * Base class for image objects to be registered with the groups
- * @class YAHOO.util.ImageLoader.imgObj
- * @constructor
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- */
-YAHOO.util.ImageLoader.imgObj = function(domId, url) {
-	/**
-	 * HTML DOM id of the image element
-	 * @property domId
-	 * @type String
-	 */
-	this.domId = domId;
-
-	/**
-	 * URL for the image
-	 * @property url
-	 * @type String
-	 */
-	this.url = url;
-
-	/**
-	 * Pixel width of the image. Will be set as a "width" attribute after the image is fetched.
-	 * Detaults to the natural width of the image.
-	 * Only appropriate with src images
-	 * @property width
-	 * @type Int
-	 */
-	this.width = null;
-
-	/**
-	 * Pixel height of the image. Will be set as a "height" attribute after the image is fetched.
-	 * Detaults to the natural height of the image.
-	 * Only appropriate with src images
-	 * @property height
-	 * @type Int
-	 */
-	this.height = null;
-
-	/**
-	 * Whether the style.visibility should be set to "visible" after the image is fetched.
-	 * Used when setting src images as visibility:hidden prior to image fetching
-	 * @property setVisible
-	 * @type Boolean
-	 */
-	this.setVisible = false;
-
-	/**
-	 * Whether the image has already been fetched. In the case of a foldCondional group, keeps track for when the trigger is fired so images aren't fetched twice
-	 * @property _fetched
-	 * @type Boolean
-	 * @private
-	 */
-	this._fetched = false;
-};
-
-/**
- * Displays the image; puts the URL into the DOM
- * @method fetch
- */
-YAHOO.util.ImageLoader.imgObj.prototype.fetch = function() {
-	if (this._fetched) {
-		return;
-	}
-	var el = document.getElementById(this.domId);
-	if (! el) {
-		return;
-	}
-	YAHOO.log('Fetching image with id "' + this.domId + '".', 'info', 'imageloader');
-	this._applyUrl(el);
-
-	if (this.setVisible) {
-		el.style.visibility = 'visible';
-	}
-	if (this.width) {
-		el.width = this.width;
-	}
-	if (this.height) {
-		el.height = this.height;
-	}
-	this._fetched = true;
-};
-
-/**
- * Inserts the image URL into the DOM so that the image is displayed.
- * Must be overridden by child class
- * @method _applyUrl
- * @param {Object}	el	HTML DOM element
- * @private
- */
-YAHOO.util.ImageLoader.imgObj.prototype._applyUrl = function(el) {
-};
-
-/**
- * Background image object. A background image is one whose URL is specified by "background-image" in the element's style
- * @class YAHOO.util.ImageLoader.bgImgObj
- * @constructor
- * @extends YAHOO.util.ImageLoader.imgObj
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- */
-YAHOO.util.ImageLoader.bgImgObj = function(domId, url) {
-	YAHOO.util.ImageLoader.bgImgObj.superclass.constructor.call(this, domId, url);
-};
-
-YAHOO.lang.extend(YAHOO.util.ImageLoader.bgImgObj, YAHOO.util.ImageLoader.imgObj);
-
-/**
- * Inserts the image URL into the DOM so that the image is displayed.
- * Sets style.backgroundImage
- * @method _applyUrl
- * @param {Object}	el	HTML DOM element
- * @private
- */
-YAHOO.util.ImageLoader.bgImgObj.prototype._applyUrl = function(el) {
-	el.style.backgroundImage = "url('" + this.url + "')";
-};
-
-/**
- * Source image object. A source image is one whose URL is specified by a src attribute in the DOM element
- * @class YAHOO.util.ImageLoader.srcImgObj
- * @constructor
- * @extends YAHOO.util.ImageLoader.imgObj
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- * @param {Int}	width	pixel width of the image - defaults to image's natural size
- * @param {Int}	height	pixel height of the image - defaults to image's natural size
- */
-YAHOO.util.ImageLoader.srcImgObj = function(domId, url, width, height) {
-	YAHOO.util.ImageLoader.srcImgObj.superclass.constructor.call(this, domId, url);
-	this.width = width;
-	this.height = height;
-};
-
-YAHOO.lang.extend(YAHOO.util.ImageLoader.srcImgObj, YAHOO.util.ImageLoader.imgObj);
-
-/**
- * Inserts the image URL into the DOM so that the image is displayed.
- * Sets src
- * @method _applyUrl
- * @param {Object}	el	HTML DOM element
- * @private
- */
-YAHOO.util.ImageLoader.srcImgObj.prototype._applyUrl = function(el) {
-	el.src = this.url;
-};
-
-/**
- * PNG background image object. A PNG background image is one whose URL is specified through AlphaImageLoader or by "background-image" in the element's style
- * @class YAHOO.util.ImageLoader.pngBgImgObj
- * @constructor
- * @extends YAHOO.util.ImageLoader.imgObj
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- */
-YAHOO.util.ImageLoader.pngBgImgObj = function(domId, url) {
-	YAHOO.util.ImageLoader.pngBgImgObj.superclass.constructor.call(this, domId, url);
-};
-
-YAHOO.lang.extend(YAHOO.util.ImageLoader.pngBgImgObj, YAHOO.util.ImageLoader.imgObj);
-
-/**
- * Inserts the image URL into the DOM so that the image is displayed.
- * If the browser is determined to be IE6 (or older), sets the AlphaImageLoader src; otherwise sets style.backgroundImage
- * @method _applyUrl
- * @param {Object}	el	HTML DOM element
- * @private
- */
-YAHOO.util.ImageLoader.pngBgImgObj.prototype._applyUrl = function(el) {
-	if (YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) {
-		el.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.url + '", sizingMethod="scale")';
-	}
-	else {
-		el.style.backgroundImage = "url('" + this.url + "')";
-	}
-};
-YAHOO.register("imageloader", YAHOO.util.ImageLoader, {version: "2.4.1", build: "742"});

Deleted: trunk/root/static/yui/imageloader/imageloader-beta-min.js
===================================================================
--- trunk/root/static/yui/imageloader/imageloader-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imageloader/imageloader-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-if(typeof (YAHOO.util.ImageLoader)=="undefined"){YAHOO.util.ImageLoader={};}YAHOO.util.ImageLoader.group=function(A,B,C){this.name="unnamed";this._imgObjs={};this.timeoutLen=C;this._timeout=null;this._triggers=[];this.foldConditional=false;this.className=null;this._classImageEls=null;YAHOO.util.Event.addListener(window,"load",this._onloadTasks,this,true);this.addTrigger(A,B);};YAHOO.util.ImageLoader.group.prototype.addTrigger=function(B,C){if(!B||!C){return ;}var A=function(){this.fetch();};this._triggers.push([B,C,A]);YAHOO.util.Event.addListener(B,C,A,this,true);};YAHOO.util.ImageLoader.group.prototype._onloadTasks=function(){if(this.timeoutLen&&typeof (this.timeoutLen)=="number"&&this.timeoutLen>0){this._timeout=setTimeout(this._getFetchTimeout(),this.timeoutLen*1000);}if(this.foldConditional){this._foldCheck();}};YAHOO.util.ImageLoader.group.prototype._getFetchTimeout=function(){var A=this;return function(){A.fetch();};};YAHOO.util.ImageLoader.group.prototype.registerBg!
 Image=function(B,A){this._imgObjs[B]=new YAHOO.util.ImageLoader.bgImgObj(B,A);return this._imgObjs[B];};YAHOO.util.ImageLoader.group.prototype.registerSrcImage=function(D,B,C,A){this._imgObjs[D]=new YAHOO.util.ImageLoader.srcImgObj(D,B,C,A);return this._imgObjs[D];};YAHOO.util.ImageLoader.group.prototype.registerPngBgImage=function(B,A){this._imgObjs[B]=new YAHOO.util.ImageLoader.pngBgImgObj(B,A);return this._imgObjs[B];};YAHOO.util.ImageLoader.group.prototype.fetch=function(){clearTimeout(this._timeout);for(var A=0;A<this._triggers.length;A++){YAHOO.util.Event.removeListener(this._triggers[A][0],this._triggers[A][1],this._triggers[A][2]);}this._fetchByClass();for(var B in this._imgObjs){if(YAHOO.lang.hasOwnProperty(this._imgObjs,B)){this._imgObjs[B].fetch();}}};YAHOO.util.ImageLoader.group.prototype._foldCheck=function(){var C=(document.compatMode!="CSS1Compat")?document.body.scrollTop:document.documentElement.scrollTop;var D=YAHOO.util.Dom.getViewportHeight();var A=C+D;va!
 r E=(document.compatMode!="CSS1Compat")?document.body.scrollLe!
 ft:docum
ent.documentElement.scrollLeft;var G=YAHOO.util.Dom.getViewportWidth();var H=E+G;for(var B in this._imgObjs){if(YAHOO.lang.hasOwnProperty(this._imgObjs,B)){var I=YAHOO.util.Dom.getXY(this._imgObjs[B].domId);if(I[1]<A&&I[0]<H){this._imgObjs[B].fetch();}}}if(this.className){this._classImageEls=YAHOO.util.Dom.getElementsByClassName(this.className);for(var F=0;F<this._classImageEls.length;F++){var I=YAHOO.util.Dom.getXY(this._classImageEls[F]);if(I[1]<A&&I[0]<H){YAHOO.util.Dom.removeClass(this._classImageEls[F],this.className);}}}};YAHOO.util.ImageLoader.group.prototype._fetchByClass=function(){if(!this.className){return ;}if(this._classImageEls===null){this._classImageEls=YAHOO.util.Dom.getElementsByClassName(this.className);}YAHOO.util.Dom.removeClass(this._classImageEls,this.className);};YAHOO.util.ImageLoader.imgObj=function(B,A){this.domId=B;this.url=A;this.width=null;this.height=null;this.setVisible=false;this._fetched=false;};YAHOO.util.ImageLoader.imgObj.prototype.fetch=!
 function(){if(this._fetched){return ;}var A=document.getElementById(this.domId);if(!A){return ;}this._applyUrl(A);if(this.setVisible){A.style.visibility="visible";}if(this.width){A.width=this.width;}if(this.height){A.height=this.height;}this._fetched=true;};YAHOO.util.ImageLoader.imgObj.prototype._applyUrl=function(A){};YAHOO.util.ImageLoader.bgImgObj=function(B,A){YAHOO.util.ImageLoader.bgImgObj.superclass.constructor.call(this,B,A);};YAHOO.lang.extend(YAHOO.util.ImageLoader.bgImgObj,YAHOO.util.ImageLoader.imgObj);YAHOO.util.ImageLoader.bgImgObj.prototype._applyUrl=function(A){A.style.backgroundImage="url('"+this.url+"')";};YAHOO.util.ImageLoader.srcImgObj=function(D,B,C,A){YAHOO.util.ImageLoader.srcImgObj.superclass.constructor.call(this,D,B);this.width=C;this.height=A;};YAHOO.lang.extend(YAHOO.util.ImageLoader.srcImgObj,YAHOO.util.ImageLoader.imgObj);YAHOO.util.ImageLoader.srcImgObj.prototype._applyUrl=function(A){A.src=this.url;};YAHOO.util.ImageLoader.pngBgImgObj=funct!
 ion(B,A){YAHOO.util.ImageLoader.pngBgImgObj.superclass.constru!
 ctor.cal
l(this,B,A);};YAHOO.lang.extend(YAHOO.util.ImageLoader.pngBgImgObj,YAHOO.util.ImageLoader.imgObj);YAHOO.util.ImageLoader.pngBgImgObj.prototype._applyUrl=function(A){if(YAHOO.env.ua.ie&&YAHOO.env.ua.ie<=6){A.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\""+this.url+"\", sizingMethod=\"scale\")";}else{A.style.backgroundImage="url('"+this.url+"')";}};YAHOO.register("imageloader",YAHOO.util.ImageLoader,{version:"2.4.1",build:"742"});
\ No newline at end of file

Deleted: trunk/root/static/yui/imageloader/imageloader-beta.js
===================================================================
--- trunk/root/static/yui/imageloader/imageloader-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imageloader/imageloader-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,436 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-/**
- * The image loader is a framework to dynamically load images
- * according to certain triggers, enabling faster load times
- * and a more responsive UI.
- *
- * @module imageloader
- * @namespace YAHOO.util
- * @experimental
- */
-
-if (typeof(YAHOO.util.ImageLoader) == 'undefined') {
-	YAHOO.util.ImageLoader = {};
-}
-
-/**
- * A group for images. A group can have one time limit and a series of triggers. Thus the images belonging to this group must share these constraints.
- * @class YAHOO.util.ImageLoader.group
- * @requires YAHOO.util.Dom
- * @requires YAHOO.util.Event
- * @constructor
- * @param {String|HTMLElement}	trigEl	The HTML element id or reference to assign the trigger event to. Can be null for no trigger
- * @param {String}	trigAct The type of event to assign to trigEl. Can be null for no trigger
- * @param {Number}	timeout	Timeout (time limit) length, in seconds. Can be undefined, or <= 0, for no time limit
- */
-YAHOO.util.ImageLoader.group = function(trigEl, trigAct, timeout) {
-	/**
-	 * Name for the group. Only used to identify the group in logging statements
-	 * @property name
-	 * @type String
-	 */
-	this.name = 'unnamed';
-	
-	/**
-	 * Collection of images registered with this group
-	 * @property _imgObjs
-	 * @private
-	 * @type Object
-	 */
-	this._imgObjs = {};
-	
-	/**
-	 * Timeout (time limit) length, in seconds
-	 * @property timeoutLen
-	 * @type Number
-	 */
-	this.timeoutLen = timeout;
-	
-	/**
-	 * Timeout object to keep a handle on the time limit
-	 * @property _timeout
-	 * @private
-	 * @type Object
-	 */
-	this._timeout = null;
-	
-	/**
-	 * Collection of triggers for this group.
-	 * Keeps track of each trigger's element, event, and event-listener-callback "fetch" function
-	 * @property _triggers
-	 * @private
-	 * @type Array
-	 */
-	this._triggers = [];
-
-	/**
-	 * Flag to check if images are above the fold. If foldConditional is true, the group will check each of its image locations at page load. If any part of the image is within the client viewport, the image is displayed immediately
-	 * @property foldConditional
-	 * @type Boolean
-	 */
-	this.foldConditional = false;
-
-	/**
-	 * Class name that will identify images belonging to the group. This class name will be removed from each element in order to fetch images.
-	 * This class should have, in its CSS style definition, "background:none !important;"
-	 * @property className
-	 * @type String
-	 */
-	this.className = null;
-
-	/**
-	 * HTML elements having the class name that is associated with this group
-	 * Elements are stored during the _foldCheck function and reused later during the fetch function. Gives a slight performance improvement when className and foldConditional are both used
-	 * @property _classImageEls
-	 * @private
-	 * @type Array
-	 */
-	this._classImageEls = null;
-
-	// add a listener to set the time limit in the onload
-	YAHOO.util.Event.addListener(window, 'load', this._onloadTasks, this, true);
-	// add the trigger
-	this.addTrigger(trigEl, trigAct);
-
-};
-
-/**
- * Adds a trigger to the group. Call this with the same style as YAHOO.util.Event.addListener
- * @method addTrigger
- * @param {String|HTMLElement} trigEl  The HTML element id or reference to assign the trigger event to
- * @param {String} trigAct The type of event to assign to trigEl
- */
-YAHOO.util.ImageLoader.group.prototype.addTrigger = function(trigEl, trigAct) {
-	if (! trigEl || ! trigAct) {
-		return;
-	}
-	/* Need to wrap the fetch function. Event Util can't distinguish prototyped functions of different instantiations
-	 *   Leads to this scenario: groupA and groupZ both have window-scroll triggers. groupZ also has a 2-sec timeout (groupA has no timeout).
-	 *   groupZ's timeout fires; we remove the triggers. The removeListener call finds the first window-scroll event with Y.u.IL.p.fetch, which is groupA's. 
-	 *   groupA's trigger is removed and never fires, leaving images unfetched
-	 */
-	var wrappedFetch = function() {
-		this.fetch();
-	};
-	this._triggers.push([trigEl, trigAct, wrappedFetch]);
-	YAHOO.util.Event.addListener(trigEl, trigAct, wrappedFetch, this, true);
-};
-
-/**
- * Setup to do in the window's onload
- * Initiates time limit for group; executes the fold check for the images
- * @method _onloadTasks
- * @private
- */
-YAHOO.util.ImageLoader.group.prototype._onloadTasks = function() {
-	if (this.timeoutLen && typeof(this.timeoutLen) == 'number' && this.timeoutLen > 0) {
-		this._timeout = setTimeout(this._getFetchTimeout(), this.timeoutLen * 1000);
-	}
-
-	if (this.foldConditional) {
-		this._foldCheck();
-	}
-};
-
-/**
- * Returns the group's fetch method, with the proper closure, for use with setTimeout
- * @method _getFetchTimeout
- * @return {Function}  group's fetch method
- * @private
- */
-YAHOO.util.ImageLoader.group.prototype._getFetchTimeout = function() {
-	var self = this;
-	return function() { self.fetch(); };
-};
-
-/**
- * Registers a background image with the group
- * @method registerBgImage
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- * @return {Object}	bgImgObj that was registered, for modifying any attributes in the object
- */
-YAHOO.util.ImageLoader.group.prototype.registerBgImage = function(domId, url) {
-	this._imgObjs[domId] = new YAHOO.util.ImageLoader.bgImgObj(domId, url);
-	return this._imgObjs[domId];
-};
-/**
- * Registers a src image with the group
- * @method registerSrcImage
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- * @param {Int}	width	pixel width of the image - defaults to image's natural size
- * @param {Int}	height	pixel height of the image - defaults to image's natural size
- * @return {Object}	srcImgObj that was registered, for modifying any attributes in the object
- */
-YAHOO.util.ImageLoader.group.prototype.registerSrcImage = function(domId, url, width, height) {
-	this._imgObjs[domId] = new YAHOO.util.ImageLoader.srcImgObj(domId, url, width, height);
-	return this._imgObjs[domId];
-};
-/**
- * Registers an alpha-channel-type png background image with the group
- * @method registerPngBgImage
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- * @return {Object}	pngBgImgObj that was registered, for modifying any attributes in the object
- */
-YAHOO.util.ImageLoader.group.prototype.registerPngBgImage = function(domId, url) {
-	this._imgObjs[domId] = new YAHOO.util.ImageLoader.pngBgImgObj(domId, url);
-	return this._imgObjs[domId];
-};
-
-/**
- * Displays the images in the group
- * @method fetch
- */
-YAHOO.util.ImageLoader.group.prototype.fetch = function() {
-
-	clearTimeout(this._timeout);
-	// remove all listeners
-	for (var i=0; i < this._triggers.length; i++) {
-		YAHOO.util.Event.removeListener(this._triggers[i][0], this._triggers[i][1], this._triggers[i][2]);
-	}
-
-	// fetch whatever we need to by className
-	this._fetchByClass();
-
-	// fetch registered images
-	for (var id in this._imgObjs) {
-		if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
-			this._imgObjs[id].fetch();
-		}
-	}
-};
-
-/**
- * Checks the position of each image in the group. If any part of the image is within the client viewport, shows the image immediately.
- * @method _foldCheck
- * @private
- */
-YAHOO.util.ImageLoader.group.prototype._foldCheck = function() {
-	var scrollTop = (document.compatMode != 'CSS1Compat') ? document.body.scrollTop : document.documentElement.scrollTop;
-	var viewHeight = YAHOO.util.Dom.getViewportHeight();
-	var hLimit = scrollTop + viewHeight;
-	var scrollLeft = (document.compatMode != 'CSS1Compat') ? document.body.scrollLeft : document.documentElement.scrollLeft;
-	var viewWidth = YAHOO.util.Dom.getViewportWidth();
-	var wLimit = scrollLeft + viewWidth;
-	for (var id in this._imgObjs) {
-		if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
-			var elPos = YAHOO.util.Dom.getXY(this._imgObjs[id].domId);
-			if (elPos[1] < hLimit && elPos[0] < wLimit) {
-				this._imgObjs[id].fetch();
-			}
-		}
-	}
-	// and by class
-	if (this.className) {
-		this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
-		for (var i=0; i < this._classImageEls.length; i++) {
-			var elPos = YAHOO.util.Dom.getXY(this._classImageEls[i]);
-			if (elPos[1] < hLimit && elPos[0] < wLimit) {
-				YAHOO.util.Dom.removeClass(this._classImageEls[i], this.className);
-			}
-		}
-	}
-};
-
-/**
- * Finds all elements in the Dom with the class name specified in the group. Removes the class from the element in order to let the style definitions trigger the image fetching
- * @method _fetchByClass
- * @private
- */
-YAHOO.util.ImageLoader.group.prototype._fetchByClass = function() {
-	if (! this.className) {
-		return;
-	}
-
-	// this._classImageEls may have been set during _foldCheck
-	if (this._classImageEls === null) {
-		this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
-	}
-	YAHOO.util.Dom.removeClass(this._classImageEls, this.className);
-};
-
-
-/**
- * Base class for image objects to be registered with the groups
- * @class YAHOO.util.ImageLoader.imgObj
- * @constructor
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- */
-YAHOO.util.ImageLoader.imgObj = function(domId, url) {
-	/**
-	 * HTML DOM id of the image element
-	 * @property domId
-	 * @type String
-	 */
-	this.domId = domId;
-
-	/**
-	 * URL for the image
-	 * @property url
-	 * @type String
-	 */
-	this.url = url;
-
-	/**
-	 * Pixel width of the image. Will be set as a "width" attribute after the image is fetched.
-	 * Detaults to the natural width of the image.
-	 * Only appropriate with src images
-	 * @property width
-	 * @type Int
-	 */
-	this.width = null;
-
-	/**
-	 * Pixel height of the image. Will be set as a "height" attribute after the image is fetched.
-	 * Detaults to the natural height of the image.
-	 * Only appropriate with src images
-	 * @property height
-	 * @type Int
-	 */
-	this.height = null;
-
-	/**
-	 * Whether the style.visibility should be set to "visible" after the image is fetched.
-	 * Used when setting src images as visibility:hidden prior to image fetching
-	 * @property setVisible
-	 * @type Boolean
-	 */
-	this.setVisible = false;
-
-	/**
-	 * Whether the image has already been fetched. In the case of a foldCondional group, keeps track for when the trigger is fired so images aren't fetched twice
-	 * @property _fetched
-	 * @type Boolean
-	 * @private
-	 */
-	this._fetched = false;
-};
-
-/**
- * Displays the image; puts the URL into the DOM
- * @method fetch
- */
-YAHOO.util.ImageLoader.imgObj.prototype.fetch = function() {
-	if (this._fetched) {
-		return;
-	}
-	var el = document.getElementById(this.domId);
-	if (! el) {
-		return;
-	}
-	this._applyUrl(el);
-
-	if (this.setVisible) {
-		el.style.visibility = 'visible';
-	}
-	if (this.width) {
-		el.width = this.width;
-	}
-	if (this.height) {
-		el.height = this.height;
-	}
-	this._fetched = true;
-};
-
-/**
- * Inserts the image URL into the DOM so that the image is displayed.
- * Must be overridden by child class
- * @method _applyUrl
- * @param {Object}	el	HTML DOM element
- * @private
- */
-YAHOO.util.ImageLoader.imgObj.prototype._applyUrl = function(el) {
-};
-
-/**
- * Background image object. A background image is one whose URL is specified by "background-image" in the element's style
- * @class YAHOO.util.ImageLoader.bgImgObj
- * @constructor
- * @extends YAHOO.util.ImageLoader.imgObj
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- */
-YAHOO.util.ImageLoader.bgImgObj = function(domId, url) {
-	YAHOO.util.ImageLoader.bgImgObj.superclass.constructor.call(this, domId, url);
-};
-
-YAHOO.lang.extend(YAHOO.util.ImageLoader.bgImgObj, YAHOO.util.ImageLoader.imgObj);
-
-/**
- * Inserts the image URL into the DOM so that the image is displayed.
- * Sets style.backgroundImage
- * @method _applyUrl
- * @param {Object}	el	HTML DOM element
- * @private
- */
-YAHOO.util.ImageLoader.bgImgObj.prototype._applyUrl = function(el) {
-	el.style.backgroundImage = "url('" + this.url + "')";
-};
-
-/**
- * Source image object. A source image is one whose URL is specified by a src attribute in the DOM element
- * @class YAHOO.util.ImageLoader.srcImgObj
- * @constructor
- * @extends YAHOO.util.ImageLoader.imgObj
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- * @param {Int}	width	pixel width of the image - defaults to image's natural size
- * @param {Int}	height	pixel height of the image - defaults to image's natural size
- */
-YAHOO.util.ImageLoader.srcImgObj = function(domId, url, width, height) {
-	YAHOO.util.ImageLoader.srcImgObj.superclass.constructor.call(this, domId, url);
-	this.width = width;
-	this.height = height;
-};
-
-YAHOO.lang.extend(YAHOO.util.ImageLoader.srcImgObj, YAHOO.util.ImageLoader.imgObj);
-
-/**
- * Inserts the image URL into the DOM so that the image is displayed.
- * Sets src
- * @method _applyUrl
- * @param {Object}	el	HTML DOM element
- * @private
- */
-YAHOO.util.ImageLoader.srcImgObj.prototype._applyUrl = function(el) {
-	el.src = this.url;
-};
-
-/**
- * PNG background image object. A PNG background image is one whose URL is specified through AlphaImageLoader or by "background-image" in the element's style
- * @class YAHOO.util.ImageLoader.pngBgImgObj
- * @constructor
- * @extends YAHOO.util.ImageLoader.imgObj
- * @param {String}	domId	HTML DOM id of the image element
- * @param {String}	url	URL for the image
- */
-YAHOO.util.ImageLoader.pngBgImgObj = function(domId, url) {
-	YAHOO.util.ImageLoader.pngBgImgObj.superclass.constructor.call(this, domId, url);
-};
-
-YAHOO.lang.extend(YAHOO.util.ImageLoader.pngBgImgObj, YAHOO.util.ImageLoader.imgObj);
-
-/**
- * Inserts the image URL into the DOM so that the image is displayed.
- * If the browser is determined to be IE6 (or older), sets the AlphaImageLoader src; otherwise sets style.backgroundImage
- * @method _applyUrl
- * @param {Object}	el	HTML DOM element
- * @private
- */
-YAHOO.util.ImageLoader.pngBgImgObj.prototype._applyUrl = function(el) {
-	if (YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) {
-		el.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.url + '", sizingMethod="scale")';
-	}
-	else {
-		el.style.backgroundImage = "url('" + this.url + "')";
-	}
-};
-YAHOO.register("imageloader", YAHOO.util.ImageLoader, {version: "2.4.1", build: "742"});

Added: trunk/root/static/yui/imageloader/imageloader-debug.js
===================================================================
--- trunk/root/static/yui/imageloader/imageloader-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imageloader/imageloader-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,487 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * The image loader is a framework to dynamically load images
+ * according to certain triggers, enabling faster load times
+ * and a more responsive UI.
+ *
+ * @module imageloader
+ * @namespace YAHOO.util
+ */
+
+if (typeof(YAHOO.util.ImageLoader) == 'undefined') {
+	YAHOO.util.ImageLoader = {};
+}
+
+/**
+ * A group for images. A group can have one time limit and a series of triggers. Thus the images belonging to this group must share these constraints.
+ * @class YAHOO.util.ImageLoader.group
+ * @requires YAHOO.util.Dom
+ * @requires YAHOO.util.Event
+ * @constructor
+ * @param {String|HTMLElement}	trigEl	The HTML element id or reference to assign the trigger event to. Can be null for no trigger
+ * @param {String}	trigAct The type of event to assign to trigEl. Can be null for no trigger
+ * @param {Number}	timeout	Timeout (time limit) length, in seconds. Can be undefined, or <= 0, for no time limit
+ */
+YAHOO.util.ImageLoader.group = function(trigEl, trigAct, timeout) {
+	/**
+	 * Name for the group. Only used to identify the group in logging statements
+	 * @property name
+	 * @type String
+	 */
+	this.name = 'unnamed';
+	
+	/**
+	 * Collection of images registered with this group
+	 * @property _imgObjs
+	 * @private
+	 * @type Object
+	 */
+	this._imgObjs = {};
+	
+	/**
+	 * Timeout (time limit) length, in seconds
+	 * @property timeoutLen
+	 * @type Number
+	 */
+	this.timeoutLen = timeout;
+	
+	/**
+	 * Timeout object to keep a handle on the time limit
+	 * @property _timeout
+	 * @private
+	 * @type Object
+	 */
+	this._timeout = null;
+	
+	/**
+	 * Collection of triggers for this group.
+	 * Keeps track of each trigger's element, event, and event-listener-callback "fetch" function
+	 * @property _triggers
+	 * @private
+	 * @type Array
+	 */
+	this._triggers = [];
+
+	/**
+	 * Collection of custom-event triggers for this group.
+	 * Keeps track of each trigger's event object and event-listener-callback "fetch" function
+	 * @property _customTriggers
+	 * @private
+	 * @type Array
+	 */
+	this._customTriggers = [];
+
+	/**
+	 * Flag to check if images are above the fold. If foldConditional is true, the group will check each of its image locations at page load. If any part of the image is within the client viewport, the image is displayed immediately
+	 * @property foldConditional
+	 * @type Boolean
+	 */
+	this.foldConditional = false;
+
+	/**
+	 * Class name that will identify images belonging to the group. This class name will be removed from each element in order to fetch images.
+	 * This class should have, in its CSS style definition, "background:none !important;"
+	 * @property className
+	 * @type String
+	 */
+	this.className = null;
+
+	/**
+	 * HTML elements having the class name that is associated with this group
+	 * Elements are stored during the _foldCheck function and reused later during the fetch function. Gives a slight performance improvement when className and foldConditional are both used
+	 * @property _classImageEls
+	 * @private
+	 * @type Array
+	 */
+	this._classImageEls = null;
+
+	// add a listener to set the time limit in the onload
+	YAHOO.util.Event.addListener(window, 'load', this._onloadTasks, this, true);
+	// add the trigger
+	this.addTrigger(trigEl, trigAct);
+
+};
+
+/**
+ * Adds a trigger to the group. Call this with the same style as YAHOO.util.Event.addListener
+ * @method addTrigger
+ * @param {String|HTMLElement} trigEl  The HTML element id or reference to assign the trigger event to
+ * @param {String} trigAct The type of event to assign to trigEl
+ */
+YAHOO.util.ImageLoader.group.prototype.addTrigger = function(trigEl, trigAct) {
+	if (! trigEl || ! trigAct) {
+		return;
+	}
+	/* Need to wrap the fetch function. Event Util can't distinguish prototyped functions of different instantiations
+	 *   Leads to this scenario: groupA and groupZ both have window-scroll triggers. groupZ also has a 2-sec timeout (groupA has no timeout).
+	 *   groupZ's timeout fires; we remove the triggers. The removeListener call finds the first window-scroll event with Y.u.IL.p.fetch, which is groupA's. 
+	 *   groupA's trigger is removed and never fires, leaving images unfetched
+	 */
+	var wrappedFetch = function() {
+		this.fetch();
+	};
+	this._triggers.push([trigEl, trigAct, wrappedFetch]);
+	YAHOO.util.Event.addListener(trigEl, trigAct, wrappedFetch, this, true);
+};
+
+/**
+ * Adds a custom event trigger to the group.
+ * @method addCustomTrigger
+ * @param {Object} event A YAHOO.util.CustomEvent object
+ */
+YAHOO.util.ImageLoader.group.prototype.addCustomTrigger = function(event) {
+	// make sure we're dealing with a CustomEvent object
+	if (! event || ! event instanceof YAHOO.util.CustomEvent) {
+		return;
+	}
+
+	// see comment in addTrigger()
+	var wrappedFetch = function() {
+		this.fetch();
+	};
+	this._customTriggers.push([event, wrappedFetch]);
+	event.subscribe(wrappedFetch, this, true);
+};
+
+/**
+ * Setup to do in the window's onload
+ * Initiates time limit for group; executes the fold check for the images
+ * @method _onloadTasks
+ * @private
+ */
+YAHOO.util.ImageLoader.group.prototype._onloadTasks = function() {
+	if (this.timeoutLen && typeof(this.timeoutLen) == 'number' && this.timeoutLen > 0) {
+		this._timeout = setTimeout(this._getFetchTimeout(), this.timeoutLen * 1000);
+	}
+
+	if (this.foldConditional) {
+		this._foldCheck();
+	}
+};
+
+/**
+ * Returns the group's fetch method, with the proper closure, for use with setTimeout
+ * @method _getFetchTimeout
+ * @return {Function}  group's fetch method
+ * @private
+ */
+YAHOO.util.ImageLoader.group.prototype._getFetchTimeout = function() {
+	var self = this;
+	return function() { self.fetch(); };
+};
+
+/**
+ * Registers a background image with the group
+ * @method registerBgImage
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ * @return {Object}	bgImgObj that was registered, for modifying any attributes in the object
+ */
+YAHOO.util.ImageLoader.group.prototype.registerBgImage = function(domId, url) {
+	this._imgObjs[domId] = new YAHOO.util.ImageLoader.bgImgObj(domId, url);
+	return this._imgObjs[domId];
+};
+/**
+ * Registers a src image with the group
+ * @method registerSrcImage
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ * @param {Int}	width	pixel width of the image - defaults to image's natural size
+ * @param {Int}	height	pixel height of the image - defaults to image's natural size
+ * @return {Object}	srcImgObj that was registered, for modifying any attributes in the object
+ */
+YAHOO.util.ImageLoader.group.prototype.registerSrcImage = function(domId, url, width, height) {
+	this._imgObjs[domId] = new YAHOO.util.ImageLoader.srcImgObj(domId, url, width, height);
+	return this._imgObjs[domId];
+};
+/**
+ * Registers an alpha-channel-type png background image with the group
+ * @method registerPngBgImage
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ * @param {Object}  ailProps The AlphaImageLoader properties to be set for the image
+ *                    Valid properties are 'sizingMethod' and 'enabled'
+ * @return {Object}	pngBgImgObj that was registered, for modifying any attributes in the object
+ */
+YAHOO.util.ImageLoader.group.prototype.registerPngBgImage = function(domId, url, ailProps) {
+	this._imgObjs[domId] = new YAHOO.util.ImageLoader.pngBgImgObj(domId, url, ailProps);
+	return this._imgObjs[domId];
+};
+
+/**
+ * Displays the images in the group
+ * @method fetch
+ */
+YAHOO.util.ImageLoader.group.prototype.fetch = function() {
+	YAHOO.log('Fetching images in group: "' + this.name + '".', 'info', 'imageloader');
+
+	clearTimeout(this._timeout);
+	// remove all listeners
+	for (var i=0, len = this._triggers.length; i < len; i++) {
+		YAHOO.util.Event.removeListener(this._triggers[i][0], this._triggers[i][1], this._triggers[i][2]);
+	}
+	// remove custom event subscriptions
+	for (var i=0, len = this._customTriggers.length; i < len; i++) {
+		this._customTriggers[i][0].unsubscribe(this._customTriggers[i][1], this);
+	}
+
+	// fetch whatever we need to by className
+	this._fetchByClass();
+
+	// fetch registered images
+	for (var id in this._imgObjs) {
+		if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
+			this._imgObjs[id].fetch();
+		}
+	}
+};
+
+/**
+ * Checks the position of each image in the group. If any part of the image is within the client viewport, shows the image immediately.
+ * @method _foldCheck
+ * @private
+ */
+YAHOO.util.ImageLoader.group.prototype._foldCheck = function() {
+	YAHOO.log('Checking for images above the fold in group: "' + this.name + '"', 'info', 'imageloader');
+	var scrollTop = (document.compatMode != 'CSS1Compat') ? document.body.scrollTop : document.documentElement.scrollTop;
+	var viewHeight = YAHOO.util.Dom.getViewportHeight();
+	var hLimit = scrollTop + viewHeight;
+	var scrollLeft = (document.compatMode != 'CSS1Compat') ? document.body.scrollLeft : document.documentElement.scrollLeft;
+	var viewWidth = YAHOO.util.Dom.getViewportWidth();
+	var wLimit = scrollLeft + viewWidth;
+	for (var id in this._imgObjs) {
+		if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
+			var elPos = YAHOO.util.Dom.getXY(this._imgObjs[id].domId);
+			if (elPos[1] < hLimit && elPos[0] < wLimit) {
+				YAHOO.log('Image with id "' + this._imgObjs[id].domId + '" is above the fold. Fetching image.', 'info', 'imageloader');
+				this._imgObjs[id].fetch();
+			}
+		}
+	}
+	// and by class
+	if (this.className) {
+		this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
+		for (var i=0, len = this._classImageEls.length; i < len; i++) {
+			var elPos = YAHOO.util.Dom.getXY(this._classImageEls[i]);
+			if (elPos[1] < hLimit && elPos[0] < wLimit) {
+				YAHOO.log('Image with id "' + this._classImageEls[i].id + '" is above the fold. Fetching image. (Image registered by class name with the group - may not have an id.)', 'info', 'imageloader');
+				YAHOO.util.Dom.removeClass(this._classImageEls[i], this.className);
+			}
+		}
+	}
+};
+
+/**
+ * Finds all elements in the Dom with the class name specified in the group. Removes the class from the element in order to let the style definitions trigger the image fetching
+ * @method _fetchByClass
+ * @private
+ */
+YAHOO.util.ImageLoader.group.prototype._fetchByClass = function() {
+	if (! this.className) {
+		return;
+	}
+
+	YAHOO.log('Fetching all images with class "' + this.className + '" in group "' + this.name + '".', 'info', 'imageloader');
+	// this._classImageEls may have been set during _foldCheck
+	if (this._classImageEls === null) {
+		this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
+	}
+	YAHOO.util.Dom.removeClass(this._classImageEls, this.className);
+};
+
+
+/**
+ * Base class for image objects to be registered with the groups
+ * @class YAHOO.util.ImageLoader.imgObj
+ * @constructor
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ */
+YAHOO.util.ImageLoader.imgObj = function(domId, url) {
+	/**
+	 * HTML DOM id of the image element
+	 * @property domId
+	 * @type String
+	 */
+	this.domId = domId;
+
+	/**
+	 * URL for the image
+	 * @property url
+	 * @type String
+	 */
+	this.url = url;
+
+	/**
+	 * Pixel width of the image. Will be set as a "width" attribute after the image is fetched.
+	 * Detaults to the natural width of the image.
+	 * Only appropriate with src images
+	 * @property width
+	 * @type Int
+	 */
+	this.width = null;
+
+	/**
+	 * Pixel height of the image. Will be set as a "height" attribute after the image is fetched.
+	 * Detaults to the natural height of the image.
+	 * Only appropriate with src images
+	 * @property height
+	 * @type Int
+	 */
+	this.height = null;
+
+	/**
+	 * Whether the style.visibility should be set to "visible" after the image is fetched.
+	 * Used when setting src images as visibility:hidden prior to image fetching
+	 * @property setVisible
+	 * @type Boolean
+	 */
+	this.setVisible = false;
+
+	/**
+	 * Whether the image has already been fetched. In the case of a foldCondional group, keeps track for when the trigger is fired so images aren't fetched twice
+	 * @property _fetched
+	 * @type Boolean
+	 * @private
+	 */
+	this._fetched = false;
+};
+
+/**
+ * Displays the image; puts the URL into the DOM
+ * @method fetch
+ */
+YAHOO.util.ImageLoader.imgObj.prototype.fetch = function() {
+	if (this._fetched) {
+		return;
+	}
+	var el = document.getElementById(this.domId);
+	if (! el) {
+		return;
+	}
+	YAHOO.log('Fetching image with id "' + this.domId + '".', 'info', 'imageloader');
+	this._applyUrl(el);
+
+	if (this.setVisible) {
+		el.style.visibility = 'visible';
+	}
+	if (this.width) {
+		el.width = this.width;
+	}
+	if (this.height) {
+		el.height = this.height;
+	}
+	this._fetched = true;
+};
+
+/**
+ * Inserts the image URL into the DOM so that the image is displayed.
+ * Must be overridden by child class
+ * @method _applyUrl
+ * @param {Object}	el	HTML DOM element
+ * @private
+ */
+YAHOO.util.ImageLoader.imgObj.prototype._applyUrl = function(el) {
+};
+
+/**
+ * Background image object. A background image is one whose URL is specified by "background-image" in the element's style
+ * @class YAHOO.util.ImageLoader.bgImgObj
+ * @constructor
+ * @extends YAHOO.util.ImageLoader.imgObj
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ */
+YAHOO.util.ImageLoader.bgImgObj = function(domId, url) {
+	YAHOO.util.ImageLoader.bgImgObj.superclass.constructor.call(this, domId, url);
+};
+
+YAHOO.lang.extend(YAHOO.util.ImageLoader.bgImgObj, YAHOO.util.ImageLoader.imgObj);
+
+/**
+ * Inserts the image URL into the DOM so that the image is displayed.
+ * Sets style.backgroundImage
+ * @method _applyUrl
+ * @param {Object}	el	HTML DOM element
+ * @private
+ */
+YAHOO.util.ImageLoader.bgImgObj.prototype._applyUrl = function(el) {
+	el.style.backgroundImage = "url('" + this.url + "')";
+};
+
+/**
+ * Source image object. A source image is one whose URL is specified by a src attribute in the DOM element
+ * @class YAHOO.util.ImageLoader.srcImgObj
+ * @constructor
+ * @extends YAHOO.util.ImageLoader.imgObj
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ * @param {Int}	width	pixel width of the image - defaults to image's natural size
+ * @param {Int}	height	pixel height of the image - defaults to image's natural size
+ */
+YAHOO.util.ImageLoader.srcImgObj = function(domId, url, width, height) {
+	YAHOO.util.ImageLoader.srcImgObj.superclass.constructor.call(this, domId, url);
+	this.width = width;
+	this.height = height;
+};
+
+YAHOO.lang.extend(YAHOO.util.ImageLoader.srcImgObj, YAHOO.util.ImageLoader.imgObj);
+
+/**
+ * Inserts the image URL into the DOM so that the image is displayed.
+ * Sets src
+ * @method _applyUrl
+ * @param {Object}	el	HTML DOM element
+ * @private
+ */
+YAHOO.util.ImageLoader.srcImgObj.prototype._applyUrl = function(el) {
+	el.src = this.url;
+};
+
+/**
+ * PNG background image object. A PNG background image is one whose URL is specified through AlphaImageLoader or by "background-image" in the element's style
+ * @class YAHOO.util.ImageLoader.pngBgImgObj
+ * @constructor
+ * @extends YAHOO.util.ImageLoader.imgObj
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ * @param {Object}  ailProps The AlphaImageLoader properties to be set for the image
+ *                    Valid properties are 'sizingMethod' and 'enabled'
+ */
+YAHOO.util.ImageLoader.pngBgImgObj = function(domId, url, ailProps) {
+	YAHOO.util.ImageLoader.pngBgImgObj.superclass.constructor.call(this, domId, url);
+
+	/**
+	 * AlphaImageLoader properties to be set for the image.
+	 * Valid properties are "sizingMethod" and "enabled".
+	 * @property props
+	 * @type Object
+	 */
+	this.props = ailProps || {};
+};
+
+YAHOO.lang.extend(YAHOO.util.ImageLoader.pngBgImgObj, YAHOO.util.ImageLoader.imgObj);
+
+/**
+ * Inserts the image URL into the DOM so that the image is displayed.
+ * If the browser is determined to be IE6 (or older), sets the AlphaImageLoader src; otherwise sets style.backgroundImage
+ * @method _applyUrl
+ * @param {Object}	el	HTML DOM element
+ * @private
+ */
+YAHOO.util.ImageLoader.pngBgImgObj.prototype._applyUrl = function(el) {
+	if (YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) {
+		var sizingMethod = (YAHOO.lang.isUndefined(this.props.sizingMethod)) ? 'scale' : this.props.sizingMethod;
+		var enabled = (YAHOO.lang.isUndefined(this.props.enabled)) ? 'true' : this.props.enabled;
+		el.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.url + '", sizingMethod="' + sizingMethod + '", enabled="' + enabled + '")';
+	}
+	else {
+		el.style.backgroundImage = "url('" + this.url + "')";
+	}
+};
+YAHOO.register("imageloader", YAHOO.util.ImageLoader, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/imageloader/imageloader-min.js
===================================================================
--- trunk/root/static/yui/imageloader/imageloader-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imageloader/imageloader-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+if(typeof (YAHOO.util.ImageLoader)=="undefined"){YAHOO.util.ImageLoader={};}YAHOO.util.ImageLoader.group=function(A,B,C){this.name="unnamed";this._imgObjs={};this.timeoutLen=C;this._timeout=null;this._triggers=[];this._customTriggers=[];this.foldConditional=false;this.className=null;this._classImageEls=null;YAHOO.util.Event.addListener(window,"load",this._onloadTasks,this,true);this.addTrigger(A,B);};YAHOO.util.ImageLoader.group.prototype.addTrigger=function(B,C){if(!B||!C){return ;}var A=function(){this.fetch();};this._triggers.push([B,C,A]);YAHOO.util.Event.addListener(B,C,A,this,true);};YAHOO.util.ImageLoader.group.prototype.addCustomTrigger=function(B){if(!B||!B instanceof YAHOO.util.CustomEvent){return ;}var A=function(){this.fetch();};this._customTriggers.push([B,A]);B.subscribe(A,this,true);};YAHOO.util.ImageLoader.group.prototype._onloadTasks=function(){if(this.timeoutLen&&typeof (this.timeoutLen)=="number"&&this.timeoutLen>0){this._timeout=setTimeout(this._getFetch!
 Timeout(),this.timeoutLen*1000);}if(this.foldConditional){this._foldCheck();}};YAHOO.util.ImageLoader.group.prototype._getFetchTimeout=function(){var A=this;return function(){A.fetch();};};YAHOO.util.ImageLoader.group.prototype.registerBgImage=function(B,A){this._imgObjs[B]=new YAHOO.util.ImageLoader.bgImgObj(B,A);return this._imgObjs[B];};YAHOO.util.ImageLoader.group.prototype.registerSrcImage=function(D,B,C,A){this._imgObjs[D]=new YAHOO.util.ImageLoader.srcImgObj(D,B,C,A);return this._imgObjs[D];};YAHOO.util.ImageLoader.group.prototype.registerPngBgImage=function(C,B,A){this._imgObjs[C]=new YAHOO.util.ImageLoader.pngBgImgObj(C,B,A);return this._imgObjs[C];};YAHOO.util.ImageLoader.group.prototype.fetch=function(){clearTimeout(this._timeout);for(var B=0,A=this._triggers.length;B<A;B++){YAHOO.util.Event.removeListener(this._triggers[B][0],this._triggers[B][1],this._triggers[B][2]);}for(var B=0,A=this._customTriggers.length;B<A;B++){this._customTriggers[B][0].unsubscribe(this!
 ._customTriggers[B][1],this);}this._fetchByClass();for(var C i!
 n this._
imgObjs){if(YAHOO.lang.hasOwnProperty(this._imgObjs,C)){this._imgObjs[C].fetch();}}};YAHOO.util.ImageLoader.group.prototype._foldCheck=function(){var C=(document.compatMode!="CSS1Compat")?document.body.scrollTop:document.documentElement.scrollTop;var D=YAHOO.util.Dom.getViewportHeight();var A=C+D;var E=(document.compatMode!="CSS1Compat")?document.body.scrollLeft:document.documentElement.scrollLeft;var G=YAHOO.util.Dom.getViewportWidth();var I=E+G;for(var B in this._imgObjs){if(YAHOO.lang.hasOwnProperty(this._imgObjs,B)){var J=YAHOO.util.Dom.getXY(this._imgObjs[B].domId);if(J[1]<A&&J[0]<I){this._imgObjs[B].fetch();}}}if(this.className){this._classImageEls=YAHOO.util.Dom.getElementsByClassName(this.className);for(var F=0,H=this._classImageEls.length;F<H;F++){var J=YAHOO.util.Dom.getXY(this._classImageEls[F]);if(J[1]<A&&J[0]<I){YAHOO.util.Dom.removeClass(this._classImageEls[F],this.className);}}}};YAHOO.util.ImageLoader.group.prototype._fetchByClass=function(){if(!this.classNam!
 e){return ;}if(this._classImageEls===null){this._classImageEls=YAHOO.util.Dom.getElementsByClassName(this.className);}YAHOO.util.Dom.removeClass(this._classImageEls,this.className);};YAHOO.util.ImageLoader.imgObj=function(B,A){this.domId=B;this.url=A;this.width=null;this.height=null;this.setVisible=false;this._fetched=false;};YAHOO.util.ImageLoader.imgObj.prototype.fetch=function(){if(this._fetched){return ;}var A=document.getElementById(this.domId);if(!A){return ;}this._applyUrl(A);if(this.setVisible){A.style.visibility="visible";}if(this.width){A.width=this.width;}if(this.height){A.height=this.height;}this._fetched=true;};YAHOO.util.ImageLoader.imgObj.prototype._applyUrl=function(A){};YAHOO.util.ImageLoader.bgImgObj=function(B,A){YAHOO.util.ImageLoader.bgImgObj.superclass.constructor.call(this,B,A);};YAHOO.lang.extend(YAHOO.util.ImageLoader.bgImgObj,YAHOO.util.ImageLoader.imgObj);YAHOO.util.ImageLoader.bgImgObj.prototype._applyUrl=function(A){A.style.backgroundImage="url(!
 '"+this.url+"')";};YAHOO.util.ImageLoader.srcImgObj=function(D!
 ,B,C,A){
YAHOO.util.ImageLoader.srcImgObj.superclass.constructor.call(this,D,B);this.width=C;this.height=A;};YAHOO.lang.extend(YAHOO.util.ImageLoader.srcImgObj,YAHOO.util.ImageLoader.imgObj);YAHOO.util.ImageLoader.srcImgObj.prototype._applyUrl=function(A){A.src=this.url;};YAHOO.util.ImageLoader.pngBgImgObj=function(C,B,A){YAHOO.util.ImageLoader.pngBgImgObj.superclass.constructor.call(this,C,B);this.props=A||{};};YAHOO.lang.extend(YAHOO.util.ImageLoader.pngBgImgObj,YAHOO.util.ImageLoader.imgObj);YAHOO.util.ImageLoader.pngBgImgObj.prototype._applyUrl=function(B){if(YAHOO.env.ua.ie&&YAHOO.env.ua.ie<=6){var C=(YAHOO.lang.isUndefined(this.props.sizingMethod))?"scale":this.props.sizingMethod;var A=(YAHOO.lang.isUndefined(this.props.enabled))?"true":this.props.enabled;B.style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+this.url+'", sizingMethod="'+C+'", enabled="'+A+'")';}else{B.style.backgroundImage="url('"+this.url+"')";}};YAHOO.register("imageloader",YAHOO.util.Imag!
 eLoader,{version:"2.5.1",build:"984"});
\ No newline at end of file

Added: trunk/root/static/yui/imageloader/imageloader.js
===================================================================
--- trunk/root/static/yui/imageloader/imageloader.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/imageloader/imageloader.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,481 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * The image loader is a framework to dynamically load images
+ * according to certain triggers, enabling faster load times
+ * and a more responsive UI.
+ *
+ * @module imageloader
+ * @namespace YAHOO.util
+ */
+
+if (typeof(YAHOO.util.ImageLoader) == 'undefined') {
+	YAHOO.util.ImageLoader = {};
+}
+
+/**
+ * A group for images. A group can have one time limit and a series of triggers. Thus the images belonging to this group must share these constraints.
+ * @class YAHOO.util.ImageLoader.group
+ * @requires YAHOO.util.Dom
+ * @requires YAHOO.util.Event
+ * @constructor
+ * @param {String|HTMLElement}	trigEl	The HTML element id or reference to assign the trigger event to. Can be null for no trigger
+ * @param {String}	trigAct The type of event to assign to trigEl. Can be null for no trigger
+ * @param {Number}	timeout	Timeout (time limit) length, in seconds. Can be undefined, or <= 0, for no time limit
+ */
+YAHOO.util.ImageLoader.group = function(trigEl, trigAct, timeout) {
+	/**
+	 * Name for the group. Only used to identify the group in logging statements
+	 * @property name
+	 * @type String
+	 */
+	this.name = 'unnamed';
+	
+	/**
+	 * Collection of images registered with this group
+	 * @property _imgObjs
+	 * @private
+	 * @type Object
+	 */
+	this._imgObjs = {};
+	
+	/**
+	 * Timeout (time limit) length, in seconds
+	 * @property timeoutLen
+	 * @type Number
+	 */
+	this.timeoutLen = timeout;
+	
+	/**
+	 * Timeout object to keep a handle on the time limit
+	 * @property _timeout
+	 * @private
+	 * @type Object
+	 */
+	this._timeout = null;
+	
+	/**
+	 * Collection of triggers for this group.
+	 * Keeps track of each trigger's element, event, and event-listener-callback "fetch" function
+	 * @property _triggers
+	 * @private
+	 * @type Array
+	 */
+	this._triggers = [];
+
+	/**
+	 * Collection of custom-event triggers for this group.
+	 * Keeps track of each trigger's event object and event-listener-callback "fetch" function
+	 * @property _customTriggers
+	 * @private
+	 * @type Array
+	 */
+	this._customTriggers = [];
+
+	/**
+	 * Flag to check if images are above the fold. If foldConditional is true, the group will check each of its image locations at page load. If any part of the image is within the client viewport, the image is displayed immediately
+	 * @property foldConditional
+	 * @type Boolean
+	 */
+	this.foldConditional = false;
+
+	/**
+	 * Class name that will identify images belonging to the group. This class name will be removed from each element in order to fetch images.
+	 * This class should have, in its CSS style definition, "background:none !important;"
+	 * @property className
+	 * @type String
+	 */
+	this.className = null;
+
+	/**
+	 * HTML elements having the class name that is associated with this group
+	 * Elements are stored during the _foldCheck function and reused later during the fetch function. Gives a slight performance improvement when className and foldConditional are both used
+	 * @property _classImageEls
+	 * @private
+	 * @type Array
+	 */
+	this._classImageEls = null;
+
+	// add a listener to set the time limit in the onload
+	YAHOO.util.Event.addListener(window, 'load', this._onloadTasks, this, true);
+	// add the trigger
+	this.addTrigger(trigEl, trigAct);
+
+};
+
+/**
+ * Adds a trigger to the group. Call this with the same style as YAHOO.util.Event.addListener
+ * @method addTrigger
+ * @param {String|HTMLElement} trigEl  The HTML element id or reference to assign the trigger event to
+ * @param {String} trigAct The type of event to assign to trigEl
+ */
+YAHOO.util.ImageLoader.group.prototype.addTrigger = function(trigEl, trigAct) {
+	if (! trigEl || ! trigAct) {
+		return;
+	}
+	/* Need to wrap the fetch function. Event Util can't distinguish prototyped functions of different instantiations
+	 *   Leads to this scenario: groupA and groupZ both have window-scroll triggers. groupZ also has a 2-sec timeout (groupA has no timeout).
+	 *   groupZ's timeout fires; we remove the triggers. The removeListener call finds the first window-scroll event with Y.u.IL.p.fetch, which is groupA's. 
+	 *   groupA's trigger is removed and never fires, leaving images unfetched
+	 */
+	var wrappedFetch = function() {
+		this.fetch();
+	};
+	this._triggers.push([trigEl, trigAct, wrappedFetch]);
+	YAHOO.util.Event.addListener(trigEl, trigAct, wrappedFetch, this, true);
+};
+
+/**
+ * Adds a custom event trigger to the group.
+ * @method addCustomTrigger
+ * @param {Object} event A YAHOO.util.CustomEvent object
+ */
+YAHOO.util.ImageLoader.group.prototype.addCustomTrigger = function(event) {
+	// make sure we're dealing with a CustomEvent object
+	if (! event || ! event instanceof YAHOO.util.CustomEvent) {
+		return;
+	}
+
+	// see comment in addTrigger()
+	var wrappedFetch = function() {
+		this.fetch();
+	};
+	this._customTriggers.push([event, wrappedFetch]);
+	event.subscribe(wrappedFetch, this, true);
+};
+
+/**
+ * Setup to do in the window's onload
+ * Initiates time limit for group; executes the fold check for the images
+ * @method _onloadTasks
+ * @private
+ */
+YAHOO.util.ImageLoader.group.prototype._onloadTasks = function() {
+	if (this.timeoutLen && typeof(this.timeoutLen) == 'number' && this.timeoutLen > 0) {
+		this._timeout = setTimeout(this._getFetchTimeout(), this.timeoutLen * 1000);
+	}
+
+	if (this.foldConditional) {
+		this._foldCheck();
+	}
+};
+
+/**
+ * Returns the group's fetch method, with the proper closure, for use with setTimeout
+ * @method _getFetchTimeout
+ * @return {Function}  group's fetch method
+ * @private
+ */
+YAHOO.util.ImageLoader.group.prototype._getFetchTimeout = function() {
+	var self = this;
+	return function() { self.fetch(); };
+};
+
+/**
+ * Registers a background image with the group
+ * @method registerBgImage
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ * @return {Object}	bgImgObj that was registered, for modifying any attributes in the object
+ */
+YAHOO.util.ImageLoader.group.prototype.registerBgImage = function(domId, url) {
+	this._imgObjs[domId] = new YAHOO.util.ImageLoader.bgImgObj(domId, url);
+	return this._imgObjs[domId];
+};
+/**
+ * Registers a src image with the group
+ * @method registerSrcImage
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ * @param {Int}	width	pixel width of the image - defaults to image's natural size
+ * @param {Int}	height	pixel height of the image - defaults to image's natural size
+ * @return {Object}	srcImgObj that was registered, for modifying any attributes in the object
+ */
+YAHOO.util.ImageLoader.group.prototype.registerSrcImage = function(domId, url, width, height) {
+	this._imgObjs[domId] = new YAHOO.util.ImageLoader.srcImgObj(domId, url, width, height);
+	return this._imgObjs[domId];
+};
+/**
+ * Registers an alpha-channel-type png background image with the group
+ * @method registerPngBgImage
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ * @param {Object}  ailProps The AlphaImageLoader properties to be set for the image
+ *                    Valid properties are 'sizingMethod' and 'enabled'
+ * @return {Object}	pngBgImgObj that was registered, for modifying any attributes in the object
+ */
+YAHOO.util.ImageLoader.group.prototype.registerPngBgImage = function(domId, url, ailProps) {
+	this._imgObjs[domId] = new YAHOO.util.ImageLoader.pngBgImgObj(domId, url, ailProps);
+	return this._imgObjs[domId];
+};
+
+/**
+ * Displays the images in the group
+ * @method fetch
+ */
+YAHOO.util.ImageLoader.group.prototype.fetch = function() {
+
+	clearTimeout(this._timeout);
+	// remove all listeners
+	for (var i=0, len = this._triggers.length; i < len; i++) {
+		YAHOO.util.Event.removeListener(this._triggers[i][0], this._triggers[i][1], this._triggers[i][2]);
+	}
+	// remove custom event subscriptions
+	for (var i=0, len = this._customTriggers.length; i < len; i++) {
+		this._customTriggers[i][0].unsubscribe(this._customTriggers[i][1], this);
+	}
+
+	// fetch whatever we need to by className
+	this._fetchByClass();
+
+	// fetch registered images
+	for (var id in this._imgObjs) {
+		if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
+			this._imgObjs[id].fetch();
+		}
+	}
+};
+
+/**
+ * Checks the position of each image in the group. If any part of the image is within the client viewport, shows the image immediately.
+ * @method _foldCheck
+ * @private
+ */
+YAHOO.util.ImageLoader.group.prototype._foldCheck = function() {
+	var scrollTop = (document.compatMode != 'CSS1Compat') ? document.body.scrollTop : document.documentElement.scrollTop;
+	var viewHeight = YAHOO.util.Dom.getViewportHeight();
+	var hLimit = scrollTop + viewHeight;
+	var scrollLeft = (document.compatMode != 'CSS1Compat') ? document.body.scrollLeft : document.documentElement.scrollLeft;
+	var viewWidth = YAHOO.util.Dom.getViewportWidth();
+	var wLimit = scrollLeft + viewWidth;
+	for (var id in this._imgObjs) {
+		if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
+			var elPos = YAHOO.util.Dom.getXY(this._imgObjs[id].domId);
+			if (elPos[1] < hLimit && elPos[0] < wLimit) {
+				this._imgObjs[id].fetch();
+			}
+		}
+	}
+	// and by class
+	if (this.className) {
+		this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
+		for (var i=0, len = this._classImageEls.length; i < len; i++) {
+			var elPos = YAHOO.util.Dom.getXY(this._classImageEls[i]);
+			if (elPos[1] < hLimit && elPos[0] < wLimit) {
+				YAHOO.util.Dom.removeClass(this._classImageEls[i], this.className);
+			}
+		}
+	}
+};
+
+/**
+ * Finds all elements in the Dom with the class name specified in the group. Removes the class from the element in order to let the style definitions trigger the image fetching
+ * @method _fetchByClass
+ * @private
+ */
+YAHOO.util.ImageLoader.group.prototype._fetchByClass = function() {
+	if (! this.className) {
+		return;
+	}
+
+	// this._classImageEls may have been set during _foldCheck
+	if (this._classImageEls === null) {
+		this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
+	}
+	YAHOO.util.Dom.removeClass(this._classImageEls, this.className);
+};
+
+
+/**
+ * Base class for image objects to be registered with the groups
+ * @class YAHOO.util.ImageLoader.imgObj
+ * @constructor
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ */
+YAHOO.util.ImageLoader.imgObj = function(domId, url) {
+	/**
+	 * HTML DOM id of the image element
+	 * @property domId
+	 * @type String
+	 */
+	this.domId = domId;
+
+	/**
+	 * URL for the image
+	 * @property url
+	 * @type String
+	 */
+	this.url = url;
+
+	/**
+	 * Pixel width of the image. Will be set as a "width" attribute after the image is fetched.
+	 * Detaults to the natural width of the image.
+	 * Only appropriate with src images
+	 * @property width
+	 * @type Int
+	 */
+	this.width = null;
+
+	/**
+	 * Pixel height of the image. Will be set as a "height" attribute after the image is fetched.
+	 * Detaults to the natural height of the image.
+	 * Only appropriate with src images
+	 * @property height
+	 * @type Int
+	 */
+	this.height = null;
+
+	/**
+	 * Whether the style.visibility should be set to "visible" after the image is fetched.
+	 * Used when setting src images as visibility:hidden prior to image fetching
+	 * @property setVisible
+	 * @type Boolean
+	 */
+	this.setVisible = false;
+
+	/**
+	 * Whether the image has already been fetched. In the case of a foldCondional group, keeps track for when the trigger is fired so images aren't fetched twice
+	 * @property _fetched
+	 * @type Boolean
+	 * @private
+	 */
+	this._fetched = false;
+};
+
+/**
+ * Displays the image; puts the URL into the DOM
+ * @method fetch
+ */
+YAHOO.util.ImageLoader.imgObj.prototype.fetch = function() {
+	if (this._fetched) {
+		return;
+	}
+	var el = document.getElementById(this.domId);
+	if (! el) {
+		return;
+	}
+	this._applyUrl(el);
+
+	if (this.setVisible) {
+		el.style.visibility = 'visible';
+	}
+	if (this.width) {
+		el.width = this.width;
+	}
+	if (this.height) {
+		el.height = this.height;
+	}
+	this._fetched = true;
+};
+
+/**
+ * Inserts the image URL into the DOM so that the image is displayed.
+ * Must be overridden by child class
+ * @method _applyUrl
+ * @param {Object}	el	HTML DOM element
+ * @private
+ */
+YAHOO.util.ImageLoader.imgObj.prototype._applyUrl = function(el) {
+};
+
+/**
+ * Background image object. A background image is one whose URL is specified by "background-image" in the element's style
+ * @class YAHOO.util.ImageLoader.bgImgObj
+ * @constructor
+ * @extends YAHOO.util.ImageLoader.imgObj
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ */
+YAHOO.util.ImageLoader.bgImgObj = function(domId, url) {
+	YAHOO.util.ImageLoader.bgImgObj.superclass.constructor.call(this, domId, url);
+};
+
+YAHOO.lang.extend(YAHOO.util.ImageLoader.bgImgObj, YAHOO.util.ImageLoader.imgObj);
+
+/**
+ * Inserts the image URL into the DOM so that the image is displayed.
+ * Sets style.backgroundImage
+ * @method _applyUrl
+ * @param {Object}	el	HTML DOM element
+ * @private
+ */
+YAHOO.util.ImageLoader.bgImgObj.prototype._applyUrl = function(el) {
+	el.style.backgroundImage = "url('" + this.url + "')";
+};
+
+/**
+ * Source image object. A source image is one whose URL is specified by a src attribute in the DOM element
+ * @class YAHOO.util.ImageLoader.srcImgObj
+ * @constructor
+ * @extends YAHOO.util.ImageLoader.imgObj
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ * @param {Int}	width	pixel width of the image - defaults to image's natural size
+ * @param {Int}	height	pixel height of the image - defaults to image's natural size
+ */
+YAHOO.util.ImageLoader.srcImgObj = function(domId, url, width, height) {
+	YAHOO.util.ImageLoader.srcImgObj.superclass.constructor.call(this, domId, url);
+	this.width = width;
+	this.height = height;
+};
+
+YAHOO.lang.extend(YAHOO.util.ImageLoader.srcImgObj, YAHOO.util.ImageLoader.imgObj);
+
+/**
+ * Inserts the image URL into the DOM so that the image is displayed.
+ * Sets src
+ * @method _applyUrl
+ * @param {Object}	el	HTML DOM element
+ * @private
+ */
+YAHOO.util.ImageLoader.srcImgObj.prototype._applyUrl = function(el) {
+	el.src = this.url;
+};
+
+/**
+ * PNG background image object. A PNG background image is one whose URL is specified through AlphaImageLoader or by "background-image" in the element's style
+ * @class YAHOO.util.ImageLoader.pngBgImgObj
+ * @constructor
+ * @extends YAHOO.util.ImageLoader.imgObj
+ * @param {String}	domId	HTML DOM id of the image element
+ * @param {String}	url	URL for the image
+ * @param {Object}  ailProps The AlphaImageLoader properties to be set for the image
+ *                    Valid properties are 'sizingMethod' and 'enabled'
+ */
+YAHOO.util.ImageLoader.pngBgImgObj = function(domId, url, ailProps) {
+	YAHOO.util.ImageLoader.pngBgImgObj.superclass.constructor.call(this, domId, url);
+
+	/**
+	 * AlphaImageLoader properties to be set for the image.
+	 * Valid properties are "sizingMethod" and "enabled".
+	 * @property props
+	 * @type Object
+	 */
+	this.props = ailProps || {};
+};
+
+YAHOO.lang.extend(YAHOO.util.ImageLoader.pngBgImgObj, YAHOO.util.ImageLoader.imgObj);
+
+/**
+ * Inserts the image URL into the DOM so that the image is displayed.
+ * If the browser is determined to be IE6 (or older), sets the AlphaImageLoader src; otherwise sets style.backgroundImage
+ * @method _applyUrl
+ * @param {Object}	el	HTML DOM element
+ * @private
+ */
+YAHOO.util.ImageLoader.pngBgImgObj.prototype._applyUrl = function(el) {
+	if (YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) {
+		var sizingMethod = (YAHOO.lang.isUndefined(this.props.sizingMethod)) ? 'scale' : this.props.sizingMethod;
+		var enabled = (YAHOO.lang.isUndefined(this.props.enabled)) ? 'true' : this.props.enabled;
+		el.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.url + '", sizingMethod="' + sizingMethod + '", enabled="' + enabled + '")';
+	}
+	else {
+		el.style.backgroundImage = "url('" + this.url + "')";
+	}
+};
+YAHOO.register("imageloader", YAHOO.util.ImageLoader, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/json/README
===================================================================
--- trunk/root/static/yui/json/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/json/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,16 @@
-*** version 2.4.1 ***
+JSON Utility - Release Notes
 
-No change
+2.5.1
+    * Updated validation regex to address poor unicode escape treatment in FF
+    * Updated special characters RegExp
+    * Changed stringification to account for odd responses to typeof
 
-*** version 2.4.0 ***
+2.5.0
+    * Restructured for customization and readability
+    * Extracted isValid method to test a JSON string
+    * Extracted dateToString method to allow overriding with custom serialization format
+    * Added stringToDate method to reconstitute Date instances from default JSON UTC date strings.  Use this in a filter method passed to lang.JSON.parse
+    * fixed walk method so filters are properly applied
 
-* Initial release
+2.4.0
+    * Initial release

Deleted: trunk/root/static/yui/json/json-beta-debug.js
===================================================================
--- trunk/root/static/yui/json/json-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/json/json-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,271 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-/**
- * Provides methods to parse JSON strings and convert objects to JSON strings.
- * @module json
- * @requires yahoo
- * @class YAHOO.lang.JSON
- * @static
- */
-YAHOO.namespace('lang');
-YAHOO.lang.JSON = {
-
-    /**
-     * Parse a JSON string, returning the native JavaScript representation.
-     * Only minor modifications from http://www.json.org/json.js.
-     * @param s {string} JSON string data
-     * @param filter {function} (optional) function(k,v) passed each key value pair of object literals, allowing pruning or altering values
-     * @return {MIXED} the native JavaScript representation of the JSON string
-     * @throws SyntaxError
-     * @method parse
-     * @static
-     * @public
-     */
-    parse : function (s,filter) {
-        var j;
-
-        function walk(k, v) {
-            var i, n;
-            if (v && typeof v === 'object') {
-                for (i in v) {
-                    if (YAHOO.lang.hasOwnProperty.apply(v, [i])) {
-                        n = walk(i, v[i]);
-                        if (n !== undefined) {
-                            v[i] = n;
-                        }
-                    }
-                }
-            }
-            return filter(k, v);
-        }
-
-
-// Parsing happens in three stages. In the first stage, we run the text against
-// a regular expression which looks for non-JSON characters. We are especially
-// concerned with '()' and 'new' because they can cause invocation, and '='
-// because it can cause mutation. But just to be safe, we will reject all
-// unexpected characters.
-
-// We split the first stage into 4 regexp operations in order to work around
-// crippling deficiencies in IE's and Safari's regexp engines. First we replace
-// all backslash pairs with '@' (a non-JSON character). Second, we replace all
-// simple value tokens with ']' characters. Third, we delete all open brackets
-// that follow a colon or comma or that begin the text. Finally, we look to see
-// that the remaining characters are only whitespace or ']' or ',' or ':' or '{'
-// or '}'. If that is so, then the text is safe for eval.
-
-        if (/^[\],:{}\s]*$/.test(s.replace(/\\./g, '@').
-                replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').
-                replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
-// In the second stage we use the eval function to compile the text into a
-// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
-// in JavaScript: it can begin a block or an object literal. We wrap the text
-// in parens to eliminate the ambiguity.
-
-            j = eval('(' + s + ')');
-
-// In the optional third stage, we recursively walk the new structure, passing
-// each name/value pair to a filter function for possible transformation.
-
-            return typeof filter === 'function' ? walk('', j) : j;
-        }
-
-// If the text is not JSON parseable, then a SyntaxError is thrown.
-
-        throw new SyntaxError('parseJSON');
-    },
-
-
-    /**
-     * Converts an arbitrary value to a JSON string representation.
-     * Cyclical object or array references are replaced with null.
-     * If a whitelist is provided, only matching object keys will be included.
-     * If a depth limit is provided, objects and arrays at that depth will
-     * be stringified as empty.
-     * @param o {MIXED} any arbitrary object to convert to JSON string
-     * @param w {Array} (optional) whitelist of acceptable object keys to include
-     * @param d {number} (optional) depth limit to recurse objects/arrays (practical minimum 1)
-     * @return {string} JSON string representation of the input
-     * @method stringify
-     * @static
-     * @public
-     */
-    stringify : function (o,w,d) {
-
-        var l = YAHOO.lang,
-
-            // Regex used to encode strings as safe JSON values
-            str_re = /["\\\x00-\x1f]/g,
-
-            // Character substitution map used by regex to prepare strings
-            m = {
-                '\b': '\\b',
-                '\t': '\\t',
-                '\n': '\\n',
-                '\f': '\\f',
-                '\r': '\\r',
-                '"' : '\\"',
-                '\\': '\\\\'
-            },
-
-            // Processing stack used to prevent cyclical references
-            pstack  = [];
-
-
-        /**
-        * Encode odd characters.  Translated characters are cached.
-        * @private
-        */
-        function _encodeChar(c) {
-            if (!m[c]) {
-                var a = c.charCodeAt();
-                m[c] = '\\u00' + Math.floor(a / 16).toString(16) +
-                                           (a % 16).toString(16);
-            }
-            return m[c];
-        }
-
-        /**
-         * zero pad single digits in dates.
-         * @private
-         */
-        function _zeroPad(v) {
-            return v < 10 ? '0' + v : v;
-        }
-
-        /**
-         * Wrap string values and object keys in double quotes after replacing
-         * any odd characters.
-         * @private
-         */
-        function _string(o) {
-            return '"' + o.replace(str_re, _encodeChar) + '"';
-        }
-    
-        /**
-         * Worker function.  Fork behavior on data type and recurse objects and
-         * arrays per the configured depth.
-         * @private
-         */
-        function _stringify(o,w,d) {
-            var t = typeof o,
-                i,len,j, // array iteration
-                k,v,     // object iteration
-                vt,      // typeof v during iteration
-                a;       // composition array for performance over string concat
-
-            // String
-            if (t === 'string') {
-                return _string(o);
-            }
-
-            // native boolean and Boolean instance
-            if (t === 'boolean' || o instanceof Boolean) {
-                return String(o);
-            }
-
-            // native number and Number instance
-            if (t === 'number' || o instanceof Number) {
-                return isFinite(o) ? String(o) : 'null';
-            }
-
-            // Date
-            if (o instanceof Date) {
-                return ['"',         o.getUTCFullYear(),  '-',
-                            _zeroPad(o.getUTCMonth() + 1),'-',
-                            _zeroPad(o.getUTCDate()),     'T',
-                            _zeroPad(o.getUTCHours()),    ':',
-                            _zeroPad(o.getUTCMinutes()),  ':',
-                            _zeroPad(o.getUTCSeconds()),  'Z"'].join('');
-            }
-
-            // Array
-            if (l.isArray(o)) {
-                // Check for cyclical references
-                for (i = 0, len = pstack.length; i < len; ++i) {
-                    if (pstack[i] === o) {
-                        return 'null';
-                    }
-                }
-
-                // Add the array to the processing stack
-                pstack[pstack.length] = o;
-
-                a = [];
-                // Only recurse if we're above depth config
-                if (d > 0) {
-                    for (i = 0, len = o.length; i < len; ++i) {
-                        a[i] = _stringify(o[i],w,d-1);
-                    }
-                }
-
-                // remove the array from the stack
-                pstack.pop();
-
-                return '[' + a.join(',') + ']';
-            }
-
-            // Object
-            if (t === 'object' && o) {
-                // Check for cyclical references
-                for (i = 0, len = pstack.length; i < len; ++i) {
-                    if (pstack[i] === o) {
-                        return 'null';
-                    }
-                }
-
-                // Add the object to the  processing stack
-                pstack[pstack.length] = o;
-
-                a = [];
-                // Only recurse if we're above depth config
-                if (d > 0) {
-
-                    // If whitelist provided, take only those keys
-                    if (w) {
-                        for (i = 0, j = 0, len = w.length; i < len; ++i) {
-                            v = o[w[i]];
-                            vt = typeof v;
-
-                            // Omit invalid values
-                            if (vt !== 'undefined' && vt !== 'function') {
-                                a[j++] = _string(w[i]) + ':' + _stringify(v,w,d-1);
-                            }
-                        }
-
-                    // Otherwise, take all valid object properties
-                    // omitting the prototype chain properties
-                    } else {
-                        j = 0;
-                        for (k in o) {
-                            if (typeof k === 'string' && l.hasOwnProperty(o,k)) {
-                                v = o[k];
-                                vt = typeof v;
-                                if (vt !== 'undefined' && vt !== 'function') {
-                                    a[j++] = _string(k) + ':' + _stringify(v,w,d-1);
-                                }
-                            }
-                        }
-                    }
-                }
-
-                // Remove the object from processing stack
-                pstack.pop();
-
-                return '{' + a.join(',') + '}';
-            }
-
-            return 'null';
-        }
-
-        // process the input
-        d = d >= 0 ? d : 1/0;  // Default depth to POSITIVE_INFINITY
-        return _stringify(o,w,d);
-    }
-};
-YAHOO.register("json", YAHOO.lang.JSON, {version: "2.4.1", build: "742"});

Deleted: trunk/root/static/yui/json/json-beta-min.js
===================================================================
--- trunk/root/static/yui/json/json-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/json/json-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-YAHOO.namespace("lang");YAHOO.lang.JSON={parse:function(s,filter){var j;function walk(k,v){var i,n;if(v&&typeof v==="object"){for(i in v){if(YAHOO.lang.hasOwnProperty.apply(v,[i])){n=walk(i,v[i]);if(n!==undefined){v[i]=n;}}}}return filter(k,v);}if(/^[\],:{}\s]*$/.test(s.replace(/\\./g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+s+")");return typeof filter==="function"?walk("",j):j;}throw new SyntaxError("parseJSON");},stringify:function(D,J,H){var F=YAHOO.lang,A=/["\\\x00-\x1f]/g,E={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r","\"":"\\\"","\\":"\\\\"},C=[];function B(M){if(!E[M]){var L=M.charCodeAt();E[M]="\\u00"+Math.floor(L/16).toString(16)+(L%16).toString(16);}return E[M];}function G(L){return L<10?"0"+L:L;}function K(L){return"\""+L.replace(A,B)+"\"";}function I(L,S,Q){var V=typeof L,O,P,N,M,T,U,R;if(V==="string"){return K(L);}if(V==="boolean"||L instanceof Boolean){return!
  String(L);}if(V==="number"||L instanceof Number){return isFinite(L)?String(L):"null";}if(L instanceof Date){return["\"",L.getUTCFullYear(),"-",G(L.getUTCMonth()+1),"-",G(L.getUTCDate()),"T",G(L.getUTCHours()),":",G(L.getUTCMinutes()),":",G(L.getUTCSeconds()),"Z\""].join("");}if(F.isArray(L)){for(O=0,P=C.length;O<P;++O){if(C[O]===L){return"null";}}C[C.length]=L;R=[];if(Q>0){for(O=0,P=L.length;O<P;++O){R[O]=I(L[O],S,Q-1);}}C.pop();return"["+R.join(",")+"]";}if(V==="object"&&L){for(O=0,P=C.length;O<P;++O){if(C[O]===L){return"null";}}C[C.length]=L;R=[];if(Q>0){if(S){for(O=0,N=0,P=S.length;O<P;++O){T=L[S[O]];U=typeof T;if(U!=="undefined"&&U!=="function"){R[N++]=K(S[O])+":"+I(T,S,Q-1);}}}else{N=0;for(M in L){if(typeof M==="string"&&F.hasOwnProperty(L,M)){T=L[M];U=typeof T;if(U!=="undefined"&&U!=="function"){R[N++]=K(M)+":"+I(T,S,Q-1);}}}}}C.pop();return"{"+R.join(",")+"}";}return"null";}H=H>=0?H:1/0;return I(D,J,H);}};YAHOO.register("json",YAHOO.lang.JSON,{version:"2.4.1",build:!
 "742"});
\ No newline at end of file

Deleted: trunk/root/static/yui/json/json-beta.js
===================================================================
--- trunk/root/static/yui/json/json-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/json/json-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,271 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-/**
- * Provides methods to parse JSON strings and convert objects to JSON strings.
- * @module json
- * @requires yahoo
- * @class YAHOO.lang.JSON
- * @static
- */
-YAHOO.namespace('lang');
-YAHOO.lang.JSON = {
-
-    /**
-     * Parse a JSON string, returning the native JavaScript representation.
-     * Only minor modifications from http://www.json.org/json.js.
-     * @param s {string} JSON string data
-     * @param filter {function} (optional) function(k,v) passed each key value pair of object literals, allowing pruning or altering values
-     * @return {MIXED} the native JavaScript representation of the JSON string
-     * @throws SyntaxError
-     * @method parse
-     * @static
-     * @public
-     */
-    parse : function (s,filter) {
-        var j;
-
-        function walk(k, v) {
-            var i, n;
-            if (v && typeof v === 'object') {
-                for (i in v) {
-                    if (YAHOO.lang.hasOwnProperty.apply(v, [i])) {
-                        n = walk(i, v[i]);
-                        if (n !== undefined) {
-                            v[i] = n;
-                        }
-                    }
-                }
-            }
-            return filter(k, v);
-        }
-
-
-// Parsing happens in three stages. In the first stage, we run the text against
-// a regular expression which looks for non-JSON characters. We are especially
-// concerned with '()' and 'new' because they can cause invocation, and '='
-// because it can cause mutation. But just to be safe, we will reject all
-// unexpected characters.
-
-// We split the first stage into 4 regexp operations in order to work around
-// crippling deficiencies in IE's and Safari's regexp engines. First we replace
-// all backslash pairs with '@' (a non-JSON character). Second, we replace all
-// simple value tokens with ']' characters. Third, we delete all open brackets
-// that follow a colon or comma or that begin the text. Finally, we look to see
-// that the remaining characters are only whitespace or ']' or ',' or ':' or '{'
-// or '}'. If that is so, then the text is safe for eval.
-
-        if (/^[\],:{}\s]*$/.test(s.replace(/\\./g, '@').
-                replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(:?[eE][+\-]?\d+)?/g, ']').
-                replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
-// In the second stage we use the eval function to compile the text into a
-// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
-// in JavaScript: it can begin a block or an object literal. We wrap the text
-// in parens to eliminate the ambiguity.
-
-            j = eval('(' + s + ')');
-
-// In the optional third stage, we recursively walk the new structure, passing
-// each name/value pair to a filter function for possible transformation.
-
-            return typeof filter === 'function' ? walk('', j) : j;
-        }
-
-// If the text is not JSON parseable, then a SyntaxError is thrown.
-
-        throw new SyntaxError('parseJSON');
-    },
-
-
-    /**
-     * Converts an arbitrary value to a JSON string representation.
-     * Cyclical object or array references are replaced with null.
-     * If a whitelist is provided, only matching object keys will be included.
-     * If a depth limit is provided, objects and arrays at that depth will
-     * be stringified as empty.
-     * @param o {MIXED} any arbitrary object to convert to JSON string
-     * @param w {Array} (optional) whitelist of acceptable object keys to include
-     * @param d {number} (optional) depth limit to recurse objects/arrays (practical minimum 1)
-     * @return {string} JSON string representation of the input
-     * @method stringify
-     * @static
-     * @public
-     */
-    stringify : function (o,w,d) {
-
-        var l = YAHOO.lang,
-
-            // Regex used to encode strings as safe JSON values
-            str_re = /["\\\x00-\x1f]/g,
-
-            // Character substitution map used by regex to prepare strings
-            m = {
-                '\b': '\\b',
-                '\t': '\\t',
-                '\n': '\\n',
-                '\f': '\\f',
-                '\r': '\\r',
-                '"' : '\\"',
-                '\\': '\\\\'
-            },
-
-            // Processing stack used to prevent cyclical references
-            pstack  = [];
-
-
-        /**
-        * Encode odd characters.  Translated characters are cached.
-        * @private
-        */
-        function _encodeChar(c) {
-            if (!m[c]) {
-                var a = c.charCodeAt();
-                m[c] = '\\u00' + Math.floor(a / 16).toString(16) +
-                                           (a % 16).toString(16);
-            }
-            return m[c];
-        }
-
-        /**
-         * zero pad single digits in dates.
-         * @private
-         */
-        function _zeroPad(v) {
-            return v < 10 ? '0' + v : v;
-        }
-
-        /**
-         * Wrap string values and object keys in double quotes after replacing
-         * any odd characters.
-         * @private
-         */
-        function _string(o) {
-            return '"' + o.replace(str_re, _encodeChar) + '"';
-        }
-    
-        /**
-         * Worker function.  Fork behavior on data type and recurse objects and
-         * arrays per the configured depth.
-         * @private
-         */
-        function _stringify(o,w,d) {
-            var t = typeof o,
-                i,len,j, // array iteration
-                k,v,     // object iteration
-                vt,      // typeof v during iteration
-                a;       // composition array for performance over string concat
-
-            // String
-            if (t === 'string') {
-                return _string(o);
-            }
-
-            // native boolean and Boolean instance
-            if (t === 'boolean' || o instanceof Boolean) {
-                return String(o);
-            }
-
-            // native number and Number instance
-            if (t === 'number' || o instanceof Number) {
-                return isFinite(o) ? String(o) : 'null';
-            }
-
-            // Date
-            if (o instanceof Date) {
-                return ['"',         o.getUTCFullYear(),  '-',
-                            _zeroPad(o.getUTCMonth() + 1),'-',
-                            _zeroPad(o.getUTCDate()),     'T',
-                            _zeroPad(o.getUTCHours()),    ':',
-                            _zeroPad(o.getUTCMinutes()),  ':',
-                            _zeroPad(o.getUTCSeconds()),  'Z"'].join('');
-            }
-
-            // Array
-            if (l.isArray(o)) {
-                // Check for cyclical references
-                for (i = 0, len = pstack.length; i < len; ++i) {
-                    if (pstack[i] === o) {
-                        return 'null';
-                    }
-                }
-
-                // Add the array to the processing stack
-                pstack[pstack.length] = o;
-
-                a = [];
-                // Only recurse if we're above depth config
-                if (d > 0) {
-                    for (i = 0, len = o.length; i < len; ++i) {
-                        a[i] = _stringify(o[i],w,d-1);
-                    }
-                }
-
-                // remove the array from the stack
-                pstack.pop();
-
-                return '[' + a.join(',') + ']';
-            }
-
-            // Object
-            if (t === 'object' && o) {
-                // Check for cyclical references
-                for (i = 0, len = pstack.length; i < len; ++i) {
-                    if (pstack[i] === o) {
-                        return 'null';
-                    }
-                }
-
-                // Add the object to the  processing stack
-                pstack[pstack.length] = o;
-
-                a = [];
-                // Only recurse if we're above depth config
-                if (d > 0) {
-
-                    // If whitelist provided, take only those keys
-                    if (w) {
-                        for (i = 0, j = 0, len = w.length; i < len; ++i) {
-                            v = o[w[i]];
-                            vt = typeof v;
-
-                            // Omit invalid values
-                            if (vt !== 'undefined' && vt !== 'function') {
-                                a[j++] = _string(w[i]) + ':' + _stringify(v,w,d-1);
-                            }
-                        }
-
-                    // Otherwise, take all valid object properties
-                    // omitting the prototype chain properties
-                    } else {
-                        j = 0;
-                        for (k in o) {
-                            if (typeof k === 'string' && l.hasOwnProperty(o,k)) {
-                                v = o[k];
-                                vt = typeof v;
-                                if (vt !== 'undefined' && vt !== 'function') {
-                                    a[j++] = _string(k) + ':' + _stringify(v,w,d-1);
-                                }
-                            }
-                        }
-                    }
-                }
-
-                // Remove the object from processing stack
-                pstack.pop();
-
-                return '{' + a.join(',') + '}';
-            }
-
-            return 'null';
-        }
-
-        // process the input
-        d = d >= 0 ? d : 1/0;  // Default depth to POSITIVE_INFINITY
-        return _stringify(o,w,d);
-    }
-};
-YAHOO.register("json", YAHOO.lang.JSON, {version: "2.4.1", build: "742"});

Added: trunk/root/static/yui/json/json-debug.js
===================================================================
--- trunk/root/static/yui/json/json-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/json/json-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,369 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+YAHOO.namespace('lang');
+
+/**
+ * Provides methods to parse JSON strings and convert objects to JSON strings.
+ * @module json
+ * @requires yahoo
+ * @class YAHOO.lang.JSON
+ * @static
+ */
+YAHOO.lang.JSON = {
+    /**
+     * First step in the validation.  Regex used to replace all escape
+     * sequences (i.e. "\\", etc) with '@' characters (a non-JSON character).
+     * @property _ESCAPES
+     * @type {RegExp}
+     * @static
+     * @private
+     */
+    _ESCAPES : /\\["\\\/bfnrtu]/g,
+    /**
+     * Second step in the validation.  Regex used to replace all simple
+     * values with ']' characters.
+     * @property _VALUES
+     * @type {RegExp}
+     * @static
+     * @private
+     */
+    _VALUES  : /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+    /**
+     * Third step in the validation.  Regex used to remove all open square
+     * brackets following a colon, comma, or at the beginning of the string.
+     * @property _BRACKETS
+     * @type {RegExp}
+     * @static
+     * @private
+     */
+    _BRACKETS : /(?:^|:|,)(?:\s*\[)+/g,
+    /**
+     * Final step in the validation.  Regex used to test the string left after
+     * all previous replacements for invalid characters.
+     * @property _INVALID
+     * @type {RegExp}
+     * @static
+     * @private
+     */
+    _INVALID  : /^[\],:{}\s]*$/,
+
+    /**
+     * Regex used to replace special characters in strings for JSON
+     * stringification.
+     * @property _SPECIAL_CHARS
+     * @type {RegExp}
+     * @static
+     * @private
+     */
+    _SPECIAL_CHARS : /["\\\x00-\x1f\x7f-\x9f]/g,
+
+    /**
+     * Regex used to reconstitute serialized Dates.
+     * @property _PARSE_DATE
+     * @type {RegExp}
+     * @static
+     * @private
+     */
+    _PARSE_DATE : /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/,
+
+    /**
+     * Character substitution map for common escapes and special characters.
+     * @property _CHARS
+     * @type {Object}
+     * @static
+     * @private
+     */
+    _CHARS : {
+        '\b': '\\b',
+        '\t': '\\t',
+        '\n': '\\n',
+        '\f': '\\f',
+        '\r': '\\r',
+        '"' : '\\"',
+        '\\': '\\\\'
+    },
+
+    /**
+     * Traverses nested objects, applying a filter or mutation function to
+     * each value.  The value returned from the function will replace the
+     * original value in the key:value pair.  If the value returned is
+     * undefined, the key will be omitted from the returned object.
+     * @method _applyFilter
+     * @param data {MIXED} Any JavaScript data
+     * @param filter {Function} filter or mutation function
+     * @return {MIXED} The results of the filtered data
+     * @static
+     * @private
+     */
+    _applyFilter : function (data, filter) {
+        var walk = function (k,v) {
+            var i, n;
+            if (v && typeof v === 'object') {
+                for (i in v) {
+                    if (YAHOO.lang.hasOwnProperty(v,i)) {
+                        n = walk(i, v[i]);
+                        if (n === undefined) {
+                            delete v[i];
+                        } else {
+                            v[i] = n;
+                        }
+                    }
+                }
+            }
+            return filter(k, v);
+        };
+
+        if (YAHOO.lang.isFunction(filter)) {
+            walk('',data);
+        }
+
+        return data;
+    },
+
+    /**
+     * Four step determination whether a string is valid JSON.  In three steps,
+     * escape sequences, safe values, and properly placed open square brackets
+     * are replaced with placeholders or removed.  Then in the final step, the
+     * result of all these replacements is checked for invalid characters.
+     * @method isValid
+     * @param str {String} JSON string to be tested
+     * @return {boolean} is the string safe for eval?
+     * @static
+     */
+    isValid : function (str) {
+        if (!YAHOO.lang.isString(str)) {
+            return false;
+        }
+
+        return this._INVALID.test(str.
+                replace(this._ESCAPES,'@').
+                replace(this._VALUES,']').
+                replace(this._BRACKETS,''));
+    },
+
+    /**
+     * Serializes a Date instance as a UTC date string.  Used internally by
+     * stringify.  Override this method if you need Dates serialized in a
+     * different format.
+     * @method dateToString
+     * @param d {Date} The Date to serialize
+     * @return {String} stringified Date in UTC format YYYY-MM-DDTHH:mm:SSZ
+     * @static
+     */
+    dateToString : function (d) {
+        function _zeroPad(v) {
+            return v < 10 ? '0' + v : v;
+        }
+
+        return '"' + d.getUTCFullYear()   + '-' +
+            _zeroPad(d.getUTCMonth() + 1) + '-' +
+            _zeroPad(d.getUTCDate())      + 'T' +
+            _zeroPad(d.getUTCHours())     + ':' +
+            _zeroPad(d.getUTCMinutes())   + ':' +
+            _zeroPad(d.getUTCSeconds())   + 'Z"';
+    },
+
+    /**
+     * Reconstitute Date instances from the default JSON UTC serialization.
+     * Reference this from a parse filter function to rebuild Dates during the
+     * parse operation.
+     * @method stringToDate
+     * @param str {String} String serialization of a Date
+     * @return {Date}
+     */
+    stringToDate : function (str) {
+        if (this._PARSE_DATE.test(str)) {
+            var d = new Date();
+            d.setUTCFullYear(RegExp.$1, (RegExp.$2|0)-1, RegExp.$3);
+            d.setUTCHours(RegExp.$4, RegExp.$5, RegExp.$6);
+            return d;
+        }
+    },
+
+    /**
+     * Parse a JSON string, returning the native JavaScript representation.
+     * Only minor modifications from http://www.json.org/json.js.
+     * @param s {string} JSON string data
+     * @param filter {function} (optional) function(k,v) passed each key value pair of object literals, allowing pruning or altering values
+     * @return {MIXED} the native JavaScript representation of the JSON string
+     * @throws SyntaxError
+     * @method parse
+     * @static
+     * @public
+     */
+    parse : function (s,filter) {
+        // Ensure valid JSON
+        if (this.isValid(s)) {
+            // Eval the text into a JavaScript data structure, apply any
+            // filter function, and return
+            return this._applyFilter( eval('(' + s + ')'), filter );
+        }
+
+        // The text is not JSON parsable
+        throw new SyntaxError('parseJSON');
+    },
+
+
+    /**
+     * Converts an arbitrary value to a JSON string representation.
+     * Cyclical object or array references are replaced with null.
+     * If a whitelist is provided, only matching object keys will be included.
+     * If a depth limit is provided, objects and arrays at that depth will
+     * be stringified as empty.
+     * @method stringify
+     * @param o {MIXED} any arbitrary object to convert to JSON string
+     * @param w {Array} (optional) whitelist of acceptable object keys to include
+     * @param d {number} (optional) depth limit to recurse objects/arrays (practical minimum 1)
+     * @return {string} JSON string representation of the input
+     * @static
+     * @public
+     */
+    stringify : function (o,w,d) {
+
+        var l      = YAHOO.lang,
+            J      = l.JSON,
+            m      = J._CHARS,
+            str_re = this._SPECIAL_CHARS,
+            pstack = []; // Processing stack used for cyclical ref protection
+
+        // escape encode special characters
+        var _char = function (c) {
+            if (!m[c]) {
+                var a = c.charCodeAt();
+                m[c] = '\\u00' + Math.floor(a / 16).toString(16) +
+                                           (a % 16).toString(16);
+            }
+            return m[c];
+        };
+
+        // Enclose the escaped string in double quotes
+        var _string = function (s) {
+            return '"' + s.replace(str_re, _char) + '"';
+        };
+
+        // Use the configured date conversion
+        var _date = J.dateToString;
+    
+        // Worker function.  Fork behavior on data type and recurse objects and
+        // arrays per the configured depth.
+        var _stringify = function (o,w,d) {
+            var t = typeof o,
+                i,len,j, // array iteration
+                k,v,     // object iteration
+                vt,      // typeof v during iteration
+                a;       // composition array for performance over string concat
+
+            // String
+            if (t === 'string') {
+                return _string(o);
+            }
+
+            // native boolean and Boolean instance
+            if (t === 'boolean' || o instanceof Boolean) {
+                return String(o);
+            }
+
+            // native number and Number instance
+            if (t === 'number' || o instanceof Number) {
+                return isFinite(o) ? String(o) : 'null';
+            }
+
+            // Date
+            if (o instanceof Date) {
+                return _date(o);
+            }
+
+            // Array
+            if (l.isArray(o)) {
+                // Check for cyclical references
+                for (i = pstack.length - 1; i >= 0; --i) {
+                    if (pstack[i] === o) {
+                        return 'null';
+                    }
+                }
+
+                // Add the array to the processing stack
+                pstack[pstack.length] = o;
+
+                a = [];
+                // Only recurse if we're above depth config
+                if (d > 0) {
+                    for (i = o.length - 1; i >= 0; --i) {
+                        a[i] = _stringify(o[i],w,d-1) || 'null';
+                    }
+                }
+
+                // remove the array from the stack
+                pstack.pop();
+
+                return '[' + a.join(',') + ']';
+            }
+
+            // Object
+            if (t === 'object') {
+                // Test for null reporting as typeof 'object'
+                if (!o) {
+                    return 'null';
+                }
+
+                // Check for cyclical references
+                for (i = pstack.length - 1; i >= 0; --i) {
+                    if (pstack[i] === o) {
+                        return 'null';
+                    }
+                }
+
+                // Add the object to the  processing stack
+                pstack[pstack.length] = o;
+
+                a = [];
+                // Only recurse if we're above depth config
+                if (d > 0) {
+
+                    // If whitelist provided, take only those keys
+                    if (w) {
+                        for (i = 0, j = 0, len = w.length; i < len; ++i) {
+                            if (typeof w[i] === 'string') {
+                                v = _stringify(o[w[i]],w,d-1);
+                                if (v) {
+                                    a[j++] = _string(w[i]) + ':' + v;
+                                }
+                            }
+                        }
+
+                    // Otherwise, take all valid object properties
+                    // omitting the prototype chain properties
+                    } else {
+                        j = 0;
+                        for (k in o) {
+                            if (typeof k === 'string' && l.hasOwnProperty(o,k)) {
+                                v = _stringify(o[k],w,d-1);
+                                if (v) {
+                                    a[j++] = _string(k) + ':' + v;
+                                }
+                            }
+                        }
+                    }
+                }
+
+                // Remove the object from processing stack
+                pstack.pop();
+
+                return '{' + a.join(',') + '}';
+            }
+
+            return undefined; // invalid input
+        };
+
+        // Default depth to POSITIVE_INFINITY
+        d = d >= 0 ? d : 1/0;
+
+        // process the input
+        return _stringify(o,w,d);
+    }
+};
+YAHOO.register("json", YAHOO.lang.JSON, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/json/json-min.js
===================================================================
--- trunk/root/static/yui/json/json-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/json/json-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+YAHOO.namespace("lang");YAHOO.lang.JSON={_ESCAPES:/\\["\\\/bfnrtu]/g,_VALUES:/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,_BRACKETS:/(?:^|:|,)(?:\s*\[)+/g,_INVALID:/^[\],:{}\s]*$/,_SPECIAL_CHARS:/["\\\x00-\x1f\x7f-\x9f]/g,_PARSE_DATE:/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/,_CHARS:{"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},_applyFilter:function(C,B){var A=function(E,D){var F,G;if(D&&typeof D==="object"){for(F in D){if(YAHOO.lang.hasOwnProperty(D,F)){G=A(F,D[F]);if(G===undefined){delete D[F];}else{D[F]=G;}}}}return B(E,D);};if(YAHOO.lang.isFunction(B)){A("",C);}return C;},isValid:function(A){if(!YAHOO.lang.isString(A)){return false;}return this._INVALID.test(A.replace(this._ESCAPES,"@").replace(this._VALUES,"]").replace(this._BRACKETS,""));},dateToString:function(B){function A(C){return C<10?"0"+C:C;}return'"'+B.getUTCFullYear()+"-"+A(B.getUTCMonth()+1)+"-"+A(B.getUTCDate())+"T"+A(B.getUTCHours())+":"+A(B.!
 getUTCMinutes())+":"+A(B.getUTCSeconds())+'Z"';},stringToDate:function(B){if(this._PARSE_DATE.test(B)){var A=new Date();A.setUTCFullYear(RegExp.$1,(RegExp.$2|0)-1,RegExp.$3);A.setUTCHours(RegExp.$4,RegExp.$5,RegExp.$6);return A;}},parse:function(s,filter){if(this.isValid(s)){return this._applyFilter(eval("("+s+")"),filter);}throw new SyntaxError("parseJSON");},stringify:function(C,K,F){var E=YAHOO.lang,H=E.JSON,D=H._CHARS,A=this._SPECIAL_CHARS,B=[];var I=function(N){if(!D[N]){var J=N.charCodeAt();D[N]="\\u00"+Math.floor(J/16).toString(16)+(J%16).toString(16);}return D[N];};var M=function(J){return'"'+J.replace(A,I)+'"';};var L=H.dateToString;var G=function(J,T,R){var W=typeof J,P,Q,O,N,U,V,S;if(W==="string"){return M(J);}if(W==="boolean"||J instanceof Boolean){return String(J);}if(W==="number"||J instanceof Number){return isFinite(J)?String(J):"null";}if(J instanceof Date){return L(J);}if(E.isArray(J)){for(P=B.length-1;P>=0;--P){if(B[P]===J){return"null";}}B[B.length]=J;S=[!
 ];if(R>0){for(P=J.length-1;P>=0;--P){S[P]=G(J[P],T,R-1)||"null!
 ";}}B.po
p();return"["+S.join(",")+"]";}if(W==="object"){if(!J){return"null";}for(P=B.length-1;P>=0;--P){if(B[P]===J){return"null";}}B[B.length]=J;S=[];if(R>0){if(T){for(P=0,O=0,Q=T.length;P<Q;++P){if(typeof T[P]==="string"){U=G(J[T[P]],T,R-1);if(U){S[O++]=M(T[P])+":"+U;}}}}else{O=0;for(N in J){if(typeof N==="string"&&E.hasOwnProperty(J,N)){U=G(J[N],T,R-1);if(U){S[O++]=M(N)+":"+U;}}}}}B.pop();return"{"+S.join(",")+"}";}return undefined;};F=F>=0?F:1/0;return G(C,K,F);}};YAHOO.register("json",YAHOO.lang.JSON,{version:"2.5.1",build:"984"});
\ No newline at end of file

Added: trunk/root/static/yui/json/json.js
===================================================================
--- trunk/root/static/yui/json/json.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/json/json.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,369 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+YAHOO.namespace('lang');
+
+/**
+ * Provides methods to parse JSON strings and convert objects to JSON strings.
+ * @module json
+ * @requires yahoo
+ * @class YAHOO.lang.JSON
+ * @static
+ */
+YAHOO.lang.JSON = {
+    /**
+     * First step in the validation.  Regex used to replace all escape
+     * sequences (i.e. "\\", etc) with '@' characters (a non-JSON character).
+     * @property _ESCAPES
+     * @type {RegExp}
+     * @static
+     * @private
+     */
+    _ESCAPES : /\\["\\\/bfnrtu]/g,
+    /**
+     * Second step in the validation.  Regex used to replace all simple
+     * values with ']' characters.
+     * @property _VALUES
+     * @type {RegExp}
+     * @static
+     * @private
+     */
+    _VALUES  : /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+    /**
+     * Third step in the validation.  Regex used to remove all open square
+     * brackets following a colon, comma, or at the beginning of the string.
+     * @property _BRACKETS
+     * @type {RegExp}
+     * @static
+     * @private
+     */
+    _BRACKETS : /(?:^|:|,)(?:\s*\[)+/g,
+    /**
+     * Final step in the validation.  Regex used to test the string left after
+     * all previous replacements for invalid characters.
+     * @property _INVALID
+     * @type {RegExp}
+     * @static
+     * @private
+     */
+    _INVALID  : /^[\],:{}\s]*$/,
+
+    /**
+     * Regex used to replace special characters in strings for JSON
+     * stringification.
+     * @property _SPECIAL_CHARS
+     * @type {RegExp}
+     * @static
+     * @private
+     */
+    _SPECIAL_CHARS : /["\\\x00-\x1f\x7f-\x9f]/g,
+
+    /**
+     * Regex used to reconstitute serialized Dates.
+     * @property _PARSE_DATE
+     * @type {RegExp}
+     * @static
+     * @private
+     */
+    _PARSE_DATE : /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/,
+
+    /**
+     * Character substitution map for common escapes and special characters.
+     * @property _CHARS
+     * @type {Object}
+     * @static
+     * @private
+     */
+    _CHARS : {
+        '\b': '\\b',
+        '\t': '\\t',
+        '\n': '\\n',
+        '\f': '\\f',
+        '\r': '\\r',
+        '"' : '\\"',
+        '\\': '\\\\'
+    },
+
+    /**
+     * Traverses nested objects, applying a filter or mutation function to
+     * each value.  The value returned from the function will replace the
+     * original value in the key:value pair.  If the value returned is
+     * undefined, the key will be omitted from the returned object.
+     * @method _applyFilter
+     * @param data {MIXED} Any JavaScript data
+     * @param filter {Function} filter or mutation function
+     * @return {MIXED} The results of the filtered data
+     * @static
+     * @private
+     */
+    _applyFilter : function (data, filter) {
+        var walk = function (k,v) {
+            var i, n;
+            if (v && typeof v === 'object') {
+                for (i in v) {
+                    if (YAHOO.lang.hasOwnProperty(v,i)) {
+                        n = walk(i, v[i]);
+                        if (n === undefined) {
+                            delete v[i];
+                        } else {
+                            v[i] = n;
+                        }
+                    }
+                }
+            }
+            return filter(k, v);
+        };
+
+        if (YAHOO.lang.isFunction(filter)) {
+            walk('',data);
+        }
+
+        return data;
+    },
+
+    /**
+     * Four step determination whether a string is valid JSON.  In three steps,
+     * escape sequences, safe values, and properly placed open square brackets
+     * are replaced with placeholders or removed.  Then in the final step, the
+     * result of all these replacements is checked for invalid characters.
+     * @method isValid
+     * @param str {String} JSON string to be tested
+     * @return {boolean} is the string safe for eval?
+     * @static
+     */
+    isValid : function (str) {
+        if (!YAHOO.lang.isString(str)) {
+            return false;
+        }
+
+        return this._INVALID.test(str.
+                replace(this._ESCAPES,'@').
+                replace(this._VALUES,']').
+                replace(this._BRACKETS,''));
+    },
+
+    /**
+     * Serializes a Date instance as a UTC date string.  Used internally by
+     * stringify.  Override this method if you need Dates serialized in a
+     * different format.
+     * @method dateToString
+     * @param d {Date} The Date to serialize
+     * @return {String} stringified Date in UTC format YYYY-MM-DDTHH:mm:SSZ
+     * @static
+     */
+    dateToString : function (d) {
+        function _zeroPad(v) {
+            return v < 10 ? '0' + v : v;
+        }
+
+        return '"' + d.getUTCFullYear()   + '-' +
+            _zeroPad(d.getUTCMonth() + 1) + '-' +
+            _zeroPad(d.getUTCDate())      + 'T' +
+            _zeroPad(d.getUTCHours())     + ':' +
+            _zeroPad(d.getUTCMinutes())   + ':' +
+            _zeroPad(d.getUTCSeconds())   + 'Z"';
+    },
+
+    /**
+     * Reconstitute Date instances from the default JSON UTC serialization.
+     * Reference this from a parse filter function to rebuild Dates during the
+     * parse operation.
+     * @method stringToDate
+     * @param str {String} String serialization of a Date
+     * @return {Date}
+     */
+    stringToDate : function (str) {
+        if (this._PARSE_DATE.test(str)) {
+            var d = new Date();
+            d.setUTCFullYear(RegExp.$1, (RegExp.$2|0)-1, RegExp.$3);
+            d.setUTCHours(RegExp.$4, RegExp.$5, RegExp.$6);
+            return d;
+        }
+    },
+
+    /**
+     * Parse a JSON string, returning the native JavaScript representation.
+     * Only minor modifications from http://www.json.org/json.js.
+     * @param s {string} JSON string data
+     * @param filter {function} (optional) function(k,v) passed each key value pair of object literals, allowing pruning or altering values
+     * @return {MIXED} the native JavaScript representation of the JSON string
+     * @throws SyntaxError
+     * @method parse
+     * @static
+     * @public
+     */
+    parse : function (s,filter) {
+        // Ensure valid JSON
+        if (this.isValid(s)) {
+            // Eval the text into a JavaScript data structure, apply any
+            // filter function, and return
+            return this._applyFilter( eval('(' + s + ')'), filter );
+        }
+
+        // The text is not JSON parsable
+        throw new SyntaxError('parseJSON');
+    },
+
+
+    /**
+     * Converts an arbitrary value to a JSON string representation.
+     * Cyclical object or array references are replaced with null.
+     * If a whitelist is provided, only matching object keys will be included.
+     * If a depth limit is provided, objects and arrays at that depth will
+     * be stringified as empty.
+     * @method stringify
+     * @param o {MIXED} any arbitrary object to convert to JSON string
+     * @param w {Array} (optional) whitelist of acceptable object keys to include
+     * @param d {number} (optional) depth limit to recurse objects/arrays (practical minimum 1)
+     * @return {string} JSON string representation of the input
+     * @static
+     * @public
+     */
+    stringify : function (o,w,d) {
+
+        var l      = YAHOO.lang,
+            J      = l.JSON,
+            m      = J._CHARS,
+            str_re = this._SPECIAL_CHARS,
+            pstack = []; // Processing stack used for cyclical ref protection
+
+        // escape encode special characters
+        var _char = function (c) {
+            if (!m[c]) {
+                var a = c.charCodeAt();
+                m[c] = '\\u00' + Math.floor(a / 16).toString(16) +
+                                           (a % 16).toString(16);
+            }
+            return m[c];
+        };
+
+        // Enclose the escaped string in double quotes
+        var _string = function (s) {
+            return '"' + s.replace(str_re, _char) + '"';
+        };
+
+        // Use the configured date conversion
+        var _date = J.dateToString;
+    
+        // Worker function.  Fork behavior on data type and recurse objects and
+        // arrays per the configured depth.
+        var _stringify = function (o,w,d) {
+            var t = typeof o,
+                i,len,j, // array iteration
+                k,v,     // object iteration
+                vt,      // typeof v during iteration
+                a;       // composition array for performance over string concat
+
+            // String
+            if (t === 'string') {
+                return _string(o);
+            }
+
+            // native boolean and Boolean instance
+            if (t === 'boolean' || o instanceof Boolean) {
+                return String(o);
+            }
+
+            // native number and Number instance
+            if (t === 'number' || o instanceof Number) {
+                return isFinite(o) ? String(o) : 'null';
+            }
+
+            // Date
+            if (o instanceof Date) {
+                return _date(o);
+            }
+
+            // Array
+            if (l.isArray(o)) {
+                // Check for cyclical references
+                for (i = pstack.length - 1; i >= 0; --i) {
+                    if (pstack[i] === o) {
+                        return 'null';
+                    }
+                }
+
+                // Add the array to the processing stack
+                pstack[pstack.length] = o;
+
+                a = [];
+                // Only recurse if we're above depth config
+                if (d > 0) {
+                    for (i = o.length - 1; i >= 0; --i) {
+                        a[i] = _stringify(o[i],w,d-1) || 'null';
+                    }
+                }
+
+                // remove the array from the stack
+                pstack.pop();
+
+                return '[' + a.join(',') + ']';
+            }
+
+            // Object
+            if (t === 'object') {
+                // Test for null reporting as typeof 'object'
+                if (!o) {
+                    return 'null';
+                }
+
+                // Check for cyclical references
+                for (i = pstack.length - 1; i >= 0; --i) {
+                    if (pstack[i] === o) {
+                        return 'null';
+                    }
+                }
+
+                // Add the object to the  processing stack
+                pstack[pstack.length] = o;
+
+                a = [];
+                // Only recurse if we're above depth config
+                if (d > 0) {
+
+                    // If whitelist provided, take only those keys
+                    if (w) {
+                        for (i = 0, j = 0, len = w.length; i < len; ++i) {
+                            if (typeof w[i] === 'string') {
+                                v = _stringify(o[w[i]],w,d-1);
+                                if (v) {
+                                    a[j++] = _string(w[i]) + ':' + v;
+                                }
+                            }
+                        }
+
+                    // Otherwise, take all valid object properties
+                    // omitting the prototype chain properties
+                    } else {
+                        j = 0;
+                        for (k in o) {
+                            if (typeof k === 'string' && l.hasOwnProperty(o,k)) {
+                                v = _stringify(o[k],w,d-1);
+                                if (v) {
+                                    a[j++] = _string(k) + ':' + v;
+                                }
+                            }
+                        }
+                    }
+                }
+
+                // Remove the object from processing stack
+                pstack.pop();
+
+                return '{' + a.join(',') + '}';
+            }
+
+            return undefined; // invalid input
+        };
+
+        // Default depth to POSITIVE_INFINITY
+        d = d >= 0 ? d : 1/0;
+
+        // process the input
+        return _stringify(o,w,d);
+    }
+};
+YAHOO.register("json", YAHOO.lang.JSON, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/layout/README
===================================================================
--- trunk/root/static/yui/layout/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/layout/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,12 @@
+**** version 2.5.1 ***
+    Bug Fixes:
+        * 1756637 - handling of scrollbar on panel resize is inconsistent
+        * 1767234 - [SF 1900012] LayoutUnit loses scrolled state on resize
+        * 1770567 - [SF 1901621] Left Unit Disappears on Expand
+        * 1778721 - [SF 1904062] Layout Manager documentation error
+        * 1781653 - Don't assume element with id "doc" is the body
+        * Removed the requirement for the collapse config option in order to programatically collapse a unit.   
+
+**** version 2.5.0 ***
+
+Initial Release

Added: trunk/root/static/yui/layout/assets/layout-core.css
===================================================================
--- trunk/root/static/yui/layout/assets/layout-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/layout/assets/layout-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,150 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+.yui-layout-loading {
+    visibility: hidden;
+}
+
+body.yui-layout {
+    overflow: hidden;
+    position: relative;
+    padding: 0;
+    margin: 0;
+}
+
+.yui-layout-doc {
+    position: relative;
+}
+
+.yui-layout-unit {
+    height: 50px;
+    width: 50px;
+    padding: 0;
+    margin: 0;
+    float: none;
+    z-index: 0;
+    overflow: hidden;
+}
+
+.yui-layout-unit-top {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+}
+
+.yui-layout-unit-left {
+    position: absolute;
+    top: 0;
+    left: 0;
+}
+
+.yui-layout-unit-right {
+    position: absolute;
+    top: 0;
+    right: 0;
+}
+
+.yui-layout-unit-bottom {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+}
+
+.yui-layout-unit-center {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+}
+
+.yui-layout div.yui-layout-hd {
+    position: absolute;
+    top: 0;
+    left: 0;
+    zoom: 1;
+    width: 100%;
+    overflow: hidden;
+}
+.yui-layout div.yui-layout-bd {
+    position: absolute;
+    top: 0;
+    left: 0;
+    zoom: 1;
+    width: 100%;
+    overflow: hidden;
+}
+.yui-layout .yui-layout-scroll div.yui-layout-bd {
+    overflow: auto;
+}
+.yui-layout div.yui-layout-ft {
+    position: absolute;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    zoom: 1;
+    overflow: hidden;
+}
+
+.yui-layout .yui-layout-unit div.yui-layout-hd h2 {
+    text-align: left;
+}
+
+.yui-layout .yui-layout-unit div.yui-layout-hd .collapse {
+    cursor: pointer;
+    height: 13px;
+    position: absolute;
+    right: 2px;
+    top: 2px;
+    width: 17px;
+    font-size: 0;
+}
+
+.yui-layout .yui-layout-unit div.yui-layout-hd .close {
+    cursor: pointer;
+    height: 13px;
+    position: absolute;
+    right: 2px;
+    top: 2px;
+    width: 17px;
+    font-size: 0;
+}
+.yui-layout .yui-layout-unit div.yui-layout-hd .collapse-close {
+    right: 25px;
+}
+
+
+.yui-layout .yui-layout-clip {
+    position: absolute;
+    height: 20px;
+    background-color: #c0c0c0;
+    display: none;
+}
+
+.yui-layout .yui-layout-clip .collapse {
+    cursor: pointer;
+    height: 13px;
+    position: absolute;
+    right: 2px;
+    top: 2px;
+    width: 17px;
+    font-size: 0px;
+}
+
+.yui-layout .yui-layout-wrap {
+    height: 100%;
+    width: 100%;
+    position: absolute;
+    left: 0;
+}
+
+.yui-layout .yui-layout-unit .yui-content {
+    overflow: hidden;
+}
+.yui-layout .yui-layout-unit .yui-layout-scroll {
+    overflow: auto;
+}

Added: trunk/root/static/yui/layout/assets/skins/sam/layout-skin.css
===================================================================
--- trunk/root/static/yui/layout/assets/skins/sam/layout-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/layout/assets/skins/sam/layout-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,197 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/* Remove the dotted border on the resize proxy */
+.yui-skin-sam .yui-layout .yui-resize-proxy {
+    border: none;
+    font-size: 0;
+    margin: 0;
+    padding: 0;
+}
+/* During resize, hide the handles */
+.yui-skin-sam .yui-layout .yui-resize-resizing .yui-resize-handle {
+    opacity: 0;
+    filter: alpha(opacity=0);
+}
+/* Style the div inside the resize proxy */
+.yui-skin-sam .yui-layout .yui-resize-proxy div {
+    position: absolute;
+    border: 1px solid #808080;
+    background-color: #EDF5FF;
+}
+/* Set the color of the Active resize handle */
+.yui-skin-sam .yui-layout .yui-resize .yui-resize-handle-active {
+    background-color: #EDF5FF;
+}
+/* Styles for the left handle */
+.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-l {
+    width: 5px;
+    height: 100%;
+    top: 0;
+    left: 0;
+}
+/* Styles for the right handle */
+.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-r {
+    width: 5px;
+    top: 0;
+    right: 0;
+    height: 100%;
+}
+/* Styles for the bottom handle */
+.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-b {
+    width: 100%;
+    bottom: 0;
+    left: 0;
+    height: 5px;
+}
+/* Styles for the top handle */
+.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-t {
+    width: 100%;
+    top: 0;
+    left: 0;
+    height: 5px;
+}
+
+/* Left Collapse button */
+.yui-skin-sam .yui-layout .yui-layout-unit-left div.yui-layout-hd .collapse {
+    background: transparent url(layout_sprite.png) no-repeat -20px -160px;
+    border: 1px solid #808080;
+}
+/* Left Collapsed Expand Button */
+.yui-skin-sam .yui-layout .yui-layout-clip-left .collapse {
+    background: transparent url(layout_sprite.png) no-repeat -20px -140px;
+    border: 1px solid #808080;
+}
+/* Right Collapse Button */
+.yui-skin-sam .yui-layout .yui-layout-unit-right div.yui-layout-hd .collapse {
+    background: transparent url(layout_sprite.png) no-repeat -20px -200px;
+    border: 1px solid #808080;
+}
+/* Right Collapsed Expand Button */
+.yui-skin-sam .yui-layout .yui-layout-clip-right .collapse {
+    background: transparent url(layout_sprite.png) no-repeat -20px -120px;
+    border: 1px solid #808080;
+}
+/* Top Collapse Button */
+.yui-skin-sam .yui-layout .yui-layout-unit-top div.yui-layout-hd .collapse {
+    background: transparent url(layout_sprite.png) no-repeat -20px -220px;
+    border: 1px solid #808080;
+}
+/* Top Collapsed Expand Button */
+.yui-skin-sam .yui-layout .yui-layout-clip-top .collapse {
+    background: transparent url(layout_sprite.png) no-repeat -20px -240px;
+    border: 1px solid #808080;
+}
+/* Bottom Collapse Button */
+.yui-skin-sam .yui-layout .yui-layout-unit-bottom div.yui-layout-hd .collapse {
+    background: transparent url(layout_sprite.png) no-repeat -20px -260px;
+    border: 1px solid #808080;
+}
+/* Bottom Collapsed Expand Button */
+.yui-skin-sam .yui-layout .yui-layout-clip-bottom .collapse {
+    background: transparent url(layout_sprite.png) no-repeat -20px -180px;
+    border: 1px solid #808080;
+}
+/* Close Button */
+.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-hd .close {
+    background: transparent url(layout_sprite.png) no-repeat -20px -100px;
+    border: 1px solid #808080;
+}
+
+/* Give the header a blue backgorund */
+.yui-skin-sam .yui-layout .yui-layout-hd {
+    background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1400px;
+    border: 1px solid #808080;
+}
+/* Set the background color */
+.yui-skin-sam .yui-layout {
+    background-color: #EDF5FF;
+}
+/* Style the text in the header */
+.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-hd h2 {
+    font-weight: bold;
+    color: #fff;
+    padding: 3px;
+}
+/* Style the body */
+.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd {
+    border: 1px solid #808080;
+    border-bottom: none;
+    border-top: none;
+    *border-bottom-width: 0;
+    *border-top-width: 0;
+    background-color: #f2f2f2;
+    text-align: left;
+}
+/* Add a border to the bottom of the body because there is no footer */
+.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd-noft {
+    border-bottom: 1px solid #808080;
+}
+/* Add a border to the top of the body because there is no header */
+.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd-nohd {
+    border-top: 1px solid #808080;
+}
+
+/* Style the Clip */
+.yui-skin-sam .yui-layout .yui-layout-clip {
+    position: absolute;
+    height: 20px;
+    background-color: #EDF5FF;
+    display: none;
+    border: 1px solid #808080;
+}
+/* Style the footer */
+.yui-skin-sam .yui-layout div.yui-layout-ft {
+    border: 1px solid #808080;
+    border-top: none;
+    *border-top-width: 0;
+    background-color: #f2f2f2;
+}
+
+/* Remove the color from the resize handle */
+.yui-skin-sam .yui-layout-unit .yui-resize-handle {
+    background-color: transparent;
+}
+/* Reposition the handles */
+.yui-skin-sam .yui-layout-unit .yui-resize-handle-r {
+    right: 0;
+    top: 0;
+    background-image: none;
+}
+.yui-skin-sam .yui-layout-unit .yui-resize-handle-l {
+    left: 0;
+    top: 0;
+    background-image: none;
+}
+.yui-skin-sam .yui-layout-unit .yui-resize-handle-b {
+    right: 0;
+    bottom: 0;
+    background-image: none;
+}
+.yui-skin-sam .yui-layout-unit .yui-resize-handle-t {
+    right: 0;
+    top: 0;
+    background-image: none;
+}
+/* Add the gripper */
+.yui-skin-sam .yui-layout-unit .yui-resize-handle-r .yui-layout-resize-knob,
+.yui-skin-sam .yui-layout-unit .yui-resize-handle-l .yui-layout-resize-knob {
+    position: absolute;
+    height: 16px;
+    width: 6px;
+    top: 45%;
+    left: 0px;
+    background: transparent url(layout_sprite.png) no-repeat 0 -5px;
+}
+/* Add the gripper */
+.yui-skin-sam .yui-layout-unit .yui-resize-handle-t .yui-layout-resize-knob,
+.yui-skin-sam .yui-layout-unit .yui-resize-handle-b .yui-layout-resize-knob {
+    position: absolute;
+    height: 6px;
+    width: 16px;
+    left: 45%;
+    background: transparent url(layout_sprite.png) no-repeat -20px 0;
+}

Added: trunk/root/static/yui/layout/assets/skins/sam/layout.css
===================================================================
--- trunk/root/static/yui/layout/assets/skins/sam/layout.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/layout/assets/skins/sam/layout.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+.yui-layout-loading{visibility:hidden;}body.yui-layout{overflow:hidden;position:relative;padding:0;margin:0;}.yui-layout-doc{position:relative;}.yui-layout-unit{height:50px;width:50px;padding:0;margin:0;float:none;z-index:0;overflow:hidden;}.yui-layout-unit-top{position:absolute;top:0;left:0;width:100%;}.yui-layout-unit-left{position:absolute;top:0;left:0;}.yui-layout-unit-right{position:absolute;top:0;right:0;}.yui-layout-unit-bottom{position:absolute;bottom:0;left:0;width:100%;}.yui-layout-unit-center{position:absolute;top:0;left:0;width:100%;}.yui-layout div.yui-layout-hd{position:absolute;top:0;left:0;zoom:1;width:100%;overflow:hidden;}.yui-layout div.yui-layout-bd{position:absolute;top:0;left:0;zoom:1;width:100%;overflow:hidden;}.yui-layout .yui-layout-scroll div.yui-layout-bd{overflow:auto;}.yui-layout div.yui-layout-ft{position:absolute;bottom:0;left:0;width:100%;zoom:1;overflow:hidden;}.yui-layout .yui-layout-unit div.yui-layout-hd h2{text-align:left;}.yui-layout .y!
 ui-layout-unit div.yui-layout-hd .collapse{cursor:pointer;height:13px;position:absolute;right:2px;top:2px;width:17px;font-size:0;}.yui-layout .yui-layout-unit div.yui-layout-hd .close{cursor:pointer;height:13px;position:absolute;right:2px;top:2px;width:17px;font-size:0;}.yui-layout .yui-layout-unit div.yui-layout-hd .collapse-close{right:25px;}.yui-layout .yui-layout-clip{position:absolute;height:20px;background-color:#c0c0c0;display:none;}.yui-layout .yui-layout-clip .collapse{cursor:pointer;height:13px;position:absolute;right:2px;top:2px;width:17px;font-size:0px;}.yui-layout .yui-layout-wrap{height:100%;width:100%;position:absolute;left:0;}.yui-layout .yui-layout-unit .yui-content{overflow:hidden;}.yui-layout .yui-layout-unit .yui-layout-scroll{overflow:auto;}.yui-skin-sam .yui-layout .yui-resize-proxy{border:none;font-size:0;margin:0;padding:0;}.yui-skin-sam .yui-layout .yui-resize-resizing .yui-resize-handle{opacity:0;filter:alpha(opacity=0);}.yui-skin-sam .yui-layout .!
 yui-resize-proxy div{position:absolute;border:1px solid #80808!
 0;backgr
ound-color:#EDF5FF;}.yui-skin-sam .yui-layout .yui-resize .yui-resize-handle-active{background-color:#EDF5FF;}.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-l{width:5px;height:100%;top:0;left:0;}.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-r{width:5px;top:0;right:0;height:100%;}.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-b{width:100%;bottom:0;left:0;height:5px;}.yui-skin-sam .yui-layout .yui-resize-proxy .yui-layout-handle-t{width:100%;top:0;left:0;height:5px;}.yui-skin-sam .yui-layout .yui-layout-unit-left div.yui-layout-hd .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -160px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip-left .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -140px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit-right div.yui-layout-hd .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -200px;b!
 order:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip-right .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -120px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit-top div.yui-layout-hd .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -220px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip-top .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -240px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit-bottom div.yui-layout-hd .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -260px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip-bottom .collapse{background:transparent url(layout_sprite.png) no-repeat -20px -180px;border:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-hd .close{background:transparent url(layout_sprite.png) no-repeat -20px -100px;border:1px solid #8080!
 80;}.yui-skin-sam .yui-layout .yui-layout-hd{background:url(..!
 /../../.
./assets/skins/sam/sprite.png) repeat-x 0 -1400px;border:1px solid #808080;}.yui-skin-sam .yui-layout{background-color:#EDF5FF;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-hd h2{font-weight:bold;color:#fff;padding:3px;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd{border:1px solid #808080;border-bottom:none;border-top:none;*border-bottom-width:0;*border-top-width:0;background-color:#f2f2f2;text-align:left;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd-noft{border-bottom:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd-nohd{border-top:1px solid #808080;}.yui-skin-sam .yui-layout .yui-layout-clip{position:absolute;height:20px;background-color:#EDF5FF;display:none;border:1px solid #808080;}.yui-skin-sam .yui-layout div.yui-layout-ft{border:1px solid #808080;border-top:none;*border-top-width:0;background-color:#f2f2f2;}.yui-skin-sam .yui-layout-unit .yui-resize-handle{background-color:transparent;}.yui-sk!
 in-sam .yui-layout-unit .yui-resize-handle-r{right:0;top:0;background-image:none;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-l{left:0;top:0;background-image:none;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-b{right:0;bottom:0;background-image:none;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-t{right:0;top:0;background-image:none;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-r .yui-layout-resize-knob,.yui-skin-sam .yui-layout-unit .yui-resize-handle-l .yui-layout-resize-knob{position:absolute;height:16px;width:6px;top:45%;left:0px;background:transparent url(layout_sprite.png) no-repeat 0 -5px;}.yui-skin-sam .yui-layout-unit .yui-resize-handle-t .yui-layout-resize-knob,.yui-skin-sam .yui-layout-unit .yui-resize-handle-b .yui-layout-resize-knob{position:absolute;height:6px;width:16px;left:45%;background:transparent url(layout_sprite.png) no-repeat -20px 0;}

Added: trunk/root/static/yui/layout/assets/skins/sam/layout_sprite.png
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/layout/assets/skins/sam/layout_sprite.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/root/static/yui/layout/layout-beta-debug.js
===================================================================
--- trunk/root/static/yui/layout/layout-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/layout/layout-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,2061 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * @description <p>Provides a fixed layout containing, top, bottom, left, right and center layout units. It can be applied to either the body or an element.</p>
+ * @namespace YAHOO.widget
+ * @requires yahoo, dom, element, event
+ * @module layout
+ * @beta
+ */
+(function() {
+    var Dom = YAHOO.util.Dom,
+        Event = YAHOO.util.Event,
+        Lang = YAHOO.lang;
+
+    /**
+     * @constructor
+     * @class Layout
+     * @extends YAHOO.util.Element
+     * @description <p>Provides a fixed layout containing, top, bottom, left, right and center layout units. It can be applied to either the body or an element.</p>
+     * @param {String/HTMLElement} el The element to make contain a layout.
+     * @param {Object} attrs Object liternal containing configuration parameters.
+    */
+
+    var Layout = function(el, config) {
+        YAHOO.log('Creating the Layout Object', 'info', 'Layout');
+        if (Lang.isObject(el) && !el.tagName) {
+            config = el;
+            el = null;
+        }
+        if (Lang.isString(el)) {
+            if (Dom.get(el)) {
+                el = Dom.get(el);
+            }
+        }
+        if (!el) {
+            el = document.body;
+        }
+
+        var oConfig = {
+            element: el,
+            attributes: config || {}
+        };
+
+        Layout.superclass.constructor.call(this, oConfig.element, oConfig.attributes);    
+    };
+
+    /**
+    * @private
+    * @static
+    * @property _instances
+    * @description Internal hash table for all layout instances
+    * @type Object
+    */ 
+    Layout._instances = {};
+    /**
+    * @static
+    * @method getLayoutById 
+    * @description Get's a layout object by the HTML id of the element associated with the Layout object.
+    * @return {Object} The Layout Object
+    */ 
+    Layout.getLayoutById = function(id) {
+        if (Layout._instances[id]) {
+            return Layout._instances[id];
+        }
+        return false;
+    };
+
+    YAHOO.extend(Layout, YAHOO.util.Element, {
+        /**
+        * @property browser
+        * @description A modified version of the YAHOO.env.ua object
+        * @type Object
+        */
+        browser: function() {
+            var b = YAHOO.env.ua;
+            b.standardsMode = false;
+            b.secure = false;
+            return b;
+        }(),
+        /**
+        * @private
+        * @property _rendered
+        * @description Set to true when the layout is rendered
+        * @type Boolean
+        */
+        _rendered: null,
+        /**
+        * @private
+        * @property _zIndex
+        * @description The zIndex to set all LayoutUnits to
+        * @type Number
+        */
+        _zIndex: null,
+        /**
+        * @private
+        * @property _sizes
+        * @description A collection of the current sizes of all usable LayoutUnits to be used for calculations
+        * @type Object
+        */
+        _sizes: null,
+        /**
+        * @private
+        * @method _setBodySize
+        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
+        * @description Used to set the body size of the layout, sets the height and width of the parent container
+        */
+        _setBodySize: function(set) {
+            var h = 0, w = 0;
+            set = ((set === false) ? false : true);
+
+            if (this._isBody) {
+                h = Dom.getClientHeight();
+                w = Dom.getClientWidth();
+            } else {
+                h = parseInt(this.getStyle('height'), 10);
+                w = parseInt(this.getStyle('width'), 10);
+                if (isNaN(w)) {
+                    w = this.get('element').clientWidth;
+                }
+                if (isNaN(h)) {
+                    h = this.get('element').clientHeight;
+                }
+            }
+            if (this.get('minWidth')) {
+                if (w < this.get('minWidth')) {
+                    w = this.get('minWidth');
+                }
+            }
+            if (this.get('minHeight')) {
+                if (h < this.get('minHeight')) {
+                    h = this.get('minHeight');
+                }
+            }
+            if (set) {
+                Dom.setStyle(this._doc, 'height', h + 'px');
+                Dom.setStyle(this._doc, 'width', w + 'px');
+            }
+            this._sizes.doc = { h: h, w: w };
+            YAHOO.log('Setting Body height and width: (' + h + ',' + w + ')', 'info', 'Layout');
+            this._setSides(set);
+        },
+        /**
+        * @private
+        * @method _setSides
+        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
+        * @description Used to set the size and position of the left, right, top and bottom units
+        */
+        _setSides: function(set) {
+            YAHOO.log('Setting side units', 'info', 'Layout');
+            var h1 = ((this._top) ? this._top.get('height') : 0),
+                h2 = ((this._bottom) ? this._bottom.get('height') : 0),
+                h = this._sizes.doc.h,
+                w = this._sizes.doc.w;
+            set = ((set === false) ? false : true);
+
+            this._sizes.top = {
+                h: h1, w: ((this._top) ? w : 0),
+                t: 0
+            };
+            this._sizes.bottom = {
+                h: h2, w: ((this._bottom) ? w : 0)
+            };
+            
+            var newH = (h - (h1 + h2));
+
+            this._sizes.left = {
+                h: newH, w: ((this._left) ? this._left.get('width') : 0)
+            };
+            this._sizes.right = {
+                h: newH, w: ((this._right) ? this._right.get('width') : 0),
+                l: ((this._right) ? (w - this._right.get('width')) : 0),
+                t: ((this._top) ? this._sizes.top.h : 0)
+            };
+            
+            if (this._right && set) {
+                this._right.set('top', this._sizes.right.t);
+                if (!this._right._collapsing) { 
+                    this._right.set('left', this._sizes.right.l);
+                }
+                this._right.set('height', this._sizes.right.h, true);
+            }
+            if (this._left) {
+                this._sizes.left.l = 0;
+                if (this._top) {
+                    this._sizes.left.t = this._sizes.top.h;
+                } else {
+                    this._sizes.left.t = 0;
+                }
+                if (set) {
+                    this._left.set('top', this._sizes.left.t);
+                    this._left.set('height', this._sizes.left.h, true);
+                    this._left.set('left', 0);
+                }
+            }
+            if (this._bottom) {
+                this._sizes.bottom.t = this._sizes.top.h + this._sizes.left.h;
+                if (set) {
+                    this._bottom.set('top', this._sizes.bottom.t);
+                    this._bottom.set('width', this._sizes.bottom.w, true);
+                }
+            }
+            if (this._top) {
+                if (set) {
+                    this._top.set('width', this._sizes.top.w, true);
+                }
+            }
+            YAHOO.log('Setting sizes: (' + Lang.dump(this._sizes) + ')', 'info', 'Layout');
+            this._setCenter(set);
+        },
+        /**
+        * @private
+        * @method _setCenter
+        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
+        * @description Used to set the size and position of the center unit
+        */
+        _setCenter: function(set) {
+            set = ((set === false) ? false : true);
+            var h = this._sizes.left.h;
+            var w = (this._sizes.doc.w - (this._sizes.left.w + this._sizes.right.w));
+            if (set) {
+                this._center.set('height', h, true);
+                this._center.set('width', w, true);
+                this._center.set('top', this._sizes.top.h);
+                this._center.set('left', this._sizes.left.w);
+            }
+            this._sizes.center = { h: h, w: w, t: this._sizes.top.h, l: this._sizes.left.w };
+            YAHOO.log('Setting Center size to: (' + h + ', ' + w + ')', 'info', 'Layout');
+        },
+        /**
+        * @method getSizes
+        * @description Get a reference to the internal Layout Unit sizes object used to build the layout wireframe
+        * @return {Object} An object of the layout unit sizes
+        */
+        getSizes: function() {
+            return this._sizes;
+        },
+        /**
+        * @method getUnitById
+        * @param {String} id The HTML element id of the unit
+        * @description Get the LayoutUnit by it's HTML id
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        getUnitById: function(id) {
+            return YAHOO.widget.LayoutUnit.getLayoutUnitById(id);
+        },
+        /**
+        * @method getUnitByPosition
+        * @param {String} pos The position of the unit in this layout
+        * @description Get the LayoutUnit by it's position in this layout
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        getUnitByPosition: function(pos) {
+            if (pos) {
+                pos = pos.toLowerCase();
+                if (this['_' + pos]) {
+                    return this['_' + pos];
+                }
+            }
+            return false;
+        },
+        /**
+        * @method removeUnit
+        * @param {Object} unit The LayoutUnit that you want to remove
+        * @description Remove the unit from this layout and resize the layout.
+        */
+        removeUnit: function(unit) {
+            this['_' + unit.get('position')] = null;
+            this.resize();
+        },
+        /**
+        * @method addUnit
+        * @param {Object} cfg The config for the LayoutUnit that you want to add
+        * @description Add a unit to this layout and if the layout is rendered, resize the layout. 
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        addUnit: function(cfg) {
+            if (!cfg.position) {
+                YAHOO.log('No position property passed', 'error', 'Layout');
+                return false;
+            }
+            if (this['_' + cfg.position]) {
+                YAHOO.log('Position already exists', 'error', 'Layout');
+                return false;
+            }
+            YAHOO.log('Adding Unit at position: ' + cfg.position, 'info', 'Layout');
+            var element = null,
+                el = null;
+
+            if (cfg.id) {
+                if (Dom.get(cfg.id)) {
+                    element = Dom.get(cfg.id);
+                    delete cfg.id;
+
+                }
+            }
+            if (cfg.element) {
+                element = cfg.element;
+            }
+
+            if (!el) {
+                el = document.createElement('div');
+                var id = Dom.generateId();
+                el.id = id;
+            }
+
+            if (!element) {
+                element = document.createElement('div');
+            }
+            Dom.addClass(element, 'yui-layout-wrap');
+            if (this.browser.ie && !this.browser.standardsMode) {
+                el.style.zoom = 1;
+                element.style.zoom = 1;
+            }
+
+            if (el.firstChild) {
+                el.insertBefore(element, el.firstChild);
+            } else {
+                el.appendChild(element);
+            }
+            this._doc.appendChild(el);
+
+            var h = false, w = false;
+
+            if (cfg.height) {
+                h = parseInt(cfg.height, 10);
+            }
+            if (cfg.width) {
+                w = parseInt(cfg.width, 10);
+            }
+            var unitConfig = {};
+            YAHOO.lang.augmentObject(unitConfig, cfg); // break obj ref
+
+            unitConfig.parent = this;
+            unitConfig.wrap = element;
+            unitConfig.height = h;
+            unitConfig.width = w;
+
+            var unit = new YAHOO.widget.LayoutUnit(el, unitConfig);
+
+            unit.on('heightChange', this.resize, this, true);
+            unit.on('widthChange', this.resize, this, true);
+            unit.on('gutterChange', this.resize, this, true);
+            this['_' + cfg.position] = unit;
+
+            if (this._rendered) {
+                this.resize();
+            }
+
+            return unit;
+        },
+        /**
+        * @private
+        * @method _createUnits
+        * @description Private method to create units from the config that was passed in.
+        */
+        _createUnits: function() {
+            var units = this.get('units');
+            for (var i in units) {
+                if (Lang.hasOwnProperty(units, i)) {
+                    this.addUnit(units[i]);
+                }
+            }
+        },
+        /**
+        * @method resize
+        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
+        * @description Starts the chain of resize routines that will resize all the units.
+        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
+        */
+        resize: function(set) {
+            set = ((set === false) ? false : true);
+            if (set) {
+                var retVal = this.fireEvent('beforeResize');
+                if (retVal === false) {
+                    set = false;
+                }
+                if (this.browser.ie) {
+                    if (this._isBody) {
+                        Dom.removeClass(document.documentElement, 'yui-layout');
+                        Dom.addClass(document.documentElement, 'yui-layout');
+                    } else {
+                        this.removeClass('yui-layout');
+                        this.addClass('yui-layout');
+                    }
+                }
+            }
+            this._setBodySize(set);
+            if (set) {
+                this.fireEvent('resize', { target: this, sizes: this._sizes });
+            }
+            return this;
+        },
+        /**
+        * @private
+        * @method _setupBodyElements
+        * @description Sets up the main doc element when using the body as the main element.
+        */
+        _setupBodyElements: function() {
+            this._doc = Dom.get('layout-doc');
+            if (!this._doc) {
+                this._doc = document.createElement('div');
+                this._doc.id = 'layout-doc';
+                if (document.body.firstChild) {
+                    document.body.insertBefore(this._doc, document.body.firstChild);
+                } else {
+                    document.body.appendChild(this._doc);
+                }
+            }
+            this._createUnits();
+            this._setBodySize();
+            Event.on(window, 'resize', this.resize, this, true);
+            Dom.addClass(this._doc, 'yui-layout-doc');
+        },
+        /**
+        * @private
+        * @method _setupElements
+        * @description Sets up the main doc element when not using the body as the main element.
+        */
+        _setupElements: function() {
+            this._doc = this.getElementsByClassName('doc')[0];
+            if (!this._doc) {
+                this._doc = document.createElement('div');
+                this.get('element').appendChild(this._doc);
+            }
+            this._createUnits();
+            this._setBodySize();
+            Event.on(window, 'resize', this.resize, this, true);
+            Dom.addClass(this._doc, 'yui-layout-doc');
+        },
+        /**
+        * @private
+        * @property _isBody
+        * @description Flag to determine if we are using the body as the root element.
+        * @type Boolean
+        */
+        _isBody: null,
+        /**
+        * @private
+        * @property _doc
+        * @description Reference to the root element
+        * @type HTMLElement
+        */
+        _doc: null,
+        /**
+        * @private
+        * @property _left
+        * @description Reference to the left LayoutUnit Object
+        * @type {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} A LayoutUnit instance
+        */
+        _left: null,
+        /**
+        * @private
+        * @property _right
+        * @description Reference to the right LayoutUnit Object
+        * @type {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} A LayoutUnit instance
+        */
+        _right: null,
+        /**
+        * @private
+        * @property _top
+        * @description Reference to the top LayoutUnit Object
+        * @type {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} A LayoutUnit instance
+        */
+        _top: null,
+        /**
+        * @private
+        * @property _bottom
+        * @description Reference to the bottom LayoutUnit Object
+        * @type {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} A LayoutUnit instance
+        */
+        _bottom: null,
+        /**
+        * @private
+        * @property _center
+        * @description Reference to the center LayoutUnit Object
+        * @type {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} A LayoutUnit instance
+        */
+        _center: null,
+        /**
+        * @private
+        * @method init
+        * @description The Layout class' initialization method
+        */        
+        init: function(p_oElement, p_oAttributes) {
+            YAHOO.log('init', 'info', 'Layout');
+            this._zIndex = 0;
+            Layout.superclass.init.call(this, p_oElement, p_oAttributes);
+            
+            if (this.get('parent')) {
+                this._zIndex = this.get('parent')._zIndex + 10;
+            }
+
+            this._sizes = {};
+
+            var id = p_oElement;
+            if (!Lang.isString(id)) {
+                id = Dom.generateId(id);
+            }
+            Layout._instances[id] = this;
+        },
+        /**
+        * @method render
+        * @description This method starts the render process, applying classnames and creating elements
+        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
+        */        
+        render: function() {
+            YAHOO.log('Render', 'info', 'Layout');
+            this._stamp();
+            var el = this.get('element');
+            if (el && el.tagName && (el.tagName.toLowerCase() == 'body')) {
+                this._isBody = true;
+                Dom.addClass(document.body, 'yui-layout');
+                if (Dom.hasClass(document.body, 'yui-skin-sam')) {
+                    //Move the class up so we can have a css chain
+                    Dom.addClass(document.documentElement, 'yui-skin-sam');
+                    Dom.removeClass(document.body, 'yui-skin-sam');
+                }
+                this._setupBodyElements();
+            } else {
+                this._isBody = false;
+                this.addClass('yui-layout');
+                this._setupElements();
+            }
+            this.resize();
+            this._rendered = true;
+            this.fireEvent('render');
+
+            return this;
+        },
+        /**
+        * @private
+        * @method _stamp
+        * @description Stamps the root node with a secure classname for ease of use. Also sets the this.browser.standardsMode variable.
+        */        
+        _stamp: function() {
+            if (document.compatMode == 'CSS1Compat') {
+                this.browser.standardsMode = true;
+            }
+            if (window.location.href.toLowerCase().indexOf("https") === 0) {
+                Dom.addClass(document.documentElement, 'secure');
+                this.browser.secure = true;
+            }
+        },
+        /**
+        * @private
+        * @method initAttributes
+        * @description Processes the config
+        */        
+        initAttributes: function(attr) {
+            Layout.superclass.initAttributes.call(this, attr);
+            /**
+            * @attribute units
+            * @description An array of config definitions for the LayoutUnits to add to this layout
+            * @type Array
+            */
+            this.setAttributeConfig('units', {
+                writeOnce: true,
+                validator: YAHOO.lang.isArray,
+                value: attr.units || []
+            });
+
+            /**
+            * @attribute minHeight
+            * @description The minimum height in pixels
+            * @type Number
+            */
+            this.setAttributeConfig('minHeight', {
+                value: attr.minHeight || false,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute minWidth
+            * @description The minimum width in pixels
+            * @type Number
+            */
+            this.setAttributeConfig('minWidth', {
+                value: attr.minWidth || false,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute height
+            * @description The height in pixels
+            * @type Number
+            */
+            this.setAttributeConfig('height', {
+                value: attr.height || false,
+                validator: YAHOO.lang.isNumber,
+                method: function(h) {
+                    this.setStyle('height', h + 'px');
+                }
+            });
+
+            /**
+            * @attribute width
+            * @description The width in pixels
+            * @type Number
+            */
+            this.setAttributeConfig('width', {
+                value: attr.width || false,
+                validator: YAHOO.lang.isNumber,
+                method: function(w) {
+                    this.setStyle('width', w + 'px');
+                }
+            });
+
+            /**
+            * @attribute parent
+            * @description If this layout is to be used as a child of another Layout instance, this config will bind the resize events together.
+            * @type Object YAHOO.widget.Layout
+            */
+            this.setAttributeConfig('parent', {
+                writeOnce: true,
+                value: attr.parent || false,
+                method: function(p) {
+                    if (p) {
+                        p.on('resize', this.resize, this, true);
+                    }
+                }
+            });
+        },
+        /**
+        * @method toString
+        * @description Returns a string representing the Layout.
+        * @return {String}
+        */        
+        toString: function() {
+            if (this.get) {
+                return 'Layout #' + this.get('id');
+            }
+            return 'Layout';
+        }
+    });
+    /**
+    * @event resize
+    * @description Fired when this.resize is called
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event startResize
+    * @description Fired when the Resize Utility for a Unit fires it's startResize Event.
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event beforeResize
+    * @description Firef at the beginning of the resize method. If you return false, the resize is cancelled.
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event render
+    * @description Fired after the render method completes.
+    * @type YAHOO.util.CustomEvent
+    */
+
+    YAHOO.widget.Layout = Layout;
+})();
+/**
+ * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
+ * @namespace YAHOO.widget
+ * @requires yahoo, dom, element, event, layout
+ * @optional animation, dragdrop, selector
+ * @beta
+ */
+(function() {
+    var Dom = YAHOO.util.Dom,
+        Sel = YAHOO.util.Selector,
+        Event = YAHOO.util.Event,
+        Lang = YAHOO.lang;
+
+    /**
+     * @constructor
+     * @class LayoutUnit
+     * @extends YAHOO.util.Element
+     * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
+     * @param {String/HTMLElement} el The element to make a unit.
+     * @param {Object} attrs Object liternal containing configuration parameters.
+    */
+
+    var LayoutUnit = function(el, config) {
+        
+        var oConfig = {
+            element: el,
+            attributes: config || {}
+        };
+
+        LayoutUnit.superclass.constructor.call(this, oConfig.element, oConfig.attributes);    
+    };
+
+    /**
+    * @private
+    * @static
+    * @property _instances
+    * @description Internal hash table for all layout unit instances
+    * @type Object
+    */ 
+    LayoutUnit._instances = {};
+    /**
+    * @static
+    * @method getLayoutUnitById 
+    * @description Get's a layout unit object by the HTML id of the element associated with the Layout Unit object.
+    * @return {Object} The Layout Object
+    */ 
+    LayoutUnit.getLayoutUnitById = function(id) {
+        if (LayoutUnit._instances[id]) {
+            return LayoutUnit._instances[id];
+        }
+        return false;
+    };
+
+    YAHOO.extend(LayoutUnit, YAHOO.util.Element, {
+        /**
+        * @property STR_CLOSE
+        * @description String used for close button title
+        * @type {String}
+        */
+        STR_CLOSE: 'Click to close this pane.',
+        /**
+        * @property STR_COLLAPSE
+        * @description String used for collapse button title
+        * @type {String}
+        */
+        STR_COLLAPSE: 'Click to collapse this pane.',
+        /**
+        * @property STR_EXPAND
+        * @description String used for expand button title
+        * @type {String}
+        */
+        STR_EXPAND: 'Click to expand this pane.',
+        /**
+        * @property browser
+        * @description A modified version of the YAHOO.env.ua object
+        * @type Object
+        */
+        browser: null,
+        /**
+        * @private
+        * @property _sizes
+        * @description A collection of the current sizes of the contents of this Layout Unit
+        * @type Object
+        */
+        _sizes: null,
+        /**
+        * @private
+        * @property _anim
+        * @description A reference to the Animation instance used by this LayouUnit
+        * @type YAHOO.util.Anim
+        */
+        _anim: null,
+        /**
+        * @private
+        * @property _resize
+        * @description A reference to the Resize instance used by this LayoutUnit
+        * @type YAHOO.util.Resize
+        */
+        _resize: null,
+        /**
+        * @private
+        * @property _clip
+        * @description A reference to the clip element used when collapsing the unit
+        * @type HTMLElement
+        */
+        _clip: null,
+        /**
+        * @private
+        * @property _gutter
+        * @description A simple hash table used to store the gutter to apply to the Unit
+        * @type Object
+        */
+        _gutter: null,
+        /**
+        * @property header
+        * @description A reference to the HTML element used for the Header
+        * @type HTMLELement
+        */
+        header: null,
+        /**
+        * @property body
+        * @description A reference to the HTML element used for the body
+        * @type HTMLElement
+        */
+        body: null,
+        /**
+        * @property footer
+        * @description A reference to the HTML element used for the footer
+        * @type HTMLElement
+        */
+        footer: null,
+        /**
+        * @private
+        * @property _collapsed
+        * @description Flag to determine if the unit is collapsed or not.
+        * @type Boolean
+        */
+        _collapsed: null,
+        /**
+        * @private
+        * @property _collapsing
+        * @description A flag set while the unit is being collapsed, used so we don't fire events while animating the size
+        * @type Boolean
+        */
+        _collapsing: null,
+        /**
+        * @private
+        * @property _lastWidth
+        * @description A holder for the last known width of the unit
+        * @type Number
+        */
+        _lastWidth: null,
+        /**
+        * @private
+        * @property _lastHeight
+        * @description A holder for the last known height of the unit
+        * @type Number
+        */
+        _lastHeight: null,
+        /**
+        * @private
+        * @property _lastTop
+        * @description A holder for the last known top of the unit
+        * @type Number
+        */
+        _lastTop: null,
+        /**
+        * @private
+        * @property _lastLeft
+        * @description A holder for the last known left of the unit
+        * @type Number
+        */
+        _lastLeft: null,
+        /**
+        * @private
+        * @property _lastScroll
+        * @description A holder for the last known scroll state of the unit
+        * @type Boolean
+        */
+        _lastScroll: null,
+        /**
+        * @private
+        * @property _lastCenetrScroll
+        * @description A holder for the last known scroll state of the center unit
+        * @type Boolean
+        */
+        _lastCenterScroll: null,
+        /**
+        * @private
+        * @property _lastScrollTop
+        * @description A holder for the last known scrollTop state of the unit
+        * @type Number
+        */
+        _lastScrollTop: null,
+        /**
+        * @method resize
+        * @description Resize either the unit or it's clipped state, also updating the box inside
+        * @param {Boolean} force This will force full calculations even when the unit is collapsed
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        resize: function(force) {
+            YAHOO.log('Resize', 'info', 'LayoutUnit');
+            var retVal = this.fireEvent('beforeResize');
+            if (retVal === false) {
+                return this;
+            }
+            if (!this._collapsing || (force === true)) {
+                var scroll = this.get('scroll');
+                this.set('scroll', false);
+
+
+                var hd = this._getBoxSize(this.header),
+                    ft = this._getBoxSize(this.footer),
+                    box = [this.get('height'), this.get('width')];
+
+
+                var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
+                    nw = box[1] - (this._gutter.left + this._gutter.right);
+
+                var wrapH = (nh + (hd[0] + ft[0])),
+                    wrapW = nw;
+
+                if (this._collapsed && !this._collapsing) {
+                    this._setHeight(this._clip, wrapH);
+                    this._setWidth(this._clip, wrapW);
+                    Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
+                    Dom.setStyle(this._clip, 'left', this.get('left') + this._gutter.left + 'px');
+                } else if (!this._collapsed || (this._collapsed && this._collapsing)) {
+                    wrapH = this._setHeight(this.get('wrap'), wrapH);
+                    wrapW = this._setWidth(this.get('wrap'), wrapW);
+                    this._sizes.wrap.h = wrapH;
+                    this._sizes.wrap.w = wrapW;
+
+                    Dom.setStyle(this.get('wrap'), 'top', this._gutter.top + 'px');
+                    Dom.setStyle(this.get('wrap'), 'left', this._gutter.left + 'px');
+
+                    this._sizes.header.w = this._setWidth(this.header, wrapW);
+                    this._sizes.header.h = hd[0];
+
+                    this._sizes.footer.w = this._setWidth(this.footer, wrapW);
+                    this._sizes.footer.h = ft[0];
+
+                    Dom.setStyle(this.footer, 'bottom', '0px');
+
+                    this._sizes.body.h = this._setHeight(this.body, (wrapH - (hd[0] + ft[0])));
+                    this._sizes.body.w =this._setWidth(this.body, wrapW);
+                    Dom.setStyle(this.body, 'top', hd[0] + 'px');
+
+                    this.set('scroll', scroll);
+                    this.fireEvent('resize');
+                }
+            }
+            return this;
+        },
+        /**
+        * @private
+        * @method _setWidth
+        * @description Sets the width of the element based on the border size of the element.
+        * @param {HTMLElement} el The HTMLElement to have it's width set
+        * @param {Number} w The width that you want it the element set to
+        * @return {Number} The new width, fixed for borders and IE QuirksMode
+        */
+        _setWidth: function(el, w) {
+            if (el) {
+                var b = this._getBorderSizes(el);
+                w = (w - (b[1] + b[3]));
+                w = this._fixQuirks(el, w, 'w');
+                Dom.setStyle(el, 'width', w + 'px');
+            }
+            return w;
+        },
+        /**
+        * @private
+        * @method _setHeight
+        * @description Sets the height of the element based on the border size of the element.
+        * @param {HTMLElement} el The HTMLElement to have it's height set
+        * @param {Number} h The height that you want it the element set to
+        * @return {Number} The new height, fixed for borders and IE QuirksMode
+        */
+        _setHeight: function(el, h) {
+            if (el) {
+                var b = this._getBorderSizes(el);
+                h = (h - (b[0] + b[2]));
+                h = this._fixQuirks(el, h, 'h');
+                Dom.setStyle(el, 'height', h + 'px');
+            }
+            return h;
+        },
+        /**
+        * @private
+        * @method _fixQuirks
+        * @description Fixes the box calculations for IE in QuirksMode
+        * @param {HTMLElement} el The HTMLElement to set the dimension on
+        * @param {Number} dim The number of the dimension to fix
+        * @param {String} side The dimension (h or w) to fix. Defaults to h
+        * @return {Number} The fixed dimension
+        */
+        _fixQuirks: function(el, dim, side) {
+            var i1 = 0, i2 = 2;
+            if (side == 'w') {
+                i1 = 1;
+                i2 = 3;
+            }
+            if (this.browser.ie && !this.browser.standardsMode) {
+                //Internet Explorer - Quirks Mode
+                var b = this._getBorderSizes(el),
+                    bp = this._getBorderSizes(el.parentNode);
+                if ((b[i1] === 0) && (b[i2] === 0)) { //No Borders, check parent
+                    if ((bp[i1] !== 0) && (bp[i2] !== 0)) { //Parent has Borders
+                        dim = (dim - (bp[i1] + bp[i2]));
+                    }
+                } else {
+                    if ((bp[i1] === 0) && (bp[i2] === 0)) {
+                        dim = (dim + (b[i1] + b[i2]));
+                    }
+                }
+            }
+            return dim;
+        },
+        /**
+        * @private
+        * @method _getBoxSize
+        * @description Get's the elements clientHeight and clientWidth plus the size of the borders
+        * @param {HTMLElement} el The HTMLElement to get the size of
+        * @return {Array} An array of height and width
+        */
+        _getBoxSize: function(el) {
+            var size = [0, 0];
+            if (el) {
+                if (this.browser.ie && !this.browser.standardsMode) {
+                    el.style.zoom = 1;
+                }
+                var b = this._getBorderSizes(el);
+                size[0] = el.clientHeight + (b[0] + b[2]);
+                size[1] = el.clientWidth + (b[1] + b[3]);
+            }
+            return size;
+        },
+        /**
+        * @private
+        * @method _getBorderSizes
+        * @description Get the CSS border size of the element passed.
+        * @param {HTMLElement} el The element to get the border size of
+        * @return {Array} An array of the top, right, bottom, left borders.
+        */
+        _getBorderSizes: function(el) {
+            var s = [];
+            el = el || this.get('element');
+            if (this.browser.ie && !this.browser.standardsMode) {
+                el.style.zoom = 1;
+            }
+            s[0] = parseInt(Dom.getStyle(el, 'borderTopWidth'), 10);
+            s[1] = parseInt(Dom.getStyle(el, 'borderRightWidth'), 10);
+            s[2] = parseInt(Dom.getStyle(el, 'borderBottomWidth'), 10);
+            s[3] = parseInt(Dom.getStyle(el, 'borderLeftWidth'), 10);
+            
+            //IE will return NaN on these if they are set to auto, we'll set them to 0
+            for (var i = 0; i < s.length; i++) {
+                if (isNaN(s[i])) {
+                    s[i] = 0;
+                }
+            }
+            return s;
+        },
+        /**
+        * @private
+        * @method _createClip
+        * @description Create the clip element used when the Unit is collapsed
+        */
+        _createClip: function() {
+            if (!this._clip) {
+                this._clip = document.createElement('div');
+                this._clip.className = 'yui-layout-clip yui-layout-clip-' + this.get('position');
+                this._clip.innerHTML = '<div class="collapse"></div>';
+                var c = this._clip.firstChild;
+                c.title = this.STR_EXPAND;
+                Event.on(c, 'click', this.expand, this, true);
+                this.get('element').parentNode.appendChild(this._clip);
+            }
+        },
+        /**
+        * @private
+        * @method _toggleClip
+        * @description Toggle th current state of the Clip element and set it's height, width and position
+        */
+        _toggleClip: function() {
+            if (!this._collapsed) {
+                //show
+                var hd = this._getBoxSize(this.header),
+                    ft = this._getBoxSize(this.footer),
+                    box = [this.get('height'), this.get('width')];
+
+
+                var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
+                    nw = box[1] - (this._gutter.left + this._gutter.right),
+                    wrapH = (nh + (hd[0] + ft[0]));
+
+                switch (this.get('position')) {
+                    case 'top':
+                    case 'bottom':
+                        this._setWidth(this._clip, nw);
+                        this._setHeight(this._clip, this.get('collapseSize'));
+                        Dom.setStyle(this._clip, 'left', (this._lastLeft + this._gutter.left) + 'px');
+                        if (this.get('position') == 'bottom') {
+                            Dom.setStyle(this._clip, 'top', ((this._lastTop + this._lastHeight) - (this.get('collapseSize') - this._gutter.top)) + 'px');
+                        } else {
+                            Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
+                        }
+                        break;
+                    case 'left':
+                    case 'right':
+                        this._setWidth(this._clip, this.get('collapseSize'));
+                        this._setHeight(this._clip, wrapH);
+                        Dom.setStyle(this._clip, 'top', (this.get('top') + this._gutter.top) + 'px');
+                        if (this.get('position') == 'right') {
+                            Dom.setStyle(this._clip, 'left', (((this._lastLeft + this._lastWidth) - this.get('collapseSize')) - this._gutter.left) + 'px');
+                        } else {
+                            Dom.setStyle(this._clip, 'left', (this.get('left') + this._gutter.left) + 'px');
+                        }
+                        break;
+                }
+
+                Dom.setStyle(this._clip, 'display', 'block');
+                this.setStyle('display', 'none');
+            } else {
+                //Hide
+                Dom.setStyle(this._clip, 'display', 'none');
+            }
+        },
+        /**
+        * @method getSizes
+        * @description Get a reference to the internal sizes object for this unit
+        * @return {Object} An object of the sizes used for calculations
+        */
+        getSizes: function() {
+            return this._sizes;
+        },
+        /**
+        * @method toggle
+        * @description Toggles the Unit, replacing it with a clipped version.
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        toggle: function() {
+            if (this._collapsed) {
+                this.expand();
+            } else {
+                this.collapse();
+            }
+            return this;
+        },
+        /**
+        * @method expand
+        * @description Expand the Unit if it is collapsed.
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        expand: function() {
+            if (!this._collapsed) {
+                return this;
+            }
+            var retVal = this.fireEvent('beforeExpand');
+            if (retVal === false) {
+                return this;
+            }
+
+            this._collapsing = true;
+            this.setStyle('zIndex', this.get('parent')._zIndex + 1);
+
+            if (this._anim) {
+                this.setStyle('display', 'none');
+                //Animation Fails Here
+                var attr = {}, s;
+
+                switch (this.get('position')) {
+                    case 'left':
+                    case 'right':
+                        this.set('width', this._lastWidth, true);
+                        this.setStyle('width', this._lastWidth + 'px');
+                        this.get('parent').resize(false);
+                        s = this.get('parent').getSizes()[this.get('position')];
+                        this.set('height', s.h, true);
+                        var left = s.l;
+                        attr = {
+                            left: {
+                                to: left
+                            }
+                        };
+                        if (this.get('position') == 'left') {
+                            attr.left.from = (left - s.w);
+                            this.setStyle('left', (left - s.w) + 'px');
+                        }
+                        break;
+                    case 'top':
+                    case 'bottom':
+                        this.set('height', this._lastHeight, true);
+                        this.setStyle('height', this._lastHeight + 'px');
+                        this.get('parent').resize(false);
+                        s = this.get('parent').getSizes()[this.get('position')];
+                        this.set('width', s.w, true);
+                        var top = s.t;
+                        attr = {
+                            top: {
+                                to: top
+                            }
+                        };
+                        if (this.get('position') == 'top') {
+                            this.setStyle('top',  (top - s.h) + 'px');
+                            attr.top.from = (top - s.h);
+                        }
+                        break;
+                }
+
+                this._anim.attributes = attr;
+                var exStart = function() {
+                    this.setStyle('display', 'block');
+                    this.resize(true);
+                    this._anim.onStart.unsubscribe(exStart, this, true);
+                };
+                var expand = function() {
+                    this._collapsing = false;
+                    this.setStyle('zIndex', this.get('parent')._zIndex);
+                    this.set('width', this._lastWidth);
+                    this.set('height', this._lastHeight);
+                    this._collapsed = false;
+                    this.resize();
+                    this.set('scroll', this._lastScroll);
+                    if (this._lastScrollTop > 0) {
+                        this.body.scrollTop = this._lastScrollTop;
+                    }
+                    this._anim.onComplete.unsubscribe(expand, this, true);
+                    this.fireEvent('expand');
+                };
+                this._anim.onStart.subscribe(exStart, this, true);
+                this._anim.onComplete.subscribe(expand, this, true);
+                this._anim.animate();
+                this._toggleClip();
+            } else {
+                this._collapsing = false;
+                this._toggleClip();
+                this.setStyle('zIndex', this.get('parent')._zIndex);
+                this.setStyle('display', 'block');
+                this.set('width', this._lastWidth);
+                this.set('height', this._lastHeight);
+                this._collapsed = false;
+                this.resize();
+                this.set('scroll', this._lastScroll);
+                if (this._lastScrollTop > 0) {
+                    this.body.scrollTop = this._lastScrollTop;
+                }
+                this.fireEvent('expand');
+            }
+            return this;
+        },
+        /**
+        * @method collapse
+        * @description Collapse the Unit if it is not collapsed.
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        collapse: function() {
+            if (this._collapsed) {
+                return this;
+            }
+            var retValue = this.fireEvent('beforeCollapse');
+            if (retValue === false) {
+                return this;
+            }
+            if (!this._clip) {
+                this._createClip();
+            }
+            this._collapsing = true;
+            var w = this.get('width'),
+                h = this.get('height'),
+                attr = {};
+            this._lastWidth = w;
+            this._lastHeight = h;
+            this._lastScroll = this.get('scroll');
+            this._lastScrollTop = this.body.scrollTop;            
+            this.set('scroll', false, true);
+            this._lastLeft = parseInt(this.get('element').style.left, 10);
+            this._lastTop = parseInt(this.get('element').style.top, 10);
+            if (isNaN(this._lastTop)) {
+                this._lastTop = 0;
+                this.set('top', 0);
+            }
+            if (isNaN(this._lastLeft)) {
+                this._lastLeft = 0;
+                this.set('left', 0);
+            }
+            this.setStyle('zIndex', this.get('parent')._zIndex + 1);
+            var pos = this.get('position');
+
+            switch (pos) {
+                case 'top':
+                case 'bottom':
+                    this.set('height', (this.get('collapseSize') + (this._gutter.top + this._gutter.bottom)));
+                    attr = {
+                        top: {
+                            to: (this.get('top') - h)
+                        }
+                    };
+                    if (pos == 'bottom') {
+                        attr.top.to = (this.get('top') + h);
+                    }
+                    break;
+                case 'left':
+                case 'right':
+                    this.set('width', (this.get('collapseSize') + (this._gutter.left + this._gutter.right)));
+                    attr = {
+                        left: {
+                            to: -(this._lastWidth)
+                        }
+                    };
+                    if (pos == 'right') {
+                        attr.left = {
+                            to: (this.get('left') + w)
+                        };
+                    }
+                    break;
+            }
+            if (this._anim) {
+                this._anim.attributes = attr;
+                var collapse = function() {
+                    this._collapsing = false;
+                    this._toggleClip();
+                    this.setStyle('zIndex', this.get('parent')._zIndex);
+                    this._collapsed = true;
+                    this.get('parent').resize();
+                    this._anim.onComplete.unsubscribe(collapse, this, true);
+                    this.fireEvent('collapse');
+                };
+                this._anim.onComplete.subscribe(collapse, this, true);
+                this._anim.animate();
+            } else {
+                this._collapsing = false;
+                this.setStyle('display', 'none');
+                this._toggleClip();
+                this.setStyle('zIndex', this.get('parent')._zIndex);
+                this.get('parent').resize();
+                this._collapsed = true;
+                this.fireEvent('collapse');
+            }
+            return this;
+        },
+        /**
+        * @method close
+        * @description Close the unit, removing it from the parent Layout.
+        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The parent Layout instance
+        */
+        close: function() {
+            this.setStyle('display', 'none');
+            this.get('parent').removeUnit(this);
+            this.fireEvent('close');
+            if (this._clip) {
+                this._clip.parentNode.removeChild(this._clip);
+                this._clip = null;
+            }
+            return this.get('parent');
+        },
+        /**
+        * @private
+        * @method init
+        * @description The initalization method inherited from Element.
+        */
+        init: function(p_oElement, p_oAttributes) {
+            YAHOO.log('init', 'info', 'LayoutUnit');
+            this._gutter = {
+                left: 0,
+                right: 0,
+                top: 0,
+                bottom: 0
+            };
+            this._sizes = {
+                wrap: {
+                    h: 0,
+                    w: 0
+                },
+                header: {
+                    h: 0,
+                    w: 0
+                },
+                body: {
+                    h: 0,
+                    w: 0
+                },
+                footer: {
+                    h: 0,
+                    w: 0
+                }
+            };
+            
+            LayoutUnit.superclass.init.call(this, p_oElement, p_oAttributes);
+
+            this.browser = this.get('parent').browser;
+            
+            var id = p_oElement;
+            if (!Lang.isString(id)) {
+                id = Dom.generateId(id);
+            }
+            LayoutUnit._instances[id] = this;
+
+            this.setStyle('position', 'absolute');
+
+            this.addClass('yui-layout-unit');
+            this.addClass('yui-layout-unit-' + this.get('position'));
+
+
+            var header = this.getElementsByClassName('yui-layout-hd', 'div')[0];
+            if (header) {
+                this.header = header;
+            }
+            var body = this.getElementsByClassName('yui-layout-bd', 'div')[0];
+            if (body) {
+                this.body = body;
+            }
+            var footer = this.getElementsByClassName('yui-layout-ft', 'div')[0];
+            if (footer) {
+                this.footer = footer;
+            }
+
+            this.on('contentChange', this.resize, this, true);
+            this._lastScrollTop = 0;
+
+            this.set('animate', this.get('animate'));
+        },
+        /**
+        * @private
+        * @method initAttributes
+        * @description Processes the config
+        */        
+        initAttributes: function(attr) {
+            LayoutUnit.superclass.initAttributes.call(this, attr);
+
+            /**
+            * @private
+            * @attribute wrap
+            * @description A reference to the wrap element
+            * @type HTMLElement
+            */
+            this.setAttributeConfig('wrap', {
+                value: attr.wrap || null,
+                method: function(w) {
+                    if (w) {
+                        var id = Dom.generateId(w);
+                        LayoutUnit._instances[id] = this;
+                    }
+                }
+            });
+            /**
+            * @attribute grids
+            * @description Set this option to true if you want the LayoutUnit to fix the first layer of YUI CSS Grids (margins)
+            * @type Boolean
+            */
+            this.setAttributeConfig('grids', {
+                value: attr.grids || false
+            });
+            /**
+            * @private
+            * @attribute top
+            * @description The current top positioning of the Unit
+            * @type Number
+            */
+            this.setAttributeConfig('top', {
+                value: attr.top || 0,
+                validator: Lang.isNumber,
+                method: function(t) {
+                    if (!this._collapsing) {
+                        this.setStyle('top', t + 'px');
+                    }
+                }
+            });
+            /**
+            * @private
+            * @attribute left
+            * @description The current left position of the Unit
+            * @type Number
+            */
+            this.setAttributeConfig('left', {
+                value: attr.left || 0,
+                validator: Lang.isNumber,
+                method: function(l) {
+                    if (!this._collapsing) {
+                        this.setStyle('left', l + 'px');
+                    }
+                }
+            });
+
+            /**
+            * @attribute minWidth
+            * @description The minWidth parameter passed to the Resize Utility
+            * @type Number
+            */
+            this.setAttributeConfig('minWidth', {
+                value: attr.minWidth || false,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute maxWidth
+            * @description The maxWidth parameter passed to the Resize Utility
+            * @type Number
+            */
+            this.setAttributeConfig('maxWidth', {
+                value: attr.maxWidth || false,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute minHeight
+            * @description The minHeight parameter passed to the Resize Utility
+            * @type Number
+            */
+            this.setAttributeConfig('minHeight', {
+                value: attr.minHeight || false,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute maxHeight
+            * @description The maxHeight parameter passed to the Resize Utility
+            * @type Number
+            */
+            this.setAttributeConfig('maxHeight', {
+                value: attr.maxHeight || false,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute height
+            * @description The height of the Unit
+            * @type Number
+            */
+            this.setAttributeConfig('height', {
+                value: attr.height,
+                validator: Lang.isNumber,
+                method: function(h) {
+                    if (!this._collapsing) {
+                        this.setStyle('height', h + 'px');
+                    }
+                }
+            });
+
+            /**
+            * @attribute width
+            * @description The width of the Unit
+            * @type Number
+            */
+            this.setAttributeConfig('width', {
+                value: attr.width,
+                validator: Lang.isNumber,
+                method: function(w) {
+                    if (!this._collapsing) {
+                        this.setStyle('width', w + 'px');
+                    }
+                }
+            });
+            /**
+            * @attribute position
+            * @description The position (top, right, bottom, left or center) of the Unit in the Layout
+            * @type {String}
+            */
+            this.setAttributeConfig('position', {
+                value: attr.position
+            });
+            /**
+            * @attribute gutter
+            * @description The gutter that we should apply to the parent Layout around this Unit. Supports standard CSS markup: (2 4 0 5) or (2) or (2 5)
+            * @type String
+            */
+            this.setAttributeConfig('gutter', {
+                value: attr.gutter || 0,
+                validator: YAHOO.lang.isString,
+                method: function(gutter) {
+                    var p = gutter.split(' ');
+                    if (p.length) {
+                        this._gutter.top = parseInt(p[0], 10);
+                        if (p[1]) {
+                            this._gutter.right = parseInt(p[1], 10);
+                        } else {
+                            this._gutter.right = this._gutter.top;
+                        }
+                        if (p[2]) {
+                            this._gutter.bottom = parseInt(p[2], 10);
+                        } else {
+                            this._gutter.bottom = this._gutter.top;
+                        }
+                        if (p[3]) {
+                            this._gutter.left = parseInt(p[3], 10);
+                        } else if (p[1]) {
+                            this._gutter.left = this._gutter.right;
+                        } else {
+                            this._gutter.left = this._gutter.top;
+                        }
+                    }
+                }
+            });
+            /**
+            * @attribute parent
+            * @description The parent Layout that we are assigned to
+            * @type {Object} YAHOO.widget.Layout
+            */
+            this.setAttributeConfig('parent', {
+                writeOnce: true,
+                value: attr.parent || false,
+                method: function(p) {
+                    if (p) {
+                        p.on('resize', this.resize, this, true);
+                    }
+
+                }
+            });
+            /**
+            * @attribute collapseSize
+            * @description The pixel size of the Clip that we will collapse to
+            * @type Number
+            */
+            this.setAttributeConfig('collapseSize', {
+                value: attr.collapseSize || 25,
+                validator: YAHOO.lang.isNumber
+            });
+            /**
+            * @attribute duration
+            * @description The duration to give the Animation Utility when animating the opening and closing of Units
+            */
+            this.setAttributeConfig('duration', {
+                value: attr.duration || 0.5
+            });
+            /**
+            * @attribute easing
+            * @description The Animation Easing to apply to the Animation instance for this unit.
+            */
+            this.setAttributeConfig('easing', {
+                value: attr.easing || ((YAHOO.util && YAHOO.util.Easing) ? YAHOO.util.Easing.BounceIn : 'false')
+            });
+            /**
+            * @attribute animate
+            * @description Use animation to collapse/expand the unit
+            * @type Boolean
+            */
+            this.setAttributeConfig('animate', {
+                value: ((attr.animate === false) ? false : true),
+                validator: function() {
+                    var anim = false;
+                    if (YAHOO.util.Anim) {
+                        anim = true;
+                    }
+                    return anim;
+                },
+                method: function(anim) {
+                    if (anim) {
+                        this._anim = new YAHOO.util.Anim(this.get('element'), {}, this.get('duration'), this.get('easing'));
+                    } else {
+                        this._anim = false;
+                    }
+                }
+            });
+            /**
+            * @attribute header
+            * @description The text to use as the Header of the Unit
+            */
+            this.setAttributeConfig('header', {
+                value: attr.header || false,
+                method: function(txt) {
+                    if (txt === false) {
+                        //Remove the footer
+                        if (this.header) {
+                            Dom.addClass(this.body, 'yui-layout-bd-nohd');
+                            this.header.parentNode.removeChild(this.header);
+                            this.header = null;
+                        }
+                    } else {
+                        if (!this.header) {
+                            var header = this.getElementsByClassName('yui-layout-hd', 'div')[0];
+                            if (!header) {
+                                header = this._createHeader();
+                            }
+                            this.header = header;
+                        }
+                        var h = this.header.getElementsByTagName('h2')[0];
+                        if (!h) {
+                            h = document.createElement('h2');
+                            this.header.appendChild(h);
+                        }
+                        h.innerHTML = txt;
+                        if (this.body) {
+                            Dom.removeClass(this.body, 'yui-layout-bd-nohd');
+                        }
+                    }
+                    this.fireEvent('contentChange', { target: 'header' });
+                }
+            });
+            /**
+            * @attribute proxy
+            * @description Use the proxy config setting for the Resize Utility
+            * @type Boolean
+            */
+            this.setAttributeConfig('proxy', {
+                writeOnce: true,
+                value: ((attr.proxy === false) ? false : true)
+            });
+            /**
+            * @attribute body
+            * @description The content for the body. If we find an element in the page with an id that matches the passed option we will move that element into the body of this unit.
+            */
+            this.setAttributeConfig('body', {
+                value: attr.body || false,
+                method: function(content) {
+                    if (!this.body) {
+                        var body = this.getElementsByClassName('yui-layout-bd', 'div')[0];
+                        if (body) {
+                            this.body = body;
+                        } else {
+                            body = document.createElement('div');
+                            body.className = 'yui-layout-bd';
+                            this.body = body;
+                            this.get('wrap').appendChild(body);
+                        }
+                    }
+                    if (!this.header) {
+                        Dom.addClass(this.body, 'yui-layout-bd-nohd');
+                    }
+                    Dom.addClass(this.body, 'yui-layout-bd-noft');
+
+
+                    var el = null;
+                    if (Lang.isString(content)) {
+                        el = Dom.get(content);
+                    } else if (content && content.tagName) {
+                        el = content;
+                    }
+                    if (el) {
+                        var id = Dom.generateId(el);
+                        LayoutUnit._instances[id] = this;
+                        this.body.appendChild(el);
+                    } else {
+                        this.body.innerHTML = content;
+                    }
+
+                    this._cleanGrids();
+
+                    this.fireEvent('contentChange', { target: 'body' });
+                }
+            });
+
+            /**
+            * @attribute footer
+            * @description The content for the footer. If we find an element in the page with an id that matches the passed option we will move that element into the footer of this unit.
+            */
+            this.setAttributeConfig('footer', {
+                value: attr.footer || false,
+                method: function(content) {
+                    if (content === false) {
+                        //Remove the footer
+                        if (this.footer) {
+                            Dom.addClass(this.body, 'yui-layout-bd-noft');
+                            this.footer.parentNode.removeChild(this.footer);
+                            this.footer = null;
+                        }
+                    } else {
+                        if (!this.footer) {
+                            var ft = this.getElementsByClassName('yui-layout-ft', 'div')[0];
+                            if (!ft) {
+                                ft = document.createElement('div');
+                                ft.className = 'yui-layout-ft';
+                                this.footer = ft;
+                                this.get('wrap').appendChild(ft);
+                            } else {
+                                this.footer = ft;
+                            }
+                        }
+                        var el = null;
+                        if (Lang.isString(content)) {
+                            el = Dom.get(content);
+                        } else if (content && content.tagName) {
+                            el = content;
+                        }
+                        if (el) {
+                            this.footer.appendChild(el);
+                        } else {
+                            this.footer.innerHTML = content;
+                        }
+                        Dom.removeClass(this.body, 'yui-layout-bd-noft');
+                    }
+                    this.fireEvent('contentChange', { target: 'footer' });
+                }
+            });
+            /**
+            * @attribute close
+            * @description Adds a close icon to the unit
+            */
+            this.setAttributeConfig('close', {
+                value: attr.close || false,
+                method: function(close) {
+                    //Position Center doesn't get this
+                    if (this.get('position') == 'center') {
+                        YAHOO.log('Position center unit cannot have close', 'error', 'LayoutUnit');
+                        return false;
+                    }
+                    if (!this.header) {
+                        this._createHeader();
+                    }
+                    var c = Dom.getElementsByClassName('close', 'div', this.header)[0];
+                    if (close) {
+                        if (!c) {
+                            c = document.createElement('div');
+                            c.className = 'close';
+                            this.header.appendChild(c);
+                            Event.on(c, 'click', this.close, this, true);
+                        }
+                        c.title = this.STR_CLOSE;
+                    } else if (c) {
+                        Event.purgeElement(c);
+                        c.parentNode.removeChild(c);
+                    }
+                    this._configs.close.value = close;
+                    this.set('collapse', this.get('collapse')); //Reset so we get the right classnames
+                }
+            });
+
+            /**
+            * @attribute collapse
+            * @description Adds a collapse icon to the unit
+            */
+            this.setAttributeConfig('collapse', {
+                value: attr.collapse || false,
+                method: function(collapse) {
+                    //Position Center doesn't get this
+                    if (this.get('position') == 'center') {
+                        YAHOO.log('Position center unit cannot have collapse', 'error', 'LayoutUnit');
+                        return false;
+                    }
+                    if (!this.header) {
+                        this._createHeader();
+                    }
+                    var c = Dom.getElementsByClassName('collapse', 'div', this.header)[0];
+                    if (collapse) {
+                        if (!c) {
+                            c = document.createElement('div');
+                            this.header.appendChild(c);
+                            Event.on(c, 'click', this.collapse, this, true);
+                        }
+                        c.title = this.STR_COLLAPSE;
+                        c.className = 'collapse' + ((this.get('close')) ? ' collapse-close' : '');
+                    } else if (c) {
+                        Event.purgeElement(c);
+                        c.parentNode.removeChild(c);
+                    }
+                }
+            });
+            /**
+            * @attribute scroll
+            * @description Adds a class to the unit to allow for overflow: auto, default is overflow: hidden
+            */
+
+            this.setAttributeConfig('scroll', {
+                value: attr.scroll || false,
+                method: function(scroll) {
+                    if ((scroll === false) && !this._collapsed) { //Removing scroll bar
+                        if (this.body) {
+                            if (this.body.scrollTop > 0) {
+                                this._lastScrollTop = this.body.scrollTop;
+                            }
+                        }
+                    }
+                    
+                    if (scroll) {
+                        this.addClass('yui-layout-scroll');
+                        if (this._lastScrollTop > 0) {
+                            if (this.body) {
+                                this.body.scrollTop = this._lastScrollTop;
+                            }
+                        }
+                    } else {
+                        this.removeClass('yui-layout-scroll');
+                    }
+                }
+            });
+            /**
+            * @attribute hover
+            * @description Config option to pass to the Resize Utility
+            */
+            this.setAttributeConfig('hover', {
+                writeOnce: true,
+                value: attr.hover || false,
+                validator: YAHOO.lang.isBoolean
+            });
+            /**
+            * @attribute resize
+            * @description Should a Resize instance be added to this unit
+            */
+
+            this.setAttributeConfig('resize', {
+                value: attr.resize || false,
+                validator: function(r) {
+                    if (YAHOO.util && YAHOO.util.Resize) {
+                        return true;
+                    }
+                    return false;
+                },
+                method: function(resize) {
+                    if (resize && !this._resize) {
+                        //Position Center doesn't get this
+                        if (this.get('position') == 'center') {
+                            YAHOO.log('Position center unit cannot have resize', 'error', 'LayoutUnit');
+                            return false;
+                        }
+                        var handle = false; //To catch center
+                        switch (this.get('position')) {
+                            case 'top':
+                                handle = 'b';
+                                break;
+                            case 'bottom':
+                                handle = 't';
+                                break;
+                            case 'right':
+                                handle = 'l';
+                                break;
+                            case 'left':
+                                handle = 'r';
+                                break;
+                        }
+
+                        this.setStyle('position', 'absolute'); //Make sure Resize get's a position
+                        
+                        if (handle) {
+                            this._resize = new YAHOO.util.Resize(this.get('element'), {
+                                proxy: this.get('proxy'),
+                                hover: this.get('hover'),
+                                status: false,
+                                autoRatio: false,
+                                handles: [handle],
+                                minWidth: this.get('minWidth'),
+                                maxWidth: this.get('maxWidth'),
+                                minHeight: this.get('minHeight'),
+                                maxHeight: this.get('maxHeight'),
+                                height: this.get('height'),
+                                width: this.get('width'),
+                                setSize: false
+                            });
+                            
+                            this._resize._handles[handle].innerHTML = '<div class="yui-layout-resize-knob"></div>';
+
+                            if (this.get('proxy')) {
+                                var proxy = this._resize.getProxyEl();
+                                proxy.innerHTML = '<div class="yui-layout-handle-' + handle + '"></div>';
+                            }
+                            this._resize.on('startResize', function(ev) {
+                                this._lastScroll = this.get('scroll');
+                                this.set('scroll', false);
+                                if (this.get('parent')) {
+                                    this.get('parent').fireEvent('startResize');
+                                    var c = this.get('parent').getUnitByPosition('center');
+                                    this._lastCenterScroll = c.get('scroll');
+                                    c.set('scroll', false);
+                                }
+                                this.fireEvent('startResize');
+                            }, this, true);
+                            this._resize.on('resize', function(ev) {
+                                this.set('height', ev.height);
+                                this.set('width', ev.width);
+                                this.set('scroll', this._lastScroll);
+                                if (this.get('parent')) {
+                                    var c = this.get('parent').getUnitByPosition('center');
+                                    c.set('scroll', this._lastCenterScroll);
+                                }
+                            }, this, true);
+                        }
+                    } else {
+                        if (this._resize) {
+                            this._resize.destroy();
+                        }
+                    }
+                }
+            });
+        },
+        /**
+        * @private
+        * @method _cleanGrids
+        * @description This method attempts to clean up the first level of the YUI CSS Grids, YAHOO.util.Selector is required for this operation.
+        */
+        _cleanGrids: function() {
+            if (this.get('grids')) {
+                var b = Sel.query('div.yui-b', this.body, true);
+                if (b) {
+                    Dom.removeClass(b, 'yui-b');
+                }
+                Event.onAvailable('yui-main', function() {
+                    Dom.setStyle(Sel.query('#yui-main'), 'margin-left', '0');
+                    Dom.setStyle(Sel.query('#yui-main'), 'margin-right', '0');
+                });
+            }
+        },
+        /**
+        * @private
+        * @method _createHeader
+        * @description Creates the HTMLElement for the header
+        * @return {HTMLElement} The new HTMLElement
+        */
+        _createHeader: function() {
+            var header = document.createElement('div');
+            header.className = 'yui-layout-hd';
+            if (this.get('firstChild')) {
+                this.get('wrap').insertBefore(header, this.get('wrap').firstChild);
+            } else {
+                this.get('wrap').appendChild(header);
+            }
+            this.header = header;
+            return header;
+        },
+        /**
+        * @method destroy
+        * @description Removes this unit from the parent and cleans up after itself.
+        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The parent Layout instance
+        */
+        destroy: function() {
+            if (this._resize) {
+                this._resize.destroy();
+            }
+            var par = this.get('parent');
+
+            this.setStyle('display', 'none');
+            par.removeUnit(this);
+            if (this._clip) {
+                this._clip.parentNode.removeChild(this._clip);
+                this._clip = null;
+            }
+
+            Event.purgeElement(this.get('element'));
+            this.get('parentNode').removeChild(this.get('element'));
+
+            delete YAHOO.widget.LayoutUnit._instances[this.get('id')];
+            //Brutal Object Destroy
+            for (var i in this) {
+                if (Lang.hasOwnProperty(this, i)) {
+                    this[i] = null;
+                    delete this[i];
+                }
+            }
+        
+            return par;
+        },
+        /**
+        * @method toString
+        * @description Returns a string representing the LayoutUnit.
+        * @return {String}
+        */        
+        toString: function() {
+            if (this.get) {
+                return 'LayoutUnit #' + this.get('id') + ' (' + this.get('position') + ')';
+            }
+            return 'LayoutUnit';
+        }
+    /**
+    * @event resize
+    * @description Fired when this.resize is called
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event startResize
+    * @description Fired when the Resize Utility fires it's startResize Event.
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event beforeResize
+    * @description Firef at the beginning of the resize method. If you return false, the resize is cancelled.
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event contentChange
+    * @description Fired when the content in the header, body or footer is changed via the API
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event close
+    * @description Fired when the unit is closed
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event beforeCollapse
+    * @description Fired before the unit is collapsed. If you return false, the collapse is cancelled.
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event collapse
+    * @description Fired when the unit is collapsed
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event expand
+    * @description Fired when the unit is exanded
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event beforeExpand
+    * @description Fired before the unit is exanded. If you return false, the collapse is cancelled.
+    * @type YAHOO.util.CustomEvent
+    */
+    });
+
+    YAHOO.widget.LayoutUnit = LayoutUnit;
+})();
+YAHOO.register("layout", YAHOO.widget.Layout, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/layout/layout-beta-min.js
===================================================================
--- trunk/root/static/yui/layout/layout-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/layout/layout-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,11 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+(function(){var C=YAHOO.util.Dom,A=YAHOO.util.Event,D=YAHOO.lang;var B=function(F,E){if(D.isObject(F)&&!F.tagName){E=F;F=null;}if(D.isString(F)){if(C.get(F)){F=C.get(F);}}if(!F){F=document.body;}var G={element:F,attributes:E||{}};B.superclass.constructor.call(this,G.element,G.attributes);};B._instances={};B.getLayoutById=function(E){if(B._instances[E]){return B._instances[E];}return false;};YAHOO.extend(B,YAHOO.util.Element,{browser:function(){var E=YAHOO.env.ua;E.standardsMode=false;E.secure=false;return E;}(),_rendered:null,_zIndex:null,_sizes:null,_setBodySize:function(G){var F=0,E=0;G=((G===false)?false:true);if(this._isBody){F=C.getClientHeight();E=C.getClientWidth();}else{F=parseInt(this.getStyle("height"),10);E=parseInt(this.getStyle("width"),10);if(isNaN(E)){E=this.get("element").clientWidth;}if(isNaN(F)){F=this.get("element").clientHeight;}}if(this.get("minWidth")){if(E<this.get("minWidth")){E=this.get("minWidth");}}if(this.get("minHeight")){if(F<this.get("minHeigh!
 t")){F=this.get("minHeight");}}if(G){C.setStyle(this._doc,"height",F+"px");C.setStyle(this._doc,"width",E+"px");}this._sizes.doc={h:F,w:E};this._setSides(G);},_setSides:function(J){var H=((this._top)?this._top.get("height"):0),G=((this._bottom)?this._bottom.get("height"):0),I=this._sizes.doc.h,E=this._sizes.doc.w;J=((J===false)?false:true);this._sizes.top={h:H,w:((this._top)?E:0),t:0};this._sizes.bottom={h:G,w:((this._bottom)?E:0)};var F=(I-(H+G));this._sizes.left={h:F,w:((this._left)?this._left.get("width"):0)};this._sizes.right={h:F,w:((this._right)?this._right.get("width"):0),l:((this._right)?(E-this._right.get("width")):0),t:((this._top)?this._sizes.top.h:0)};if(this._right&&J){this._right.set("top",this._sizes.right.t);if(!this._right._collapsing){this._right.set("left",this._sizes.right.l);}this._right.set("height",this._sizes.right.h,true);}if(this._left){this._sizes.left.l=0;if(this._top){this._sizes.left.t=this._sizes.top.h;}else{this._sizes.left.t=0;}if(J){this._l!
 eft.set("top",this._sizes.left.t);this._left.set("height",this!
 ._sizes.
left.h,true);this._left.set("left",0);}}if(this._bottom){this._sizes.bottom.t=this._sizes.top.h+this._sizes.left.h;if(J){this._bottom.set("top",this._sizes.bottom.t);this._bottom.set("width",this._sizes.bottom.w,true);}}if(this._top){if(J){this._top.set("width",this._sizes.top.w,true);}}this._setCenter(J);},_setCenter:function(G){G=((G===false)?false:true);var F=this._sizes.left.h;var E=(this._sizes.doc.w-(this._sizes.left.w+this._sizes.right.w));if(G){this._center.set("height",F,true);this._center.set("width",E,true);this._center.set("top",this._sizes.top.h);this._center.set("left",this._sizes.left.w);}this._sizes.center={h:F,w:E,t:this._sizes.top.h,l:this._sizes.left.w};},getSizes:function(){return this._sizes;},getUnitById:function(E){return YAHOO.widget.LayoutUnit.getLayoutUnitById(E);},getUnitByPosition:function(E){if(E){E=E.toLowerCase();if(this["_"+E]){return this["_"+E];}}return false;},removeUnit:function(E){this["_"+E.get("position")]=null;this.resize();},addUnit:f!
 unction(G){if(!G.position){return false;}if(this["_"+G.position]){return false;}var H=null,J=null;if(G.id){if(C.get(G.id)){H=C.get(G.id);delete G.id;}}if(G.element){H=G.element;}if(!J){J=document.createElement("div");var L=C.generateId();J.id=L;}if(!H){H=document.createElement("div");}C.addClass(H,"yui-layout-wrap");if(this.browser.ie&&!this.browser.standardsMode){J.style.zoom=1;H.style.zoom=1;}if(J.firstChild){J.insertBefore(H,J.firstChild);}else{J.appendChild(H);}this._doc.appendChild(J);var I=false,F=false;if(G.height){I=parseInt(G.height,10);}if(G.width){F=parseInt(G.width,10);}var E={};YAHOO.lang.augmentObject(E,G);E.parent=this;E.wrap=H;E.height=I;E.width=F;var K=new YAHOO.widget.LayoutUnit(J,E);K.on("heightChange",this.resize,this,true);K.on("widthChange",this.resize,this,true);K.on("gutterChange",this.resize,this,true);this["_"+G.position]=K;if(this._rendered){this.resize();}return K;},_createUnits:function(){var E=this.get("units");for(var F in E){if(D.hasOwnProper!
 ty(E,F)){this.addUnit(E[F]);}}},resize:function(F){F=((F===fal!
 se)?fals
e:true);if(F){var E=this.fireEvent("beforeResize");if(E===false){F=false;}if(this.browser.ie){if(this._isBody){C.removeClass(document.documentElement,"yui-layout");C.addClass(document.documentElement,"yui-layout");}else{this.removeClass("yui-layout");this.addClass("yui-layout");}}}this._setBodySize(F);if(F){this.fireEvent("resize",{target:this,sizes:this._sizes});}return this;},_setupBodyElements:function(){this._doc=C.get("layout-doc");if(!this._doc){this._doc=document.createElement("div");this._doc.id="layout-doc";if(document.body.firstChild){document.body.insertBefore(this._doc,document.body.firstChild);}else{document.body.appendChild(this._doc);}}this._createUnits();this._setBodySize();A.on(window,"resize",this.resize,this,true);C.addClass(this._doc,"yui-layout-doc");},_setupElements:function(){this._doc=this.getElementsByClassName("doc")[0];if(!this._doc){this._doc=document.createElement("div");this.get("element").appendChild(this._doc);}this._createUnits();this._setBod!
 ySize();A.on(window,"resize",this.resize,this,true);C.addClass(this._doc,"yui-layout-doc");},_isBody:null,_doc:null,_left:null,_right:null,_top:null,_bottom:null,_center:null,init:function(F,E){this._zIndex=0;B.superclass.init.call(this,F,E);if(this.get("parent")){this._zIndex=this.get("parent")._zIndex+10;}this._sizes={};var G=F;if(!D.isString(G)){G=C.generateId(G);}B._instances[G]=this;},render:function(){this._stamp();var E=this.get("element");if(E&&E.tagName&&(E.tagName.toLowerCase()=="body")){this._isBody=true;C.addClass(document.body,"yui-layout");if(C.hasClass(document.body,"yui-skin-sam")){C.addClass(document.documentElement,"yui-skin-sam");C.removeClass(document.body,"yui-skin-sam");}this._setupBodyElements();}else{this._isBody=false;this.addClass("yui-layout");this._setupElements();}this.resize();this._rendered=true;this.fireEvent("render");return this;},_stamp:function(){if(document.compatMode=="CSS1Compat"){this.browser.standardsMode=true;
+}if(window.location.href.toLowerCase().indexOf("https")===0){C.addClass(document.documentElement,"secure");this.browser.secure=true;}},initAttributes:function(E){B.superclass.initAttributes.call(this,E);this.setAttributeConfig("units",{writeOnce:true,validator:YAHOO.lang.isArray,value:E.units||[]});this.setAttributeConfig("minHeight",{value:E.minHeight||false,validator:YAHOO.lang.isNumber});this.setAttributeConfig("minWidth",{value:E.minWidth||false,validator:YAHOO.lang.isNumber});this.setAttributeConfig("height",{value:E.height||false,validator:YAHOO.lang.isNumber,method:function(F){this.setStyle("height",F+"px");}});this.setAttributeConfig("width",{value:E.width||false,validator:YAHOO.lang.isNumber,method:function(F){this.setStyle("width",F+"px");}});this.setAttributeConfig("parent",{writeOnce:true,value:E.parent||false,method:function(F){if(F){F.on("resize",this.resize,this,true);}}});},toString:function(){if(this.get){return"Layout #"+this.get("id");}return"Layout";}});!
 YAHOO.widget.Layout=B;})();(function(){var D=YAHOO.util.Dom,C=YAHOO.util.Selector,A=YAHOO.util.Event,E=YAHOO.lang;var B=function(G,F){var H={element:G,attributes:F||{}};B.superclass.constructor.call(this,H.element,H.attributes);};B._instances={};B.getLayoutUnitById=function(F){if(B._instances[F]){return B._instances[F];}return false;};YAHOO.extend(B,YAHOO.util.Element,{STR_CLOSE:"Click to close this pane.",STR_COLLAPSE:"Click to collapse this pane.",STR_EXPAND:"Click to expand this pane.",browser:null,_sizes:null,_anim:null,_resize:null,_clip:null,_gutter:null,header:null,body:null,footer:null,_collapsed:null,_collapsing:null,_lastWidth:null,_lastHeight:null,_lastTop:null,_lastLeft:null,_lastScroll:null,_lastCenterScroll:null,_lastScrollTop:null,resize:function(F){var G=this.fireEvent("beforeResize");if(G===false){return this;}if(!this._collapsing||(F===true)){var N=this.get("scroll");this.set("scroll",false);var K=this._getBoxSize(this.header),J=this._getBoxSize(this.foote!
 r),L=[this.get("height"),this.get("width")];var H=(L[0]-K[0]-J!
 [0])-(th
is._gutter.top+this._gutter.bottom),M=L[1]-(this._gutter.left+this._gutter.right);var O=(H+(K[0]+J[0])),I=M;if(this._collapsed&&!this._collapsing){this._setHeight(this._clip,O);this._setWidth(this._clip,I);D.setStyle(this._clip,"top",this.get("top")+this._gutter.top+"px");D.setStyle(this._clip,"left",this.get("left")+this._gutter.left+"px");}else{if(!this._collapsed||(this._collapsed&&this._collapsing)){O=this._setHeight(this.get("wrap"),O);I=this._setWidth(this.get("wrap"),I);this._sizes.wrap.h=O;this._sizes.wrap.w=I;D.setStyle(this.get("wrap"),"top",this._gutter.top+"px");D.setStyle(this.get("wrap"),"left",this._gutter.left+"px");this._sizes.header.w=this._setWidth(this.header,I);this._sizes.header.h=K[0];this._sizes.footer.w=this._setWidth(this.footer,I);this._sizes.footer.h=J[0];D.setStyle(this.footer,"bottom","0px");this._sizes.body.h=this._setHeight(this.body,(O-(K[0]+J[0])));this._sizes.body.w=this._setWidth(this.body,I);D.setStyle(this.body,"top",K[0]+"px");this.set(!
 "scroll",N);this.fireEvent("resize");}}}return this;},_setWidth:function(H,G){if(H){var F=this._getBorderSizes(H);G=(G-(F[1]+F[3]));G=this._fixQuirks(H,G,"w");D.setStyle(H,"width",G+"px");}return G;},_setHeight:function(H,G){if(H){var F=this._getBorderSizes(H);G=(G-(F[0]+F[2]));G=this._fixQuirks(H,G,"h");D.setStyle(H,"height",G+"px");}return G;},_fixQuirks:function(I,L,G){var K=0,H=2;if(G=="w"){K=1;H=3;}if(this.browser.ie&&!this.browser.standardsMode){var F=this._getBorderSizes(I),J=this._getBorderSizes(I.parentNode);if((F[K]===0)&&(F[H]===0)){if((J[K]!==0)&&(J[H]!==0)){L=(L-(J[K]+J[H]));}}else{if((J[K]===0)&&(J[H]===0)){L=(L+(F[K]+F[H]));}}}return L;},_getBoxSize:function(H){var G=[0,0];if(H){if(this.browser.ie&&!this.browser.standardsMode){H.style.zoom=1;}var F=this._getBorderSizes(H);G[0]=H.clientHeight+(F[0]+F[2]);G[1]=H.clientWidth+(F[1]+F[3]);}return G;},_getBorderSizes:function(H){var G=[];H=H||this.get("element");if(this.browser.ie&&!this.browser.standardsMode){H.st!
 yle.zoom=1;}G[0]=parseInt(D.getStyle(H,"borderTopWidth"),10);G!
 [1]=pars
eInt(D.getStyle(H,"borderRightWidth"),10);G[2]=parseInt(D.getStyle(H,"borderBottomWidth"),10);G[3]=parseInt(D.getStyle(H,"borderLeftWidth"),10);for(var F=0;F<G.length;F++){if(isNaN(G[F])){G[F]=0;}}return G;},_createClip:function(){if(!this._clip){this._clip=document.createElement("div");this._clip.className="yui-layout-clip yui-layout-clip-"+this.get("position");this._clip.innerHTML='<div class="collapse"></div>';var F=this._clip.firstChild;F.title=this.STR_EXPAND;A.on(F,"click",this.expand,this,true);this.get("element").parentNode.appendChild(this._clip);}},_toggleClip:function(){if(!this._collapsed){var J=this._getBoxSize(this.header),K=this._getBoxSize(this.footer),I=[this.get("height"),this.get("width")];var H=(I[0]-J[0]-K[0])-(this._gutter.top+this._gutter.bottom),F=I[1]-(this._gutter.left+this._gutter.right),G=(H+(J[0]+K[0]));switch(this.get("position")){case"top":case"bottom":this._setWidth(this._clip,F);this._setHeight(this._clip,this.get("collapseSize"));D.setStyle(!
 this._clip,"left",(this._lastLeft+this._gutter.left)+"px");if(this.get("position")=="bottom"){D.setStyle(this._clip,"top",((this._lastTop+this._lastHeight)-(this.get("collapseSize")-this._gutter.top))+"px");}else{D.setStyle(this._clip,"top",this.get("top")+this._gutter.top+"px");}break;case"left":case"right":this._setWidth(this._clip,this.get("collapseSize"));this._setHeight(this._clip,G);D.setStyle(this._clip,"top",(this.get("top")+this._gutter.top)+"px");if(this.get("position")=="right"){D.setStyle(this._clip,"left",(((this._lastLeft+this._lastWidth)-this.get("collapseSize"))-this._gutter.left)+"px");}else{D.setStyle(this._clip,"left",(this.get("left")+this._gutter.left)+"px");}break;}D.setStyle(this._clip,"display","block");this.setStyle("display","none");}else{D.setStyle(this._clip,"display","none");}},getSizes:function(){return this._sizes;},toggle:function(){if(this._collapsed){this.expand();}else{this.collapse();
+}return this;},expand:function(){if(!this._collapsed){return this;}var L=this.fireEvent("beforeExpand");if(L===false){return this;}this._collapsing=true;this.setStyle("zIndex",this.get("parent")._zIndex+1);if(this._anim){this.setStyle("display","none");var F={},H;switch(this.get("position")){case"left":case"right":this.set("width",this._lastWidth,true);this.setStyle("width",this._lastWidth+"px");this.get("parent").resize(false);H=this.get("parent").getSizes()[this.get("position")];this.set("height",H.h,true);var K=H.l;F={left:{to:K}};if(this.get("position")=="left"){F.left.from=(K-H.w);this.setStyle("left",(K-H.w)+"px");}break;case"top":case"bottom":this.set("height",this._lastHeight,true);this.setStyle("height",this._lastHeight+"px");this.get("parent").resize(false);H=this.get("parent").getSizes()[this.get("position")];this.set("width",H.w,true);var J=H.t;F={top:{to:J}};if(this.get("position")=="top"){this.setStyle("top",(J-H.h)+"px");F.top.from=(J-H.h);}break;}this._anim.!
 attributes=F;var I=function(){this.setStyle("display","block");this.resize(true);this._anim.onStart.unsubscribe(I,this,true);};var G=function(){this._collapsing=false;this.setStyle("zIndex",this.get("parent")._zIndex);this.set("width",this._lastWidth);this.set("height",this._lastHeight);this._collapsed=false;this.resize();this.set("scroll",this._lastScroll);if(this._lastScrollTop>0){this.body.scrollTop=this._lastScrollTop;}this._anim.onComplete.unsubscribe(G,this,true);this.fireEvent("expand");};this._anim.onStart.subscribe(I,this,true);this._anim.onComplete.subscribe(G,this,true);this._anim.animate();this._toggleClip();}else{this._collapsing=false;this._toggleClip();this.setStyle("zIndex",this.get("parent")._zIndex);this.setStyle("display","block");this.set("width",this._lastWidth);this.set("height",this._lastHeight);this._collapsed=false;this.resize();this.set("scroll",this._lastScroll);if(this._lastScrollTop>0){this.body.scrollTop=this._lastScrollTop;}this.fireEvent("exp!
 and");}return this;},collapse:function(){if(this._collapsed){r!
 eturn th
is;}var J=this.fireEvent("beforeCollapse");if(J===false){return this;}if(!this._clip){this._createClip();}this._collapsing=true;var G=this.get("width"),H=this.get("height"),F={};this._lastWidth=G;this._lastHeight=H;this._lastScroll=this.get("scroll");this._lastScrollTop=this.body.scrollTop;this.set("scroll",false,true);this._lastLeft=parseInt(this.get("element").style.left,10);this._lastTop=parseInt(this.get("element").style.top,10);if(isNaN(this._lastTop)){this._lastTop=0;this.set("top",0);}if(isNaN(this._lastLeft)){this._lastLeft=0;this.set("left",0);}this.setStyle("zIndex",this.get("parent")._zIndex+1);var K=this.get("position");switch(K){case"top":case"bottom":this.set("height",(this.get("collapseSize")+(this._gutter.top+this._gutter.bottom)));F={top:{to:(this.get("top")-H)}};if(K=="bottom"){F.top.to=(this.get("top")+H);}break;case"left":case"right":this.set("width",(this.get("collapseSize")+(this._gutter.left+this._gutter.right)));F={left:{to:-(this._lastWidth)}};if(K==!
 "right"){F.left={to:(this.get("left")+G)};}break;}if(this._anim){this._anim.attributes=F;var I=function(){this._collapsing=false;this._toggleClip();this.setStyle("zIndex",this.get("parent")._zIndex);this._collapsed=true;this.get("parent").resize();this._anim.onComplete.unsubscribe(I,this,true);this.fireEvent("collapse");};this._anim.onComplete.subscribe(I,this,true);this._anim.animate();}else{this._collapsing=false;this.setStyle("display","none");this._toggleClip();this.setStyle("zIndex",this.get("parent")._zIndex);this.get("parent").resize();this._collapsed=true;this.fireEvent("collapse");}return this;},close:function(){this.setStyle("display","none");this.get("parent").removeUnit(this);this.fireEvent("close");if(this._clip){this._clip.parentNode.removeChild(this._clip);this._clip=null;}return this.get("parent");},init:function(H,G){this._gutter={left:0,right:0,top:0,bottom:0};this._sizes={wrap:{h:0,w:0},header:{h:0,w:0},body:{h:0,w:0},footer:{h:0,w:0}};B.superclass.init.c!
 all(this,H,G);this.browser=this.get("parent").browser;var K=H;!
 if(!E.is
String(K)){K=D.generateId(K);}B._instances[K]=this;this.setStyle("position","absolute");this.addClass("yui-layout-unit");this.addClass("yui-layout-unit-"+this.get("position"));var J=this.getElementsByClassName("yui-layout-hd","div")[0];if(J){this.header=J;}var F=this.getElementsByClassName("yui-layout-bd","div")[0];if(F){this.body=F;}var I=this.getElementsByClassName("yui-layout-ft","div")[0];if(I){this.footer=I;}this.on("contentChange",this.resize,this,true);this._lastScrollTop=0;this.set("animate",this.get("animate"));},initAttributes:function(F){B.superclass.initAttributes.call(this,F);this.setAttributeConfig("wrap",{value:F.wrap||null,method:function(G){if(G){var H=D.generateId(G);B._instances[H]=this;}}});this.setAttributeConfig("grids",{value:F.grids||false});this.setAttributeConfig("top",{value:F.top||0,validator:E.isNumber,method:function(G){if(!this._collapsing){this.setStyle("top",G+"px");}}});this.setAttributeConfig("left",{value:F.left||0,validator:E.isNumber,met!
 hod:function(G){if(!this._collapsing){this.setStyle("left",G+"px");}}});this.setAttributeConfig("minWidth",{value:F.minWidth||false,validator:YAHOO.lang.isNumber});this.setAttributeConfig("maxWidth",{value:F.maxWidth||false,validator:YAHOO.lang.isNumber});this.setAttributeConfig("minHeight",{value:F.minHeight||false,validator:YAHOO.lang.isNumber});this.setAttributeConfig("maxHeight",{value:F.maxHeight||false,validator:YAHOO.lang.isNumber});this.setAttributeConfig("height",{value:F.height,validator:E.isNumber,method:function(G){if(!this._collapsing){this.setStyle("height",G+"px");}}});this.setAttributeConfig("width",{value:F.width,validator:E.isNumber,method:function(G){if(!this._collapsing){this.setStyle("width",G+"px");}}});this.setAttributeConfig("position",{value:F.position});this.setAttributeConfig("gutter",{value:F.gutter||0,validator:YAHOO.lang.isString,method:function(H){var G=H.split(" ");if(G.length){this._gutter.top=parseInt(G[0],10);
+if(G[1]){this._gutter.right=parseInt(G[1],10);}else{this._gutter.right=this._gutter.top;}if(G[2]){this._gutter.bottom=parseInt(G[2],10);}else{this._gutter.bottom=this._gutter.top;}if(G[3]){this._gutter.left=parseInt(G[3],10);}else{if(G[1]){this._gutter.left=this._gutter.right;}else{this._gutter.left=this._gutter.top;}}}}});this.setAttributeConfig("parent",{writeOnce:true,value:F.parent||false,method:function(G){if(G){G.on("resize",this.resize,this,true);}}});this.setAttributeConfig("collapseSize",{value:F.collapseSize||25,validator:YAHOO.lang.isNumber});this.setAttributeConfig("duration",{value:F.duration||0.5});this.setAttributeConfig("easing",{value:F.easing||((YAHOO.util&&YAHOO.util.Easing)?YAHOO.util.Easing.BounceIn:"false")});this.setAttributeConfig("animate",{value:((F.animate===false)?false:true),validator:function(){var G=false;if(YAHOO.util.Anim){G=true;}return G;},method:function(G){if(G){this._anim=new YAHOO.util.Anim(this.get("element"),{},this.get("duration"),t!
 his.get("easing"));}else{this._anim=false;}}});this.setAttributeConfig("header",{value:F.header||false,method:function(G){if(G===false){if(this.header){D.addClass(this.body,"yui-layout-bd-nohd");this.header.parentNode.removeChild(this.header);this.header=null;}}else{if(!this.header){var I=this.getElementsByClassName("yui-layout-hd","div")[0];if(!I){I=this._createHeader();}this.header=I;}var H=this.header.getElementsByTagName("h2")[0];if(!H){H=document.createElement("h2");this.header.appendChild(H);}H.innerHTML=G;if(this.body){D.removeClass(this.body,"yui-layout-bd-nohd");}}this.fireEvent("contentChange",{target:"header"});}});this.setAttributeConfig("proxy",{writeOnce:true,value:((F.proxy===false)?false:true)});this.setAttributeConfig("body",{value:F.body||false,method:function(I){if(!this.body){var G=this.getElementsByClassName("yui-layout-bd","div")[0];if(G){this.body=G;}else{G=document.createElement("div");G.className="yui-layout-bd";this.body=G;this.get("wrap").appendCh!
 ild(G);}}if(!this.header){D.addClass(this.body,"yui-layout-bd-!
 nohd");}
D.addClass(this.body,"yui-layout-bd-noft");var H=null;if(E.isString(I)){H=D.get(I);}else{if(I&&I.tagName){H=I;}}if(H){var J=D.generateId(H);B._instances[J]=this;this.body.appendChild(H);}else{this.body.innerHTML=I;}this._cleanGrids();this.fireEvent("contentChange",{target:"body"});}});this.setAttributeConfig("footer",{value:F.footer||false,method:function(H){if(H===false){if(this.footer){D.addClass(this.body,"yui-layout-bd-noft");this.footer.parentNode.removeChild(this.footer);this.footer=null;}}else{if(!this.footer){var I=this.getElementsByClassName("yui-layout-ft","div")[0];if(!I){I=document.createElement("div");I.className="yui-layout-ft";this.footer=I;this.get("wrap").appendChild(I);}else{this.footer=I;}}var G=null;if(E.isString(H)){G=D.get(H);}else{if(H&&H.tagName){G=H;}}if(G){this.footer.appendChild(G);}else{this.footer.innerHTML=H;}D.removeClass(this.body,"yui-layout-bd-noft");}this.fireEvent("contentChange",{target:"footer"});}});this.setAttributeConfig("close",{valu!
 e:F.close||false,method:function(G){if(this.get("position")=="center"){return false;}if(!this.header){this._createHeader();}var H=D.getElementsByClassName("close","div",this.header)[0];if(G){if(!H){H=document.createElement("div");H.className="close";this.header.appendChild(H);A.on(H,"click",this.close,this,true);}H.title=this.STR_CLOSE;}else{if(H){A.purgeElement(H);H.parentNode.removeChild(H);}}this._configs.close.value=G;this.set("collapse",this.get("collapse"));}});this.setAttributeConfig("collapse",{value:F.collapse||false,method:function(G){if(this.get("position")=="center"){return false;}if(!this.header){this._createHeader();}var H=D.getElementsByClassName("collapse","div",this.header)[0];if(G){if(!H){H=document.createElement("div");this.header.appendChild(H);A.on(H,"click",this.collapse,this,true);}H.title=this.STR_COLLAPSE;H.className="collapse"+((this.get("close"))?" collapse-close":"");}else{if(H){A.purgeElement(H);H.parentNode.removeChild(H);}}}});this.setAttribut!
 eConfig("scroll",{value:F.scroll||false,method:function(G){if(!
 (G===fal
se)&&!this._collapsed){if(this.body){if(this.body.scrollTop>0){this._lastScrollTop=this.body.scrollTop;}}}if(G){this.addClass("yui-layout-scroll");if(this._lastScrollTop>0){if(this.body){this.body.scrollTop=this._lastScrollTop;}}}else{this.removeClass("yui-layout-scroll");}}});this.setAttributeConfig("hover",{writeOnce:true,value:F.hover||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("resize",{value:F.resize||false,validator:function(G){if(YAHOO.util&&YAHOO.util.Resize){return true;}return false;},method:function(G){if(G&&!this._resize){if(this.get("position")=="center"){return false;}var I=false;switch(this.get("position")){case"top":I="b";break;case"bottom":I="t";break;case"right":I="l";break;case"left":I="r";break;}this.setStyle("position","absolute");if(I){this._resize=new YAHOO.util.Resize(this.get("element"),{proxy:this.get("proxy"),hover:this.get("hover"),status:false,autoRatio:false,handles:[I],minWidth:this.get("minWidth"),maxWidth:this.get("maxWidt!
 h"),minHeight:this.get("minHeight"),maxHeight:this.get("maxHeight"),height:this.get("height"),width:this.get("width"),setSize:false});this._resize._handles[I].innerHTML='<div class="yui-layout-resize-knob"></div>';if(this.get("proxy")){var H=this._resize.getProxyEl();H.innerHTML='<div class="yui-layout-handle-'+I+'"></div>';}this._resize.on("startResize",function(J){this._lastScroll=this.get("scroll");this.set("scroll",false);if(this.get("parent")){this.get("parent").fireEvent("startResize");var K=this.get("parent").getUnitByPosition("center");this._lastCenterScroll=K.get("scroll");K.set("scroll",false);}this.fireEvent("startResize");},this,true);this._resize.on("resize",function(J){this.set("height",J.height);this.set("width",J.width);this.set("scroll",this._lastScroll);if(this.get("parent")){var K=this.get("parent").getUnitByPosition("center");K.set("scroll",this._lastCenterScroll);}},this,true);}}else{if(this._resize){this._resize.destroy();
+}}}});},_cleanGrids:function(){if(this.get("grids")){var F=C.query("div.yui-b",this.body,true);if(F){D.removeClass(F,"yui-b");}A.onAvailable("yui-main",function(){D.setStyle(C.query("#yui-main"),"margin-left","0");D.setStyle(C.query("#yui-main"),"margin-right","0");});}},_createHeader:function(){var F=document.createElement("div");F.className="yui-layout-hd";if(this.get("firstChild")){this.get("wrap").insertBefore(F,this.get("wrap").firstChild);}else{this.get("wrap").appendChild(F);}this.header=F;return F;},destroy:function(){if(this._resize){this._resize.destroy();}var G=this.get("parent");this.setStyle("display","none");G.removeUnit(this);if(this._clip){this._clip.parentNode.removeChild(this._clip);this._clip=null;}A.purgeElement(this.get("element"));this.get("parentNode").removeChild(this.get("element"));delete YAHOO.widget.LayoutUnit._instances[this.get("id")];for(var F in this){if(E.hasOwnProperty(this,F)){this[F]=null;delete this[F];}}return G;},toString:function(){if!
 (this.get){return"LayoutUnit #"+this.get("id")+" ("+this.get("position")+")";}return"LayoutUnit";}});YAHOO.widget.LayoutUnit=B;})();YAHOO.register("layout",YAHOO.widget.Layout,{version:"2.5.1",build:"984"});
\ No newline at end of file

Added: trunk/root/static/yui/layout/layout-beta.js
===================================================================
--- trunk/root/static/yui/layout/layout-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/layout/layout-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,2046 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * @description <p>Provides a fixed layout containing, top, bottom, left, right and center layout units. It can be applied to either the body or an element.</p>
+ * @namespace YAHOO.widget
+ * @requires yahoo, dom, element, event
+ * @module layout
+ * @beta
+ */
+(function() {
+    var Dom = YAHOO.util.Dom,
+        Event = YAHOO.util.Event,
+        Lang = YAHOO.lang;
+
+    /**
+     * @constructor
+     * @class Layout
+     * @extends YAHOO.util.Element
+     * @description <p>Provides a fixed layout containing, top, bottom, left, right and center layout units. It can be applied to either the body or an element.</p>
+     * @param {String/HTMLElement} el The element to make contain a layout.
+     * @param {Object} attrs Object liternal containing configuration parameters.
+    */
+
+    var Layout = function(el, config) {
+        if (Lang.isObject(el) && !el.tagName) {
+            config = el;
+            el = null;
+        }
+        if (Lang.isString(el)) {
+            if (Dom.get(el)) {
+                el = Dom.get(el);
+            }
+        }
+        if (!el) {
+            el = document.body;
+        }
+
+        var oConfig = {
+            element: el,
+            attributes: config || {}
+        };
+
+        Layout.superclass.constructor.call(this, oConfig.element, oConfig.attributes);    
+    };
+
+    /**
+    * @private
+    * @static
+    * @property _instances
+    * @description Internal hash table for all layout instances
+    * @type Object
+    */ 
+    Layout._instances = {};
+    /**
+    * @static
+    * @method getLayoutById 
+    * @description Get's a layout object by the HTML id of the element associated with the Layout object.
+    * @return {Object} The Layout Object
+    */ 
+    Layout.getLayoutById = function(id) {
+        if (Layout._instances[id]) {
+            return Layout._instances[id];
+        }
+        return false;
+    };
+
+    YAHOO.extend(Layout, YAHOO.util.Element, {
+        /**
+        * @property browser
+        * @description A modified version of the YAHOO.env.ua object
+        * @type Object
+        */
+        browser: function() {
+            var b = YAHOO.env.ua;
+            b.standardsMode = false;
+            b.secure = false;
+            return b;
+        }(),
+        /**
+        * @private
+        * @property _rendered
+        * @description Set to true when the layout is rendered
+        * @type Boolean
+        */
+        _rendered: null,
+        /**
+        * @private
+        * @property _zIndex
+        * @description The zIndex to set all LayoutUnits to
+        * @type Number
+        */
+        _zIndex: null,
+        /**
+        * @private
+        * @property _sizes
+        * @description A collection of the current sizes of all usable LayoutUnits to be used for calculations
+        * @type Object
+        */
+        _sizes: null,
+        /**
+        * @private
+        * @method _setBodySize
+        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
+        * @description Used to set the body size of the layout, sets the height and width of the parent container
+        */
+        _setBodySize: function(set) {
+            var h = 0, w = 0;
+            set = ((set === false) ? false : true);
+
+            if (this._isBody) {
+                h = Dom.getClientHeight();
+                w = Dom.getClientWidth();
+            } else {
+                h = parseInt(this.getStyle('height'), 10);
+                w = parseInt(this.getStyle('width'), 10);
+                if (isNaN(w)) {
+                    w = this.get('element').clientWidth;
+                }
+                if (isNaN(h)) {
+                    h = this.get('element').clientHeight;
+                }
+            }
+            if (this.get('minWidth')) {
+                if (w < this.get('minWidth')) {
+                    w = this.get('minWidth');
+                }
+            }
+            if (this.get('minHeight')) {
+                if (h < this.get('minHeight')) {
+                    h = this.get('minHeight');
+                }
+            }
+            if (set) {
+                Dom.setStyle(this._doc, 'height', h + 'px');
+                Dom.setStyle(this._doc, 'width', w + 'px');
+            }
+            this._sizes.doc = { h: h, w: w };
+            this._setSides(set);
+        },
+        /**
+        * @private
+        * @method _setSides
+        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
+        * @description Used to set the size and position of the left, right, top and bottom units
+        */
+        _setSides: function(set) {
+            var h1 = ((this._top) ? this._top.get('height') : 0),
+                h2 = ((this._bottom) ? this._bottom.get('height') : 0),
+                h = this._sizes.doc.h,
+                w = this._sizes.doc.w;
+            set = ((set === false) ? false : true);
+
+            this._sizes.top = {
+                h: h1, w: ((this._top) ? w : 0),
+                t: 0
+            };
+            this._sizes.bottom = {
+                h: h2, w: ((this._bottom) ? w : 0)
+            };
+            
+            var newH = (h - (h1 + h2));
+
+            this._sizes.left = {
+                h: newH, w: ((this._left) ? this._left.get('width') : 0)
+            };
+            this._sizes.right = {
+                h: newH, w: ((this._right) ? this._right.get('width') : 0),
+                l: ((this._right) ? (w - this._right.get('width')) : 0),
+                t: ((this._top) ? this._sizes.top.h : 0)
+            };
+            
+            if (this._right && set) {
+                this._right.set('top', this._sizes.right.t);
+                if (!this._right._collapsing) { 
+                    this._right.set('left', this._sizes.right.l);
+                }
+                this._right.set('height', this._sizes.right.h, true);
+            }
+            if (this._left) {
+                this._sizes.left.l = 0;
+                if (this._top) {
+                    this._sizes.left.t = this._sizes.top.h;
+                } else {
+                    this._sizes.left.t = 0;
+                }
+                if (set) {
+                    this._left.set('top', this._sizes.left.t);
+                    this._left.set('height', this._sizes.left.h, true);
+                    this._left.set('left', 0);
+                }
+            }
+            if (this._bottom) {
+                this._sizes.bottom.t = this._sizes.top.h + this._sizes.left.h;
+                if (set) {
+                    this._bottom.set('top', this._sizes.bottom.t);
+                    this._bottom.set('width', this._sizes.bottom.w, true);
+                }
+            }
+            if (this._top) {
+                if (set) {
+                    this._top.set('width', this._sizes.top.w, true);
+                }
+            }
+            this._setCenter(set);
+        },
+        /**
+        * @private
+        * @method _setCenter
+        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
+        * @description Used to set the size and position of the center unit
+        */
+        _setCenter: function(set) {
+            set = ((set === false) ? false : true);
+            var h = this._sizes.left.h;
+            var w = (this._sizes.doc.w - (this._sizes.left.w + this._sizes.right.w));
+            if (set) {
+                this._center.set('height', h, true);
+                this._center.set('width', w, true);
+                this._center.set('top', this._sizes.top.h);
+                this._center.set('left', this._sizes.left.w);
+            }
+            this._sizes.center = { h: h, w: w, t: this._sizes.top.h, l: this._sizes.left.w };
+        },
+        /**
+        * @method getSizes
+        * @description Get a reference to the internal Layout Unit sizes object used to build the layout wireframe
+        * @return {Object} An object of the layout unit sizes
+        */
+        getSizes: function() {
+            return this._sizes;
+        },
+        /**
+        * @method getUnitById
+        * @param {String} id The HTML element id of the unit
+        * @description Get the LayoutUnit by it's HTML id
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        getUnitById: function(id) {
+            return YAHOO.widget.LayoutUnit.getLayoutUnitById(id);
+        },
+        /**
+        * @method getUnitByPosition
+        * @param {String} pos The position of the unit in this layout
+        * @description Get the LayoutUnit by it's position in this layout
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        getUnitByPosition: function(pos) {
+            if (pos) {
+                pos = pos.toLowerCase();
+                if (this['_' + pos]) {
+                    return this['_' + pos];
+                }
+            }
+            return false;
+        },
+        /**
+        * @method removeUnit
+        * @param {Object} unit The LayoutUnit that you want to remove
+        * @description Remove the unit from this layout and resize the layout.
+        */
+        removeUnit: function(unit) {
+            this['_' + unit.get('position')] = null;
+            this.resize();
+        },
+        /**
+        * @method addUnit
+        * @param {Object} cfg The config for the LayoutUnit that you want to add
+        * @description Add a unit to this layout and if the layout is rendered, resize the layout. 
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        addUnit: function(cfg) {
+            if (!cfg.position) {
+                return false;
+            }
+            if (this['_' + cfg.position]) {
+                return false;
+            }
+            var element = null,
+                el = null;
+
+            if (cfg.id) {
+                if (Dom.get(cfg.id)) {
+                    element = Dom.get(cfg.id);
+                    delete cfg.id;
+
+                }
+            }
+            if (cfg.element) {
+                element = cfg.element;
+            }
+
+            if (!el) {
+                el = document.createElement('div');
+                var id = Dom.generateId();
+                el.id = id;
+            }
+
+            if (!element) {
+                element = document.createElement('div');
+            }
+            Dom.addClass(element, 'yui-layout-wrap');
+            if (this.browser.ie && !this.browser.standardsMode) {
+                el.style.zoom = 1;
+                element.style.zoom = 1;
+            }
+
+            if (el.firstChild) {
+                el.insertBefore(element, el.firstChild);
+            } else {
+                el.appendChild(element);
+            }
+            this._doc.appendChild(el);
+
+            var h = false, w = false;
+
+            if (cfg.height) {
+                h = parseInt(cfg.height, 10);
+            }
+            if (cfg.width) {
+                w = parseInt(cfg.width, 10);
+            }
+            var unitConfig = {};
+            YAHOO.lang.augmentObject(unitConfig, cfg); // break obj ref
+
+            unitConfig.parent = this;
+            unitConfig.wrap = element;
+            unitConfig.height = h;
+            unitConfig.width = w;
+
+            var unit = new YAHOO.widget.LayoutUnit(el, unitConfig);
+
+            unit.on('heightChange', this.resize, this, true);
+            unit.on('widthChange', this.resize, this, true);
+            unit.on('gutterChange', this.resize, this, true);
+            this['_' + cfg.position] = unit;
+
+            if (this._rendered) {
+                this.resize();
+            }
+
+            return unit;
+        },
+        /**
+        * @private
+        * @method _createUnits
+        * @description Private method to create units from the config that was passed in.
+        */
+        _createUnits: function() {
+            var units = this.get('units');
+            for (var i in units) {
+                if (Lang.hasOwnProperty(units, i)) {
+                    this.addUnit(units[i]);
+                }
+            }
+        },
+        /**
+        * @method resize
+        * @param {Boolean} set If set to false, it will NOT set the size, just perform the calculations (used for collapsing units)
+        * @description Starts the chain of resize routines that will resize all the units.
+        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
+        */
+        resize: function(set) {
+            set = ((set === false) ? false : true);
+            if (set) {
+                var retVal = this.fireEvent('beforeResize');
+                if (retVal === false) {
+                    set = false;
+                }
+                if (this.browser.ie) {
+                    if (this._isBody) {
+                        Dom.removeClass(document.documentElement, 'yui-layout');
+                        Dom.addClass(document.documentElement, 'yui-layout');
+                    } else {
+                        this.removeClass('yui-layout');
+                        this.addClass('yui-layout');
+                    }
+                }
+            }
+            this._setBodySize(set);
+            if (set) {
+                this.fireEvent('resize', { target: this, sizes: this._sizes });
+            }
+            return this;
+        },
+        /**
+        * @private
+        * @method _setupBodyElements
+        * @description Sets up the main doc element when using the body as the main element.
+        */
+        _setupBodyElements: function() {
+            this._doc = Dom.get('layout-doc');
+            if (!this._doc) {
+                this._doc = document.createElement('div');
+                this._doc.id = 'layout-doc';
+                if (document.body.firstChild) {
+                    document.body.insertBefore(this._doc, document.body.firstChild);
+                } else {
+                    document.body.appendChild(this._doc);
+                }
+            }
+            this._createUnits();
+            this._setBodySize();
+            Event.on(window, 'resize', this.resize, this, true);
+            Dom.addClass(this._doc, 'yui-layout-doc');
+        },
+        /**
+        * @private
+        * @method _setupElements
+        * @description Sets up the main doc element when not using the body as the main element.
+        */
+        _setupElements: function() {
+            this._doc = this.getElementsByClassName('doc')[0];
+            if (!this._doc) {
+                this._doc = document.createElement('div');
+                this.get('element').appendChild(this._doc);
+            }
+            this._createUnits();
+            this._setBodySize();
+            Event.on(window, 'resize', this.resize, this, true);
+            Dom.addClass(this._doc, 'yui-layout-doc');
+        },
+        /**
+        * @private
+        * @property _isBody
+        * @description Flag to determine if we are using the body as the root element.
+        * @type Boolean
+        */
+        _isBody: null,
+        /**
+        * @private
+        * @property _doc
+        * @description Reference to the root element
+        * @type HTMLElement
+        */
+        _doc: null,
+        /**
+        * @private
+        * @property _left
+        * @description Reference to the left LayoutUnit Object
+        * @type {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} A LayoutUnit instance
+        */
+        _left: null,
+        /**
+        * @private
+        * @property _right
+        * @description Reference to the right LayoutUnit Object
+        * @type {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} A LayoutUnit instance
+        */
+        _right: null,
+        /**
+        * @private
+        * @property _top
+        * @description Reference to the top LayoutUnit Object
+        * @type {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} A LayoutUnit instance
+        */
+        _top: null,
+        /**
+        * @private
+        * @property _bottom
+        * @description Reference to the bottom LayoutUnit Object
+        * @type {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} A LayoutUnit instance
+        */
+        _bottom: null,
+        /**
+        * @private
+        * @property _center
+        * @description Reference to the center LayoutUnit Object
+        * @type {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} A LayoutUnit instance
+        */
+        _center: null,
+        /**
+        * @private
+        * @method init
+        * @description The Layout class' initialization method
+        */        
+        init: function(p_oElement, p_oAttributes) {
+            this._zIndex = 0;
+            Layout.superclass.init.call(this, p_oElement, p_oAttributes);
+            
+            if (this.get('parent')) {
+                this._zIndex = this.get('parent')._zIndex + 10;
+            }
+
+            this._sizes = {};
+
+            var id = p_oElement;
+            if (!Lang.isString(id)) {
+                id = Dom.generateId(id);
+            }
+            Layout._instances[id] = this;
+        },
+        /**
+        * @method render
+        * @description This method starts the render process, applying classnames and creating elements
+        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The Layout instance
+        */        
+        render: function() {
+            this._stamp();
+            var el = this.get('element');
+            if (el && el.tagName && (el.tagName.toLowerCase() == 'body')) {
+                this._isBody = true;
+                Dom.addClass(document.body, 'yui-layout');
+                if (Dom.hasClass(document.body, 'yui-skin-sam')) {
+                    //Move the class up so we can have a css chain
+                    Dom.addClass(document.documentElement, 'yui-skin-sam');
+                    Dom.removeClass(document.body, 'yui-skin-sam');
+                }
+                this._setupBodyElements();
+            } else {
+                this._isBody = false;
+                this.addClass('yui-layout');
+                this._setupElements();
+            }
+            this.resize();
+            this._rendered = true;
+            this.fireEvent('render');
+
+            return this;
+        },
+        /**
+        * @private
+        * @method _stamp
+        * @description Stamps the root node with a secure classname for ease of use. Also sets the this.browser.standardsMode variable.
+        */        
+        _stamp: function() {
+            if (document.compatMode == 'CSS1Compat') {
+                this.browser.standardsMode = true;
+            }
+            if (window.location.href.toLowerCase().indexOf("https") === 0) {
+                Dom.addClass(document.documentElement, 'secure');
+                this.browser.secure = true;
+            }
+        },
+        /**
+        * @private
+        * @method initAttributes
+        * @description Processes the config
+        */        
+        initAttributes: function(attr) {
+            Layout.superclass.initAttributes.call(this, attr);
+            /**
+            * @attribute units
+            * @description An array of config definitions for the LayoutUnits to add to this layout
+            * @type Array
+            */
+            this.setAttributeConfig('units', {
+                writeOnce: true,
+                validator: YAHOO.lang.isArray,
+                value: attr.units || []
+            });
+
+            /**
+            * @attribute minHeight
+            * @description The minimum height in pixels
+            * @type Number
+            */
+            this.setAttributeConfig('minHeight', {
+                value: attr.minHeight || false,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute minWidth
+            * @description The minimum width in pixels
+            * @type Number
+            */
+            this.setAttributeConfig('minWidth', {
+                value: attr.minWidth || false,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute height
+            * @description The height in pixels
+            * @type Number
+            */
+            this.setAttributeConfig('height', {
+                value: attr.height || false,
+                validator: YAHOO.lang.isNumber,
+                method: function(h) {
+                    this.setStyle('height', h + 'px');
+                }
+            });
+
+            /**
+            * @attribute width
+            * @description The width in pixels
+            * @type Number
+            */
+            this.setAttributeConfig('width', {
+                value: attr.width || false,
+                validator: YAHOO.lang.isNumber,
+                method: function(w) {
+                    this.setStyle('width', w + 'px');
+                }
+            });
+
+            /**
+            * @attribute parent
+            * @description If this layout is to be used as a child of another Layout instance, this config will bind the resize events together.
+            * @type Object YAHOO.widget.Layout
+            */
+            this.setAttributeConfig('parent', {
+                writeOnce: true,
+                value: attr.parent || false,
+                method: function(p) {
+                    if (p) {
+                        p.on('resize', this.resize, this, true);
+                    }
+                }
+            });
+        },
+        /**
+        * @method toString
+        * @description Returns a string representing the Layout.
+        * @return {String}
+        */        
+        toString: function() {
+            if (this.get) {
+                return 'Layout #' + this.get('id');
+            }
+            return 'Layout';
+        }
+    });
+    /**
+    * @event resize
+    * @description Fired when this.resize is called
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event startResize
+    * @description Fired when the Resize Utility for a Unit fires it's startResize Event.
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event beforeResize
+    * @description Firef at the beginning of the resize method. If you return false, the resize is cancelled.
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event render
+    * @description Fired after the render method completes.
+    * @type YAHOO.util.CustomEvent
+    */
+
+    YAHOO.widget.Layout = Layout;
+})();
+/**
+ * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
+ * @namespace YAHOO.widget
+ * @requires yahoo, dom, element, event, layout
+ * @optional animation, dragdrop, selector
+ * @beta
+ */
+(function() {
+    var Dom = YAHOO.util.Dom,
+        Sel = YAHOO.util.Selector,
+        Event = YAHOO.util.Event,
+        Lang = YAHOO.lang;
+
+    /**
+     * @constructor
+     * @class LayoutUnit
+     * @extends YAHOO.util.Element
+     * @description <p>Provides a fixed position unit containing a header, body and footer for use with a YAHOO.widget.Layout instance.</p>
+     * @param {String/HTMLElement} el The element to make a unit.
+     * @param {Object} attrs Object liternal containing configuration parameters.
+    */
+
+    var LayoutUnit = function(el, config) {
+        
+        var oConfig = {
+            element: el,
+            attributes: config || {}
+        };
+
+        LayoutUnit.superclass.constructor.call(this, oConfig.element, oConfig.attributes);    
+    };
+
+    /**
+    * @private
+    * @static
+    * @property _instances
+    * @description Internal hash table for all layout unit instances
+    * @type Object
+    */ 
+    LayoutUnit._instances = {};
+    /**
+    * @static
+    * @method getLayoutUnitById 
+    * @description Get's a layout unit object by the HTML id of the element associated with the Layout Unit object.
+    * @return {Object} The Layout Object
+    */ 
+    LayoutUnit.getLayoutUnitById = function(id) {
+        if (LayoutUnit._instances[id]) {
+            return LayoutUnit._instances[id];
+        }
+        return false;
+    };
+
+    YAHOO.extend(LayoutUnit, YAHOO.util.Element, {
+        /**
+        * @property STR_CLOSE
+        * @description String used for close button title
+        * @type {String}
+        */
+        STR_CLOSE: 'Click to close this pane.',
+        /**
+        * @property STR_COLLAPSE
+        * @description String used for collapse button title
+        * @type {String}
+        */
+        STR_COLLAPSE: 'Click to collapse this pane.',
+        /**
+        * @property STR_EXPAND
+        * @description String used for expand button title
+        * @type {String}
+        */
+        STR_EXPAND: 'Click to expand this pane.',
+        /**
+        * @property browser
+        * @description A modified version of the YAHOO.env.ua object
+        * @type Object
+        */
+        browser: null,
+        /**
+        * @private
+        * @property _sizes
+        * @description A collection of the current sizes of the contents of this Layout Unit
+        * @type Object
+        */
+        _sizes: null,
+        /**
+        * @private
+        * @property _anim
+        * @description A reference to the Animation instance used by this LayouUnit
+        * @type YAHOO.util.Anim
+        */
+        _anim: null,
+        /**
+        * @private
+        * @property _resize
+        * @description A reference to the Resize instance used by this LayoutUnit
+        * @type YAHOO.util.Resize
+        */
+        _resize: null,
+        /**
+        * @private
+        * @property _clip
+        * @description A reference to the clip element used when collapsing the unit
+        * @type HTMLElement
+        */
+        _clip: null,
+        /**
+        * @private
+        * @property _gutter
+        * @description A simple hash table used to store the gutter to apply to the Unit
+        * @type Object
+        */
+        _gutter: null,
+        /**
+        * @property header
+        * @description A reference to the HTML element used for the Header
+        * @type HTMLELement
+        */
+        header: null,
+        /**
+        * @property body
+        * @description A reference to the HTML element used for the body
+        * @type HTMLElement
+        */
+        body: null,
+        /**
+        * @property footer
+        * @description A reference to the HTML element used for the footer
+        * @type HTMLElement
+        */
+        footer: null,
+        /**
+        * @private
+        * @property _collapsed
+        * @description Flag to determine if the unit is collapsed or not.
+        * @type Boolean
+        */
+        _collapsed: null,
+        /**
+        * @private
+        * @property _collapsing
+        * @description A flag set while the unit is being collapsed, used so we don't fire events while animating the size
+        * @type Boolean
+        */
+        _collapsing: null,
+        /**
+        * @private
+        * @property _lastWidth
+        * @description A holder for the last known width of the unit
+        * @type Number
+        */
+        _lastWidth: null,
+        /**
+        * @private
+        * @property _lastHeight
+        * @description A holder for the last known height of the unit
+        * @type Number
+        */
+        _lastHeight: null,
+        /**
+        * @private
+        * @property _lastTop
+        * @description A holder for the last known top of the unit
+        * @type Number
+        */
+        _lastTop: null,
+        /**
+        * @private
+        * @property _lastLeft
+        * @description A holder for the last known left of the unit
+        * @type Number
+        */
+        _lastLeft: null,
+        /**
+        * @private
+        * @property _lastScroll
+        * @description A holder for the last known scroll state of the unit
+        * @type Boolean
+        */
+        _lastScroll: null,
+        /**
+        * @private
+        * @property _lastCenetrScroll
+        * @description A holder for the last known scroll state of the center unit
+        * @type Boolean
+        */
+        _lastCenterScroll: null,
+        /**
+        * @private
+        * @property _lastScrollTop
+        * @description A holder for the last known scrollTop state of the unit
+        * @type Number
+        */
+        _lastScrollTop: null,
+        /**
+        * @method resize
+        * @description Resize either the unit or it's clipped state, also updating the box inside
+        * @param {Boolean} force This will force full calculations even when the unit is collapsed
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        resize: function(force) {
+            var retVal = this.fireEvent('beforeResize');
+            if (retVal === false) {
+                return this;
+            }
+            if (!this._collapsing || (force === true)) {
+                var scroll = this.get('scroll');
+                this.set('scroll', false);
+
+
+                var hd = this._getBoxSize(this.header),
+                    ft = this._getBoxSize(this.footer),
+                    box = [this.get('height'), this.get('width')];
+
+
+                var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
+                    nw = box[1] - (this._gutter.left + this._gutter.right);
+
+                var wrapH = (nh + (hd[0] + ft[0])),
+                    wrapW = nw;
+
+                if (this._collapsed && !this._collapsing) {
+                    this._setHeight(this._clip, wrapH);
+                    this._setWidth(this._clip, wrapW);
+                    Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
+                    Dom.setStyle(this._clip, 'left', this.get('left') + this._gutter.left + 'px');
+                } else if (!this._collapsed || (this._collapsed && this._collapsing)) {
+                    wrapH = this._setHeight(this.get('wrap'), wrapH);
+                    wrapW = this._setWidth(this.get('wrap'), wrapW);
+                    this._sizes.wrap.h = wrapH;
+                    this._sizes.wrap.w = wrapW;
+
+                    Dom.setStyle(this.get('wrap'), 'top', this._gutter.top + 'px');
+                    Dom.setStyle(this.get('wrap'), 'left', this._gutter.left + 'px');
+
+                    this._sizes.header.w = this._setWidth(this.header, wrapW);
+                    this._sizes.header.h = hd[0];
+
+                    this._sizes.footer.w = this._setWidth(this.footer, wrapW);
+                    this._sizes.footer.h = ft[0];
+
+                    Dom.setStyle(this.footer, 'bottom', '0px');
+
+                    this._sizes.body.h = this._setHeight(this.body, (wrapH - (hd[0] + ft[0])));
+                    this._sizes.body.w =this._setWidth(this.body, wrapW);
+                    Dom.setStyle(this.body, 'top', hd[0] + 'px');
+
+                    this.set('scroll', scroll);
+                    this.fireEvent('resize');
+                }
+            }
+            return this;
+        },
+        /**
+        * @private
+        * @method _setWidth
+        * @description Sets the width of the element based on the border size of the element.
+        * @param {HTMLElement} el The HTMLElement to have it's width set
+        * @param {Number} w The width that you want it the element set to
+        * @return {Number} The new width, fixed for borders and IE QuirksMode
+        */
+        _setWidth: function(el, w) {
+            if (el) {
+                var b = this._getBorderSizes(el);
+                w = (w - (b[1] + b[3]));
+                w = this._fixQuirks(el, w, 'w');
+                Dom.setStyle(el, 'width', w + 'px');
+            }
+            return w;
+        },
+        /**
+        * @private
+        * @method _setHeight
+        * @description Sets the height of the element based on the border size of the element.
+        * @param {HTMLElement} el The HTMLElement to have it's height set
+        * @param {Number} h The height that you want it the element set to
+        * @return {Number} The new height, fixed for borders and IE QuirksMode
+        */
+        _setHeight: function(el, h) {
+            if (el) {
+                var b = this._getBorderSizes(el);
+                h = (h - (b[0] + b[2]));
+                h = this._fixQuirks(el, h, 'h');
+                Dom.setStyle(el, 'height', h + 'px');
+            }
+            return h;
+        },
+        /**
+        * @private
+        * @method _fixQuirks
+        * @description Fixes the box calculations for IE in QuirksMode
+        * @param {HTMLElement} el The HTMLElement to set the dimension on
+        * @param {Number} dim The number of the dimension to fix
+        * @param {String} side The dimension (h or w) to fix. Defaults to h
+        * @return {Number} The fixed dimension
+        */
+        _fixQuirks: function(el, dim, side) {
+            var i1 = 0, i2 = 2;
+            if (side == 'w') {
+                i1 = 1;
+                i2 = 3;
+            }
+            if (this.browser.ie && !this.browser.standardsMode) {
+                //Internet Explorer - Quirks Mode
+                var b = this._getBorderSizes(el),
+                    bp = this._getBorderSizes(el.parentNode);
+                if ((b[i1] === 0) && (b[i2] === 0)) { //No Borders, check parent
+                    if ((bp[i1] !== 0) && (bp[i2] !== 0)) { //Parent has Borders
+                        dim = (dim - (bp[i1] + bp[i2]));
+                    }
+                } else {
+                    if ((bp[i1] === 0) && (bp[i2] === 0)) {
+                        dim = (dim + (b[i1] + b[i2]));
+                    }
+                }
+            }
+            return dim;
+        },
+        /**
+        * @private
+        * @method _getBoxSize
+        * @description Get's the elements clientHeight and clientWidth plus the size of the borders
+        * @param {HTMLElement} el The HTMLElement to get the size of
+        * @return {Array} An array of height and width
+        */
+        _getBoxSize: function(el) {
+            var size = [0, 0];
+            if (el) {
+                if (this.browser.ie && !this.browser.standardsMode) {
+                    el.style.zoom = 1;
+                }
+                var b = this._getBorderSizes(el);
+                size[0] = el.clientHeight + (b[0] + b[2]);
+                size[1] = el.clientWidth + (b[1] + b[3]);
+            }
+            return size;
+        },
+        /**
+        * @private
+        * @method _getBorderSizes
+        * @description Get the CSS border size of the element passed.
+        * @param {HTMLElement} el The element to get the border size of
+        * @return {Array} An array of the top, right, bottom, left borders.
+        */
+        _getBorderSizes: function(el) {
+            var s = [];
+            el = el || this.get('element');
+            if (this.browser.ie && !this.browser.standardsMode) {
+                el.style.zoom = 1;
+            }
+            s[0] = parseInt(Dom.getStyle(el, 'borderTopWidth'), 10);
+            s[1] = parseInt(Dom.getStyle(el, 'borderRightWidth'), 10);
+            s[2] = parseInt(Dom.getStyle(el, 'borderBottomWidth'), 10);
+            s[3] = parseInt(Dom.getStyle(el, 'borderLeftWidth'), 10);
+            
+            //IE will return NaN on these if they are set to auto, we'll set them to 0
+            for (var i = 0; i < s.length; i++) {
+                if (isNaN(s[i])) {
+                    s[i] = 0;
+                }
+            }
+            return s;
+        },
+        /**
+        * @private
+        * @method _createClip
+        * @description Create the clip element used when the Unit is collapsed
+        */
+        _createClip: function() {
+            if (!this._clip) {
+                this._clip = document.createElement('div');
+                this._clip.className = 'yui-layout-clip yui-layout-clip-' + this.get('position');
+                this._clip.innerHTML = '<div class="collapse"></div>';
+                var c = this._clip.firstChild;
+                c.title = this.STR_EXPAND;
+                Event.on(c, 'click', this.expand, this, true);
+                this.get('element').parentNode.appendChild(this._clip);
+            }
+        },
+        /**
+        * @private
+        * @method _toggleClip
+        * @description Toggle th current state of the Clip element and set it's height, width and position
+        */
+        _toggleClip: function() {
+            if (!this._collapsed) {
+                //show
+                var hd = this._getBoxSize(this.header),
+                    ft = this._getBoxSize(this.footer),
+                    box = [this.get('height'), this.get('width')];
+
+
+                var nh = (box[0] - hd[0] - ft[0]) - (this._gutter.top + this._gutter.bottom),
+                    nw = box[1] - (this._gutter.left + this._gutter.right),
+                    wrapH = (nh + (hd[0] + ft[0]));
+
+                switch (this.get('position')) {
+                    case 'top':
+                    case 'bottom':
+                        this._setWidth(this._clip, nw);
+                        this._setHeight(this._clip, this.get('collapseSize'));
+                        Dom.setStyle(this._clip, 'left', (this._lastLeft + this._gutter.left) + 'px');
+                        if (this.get('position') == 'bottom') {
+                            Dom.setStyle(this._clip, 'top', ((this._lastTop + this._lastHeight) - (this.get('collapseSize') - this._gutter.top)) + 'px');
+                        } else {
+                            Dom.setStyle(this._clip, 'top', this.get('top') + this._gutter.top + 'px');
+                        }
+                        break;
+                    case 'left':
+                    case 'right':
+                        this._setWidth(this._clip, this.get('collapseSize'));
+                        this._setHeight(this._clip, wrapH);
+                        Dom.setStyle(this._clip, 'top', (this.get('top') + this._gutter.top) + 'px');
+                        if (this.get('position') == 'right') {
+                            Dom.setStyle(this._clip, 'left', (((this._lastLeft + this._lastWidth) - this.get('collapseSize')) - this._gutter.left) + 'px');
+                        } else {
+                            Dom.setStyle(this._clip, 'left', (this.get('left') + this._gutter.left) + 'px');
+                        }
+                        break;
+                }
+
+                Dom.setStyle(this._clip, 'display', 'block');
+                this.setStyle('display', 'none');
+            } else {
+                //Hide
+                Dom.setStyle(this._clip, 'display', 'none');
+            }
+        },
+        /**
+        * @method getSizes
+        * @description Get a reference to the internal sizes object for this unit
+        * @return {Object} An object of the sizes used for calculations
+        */
+        getSizes: function() {
+            return this._sizes;
+        },
+        /**
+        * @method toggle
+        * @description Toggles the Unit, replacing it with a clipped version.
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        toggle: function() {
+            if (this._collapsed) {
+                this.expand();
+            } else {
+                this.collapse();
+            }
+            return this;
+        },
+        /**
+        * @method expand
+        * @description Expand the Unit if it is collapsed.
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        expand: function() {
+            if (!this._collapsed) {
+                return this;
+            }
+            var retVal = this.fireEvent('beforeExpand');
+            if (retVal === false) {
+                return this;
+            }
+
+            this._collapsing = true;
+            this.setStyle('zIndex', this.get('parent')._zIndex + 1);
+
+            if (this._anim) {
+                this.setStyle('display', 'none');
+                //Animation Fails Here
+                var attr = {}, s;
+
+                switch (this.get('position')) {
+                    case 'left':
+                    case 'right':
+                        this.set('width', this._lastWidth, true);
+                        this.setStyle('width', this._lastWidth + 'px');
+                        this.get('parent').resize(false);
+                        s = this.get('parent').getSizes()[this.get('position')];
+                        this.set('height', s.h, true);
+                        var left = s.l;
+                        attr = {
+                            left: {
+                                to: left
+                            }
+                        };
+                        if (this.get('position') == 'left') {
+                            attr.left.from = (left - s.w);
+                            this.setStyle('left', (left - s.w) + 'px');
+                        }
+                        break;
+                    case 'top':
+                    case 'bottom':
+                        this.set('height', this._lastHeight, true);
+                        this.setStyle('height', this._lastHeight + 'px');
+                        this.get('parent').resize(false);
+                        s = this.get('parent').getSizes()[this.get('position')];
+                        this.set('width', s.w, true);
+                        var top = s.t;
+                        attr = {
+                            top: {
+                                to: top
+                            }
+                        };
+                        if (this.get('position') == 'top') {
+                            this.setStyle('top',  (top - s.h) + 'px');
+                            attr.top.from = (top - s.h);
+                        }
+                        break;
+                }
+
+                this._anim.attributes = attr;
+                var exStart = function() {
+                    this.setStyle('display', 'block');
+                    this.resize(true);
+                    this._anim.onStart.unsubscribe(exStart, this, true);
+                };
+                var expand = function() {
+                    this._collapsing = false;
+                    this.setStyle('zIndex', this.get('parent')._zIndex);
+                    this.set('width', this._lastWidth);
+                    this.set('height', this._lastHeight);
+                    this._collapsed = false;
+                    this.resize();
+                    this.set('scroll', this._lastScroll);
+                    if (this._lastScrollTop > 0) {
+                        this.body.scrollTop = this._lastScrollTop;
+                    }
+                    this._anim.onComplete.unsubscribe(expand, this, true);
+                    this.fireEvent('expand');
+                };
+                this._anim.onStart.subscribe(exStart, this, true);
+                this._anim.onComplete.subscribe(expand, this, true);
+                this._anim.animate();
+                this._toggleClip();
+            } else {
+                this._collapsing = false;
+                this._toggleClip();
+                this.setStyle('zIndex', this.get('parent')._zIndex);
+                this.setStyle('display', 'block');
+                this.set('width', this._lastWidth);
+                this.set('height', this._lastHeight);
+                this._collapsed = false;
+                this.resize();
+                this.set('scroll', this._lastScroll);
+                if (this._lastScrollTop > 0) {
+                    this.body.scrollTop = this._lastScrollTop;
+                }
+                this.fireEvent('expand');
+            }
+            return this;
+        },
+        /**
+        * @method collapse
+        * @description Collapse the Unit if it is not collapsed.
+        * @return {<a href="YAHOO.widget.LayoutUnit.html">YAHOO.widget.LayoutUnit</a>} The LayoutUnit instance
+        */
+        collapse: function() {
+            if (this._collapsed) {
+                return this;
+            }
+            var retValue = this.fireEvent('beforeCollapse');
+            if (retValue === false) {
+                return this;
+            }
+            if (!this._clip) {
+                this._createClip();
+            }
+            this._collapsing = true;
+            var w = this.get('width'),
+                h = this.get('height'),
+                attr = {};
+            this._lastWidth = w;
+            this._lastHeight = h;
+            this._lastScroll = this.get('scroll');
+            this._lastScrollTop = this.body.scrollTop;            
+            this.set('scroll', false, true);
+            this._lastLeft = parseInt(this.get('element').style.left, 10);
+            this._lastTop = parseInt(this.get('element').style.top, 10);
+            if (isNaN(this._lastTop)) {
+                this._lastTop = 0;
+                this.set('top', 0);
+            }
+            if (isNaN(this._lastLeft)) {
+                this._lastLeft = 0;
+                this.set('left', 0);
+            }
+            this.setStyle('zIndex', this.get('parent')._zIndex + 1);
+            var pos = this.get('position');
+
+            switch (pos) {
+                case 'top':
+                case 'bottom':
+                    this.set('height', (this.get('collapseSize') + (this._gutter.top + this._gutter.bottom)));
+                    attr = {
+                        top: {
+                            to: (this.get('top') - h)
+                        }
+                    };
+                    if (pos == 'bottom') {
+                        attr.top.to = (this.get('top') + h);
+                    }
+                    break;
+                case 'left':
+                case 'right':
+                    this.set('width', (this.get('collapseSize') + (this._gutter.left + this._gutter.right)));
+                    attr = {
+                        left: {
+                            to: -(this._lastWidth)
+                        }
+                    };
+                    if (pos == 'right') {
+                        attr.left = {
+                            to: (this.get('left') + w)
+                        };
+                    }
+                    break;
+            }
+            if (this._anim) {
+                this._anim.attributes = attr;
+                var collapse = function() {
+                    this._collapsing = false;
+                    this._toggleClip();
+                    this.setStyle('zIndex', this.get('parent')._zIndex);
+                    this._collapsed = true;
+                    this.get('parent').resize();
+                    this._anim.onComplete.unsubscribe(collapse, this, true);
+                    this.fireEvent('collapse');
+                };
+                this._anim.onComplete.subscribe(collapse, this, true);
+                this._anim.animate();
+            } else {
+                this._collapsing = false;
+                this.setStyle('display', 'none');
+                this._toggleClip();
+                this.setStyle('zIndex', this.get('parent')._zIndex);
+                this.get('parent').resize();
+                this._collapsed = true;
+                this.fireEvent('collapse');
+            }
+            return this;
+        },
+        /**
+        * @method close
+        * @description Close the unit, removing it from the parent Layout.
+        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The parent Layout instance
+        */
+        close: function() {
+            this.setStyle('display', 'none');
+            this.get('parent').removeUnit(this);
+            this.fireEvent('close');
+            if (this._clip) {
+                this._clip.parentNode.removeChild(this._clip);
+                this._clip = null;
+            }
+            return this.get('parent');
+        },
+        /**
+        * @private
+        * @method init
+        * @description The initalization method inherited from Element.
+        */
+        init: function(p_oElement, p_oAttributes) {
+            this._gutter = {
+                left: 0,
+                right: 0,
+                top: 0,
+                bottom: 0
+            };
+            this._sizes = {
+                wrap: {
+                    h: 0,
+                    w: 0
+                },
+                header: {
+                    h: 0,
+                    w: 0
+                },
+                body: {
+                    h: 0,
+                    w: 0
+                },
+                footer: {
+                    h: 0,
+                    w: 0
+                }
+            };
+            
+            LayoutUnit.superclass.init.call(this, p_oElement, p_oAttributes);
+
+            this.browser = this.get('parent').browser;
+            
+            var id = p_oElement;
+            if (!Lang.isString(id)) {
+                id = Dom.generateId(id);
+            }
+            LayoutUnit._instances[id] = this;
+
+            this.setStyle('position', 'absolute');
+
+            this.addClass('yui-layout-unit');
+            this.addClass('yui-layout-unit-' + this.get('position'));
+
+
+            var header = this.getElementsByClassName('yui-layout-hd', 'div')[0];
+            if (header) {
+                this.header = header;
+            }
+            var body = this.getElementsByClassName('yui-layout-bd', 'div')[0];
+            if (body) {
+                this.body = body;
+            }
+            var footer = this.getElementsByClassName('yui-layout-ft', 'div')[0];
+            if (footer) {
+                this.footer = footer;
+            }
+
+            this.on('contentChange', this.resize, this, true);
+            this._lastScrollTop = 0;
+
+            this.set('animate', this.get('animate'));
+        },
+        /**
+        * @private
+        * @method initAttributes
+        * @description Processes the config
+        */        
+        initAttributes: function(attr) {
+            LayoutUnit.superclass.initAttributes.call(this, attr);
+
+            /**
+            * @private
+            * @attribute wrap
+            * @description A reference to the wrap element
+            * @type HTMLElement
+            */
+            this.setAttributeConfig('wrap', {
+                value: attr.wrap || null,
+                method: function(w) {
+                    if (w) {
+                        var id = Dom.generateId(w);
+                        LayoutUnit._instances[id] = this;
+                    }
+                }
+            });
+            /**
+            * @attribute grids
+            * @description Set this option to true if you want the LayoutUnit to fix the first layer of YUI CSS Grids (margins)
+            * @type Boolean
+            */
+            this.setAttributeConfig('grids', {
+                value: attr.grids || false
+            });
+            /**
+            * @private
+            * @attribute top
+            * @description The current top positioning of the Unit
+            * @type Number
+            */
+            this.setAttributeConfig('top', {
+                value: attr.top || 0,
+                validator: Lang.isNumber,
+                method: function(t) {
+                    if (!this._collapsing) {
+                        this.setStyle('top', t + 'px');
+                    }
+                }
+            });
+            /**
+            * @private
+            * @attribute left
+            * @description The current left position of the Unit
+            * @type Number
+            */
+            this.setAttributeConfig('left', {
+                value: attr.left || 0,
+                validator: Lang.isNumber,
+                method: function(l) {
+                    if (!this._collapsing) {
+                        this.setStyle('left', l + 'px');
+                    }
+                }
+            });
+
+            /**
+            * @attribute minWidth
+            * @description The minWidth parameter passed to the Resize Utility
+            * @type Number
+            */
+            this.setAttributeConfig('minWidth', {
+                value: attr.minWidth || false,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute maxWidth
+            * @description The maxWidth parameter passed to the Resize Utility
+            * @type Number
+            */
+            this.setAttributeConfig('maxWidth', {
+                value: attr.maxWidth || false,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute minHeight
+            * @description The minHeight parameter passed to the Resize Utility
+            * @type Number
+            */
+            this.setAttributeConfig('minHeight', {
+                value: attr.minHeight || false,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute maxHeight
+            * @description The maxHeight parameter passed to the Resize Utility
+            * @type Number
+            */
+            this.setAttributeConfig('maxHeight', {
+                value: attr.maxHeight || false,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute height
+            * @description The height of the Unit
+            * @type Number
+            */
+            this.setAttributeConfig('height', {
+                value: attr.height,
+                validator: Lang.isNumber,
+                method: function(h) {
+                    if (!this._collapsing) {
+                        this.setStyle('height', h + 'px');
+                    }
+                }
+            });
+
+            /**
+            * @attribute width
+            * @description The width of the Unit
+            * @type Number
+            */
+            this.setAttributeConfig('width', {
+                value: attr.width,
+                validator: Lang.isNumber,
+                method: function(w) {
+                    if (!this._collapsing) {
+                        this.setStyle('width', w + 'px');
+                    }
+                }
+            });
+            /**
+            * @attribute position
+            * @description The position (top, right, bottom, left or center) of the Unit in the Layout
+            * @type {String}
+            */
+            this.setAttributeConfig('position', {
+                value: attr.position
+            });
+            /**
+            * @attribute gutter
+            * @description The gutter that we should apply to the parent Layout around this Unit. Supports standard CSS markup: (2 4 0 5) or (2) or (2 5)
+            * @type String
+            */
+            this.setAttributeConfig('gutter', {
+                value: attr.gutter || 0,
+                validator: YAHOO.lang.isString,
+                method: function(gutter) {
+                    var p = gutter.split(' ');
+                    if (p.length) {
+                        this._gutter.top = parseInt(p[0], 10);
+                        if (p[1]) {
+                            this._gutter.right = parseInt(p[1], 10);
+                        } else {
+                            this._gutter.right = this._gutter.top;
+                        }
+                        if (p[2]) {
+                            this._gutter.bottom = parseInt(p[2], 10);
+                        } else {
+                            this._gutter.bottom = this._gutter.top;
+                        }
+                        if (p[3]) {
+                            this._gutter.left = parseInt(p[3], 10);
+                        } else if (p[1]) {
+                            this._gutter.left = this._gutter.right;
+                        } else {
+                            this._gutter.left = this._gutter.top;
+                        }
+                    }
+                }
+            });
+            /**
+            * @attribute parent
+            * @description The parent Layout that we are assigned to
+            * @type {Object} YAHOO.widget.Layout
+            */
+            this.setAttributeConfig('parent', {
+                writeOnce: true,
+                value: attr.parent || false,
+                method: function(p) {
+                    if (p) {
+                        p.on('resize', this.resize, this, true);
+                    }
+
+                }
+            });
+            /**
+            * @attribute collapseSize
+            * @description The pixel size of the Clip that we will collapse to
+            * @type Number
+            */
+            this.setAttributeConfig('collapseSize', {
+                value: attr.collapseSize || 25,
+                validator: YAHOO.lang.isNumber
+            });
+            /**
+            * @attribute duration
+            * @description The duration to give the Animation Utility when animating the opening and closing of Units
+            */
+            this.setAttributeConfig('duration', {
+                value: attr.duration || 0.5
+            });
+            /**
+            * @attribute easing
+            * @description The Animation Easing to apply to the Animation instance for this unit.
+            */
+            this.setAttributeConfig('easing', {
+                value: attr.easing || ((YAHOO.util && YAHOO.util.Easing) ? YAHOO.util.Easing.BounceIn : 'false')
+            });
+            /**
+            * @attribute animate
+            * @description Use animation to collapse/expand the unit
+            * @type Boolean
+            */
+            this.setAttributeConfig('animate', {
+                value: ((attr.animate === false) ? false : true),
+                validator: function() {
+                    var anim = false;
+                    if (YAHOO.util.Anim) {
+                        anim = true;
+                    }
+                    return anim;
+                },
+                method: function(anim) {
+                    if (anim) {
+                        this._anim = new YAHOO.util.Anim(this.get('element'), {}, this.get('duration'), this.get('easing'));
+                    } else {
+                        this._anim = false;
+                    }
+                }
+            });
+            /**
+            * @attribute header
+            * @description The text to use as the Header of the Unit
+            */
+            this.setAttributeConfig('header', {
+                value: attr.header || false,
+                method: function(txt) {
+                    if (txt === false) {
+                        //Remove the footer
+                        if (this.header) {
+                            Dom.addClass(this.body, 'yui-layout-bd-nohd');
+                            this.header.parentNode.removeChild(this.header);
+                            this.header = null;
+                        }
+                    } else {
+                        if (!this.header) {
+                            var header = this.getElementsByClassName('yui-layout-hd', 'div')[0];
+                            if (!header) {
+                                header = this._createHeader();
+                            }
+                            this.header = header;
+                        }
+                        var h = this.header.getElementsByTagName('h2')[0];
+                        if (!h) {
+                            h = document.createElement('h2');
+                            this.header.appendChild(h);
+                        }
+                        h.innerHTML = txt;
+                        if (this.body) {
+                            Dom.removeClass(this.body, 'yui-layout-bd-nohd');
+                        }
+                    }
+                    this.fireEvent('contentChange', { target: 'header' });
+                }
+            });
+            /**
+            * @attribute proxy
+            * @description Use the proxy config setting for the Resize Utility
+            * @type Boolean
+            */
+            this.setAttributeConfig('proxy', {
+                writeOnce: true,
+                value: ((attr.proxy === false) ? false : true)
+            });
+            /**
+            * @attribute body
+            * @description The content for the body. If we find an element in the page with an id that matches the passed option we will move that element into the body of this unit.
+            */
+            this.setAttributeConfig('body', {
+                value: attr.body || false,
+                method: function(content) {
+                    if (!this.body) {
+                        var body = this.getElementsByClassName('yui-layout-bd', 'div')[0];
+                        if (body) {
+                            this.body = body;
+                        } else {
+                            body = document.createElement('div');
+                            body.className = 'yui-layout-bd';
+                            this.body = body;
+                            this.get('wrap').appendChild(body);
+                        }
+                    }
+                    if (!this.header) {
+                        Dom.addClass(this.body, 'yui-layout-bd-nohd');
+                    }
+                    Dom.addClass(this.body, 'yui-layout-bd-noft');
+
+
+                    var el = null;
+                    if (Lang.isString(content)) {
+                        el = Dom.get(content);
+                    } else if (content && content.tagName) {
+                        el = content;
+                    }
+                    if (el) {
+                        var id = Dom.generateId(el);
+                        LayoutUnit._instances[id] = this;
+                        this.body.appendChild(el);
+                    } else {
+                        this.body.innerHTML = content;
+                    }
+
+                    this._cleanGrids();
+
+                    this.fireEvent('contentChange', { target: 'body' });
+                }
+            });
+
+            /**
+            * @attribute footer
+            * @description The content for the footer. If we find an element in the page with an id that matches the passed option we will move that element into the footer of this unit.
+            */
+            this.setAttributeConfig('footer', {
+                value: attr.footer || false,
+                method: function(content) {
+                    if (content === false) {
+                        //Remove the footer
+                        if (this.footer) {
+                            Dom.addClass(this.body, 'yui-layout-bd-noft');
+                            this.footer.parentNode.removeChild(this.footer);
+                            this.footer = null;
+                        }
+                    } else {
+                        if (!this.footer) {
+                            var ft = this.getElementsByClassName('yui-layout-ft', 'div')[0];
+                            if (!ft) {
+                                ft = document.createElement('div');
+                                ft.className = 'yui-layout-ft';
+                                this.footer = ft;
+                                this.get('wrap').appendChild(ft);
+                            } else {
+                                this.footer = ft;
+                            }
+                        }
+                        var el = null;
+                        if (Lang.isString(content)) {
+                            el = Dom.get(content);
+                        } else if (content && content.tagName) {
+                            el = content;
+                        }
+                        if (el) {
+                            this.footer.appendChild(el);
+                        } else {
+                            this.footer.innerHTML = content;
+                        }
+                        Dom.removeClass(this.body, 'yui-layout-bd-noft');
+                    }
+                    this.fireEvent('contentChange', { target: 'footer' });
+                }
+            });
+            /**
+            * @attribute close
+            * @description Adds a close icon to the unit
+            */
+            this.setAttributeConfig('close', {
+                value: attr.close || false,
+                method: function(close) {
+                    //Position Center doesn't get this
+                    if (this.get('position') == 'center') {
+                        return false;
+                    }
+                    if (!this.header) {
+                        this._createHeader();
+                    }
+                    var c = Dom.getElementsByClassName('close', 'div', this.header)[0];
+                    if (close) {
+                        if (!c) {
+                            c = document.createElement('div');
+                            c.className = 'close';
+                            this.header.appendChild(c);
+                            Event.on(c, 'click', this.close, this, true);
+                        }
+                        c.title = this.STR_CLOSE;
+                    } else if (c) {
+                        Event.purgeElement(c);
+                        c.parentNode.removeChild(c);
+                    }
+                    this._configs.close.value = close;
+                    this.set('collapse', this.get('collapse')); //Reset so we get the right classnames
+                }
+            });
+
+            /**
+            * @attribute collapse
+            * @description Adds a collapse icon to the unit
+            */
+            this.setAttributeConfig('collapse', {
+                value: attr.collapse || false,
+                method: function(collapse) {
+                    //Position Center doesn't get this
+                    if (this.get('position') == 'center') {
+                        return false;
+                    }
+                    if (!this.header) {
+                        this._createHeader();
+                    }
+                    var c = Dom.getElementsByClassName('collapse', 'div', this.header)[0];
+                    if (collapse) {
+                        if (!c) {
+                            c = document.createElement('div');
+                            this.header.appendChild(c);
+                            Event.on(c, 'click', this.collapse, this, true);
+                        }
+                        c.title = this.STR_COLLAPSE;
+                        c.className = 'collapse' + ((this.get('close')) ? ' collapse-close' : '');
+                    } else if (c) {
+                        Event.purgeElement(c);
+                        c.parentNode.removeChild(c);
+                    }
+                }
+            });
+            /**
+            * @attribute scroll
+            * @description Adds a class to the unit to allow for overflow: auto, default is overflow: hidden
+            */
+
+            this.setAttributeConfig('scroll', {
+                value: attr.scroll || false,
+                method: function(scroll) {
+                    if ((scroll === false) && !this._collapsed) { //Removing scroll bar
+                        if (this.body) {
+                            if (this.body.scrollTop > 0) {
+                                this._lastScrollTop = this.body.scrollTop;
+                            }
+                        }
+                    }
+                    
+                    if (scroll) {
+                        this.addClass('yui-layout-scroll');
+                        if (this._lastScrollTop > 0) {
+                            if (this.body) {
+                                this.body.scrollTop = this._lastScrollTop;
+                            }
+                        }
+                    } else {
+                        this.removeClass('yui-layout-scroll');
+                    }
+                }
+            });
+            /**
+            * @attribute hover
+            * @description Config option to pass to the Resize Utility
+            */
+            this.setAttributeConfig('hover', {
+                writeOnce: true,
+                value: attr.hover || false,
+                validator: YAHOO.lang.isBoolean
+            });
+            /**
+            * @attribute resize
+            * @description Should a Resize instance be added to this unit
+            */
+
+            this.setAttributeConfig('resize', {
+                value: attr.resize || false,
+                validator: function(r) {
+                    if (YAHOO.util && YAHOO.util.Resize) {
+                        return true;
+                    }
+                    return false;
+                },
+                method: function(resize) {
+                    if (resize && !this._resize) {
+                        //Position Center doesn't get this
+                        if (this.get('position') == 'center') {
+                            return false;
+                        }
+                        var handle = false; //To catch center
+                        switch (this.get('position')) {
+                            case 'top':
+                                handle = 'b';
+                                break;
+                            case 'bottom':
+                                handle = 't';
+                                break;
+                            case 'right':
+                                handle = 'l';
+                                break;
+                            case 'left':
+                                handle = 'r';
+                                break;
+                        }
+
+                        this.setStyle('position', 'absolute'); //Make sure Resize get's a position
+                        
+                        if (handle) {
+                            this._resize = new YAHOO.util.Resize(this.get('element'), {
+                                proxy: this.get('proxy'),
+                                hover: this.get('hover'),
+                                status: false,
+                                autoRatio: false,
+                                handles: [handle],
+                                minWidth: this.get('minWidth'),
+                                maxWidth: this.get('maxWidth'),
+                                minHeight: this.get('minHeight'),
+                                maxHeight: this.get('maxHeight'),
+                                height: this.get('height'),
+                                width: this.get('width'),
+                                setSize: false
+                            });
+                            
+                            this._resize._handles[handle].innerHTML = '<div class="yui-layout-resize-knob"></div>';
+
+                            if (this.get('proxy')) {
+                                var proxy = this._resize.getProxyEl();
+                                proxy.innerHTML = '<div class="yui-layout-handle-' + handle + '"></div>';
+                            }
+                            this._resize.on('startResize', function(ev) {
+                                this._lastScroll = this.get('scroll');
+                                this.set('scroll', false);
+                                if (this.get('parent')) {
+                                    this.get('parent').fireEvent('startResize');
+                                    var c = this.get('parent').getUnitByPosition('center');
+                                    this._lastCenterScroll = c.get('scroll');
+                                    c.set('scroll', false);
+                                }
+                                this.fireEvent('startResize');
+                            }, this, true);
+                            this._resize.on('resize', function(ev) {
+                                this.set('height', ev.height);
+                                this.set('width', ev.width);
+                                this.set('scroll', this._lastScroll);
+                                if (this.get('parent')) {
+                                    var c = this.get('parent').getUnitByPosition('center');
+                                    c.set('scroll', this._lastCenterScroll);
+                                }
+                            }, this, true);
+                        }
+                    } else {
+                        if (this._resize) {
+                            this._resize.destroy();
+                        }
+                    }
+                }
+            });
+        },
+        /**
+        * @private
+        * @method _cleanGrids
+        * @description This method attempts to clean up the first level of the YUI CSS Grids, YAHOO.util.Selector is required for this operation.
+        */
+        _cleanGrids: function() {
+            if (this.get('grids')) {
+                var b = Sel.query('div.yui-b', this.body, true);
+                if (b) {
+                    Dom.removeClass(b, 'yui-b');
+                }
+                Event.onAvailable('yui-main', function() {
+                    Dom.setStyle(Sel.query('#yui-main'), 'margin-left', '0');
+                    Dom.setStyle(Sel.query('#yui-main'), 'margin-right', '0');
+                });
+            }
+        },
+        /**
+        * @private
+        * @method _createHeader
+        * @description Creates the HTMLElement for the header
+        * @return {HTMLElement} The new HTMLElement
+        */
+        _createHeader: function() {
+            var header = document.createElement('div');
+            header.className = 'yui-layout-hd';
+            if (this.get('firstChild')) {
+                this.get('wrap').insertBefore(header, this.get('wrap').firstChild);
+            } else {
+                this.get('wrap').appendChild(header);
+            }
+            this.header = header;
+            return header;
+        },
+        /**
+        * @method destroy
+        * @description Removes this unit from the parent and cleans up after itself.
+        * @return {<a href="YAHOO.widget.Layout.html">YAHOO.widget.Layout</a>} The parent Layout instance
+        */
+        destroy: function() {
+            if (this._resize) {
+                this._resize.destroy();
+            }
+            var par = this.get('parent');
+
+            this.setStyle('display', 'none');
+            par.removeUnit(this);
+            if (this._clip) {
+                this._clip.parentNode.removeChild(this._clip);
+                this._clip = null;
+            }
+
+            Event.purgeElement(this.get('element'));
+            this.get('parentNode').removeChild(this.get('element'));
+
+            delete YAHOO.widget.LayoutUnit._instances[this.get('id')];
+            //Brutal Object Destroy
+            for (var i in this) {
+                if (Lang.hasOwnProperty(this, i)) {
+                    this[i] = null;
+                    delete this[i];
+                }
+            }
+        
+            return par;
+        },
+        /**
+        * @method toString
+        * @description Returns a string representing the LayoutUnit.
+        * @return {String}
+        */        
+        toString: function() {
+            if (this.get) {
+                return 'LayoutUnit #' + this.get('id') + ' (' + this.get('position') + ')';
+            }
+            return 'LayoutUnit';
+        }
+    /**
+    * @event resize
+    * @description Fired when this.resize is called
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event startResize
+    * @description Fired when the Resize Utility fires it's startResize Event.
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event beforeResize
+    * @description Firef at the beginning of the resize method. If you return false, the resize is cancelled.
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event contentChange
+    * @description Fired when the content in the header, body or footer is changed via the API
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event close
+    * @description Fired when the unit is closed
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event beforeCollapse
+    * @description Fired before the unit is collapsed. If you return false, the collapse is cancelled.
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event collapse
+    * @description Fired when the unit is collapsed
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event expand
+    * @description Fired when the unit is exanded
+    * @type YAHOO.util.CustomEvent
+    */
+    /**
+    * @event beforeExpand
+    * @description Fired before the unit is exanded. If you return false, the collapse is cancelled.
+    * @type YAHOO.util.CustomEvent
+    */
+    });
+
+    YAHOO.widget.LayoutUnit = LayoutUnit;
+})();
+YAHOO.register("layout", YAHOO.widget.Layout, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/logger/README
===================================================================
--- trunk/root/static/yui/logger/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/logger/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,18 @@
 Logger Release Notes
 
-*** version 2.4.1 ***
-No change
+*** version 2.5.1 ***
 
+* Support object introspection to Firebug.
+* Better performance when rendering messages to LogReader.
+
+
+
+*** version 2.5.0 ***
+
+* No changes.
+
+
+
 *** version 2.4.0 ***
 
 * Global window error event no longer being handled by default. Implemented

Modified: trunk/root/static/yui/logger/assets/logger-core.css
===================================================================
--- trunk/root/static/yui/logger/assets/logger-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/logger/assets/logger-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-/* This file intentionally left blank */
+/* This file intentionally left blank */

Modified: trunk/root/static/yui/logger/assets/logger.css
===================================================================
--- trunk/root/static/yui/logger/assets/logger.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/logger/assets/logger.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* logger default styles */
 /* default width: 31em */

Modified: trunk/root/static/yui/logger/assets/skins/sam/logger-skin.css
===================================================================
--- trunk/root/static/yui/logger/assets/skins/sam/logger-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/logger/assets/skins/sam/logger-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* logger default styles */
 /* default width: 31em */

Modified: trunk/root/static/yui/logger/assets/skins/sam/logger.css
===================================================================
--- trunk/root/static/yui/logger/assets/skins/sam/logger.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/logger/assets/skins/sam/logger.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-skin-sam .yui-log{padding:1em;width:31em;background-color:#AAA;color:#000;border:1px solid black;font-family:monospace;font-size:77%;text-align:left;z-index:9000;}.yui-skin-sam .yui-log-container{position:absolute;top:1em;right:1em;}.yui-skin-sam .yui-log input{margin:0;padding:0;font-family:arial;font-size:100%;font-weight:normal;}.yui-skin-sam .yui-log .yui-log-btns{position:relative;float:right;bottom:.25em;}.yui-skin-sam .yui-log .yui-log-hd{margin-top:1em;padding:.5em;background-color:#575757;}.yui-skin-sam .yui-log .yui-log-hd h4{margin:0;padding:0;font-size:108%;font-weight:bold;color:#FFF;}.yui-skin-sam .yui-log .yui-log-bd{width:100%;height:20em;background-color:#FFF;border:1px solid gray;overflow:auto;}.yui-skin-sam .yui-log p{margin:1px;padding:.1em;}.yui-skin-sam .yui-log pre{margin:0;padding:0;}.yui-skin-sam .yui-log pre.yui-log-verbose{white-space:pre-wrap;white-space:-moz-pre-wrap !important;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-w!
 ord;}.yui-skin-sam .yui-log .yui-log-ft{margin-top:.5em;}.yui-skin-sam .yui-log .yui-log-ft .yui-log-categoryfilters{}.yui-skin-sam .yui-log .yui-log-ft .yui-log-sourcefilters{width:100%;border-top:1px solid #575757;margin-top:.75em;padding-top:.75em;}.yui-skin-sam .yui-log .yui-log-filtergrp{margin-right:.5em;}.yui-skin-sam .yui-log .info{background-color:#A7CC25;}.yui-skin-sam .yui-log .warn{background-color:#F58516;}.yui-skin-sam .yui-log .error{background-color:#E32F0B;}.yui-skin-sam .yui-log .time{background-color:#A6C9D7;}.yui-skin-sam .yui-log .window{background-color:#F2E886;}

Modified: trunk/root/static/yui/logger/logger-debug.js
===================================================================
--- trunk/root/static/yui/logger/logger-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/logger/logger-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /****************************************************************************/
 /****************************************************************************/
@@ -15,63 +15,55 @@
  * @constructor
  * @param oConfigs {Object} Object literal of configuration params.
  */
- YAHOO.widget.LogMsg = function(oConfigs) {
+YAHOO.widget.LogMsg = function(oConfigs) {
     // Parse configs
+    /**
+     * Log message.
+     *
+     * @property msg
+     * @type String
+     */
+    this.msg =
+    /**
+     * Log timestamp.
+     *
+     * @property time
+     * @type Date
+     */
+    this.time =
+
+    /**
+     * Log category.
+     *
+     * @property category
+     * @type String
+     */
+    this.category =
+
+    /**
+     * Log source. The first word passed in as the source argument.
+     *
+     * @property source
+     * @type String
+     */
+    this.source =
+
+    /**
+     * Log source detail. The remainder of the string passed in as the source argument, not
+     * including the first word (if any).
+     *
+     * @property sourceDetail
+     * @type String
+     */
+    this.sourceDetail = null;
+
     if (oConfigs && (oConfigs.constructor == Object)) {
         for(var param in oConfigs) {
             this[param] = oConfigs[param];
         }
     }
- };
- 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public member variables
-//
-/////////////////////////////////////////////////////////////////////////////
+};
 
-/**
- * Log message.
- *
- * @property msg
- * @type String
- */
-YAHOO.widget.LogMsg.prototype.msg = null;
- 
-/**
- * Log timestamp.
- *
- * @property time
- * @type Date
- */
-YAHOO.widget.LogMsg.prototype.time = null;
-
-/**
- * Log category.
- *
- * @property category
- * @type String
- */
-YAHOO.widget.LogMsg.prototype.category = null;
-
-/**
- * Log source. The first word passed in as the source argument.
- *
- * @property source
- * @type String
- */
-YAHOO.widget.LogMsg.prototype.source = null;
-
-/**
- * Log source detail. The remainder of the string passed in as the source argument, not
- * including the first word (if any).
- *
- * @property sourceDetail
- * @type String
- */
-YAHOO.widget.LogMsg.prototype.sourceDetail = null;
-
-
 /****************************************************************************/
 /****************************************************************************/
 /****************************************************************************/
@@ -222,1286 +214,1342 @@
 
 /////////////////////////////////////////////////////////////////////////////
 //
+// Static member variables
+//
+/////////////////////////////////////////////////////////////////////////////
+YAHOO.lang.augmentObject(YAHOO.widget.LogReader, {
+    /**
+     * Internal class member to index multiple LogReader instances.
+     *
+     * @property _memberName
+     * @static
+     * @type Number
+     * @default 0
+     * @private
+     */
+    _index : 0,
+
+    /**
+     * Node template for the log entries
+     * @property ENTRY_TEMPLATE
+     * @static
+     * @type {HTMLElement}
+     * @default PRE.yui-log-entry element
+     */
+    ENTRY_TEMPLATE : (function () {
+        var t = document.createElement('pre');
+        YAHOO.util.Dom.addClass(t,'yui-log-entry');
+        return t;
+    })(),
+
+    /**
+     * Template used for innerHTML of verbose entry output.
+     * @property VERBOSE_TEMPLATE
+     * @static
+     * @default "<span class='{category}'>{label}</span>{totalTime}ms (+{elapsedTime}) {localTime}:</p><p>{sourceAndDetail}</p><p>{message}</p>"
+     */
+    VERBOSE_TEMPLATE : "<span class='{category}'>{label}</span>{totalTime}ms (+{elapsedTime}) {localTime}:</p><p>{sourceAndDetail}</p><p>{message}</p>",
+
+    /**
+     * Template used for innerHTML of compact entry output.
+     * @property BASIC_TEMPLATE
+     * @static
+     * @default "<p><span class='{category}'>{label}</span>{totalTime}ms (+{elapsedTime}) {localTime}: {sourceAndDetail}: {message}</p>"
+     */
+    BASIC_TEMPLATE : "<p><span class='{category}'>{label}</span>{totalTime}ms (+{elapsedTime}) {localTime}: {sourceAndDetail}: {message}</p>"
+});
+
+/////////////////////////////////////////////////////////////////////////////
+//
 // Public member variables
 //
 /////////////////////////////////////////////////////////////////////////////
 
-/**
- * Whether or not LogReader is enabled to output log messages.
- *
- * @property logReaderEnabled
- * @type Boolean
- * @default true
- */
-YAHOO.widget.LogReader.prototype.logReaderEnabled = true;
+YAHOO.widget.LogReader.prototype = {
+    /**
+     * Whether or not LogReader is enabled to output log messages.
+     *
+     * @property logReaderEnabled
+     * @type Boolean
+     * @default true
+     */
+    logReaderEnabled : true,
 
-/**
- * Public member to access CSS width of the LogReader container.
- *
- * @property width
- * @type String
- */
-YAHOO.widget.LogReader.prototype.width = null;
+    /**
+     * Public member to access CSS width of the LogReader container.
+     *
+     * @property width
+     * @type String
+     */
+    width : null,
 
-/**
- * Public member to access CSS height of the LogReader container.
- *
- * @property height
- * @type String
- */
-YAHOO.widget.LogReader.prototype.height = null;
+    /**
+     * Public member to access CSS height of the LogReader container.
+     *
+     * @property height
+     * @type String
+     */
+    height : null,
 
-/**
- * Public member to access CSS top position of the LogReader container.
- *
- * @property top
- * @type String
- */
-YAHOO.widget.LogReader.prototype.top = null;
+    /**
+     * Public member to access CSS top position of the LogReader container.
+     *
+     * @property top
+     * @type String
+     */
+    top : null,
 
-/**
- * Public member to access CSS left position of the LogReader container.
- *
- * @property left
- * @type String
- */
-YAHOO.widget.LogReader.prototype.left = null;
+    /**
+     * Public member to access CSS left position of the LogReader container.
+     *
+     * @property left
+     * @type String
+     */
+    left : null,
 
-/**
- * Public member to access CSS right position of the LogReader container.
- *
- * @property right
- * @type String
- */
-YAHOO.widget.LogReader.prototype.right = null;
+    /**
+     * Public member to access CSS right position of the LogReader container.
+     *
+     * @property right
+     * @type String
+     */
+    right : null,
 
-/**
- * Public member to access CSS bottom position of the LogReader container.
- *
- * @property bottom
- * @type String
- */
-YAHOO.widget.LogReader.prototype.bottom = null;
+    /**
+     * Public member to access CSS bottom position of the LogReader container.
+     *
+     * @property bottom
+     * @type String
+     */
+    bottom : null,
 
-/**
- * Public member to access CSS font size of the LogReader container.
- *
- * @property fontSize
- * @type String
- */
-YAHOO.widget.LogReader.prototype.fontSize = null;
+    /**
+     * Public member to access CSS font size of the LogReader container.
+     *
+     * @property fontSize
+     * @type String
+     */
+    fontSize : null,
 
-/**
- * Whether or not the footer UI is enabled for the LogReader.
- *
- * @property footerEnabled
- * @type Boolean
- * @default true
- */
-YAHOO.widget.LogReader.prototype.footerEnabled = true;
+    /**
+     * Whether or not the footer UI is enabled for the LogReader.
+     *
+     * @property footerEnabled
+     * @type Boolean
+     * @default true
+     */
+    footerEnabled : true,
 
-/**
- * Whether or not output is verbose (more readable). Setting to true will make
- * output more compact (less readable).
- *
- * @property verboseOutput
- * @type Boolean
- * @default true
- */
-YAHOO.widget.LogReader.prototype.verboseOutput = true;
+    /**
+     * Whether or not output is verbose (more readable). Setting to true will make
+     * output more compact (less readable).
+     *
+     * @property verboseOutput
+     * @type Boolean
+     * @default true
+     */
+    verboseOutput : true,
 
-/**
- * Whether or not newest message is printed on top.
- *
- * @property newestOnTop
- * @type Boolean
- */
-YAHOO.widget.LogReader.prototype.newestOnTop = true;
+    /**
+     * Custom output format for log messages.  Defaults to null, which falls
+     * back to verboseOutput param deciding between LogReader.VERBOSE_TEMPLATE
+     * and LogReader.BASIC_TEMPLATE.  Use bracketed place holders to mark where
+     * message info should go.  Available place holder names include:
+     * <ul>
+     *  <li>category</li>
+     *  <li>label</li>
+     *  <li>sourceAndDetail</li>
+     *  <li>message</li>
+     *  <li>localTime</li>
+     *  <li>elapsedTime</li>
+     *  <li>totalTime</li>
+     * </ul>
+     *
+     * @property entryFormat
+     * @type String
+     * @default null
+     */
+    entryFormat : null,
 
-/**
- * Output timeout buffer in milliseconds.
- *
- * @property outputBuffer
- * @type Number
- * @default 100
- */
-YAHOO.widget.LogReader.prototype.outputBuffer = 100;
+    /**
+     * Whether or not newest message is printed on top.
+     *
+     * @property newestOnTop
+     * @type Boolean
+     */
+    newestOnTop : true,
 
-/**
- * Maximum number of messages a LogReader console will display.
- *
- * @property thresholdMax
- * @type Number
- * @default 500
- */
-YAHOO.widget.LogReader.prototype.thresholdMax = 500;
+    /**
+     * Output timeout buffer in milliseconds.
+     *
+     * @property outputBuffer
+     * @type Number
+     * @default 100
+     */
+    outputBuffer : 100,
 
-/**
- * When a LogReader console reaches its thresholdMax, it will clear out messages
- * and print out the latest thresholdMin number of messages.
- *
- * @property thresholdMin
- * @type Number
- * @default 100
- */
-YAHOO.widget.LogReader.prototype.thresholdMin = 100;
+    /**
+     * Maximum number of messages a LogReader console will display.
+     *
+     * @property thresholdMax
+     * @type Number
+     * @default 500
+     */
+    thresholdMax : 500,
 
-/**
- * True when LogReader is in a collapsed state, false otherwise.
- *
- * @property isCollapsed
- * @type Boolean
- * @default false
- */
-YAHOO.widget.LogReader.prototype.isCollapsed = false;
+    /**
+     * When a LogReader console reaches its thresholdMax, it will clear out messages
+     * and print out the latest thresholdMin number of messages.
+     *
+     * @property thresholdMin
+     * @type Number
+     * @default 100
+     */
+    thresholdMin : 100,
 
-/**
- * True when LogReader is in a paused state, false otherwise.
- *
- * @property isPaused
- * @type Boolean
- * @default false
- */
-YAHOO.widget.LogReader.prototype.isPaused = false;
+    /**
+     * True when LogReader is in a collapsed state, false otherwise.
+     *
+     * @property isCollapsed
+     * @type Boolean
+     * @default false
+     */
+    isCollapsed : false,
 
-/**
- * Enables draggable LogReader if DragDrop Utility is present.
- *
- * @property draggable
- * @type Boolean
- * @default true
- */
-YAHOO.widget.LogReader.prototype.draggable = true;
+    /**
+     * True when LogReader is in a paused state, false otherwise.
+     *
+     * @property isPaused
+     * @type Boolean
+     * @default false
+     */
+    isPaused : false,
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public methods
-//
-/////////////////////////////////////////////////////////////////////////////
+    /**
+     * Enables draggable LogReader if DragDrop Utility is present.
+     *
+     * @property draggable
+     * @type Boolean
+     * @default true
+     */
+    draggable : true,
 
- /**
- * Public accessor to the unique name of the LogReader instance.
- *
- * @method toString
- * @return {String} Unique name of the LogReader instance.
- */
-YAHOO.widget.LogReader.prototype.toString = function() {
-    return "LogReader instance" + this._sName;
-};
-/**
- * Pauses output of log messages. While paused, log messages are not lost, but
- * get saved to a buffer and then output upon resume of LogReader.
- *
- * @method pause
- */
-YAHOO.widget.LogReader.prototype.pause = function() {
-    this.isPaused = true;
-    this._btnPause.value = "Resume";
-    this._timeout = null;
-    this.logReaderEnabled = false;
-};
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
 
-/**
- * Resumes output of log messages, including outputting any log messages that
- * have been saved to buffer while paused.
- *
- * @method resume
- */
-YAHOO.widget.LogReader.prototype.resume = function() {
-    this.isPaused = false;
-    this._btnPause.value = "Pause";
-    this.logReaderEnabled = true;
-    this._printBuffer();
-};
+     /**
+     * Public accessor to the unique name of the LogReader instance.
+     *
+     * @method toString
+     * @return {String} Unique name of the LogReader instance.
+     */
+    toString : function() {
+        return "LogReader instance" + this._sName;
+    },
+    /**
+     * Pauses output of log messages. While paused, log messages are not lost, but
+     * get saved to a buffer and then output upon resume of LogReader.
+     *
+     * @method pause
+     */
+    pause : function() {
+        this.isPaused = true;
+        this._btnPause.value = "Resume";
+        this._timeout = null;
+        this.logReaderEnabled = false;
+    },
 
-/**
- * Hides UI of LogReader. Logging functionality is not disrupted.
- *
- * @method hide
- */
-YAHOO.widget.LogReader.prototype.hide = function() {
-    this._elContainer.style.display = "none";
-};
+    /**
+     * Resumes output of log messages, including outputting any log messages that
+     * have been saved to buffer while paused.
+     *
+     * @method resume
+     */
+    resume : function() {
+        this.isPaused = false;
+        this._btnPause.value = "Pause";
+        this.logReaderEnabled = true;
+        this._printBuffer();
+    },
 
-/**
- * Shows UI of LogReader. Logging functionality is not disrupted.
- *
- * @method show
- */
-YAHOO.widget.LogReader.prototype.show = function() {
-    this._elContainer.style.display = "block";
-};
+    /**
+     * Hides UI of LogReader. Logging functionality is not disrupted.
+     *
+     * @method hide
+     */
+    hide : function() {
+        this._elContainer.style.display = "none";
+    },
 
-/**
- * Collapses UI of LogReader. Logging functionality is not disrupted.
- *
- * @method collapse
- */
-YAHOO.widget.LogReader.prototype.collapse = function() {
-    this._elConsole.style.display = "none";
-    if(this._elFt) {
-        this._elFt.style.display = "none";
-    }
-    this._btnCollapse.value = "Expand";
-    this.isCollapsed = true;
-};
+    /**
+     * Shows UI of LogReader. Logging functionality is not disrupted.
+     *
+     * @method show
+     */
+    show : function() {
+        this._elContainer.style.display = "block";
+    },
 
-/**
- * Expands UI of LogReader. Logging functionality is not disrupted.
- *
- * @method expand
- */
-YAHOO.widget.LogReader.prototype.expand = function() {
-    this._elConsole.style.display = "block";
-    if(this._elFt) {
-        this._elFt.style.display = "block";
-    }
-    this._btnCollapse.value = "Collapse";
-    this.isCollapsed = false;
-};
+    /**
+     * Collapses UI of LogReader. Logging functionality is not disrupted.
+     *
+     * @method collapse
+     */
+    collapse : function() {
+        this._elConsole.style.display = "none";
+        if(this._elFt) {
+            this._elFt.style.display = "none";
+        }
+        this._btnCollapse.value = "Expand";
+        this.isCollapsed = true;
+    },
 
-/**
- * Returns related checkbox element for given filter (i.e., category or source).
- *
- * @method getCheckbox
- * @param {String} Category or source name.
- * @return {Array} Array of all filter checkboxes.
- */
-YAHOO.widget.LogReader.prototype.getCheckbox = function(filter) {
-    return this._filterCheckboxes[filter];
-};
+    /**
+     * Expands UI of LogReader. Logging functionality is not disrupted.
+     *
+     * @method expand
+     */
+    expand : function() {
+        this._elConsole.style.display = "block";
+        if(this._elFt) {
+            this._elFt.style.display = "block";
+        }
+        this._btnCollapse.value = "Collapse";
+        this.isCollapsed = false;
+    },
 
-/**
- * Returns array of enabled categories.
- *
- * @method getCategories
- * @return {String[]} Array of enabled categories.
- */
-YAHOO.widget.LogReader.prototype.getCategories = function() {
-    return this._categoryFilters;
-};
+    /**
+     * Returns related checkbox element for given filter (i.e., category or source).
+     *
+     * @method getCheckbox
+     * @param {String} Category or source name.
+     * @return {Array} Array of all filter checkboxes.
+     */
+    getCheckbox : function(filter) {
+        return this._filterCheckboxes[filter];
+    },
 
-/**
- * Shows log messages associated with given category.
- *
- * @method showCategory
- * @param {String} Category name.
- */
-YAHOO.widget.LogReader.prototype.showCategory = function(sCategory) {
-    var filtersArray = this._categoryFilters;
-    // Don't do anything if category is already enabled
-    // Use Array.indexOf if available...
-    if(filtersArray.indexOf) {
-         if(filtersArray.indexOf(sCategory) >  -1) {
-            return;
-        }
-    }
-    // ...or do it the old-fashioned way
-    else {
-        for(var i=0; i<filtersArray.length; i++) {
-           if(filtersArray[i] === sCategory){
+    /**
+     * Returns array of enabled categories.
+     *
+     * @method getCategories
+     * @return {String[]} Array of enabled categories.
+     */
+    getCategories : function() {
+        return this._categoryFilters;
+    },
+
+    /**
+     * Shows log messages associated with given category.
+     *
+     * @method showCategory
+     * @param {String} Category name.
+     */
+    showCategory : function(sCategory) {
+        var filtersArray = this._categoryFilters;
+        // Don't do anything if category is already enabled
+        // Use Array.indexOf if available...
+        if(filtersArray.indexOf) {
+             if(filtersArray.indexOf(sCategory) >  -1) {
                 return;
             }
         }
-    }
+        // ...or do it the old-fashioned way
+        else {
+            for(var i=0; i<filtersArray.length; i++) {
+               if(filtersArray[i] === sCategory){
+                    return;
+                }
+            }
+        }
 
-    this._categoryFilters.push(sCategory);
-    this._filterLogs();
-    var elCheckbox = this.getCheckbox(sCategory);
-    if(elCheckbox) {
-        elCheckbox.checked = true;
-    }
-};
+        this._categoryFilters.push(sCategory);
+        this._filterLogs();
+        var elCheckbox = this.getCheckbox(sCategory);
+        if(elCheckbox) {
+            elCheckbox.checked = true;
+        }
+    },
 
-/**
- * Hides log messages associated with given category.
- *
- * @method hideCategory
- * @param {String} Category name.
- */
-YAHOO.widget.LogReader.prototype.hideCategory = function(sCategory) {
-    var filtersArray = this._categoryFilters;
-    for(var i=0; i<filtersArray.length; i++) {
-        if(sCategory == filtersArray[i]) {
-            filtersArray.splice(i, 1);
-            break;
+    /**
+     * Hides log messages associated with given category.
+     *
+     * @method hideCategory
+     * @param {String} Category name.
+     */
+    hideCategory : function(sCategory) {
+        var filtersArray = this._categoryFilters;
+        for(var i=0; i<filtersArray.length; i++) {
+            if(sCategory == filtersArray[i]) {
+                filtersArray.splice(i, 1);
+                break;
+            }
         }
-    }
-    this._filterLogs();
-    var elCheckbox = this.getCheckbox(sCategory);
-    if(elCheckbox) {
-        elCheckbox.checked = false;
-    }
-};
+        this._filterLogs();
+        var elCheckbox = this.getCheckbox(sCategory);
+        if(elCheckbox) {
+            elCheckbox.checked = false;
+        }
+    },
 
-/**
- * Returns array of enabled sources.
- *
- * @method getSources
- * @return {Array} Array of enabled sources.
- */
-YAHOO.widget.LogReader.prototype.getSources = function() {
-    return this._sourceFilters;
-};
+    /**
+     * Returns array of enabled sources.
+     *
+     * @method getSources
+     * @return {Array} Array of enabled sources.
+     */
+    getSources : function() {
+        return this._sourceFilters;
+    },
 
-/**
- * Shows log messages associated with given source.
- *
- * @method showSource
- * @param {String} Source name.
- */
-YAHOO.widget.LogReader.prototype.showSource = function(sSource) {
-    var filtersArray = this._sourceFilters;
-    // Don't do anything if category is already enabled
-    // Use Array.indexOf if available...
-    if(filtersArray.indexOf) {
-         if(filtersArray.indexOf(sSource) >  -1) {
-            return;
-        }
-    }
-    // ...or do it the old-fashioned way
-    else {
-        for(var i=0; i<filtersArray.length; i++) {
-           if(sSource == filtersArray[i]){
+    /**
+     * Shows log messages associated with given source.
+     *
+     * @method showSource
+     * @param {String} Source name.
+     */
+    showSource : function(sSource) {
+        var filtersArray = this._sourceFilters;
+        // Don't do anything if category is already enabled
+        // Use Array.indexOf if available...
+        if(filtersArray.indexOf) {
+             if(filtersArray.indexOf(sSource) >  -1) {
                 return;
             }
         }
-    }
-    filtersArray.push(sSource);
-    this._filterLogs();
-    var elCheckbox = this.getCheckbox(sSource);
-    if(elCheckbox) {
-        elCheckbox.checked = true;
-    }
-};
+        // ...or do it the old-fashioned way
+        else {
+            for(var i=0; i<filtersArray.length; i++) {
+               if(sSource == filtersArray[i]){
+                    return;
+                }
+            }
+        }
+        filtersArray.push(sSource);
+        this._filterLogs();
+        var elCheckbox = this.getCheckbox(sSource);
+        if(elCheckbox) {
+            elCheckbox.checked = true;
+        }
+    },
 
-/**
- * Hides log messages associated with given source.
- *
- * @method hideSource
- * @param {String} Source name.
- */
-YAHOO.widget.LogReader.prototype.hideSource = function(sSource) {
-    var filtersArray = this._sourceFilters;
-    for(var i=0; i<filtersArray.length; i++) {
-        if(sSource == filtersArray[i]) {
-            filtersArray.splice(i, 1);
-            break;
+    /**
+     * Hides log messages associated with given source.
+     *
+     * @method hideSource
+     * @param {String} Source name.
+     */
+    hideSource : function(sSource) {
+        var filtersArray = this._sourceFilters;
+        for(var i=0; i<filtersArray.length; i++) {
+            if(sSource == filtersArray[i]) {
+                filtersArray.splice(i, 1);
+                break;
+            }
         }
-    }
-    this._filterLogs();
-    var elCheckbox = this.getCheckbox(sSource);
-    if(elCheckbox) {
-        elCheckbox.checked = false;
-    }
-};
+        this._filterLogs();
+        var elCheckbox = this.getCheckbox(sSource);
+        if(elCheckbox) {
+            elCheckbox.checked = false;
+        }
+    },
 
-/**
- * Does not delete any log messages, but clears all printed log messages from
- * the console. Log messages will be printed out again if user re-filters. The
- * static method YAHOO.widget.Logger.reset() should be called in order to
- * actually delete log messages.
- *
- * @method clearConsole
- */
-YAHOO.widget.LogReader.prototype.clearConsole = function() {
-    // Clear the buffer of any pending messages
-    this._timeout = null;
-    this._buffer = [];
-    this._consoleMsgCount = 0;
+    /**
+     * Does not delete any log messages, but clears all printed log messages from
+     * the console. Log messages will be printed out again if user re-filters. The
+     * static method YAHOO.widget.Logger.reset() should be called in order to
+     * actually delete log messages.
+     *
+     * @method clearConsole
+     */
+    clearConsole : function() {
+        // Clear the buffer of any pending messages
+        this._timeout = null;
+        this._buffer = [];
+        this._consoleMsgCount = 0;
 
-    var elConsole = this._elConsole;
-    while(elConsole.hasChildNodes()) {
-        elConsole.removeChild(elConsole.firstChild);
-    }
-};
+        var elConsole = this._elConsole;
+        elConsole.innerHTML = '';
+    },
 
-/**
- * Updates title to given string.
- *
- * @method setTitle
- * @param sTitle {String} New title.
- */
-YAHOO.widget.LogReader.prototype.setTitle = function(sTitle) {
-    this._title.innerHTML = this.html2Text(sTitle);
-};
+    /**
+     * Updates title to given string.
+     *
+     * @method setTitle
+     * @param sTitle {String} New title.
+     */
+    setTitle : function(sTitle) {
+        this._title.innerHTML = this.html2Text(sTitle);
+    },
 
-/**
- * Gets timestamp of the last log.
- *
- * @method getLastTime
- * @return {Date} Timestamp of the last log.
- */
-YAHOO.widget.LogReader.prototype.getLastTime = function() {
-    return this._lastTime;
-};
+    /**
+     * Gets timestamp of the last log.
+     *
+     * @method getLastTime
+     * @return {Date} Timestamp of the last log.
+     */
+    getLastTime : function() {
+        return this._lastTime;
+    },
 
-/**
- * Formats message string to HTML for output to console.
- *
- * @method formatMsg
- * @param oLogMsg {Object} Log message object.
- * @return {String} HTML-formatted message for output to console.
- */
-YAHOO.widget.LogReader.prototype.formatMsg = function(oLogMsg) {
-    var category = oLogMsg.category;
-    
-    // Label for color-coded display
-    var label = category.substring(0,4).toUpperCase();
+    formatMsg : function (entry) {
+        var Static      = YAHOO.widget.LogReader,
+            entryFormat = this.entryFormat || (this.verboseOutput ?
+                          Static.VERBOSE_TEMPLATE : Static.BASIC_TEMPLATE),
+            info        = {
+                category : entry.category,
 
-    // Calculate the elapsed time to be from the last item that passed through the filter,
-    // not the absolute previous item in the stack
+                // Label for color-coded display
+                label : entry.category.substring(0,4).toUpperCase(),
 
-    var time = oLogMsg.time;
-    var localTime;
-    if (time.toLocaleTimeString) {
-        localTime  = time.toLocaleTimeString();
-    }
-    else {
-        localTime = time.toString();
-    }
+                sourceAndDetail : entry.sourceDetail ?
+                                  entry.source + " " + entry.sourceDetail :
+                                  entry.source,
 
-    var msecs = time.getTime();
-    var startTime = YAHOO.widget.Logger.getStartTime();
-    var totalTime = msecs - startTime;
-    var elapsedTime = msecs - this.getLastTime();
+                // Escape HTML entities in the log message itself for output
+                // to console
+                message : this.html2Text(entry.msg || entry.message || '')
+            };
 
-    var source = oLogMsg.source;
-    var sourceDetail = oLogMsg.sourceDetail;
-    var sourceAndDetail = (sourceDetail) ?
-        source + " " + sourceDetail : source;
-        
-    
-    // Escape HTML entities in the log message itself for output to console
-    //var msg = this.html2Text(oLogMsg.msg); //TODO: delete
-    var msg = this.html2Text(YAHOO.lang.dump(oLogMsg.msg));
+        // Add time info
+        if (entry.time && entry.time.getTime) {
+            info.localTime = entry.time.toLocaleTimeString ?
+                             entry.time.toLocaleTimeString() :
+                             entry.time.toString();
 
-    // Verbose output includes extra line breaks
-    var output =  (this.verboseOutput) ?
-        ["<pre class=\"yui-log-verbose\"><p><span class='", category, "'>", label, "</span> ",
-        totalTime, "ms (+", elapsedTime, ") ",
-        localTime, ": ",
-        "</p><p>",
-        sourceAndDetail,
-        ": </p><p>",
-        msg,
-        "</p></pre>"] :
+            // Calculate the elapsed time to be from the last item that
+            // passed through the filter, not the absolute previous item
+            // in the stack
+            info.elapsedTime = entry.time.getTime() - this.getLastTime();
 
-        ["<pre><p><span class='", category, "'>", label, "</span> ",
-        totalTime, "ms (+", elapsedTime, ") ",
-        localTime, ": ",
-        sourceAndDetail, ": ",
-        msg, "</p></pre>"];
+            info.totalTime = entry.time.getTime() -
+                               YAHOO.widget.Logger.getStartTime();
+        }
 
-    return output.join("");
-};
+        var msg = Static.ENTRY_TEMPLATE.cloneNode(true);
+        if (this.verboseOutput) {
+            msg.className += ' yui-log-verbose';
+        }
 
-/**
- * Converts input chars "<", ">", and "&" to HTML entities.
- *
- * @method html2Text
- * @param sHtml {String} String to convert.
- * @private
- */
-YAHOO.widget.LogReader.prototype.html2Text = function(sHtml) {
-    if(sHtml) {
-        sHtml += "";
-        return sHtml.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
-    }
-    return "";
-};
+        msg.innerHTML = YAHOO.lang.substitute(entryFormat, info);
 
+        return msg;
+    },
+
+    /**
+     * Converts input chars "<", ">", and "&" to HTML entities.
+     *
+     * @method html2Text
+     * @param sHtml {String} String to convert.
+     * @private
+     */
+    html2Text : function(sHtml) {
+        if(sHtml) {
+            sHtml += "";
+            return sHtml.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
+        }
+        return "";
+    },
+
 /////////////////////////////////////////////////////////////////////////////
 //
 // Private member variables
 //
 /////////////////////////////////////////////////////////////////////////////
 
-/**
- * Internal class member to index multiple LogReader instances.
- *
- * @property _memberName
- * @static
- * @type Number
- * @default 0
- * @private
- */
-YAHOO.widget.LogReader._index = 0;
+    /**
+     * Name of LogReader instance.
+     *
+     * @property _sName
+     * @type String
+     * @private
+     */
+    _sName : null,
 
-/**
- * Name of LogReader instance.
- *
- * @property _sName
- * @type String
- * @private
- */
-YAHOO.widget.LogReader.prototype._sName = null;
+    //TODO: remove
+    /**
+     * A class member shared by all LogReaders if a container needs to be
+     * created during instantiation. Will be null if a container element never needs to
+     * be created on the fly, such as when the implementer passes in their own element.
+     *
+     * @property _elDefaultContainer
+     * @type HTMLElement
+     * @private
+     */
+    //YAHOO.widget.LogReader._elDefaultContainer = null;
 
-//TODO: remove
-/**
- * A class member shared by all LogReaders if a container needs to be
- * created during instantiation. Will be null if a container element never needs to
- * be created on the fly, such as when the implementer passes in their own element.
- *
- * @property _elDefaultContainer
- * @type HTMLElement
- * @private
- */
-//YAHOO.widget.LogReader._elDefaultContainer = null;
+    /**
+     * Buffer of log message objects for batch output.
+     *
+     * @property _buffer
+     * @type Object[]
+     * @private
+     */
+    _buffer : null,
 
-/**
- * Buffer of log message objects for batch output.
- *
- * @property _buffer
- * @type Object[]
- * @private
- */
-YAHOO.widget.LogReader.prototype._buffer = null;
+    /**
+     * Number of log messages output to console.
+     *
+     * @property _consoleMsgCount
+     * @type Number
+     * @default 0
+     * @private
+     */
+    _consoleMsgCount : 0,
 
-/**
- * Number of log messages output to console.
- *
- * @property _consoleMsgCount
- * @type Number
- * @default 0
- * @private
- */
-YAHOO.widget.LogReader.prototype._consoleMsgCount = 0;
+    /**
+     * Date of last output log message.
+     *
+     * @property _lastTime
+     * @type Date
+     * @private
+     */
+    _lastTime : null,
 
-/**
- * Date of last output log message.
- *
- * @property _lastTime
- * @type Date
- * @private
- */
-YAHOO.widget.LogReader.prototype._lastTime = null;
+    /**
+     * Batched output timeout ID.
+     *
+     * @property _timeout
+     * @type Number
+     * @private
+     */
+    _timeout : null,
 
-/**
- * Batched output timeout ID.
- *
- * @property _timeout
- * @type Number
- * @private
- */
-YAHOO.widget.LogReader.prototype._timeout = null;
+    /**
+     * Hash of filters and their related checkbox elements.
+     *
+     * @property _filterCheckboxes
+     * @type Object
+     * @private
+     */
+    _filterCheckboxes : null,
 
-/**
- * Hash of filters and their related checkbox elements.
- *
- * @property _filterCheckboxes
- * @type Object
- * @private
- */
-YAHOO.widget.LogReader.prototype._filterCheckboxes = null;
+    /**
+     * Array of filters for log message categories.
+     *
+     * @property _categoryFilters
+     * @type String[]
+     * @private
+     */
+    _categoryFilters : null,
 
-/**
- * Array of filters for log message categories.
- *
- * @property _categoryFilters
- * @type String[]
- * @private
- */
-YAHOO.widget.LogReader.prototype._categoryFilters = null;
+    /**
+     * Array of filters for log message sources.
+     *
+     * @property _sourceFilters
+     * @type String[]
+     * @private
+     */
+    _sourceFilters : null,
 
-/**
- * Array of filters for log message sources.
- *
- * @property _sourceFilters
- * @type String[]
- * @private
- */
-YAHOO.widget.LogReader.prototype._sourceFilters = null;
+    /**
+     * LogReader container element.
+     *
+     * @property _elContainer
+     * @type HTMLElement
+     * @private
+     */
+    _elContainer : null,
 
-/**
- * LogReader container element.
- *
- * @property _elContainer
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elContainer = null;
+    /**
+     * LogReader header element.
+     *
+     * @property _elHd
+     * @type HTMLElement
+     * @private
+     */
+    _elHd : null,
 
-/**
- * LogReader header element.
- *
- * @property _elHd
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elHd = null;
+    /**
+     * LogReader collapse element.
+     *
+     * @property _elCollapse
+     * @type HTMLElement
+     * @private
+     */
+    _elCollapse : null,
 
-/**
- * LogReader collapse element.
- *
- * @property _elCollapse
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elCollapse = null;
+    /**
+     * LogReader collapse button element.
+     *
+     * @property _btnCollapse
+     * @type HTMLElement
+     * @private
+     */
+    _btnCollapse : null,
 
-/**
- * LogReader collapse button element.
- *
- * @property _btnCollapse
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._btnCollapse = null;
+    /**
+     * LogReader title header element.
+     *
+     * @property _title
+     * @type HTMLElement
+     * @private
+     */
+    _title : null,
 
-/**
- * LogReader title header element.
- *
- * @property _title
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._title = null;
+    /**
+     * LogReader console element.
+     *
+     * @property _elConsole
+     * @type HTMLElement
+     * @private
+     */
+    _elConsole : null,
 
-/**
- * LogReader console element.
- *
- * @property _elConsole
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elConsole = null;
+    /**
+     * LogReader footer element.
+     *
+     * @property _elFt
+     * @type HTMLElement
+     * @private
+     */
+    _elFt : null,
 
-/**
- * LogReader footer element.
- *
- * @property _elFt
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elFt = null;
+    /**
+     * LogReader buttons container element.
+     *
+     * @property _elBtns
+     * @type HTMLElement
+     * @private
+     */
+    _elBtns : null,
 
-/**
- * LogReader buttons container element.
- *
- * @property _elBtns
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elBtns = null;
+    /**
+     * Container element for LogReader category filter checkboxes.
+     *
+     * @property _elCategoryFilters
+     * @type HTMLElement
+     * @private
+     */
+    _elCategoryFilters : null,
 
-/**
- * Container element for LogReader category filter checkboxes.
- *
- * @property _elCategoryFilters
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elCategoryFilters = null;
+    /**
+     * Container element for LogReader source filter checkboxes.
+     *
+     * @property _elSourceFilters
+     * @type HTMLElement
+     * @private
+     */
+    _elSourceFilters : null,
 
-/**
- * Container element for LogReader source filter checkboxes.
- *
- * @property _elSourceFilters
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elSourceFilters = null;
+    /**
+     * LogReader pause button element.
+     *
+     * @property _btnPause
+     * @type HTMLElement
+     * @private
+     */
+    _btnPause : null,
 
-/**
- * LogReader pause button element.
- *
- * @property _btnPause
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._btnPause = null;
+    /**
+     * Clear button element.
+     *
+     * @property _btnClear
+     * @type HTMLElement
+     * @private
+     */
+    _btnClear : null,
 
-/**
- * Clear button element.
- *
- * @property _btnClear
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._btnClear = null;
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Private methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Private methods
-//
-/////////////////////////////////////////////////////////////////////////////
+    /**
+     * Initializes the primary container element.
+     *
+     * @method _initContainerEl
+     * @param elContainer {HTMLElement} Container element by reference or string ID.
+     * @private
+     */
+    _initContainerEl : function(elContainer) {
+        // Validate container
+        elContainer = YAHOO.util.Dom.get(elContainer);
+        // Attach to existing container...
+        if(elContainer && elContainer.tagName && (elContainer.tagName.toLowerCase() == "div")) {
+            this._elContainer = elContainer;
+            YAHOO.util.Dom.addClass(this._elContainer,"yui-log");
+        }
+        // ...or create container from scratch
+        else {
+            this._elContainer = document.body.appendChild(document.createElement("div"));
+            //this._elContainer.id = "yui-log" + this._sName;
+            YAHOO.util.Dom.addClass(this._elContainer,"yui-log");
+            YAHOO.util.Dom.addClass(this._elContainer,"yui-log-container");
 
-/**
- * Initializes the primary container element.
- *
- * @method _initContainerEl
- * @param elContainer {HTMLElement} Container element by reference or string ID.
- * @private
- */
-YAHOO.widget.LogReader.prototype._initContainerEl = function(elContainer) {
-    // Validate container
-    elContainer = YAHOO.util.Dom.get(elContainer);
-    // Attach to existing container...
-    if(elContainer && elContainer.tagName && (elContainer.tagName.toLowerCase() == "div")) {
-        this._elContainer = elContainer;
-        YAHOO.util.Dom.addClass(this._elContainer,"yui-log");
-    }
-    // ...or create container from scratch
-    else {
-        this._elContainer = document.body.appendChild(document.createElement("div"));
-        //this._elContainer.id = "yui-log" + this._sName;
-        YAHOO.util.Dom.addClass(this._elContainer,"yui-log");
-        YAHOO.util.Dom.addClass(this._elContainer,"yui-log-container");
+            //YAHOO.widget.LogReader._elDefaultContainer = this._elContainer;
 
-        //YAHOO.widget.LogReader._elDefaultContainer = this._elContainer;
-
-        // If implementer has provided container values, trust and set those
-        var containerStyle = this._elContainer.style;
-        if(this.width) {
-            containerStyle.width = this.width;
+            // If implementer has provided container values, trust and set those
+            var containerStyle = this._elContainer.style;
+            if(this.width) {
+                containerStyle.width = this.width;
+            }
+            if(this.right) {
+                containerStyle.right = this.right;
+            }
+            if(this.top) {
+                containerStyle.top = this.top;
+            }
+             if(this.left) {
+                containerStyle.left = this.left;
+                containerStyle.right = "auto";
+            }
+            if(this.bottom) {
+                containerStyle.bottom = this.bottom;
+                containerStyle.top = "auto";
+            }
+           if(this.fontSize) {
+                containerStyle.fontSize = this.fontSize;
+            }
+            // For Opera
+            if(navigator.userAgent.toLowerCase().indexOf("opera") != -1) {
+                document.body.style += '';
+            }
         }
-        if(this.right) {
-            containerStyle.right = this.right;
-        }
-        if(this.top) {
-            containerStyle.top = this.top;
-        }
-         if(this.left) {
-            containerStyle.left = this.left;
-            containerStyle.right = "auto";
-        }
-        if(this.bottom) {
-            containerStyle.bottom = this.bottom;
-            containerStyle.top = "auto";
-        }
-       if(this.fontSize) {
-            containerStyle.fontSize = this.fontSize;
-        }
-        // For Opera
-        if(navigator.userAgent.toLowerCase().indexOf("opera") != -1) {
-            document.body.style += '';
-        }
-    }
-};
+    },
 
-/**
- * Initializes the header element.
- *
- * @method _initHeaderEl
- * @private
- */
-YAHOO.widget.LogReader.prototype._initHeaderEl = function() {
-    var oSelf = this;
+    /**
+     * Initializes the header element.
+     *
+     * @method _initHeaderEl
+     * @private
+     */
+    _initHeaderEl : function() {
+        var oSelf = this;
 
-    // Destroy header
-    if(this._elHd) {
-        // Unhook DOM events
-        YAHOO.util.Event.purgeElement(this._elHd, true);
+        // Destroy header
+        if(this._elHd) {
+            // Unhook DOM events
+            YAHOO.util.Event.purgeElement(this._elHd, true);
 
-        // Remove DOM elements
-        this._elHd.innerHTML = "";
-    }
-    
-    // Create header
-    this._elHd = this._elContainer.appendChild(document.createElement("div"));
-    this._elHd.id = "yui-log-hd" + this._sName;
-    this._elHd.className = "yui-log-hd";
+            // Remove DOM elements
+            this._elHd.innerHTML = "";
+        }
+        
+        // Create header
+        this._elHd = this._elContainer.appendChild(document.createElement("div"));
+        this._elHd.id = "yui-log-hd" + this._sName;
+        this._elHd.className = "yui-log-hd";
 
-    this._elCollapse = this._elHd.appendChild(document.createElement("div"));
-    this._elCollapse.className = "yui-log-btns";
+        this._elCollapse = this._elHd.appendChild(document.createElement("div"));
+        this._elCollapse.className = "yui-log-btns";
 
-    this._btnCollapse = document.createElement("input");
-    this._btnCollapse.type = "button";
-    //this._btnCollapse.style.fontSize =
-    //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
-    this._btnCollapse.className = "yui-log-button";
-    this._btnCollapse.value = "Collapse";
-    this._btnCollapse = this._elCollapse.appendChild(this._btnCollapse);
-    YAHOO.util.Event.addListener(
-        oSelf._btnCollapse,'click',oSelf._onClickCollapseBtn,oSelf);
+        this._btnCollapse = document.createElement("input");
+        this._btnCollapse.type = "button";
+        //this._btnCollapse.style.fontSize =
+        //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
+        this._btnCollapse.className = "yui-log-button";
+        this._btnCollapse.value = "Collapse";
+        this._btnCollapse = this._elCollapse.appendChild(this._btnCollapse);
+        YAHOO.util.Event.addListener(
+            oSelf._btnCollapse,'click',oSelf._onClickCollapseBtn,oSelf);
 
-    this._title = this._elHd.appendChild(document.createElement("h4"));
-    this._title.innerHTML = "Logger Console";
-};
+        this._title = this._elHd.appendChild(document.createElement("h4"));
+        this._title.innerHTML = "Logger Console";
+    },
 
-/**
- * Initializes the console element.
- *
- * @method _initConsoleEl
- * @private
- */
-YAHOO.widget.LogReader.prototype._initConsoleEl = function() {
-    // Destroy console
-    if(this._elConsole) {
-        // Unhook DOM events
-        YAHOO.util.Event.purgeElement(this._elConsole, true);
+    /**
+     * Initializes the console element.
+     *
+     * @method _initConsoleEl
+     * @private
+     */
+    _initConsoleEl : function() {
+        // Destroy console
+        if(this._elConsole) {
+            // Unhook DOM events
+            YAHOO.util.Event.purgeElement(this._elConsole, true);
 
-        // Remove DOM elements
-        this._elConsole.innerHTML = "";
-    }
+            // Remove DOM elements
+            this._elConsole.innerHTML = "";
+        }
 
-    // Ceate console
-    this._elConsole = this._elContainer.appendChild(document.createElement("div"));
-    this._elConsole.className = "yui-log-bd";
+        // Ceate console
+        this._elConsole = this._elContainer.appendChild(document.createElement("div"));
+        this._elConsole.className = "yui-log-bd";
 
-    // If implementer has provided console, trust and set those
-    if(this.height) {
-        this._elConsole.style.height = this.height;
-    }
-};
+        // If implementer has provided console, trust and set those
+        if(this.height) {
+            this._elConsole.style.height = this.height;
+        }
+    },
 
-/**
- * Initializes the footer element.
- *
- * @method _initFooterEl
- * @private
- */
-YAHOO.widget.LogReader.prototype._initFooterEl = function() {
-    var oSelf = this;
+    /**
+     * Initializes the footer element.
+     *
+     * @method _initFooterEl
+     * @private
+     */
+    _initFooterEl : function() {
+        var oSelf = this;
 
-    // Don't create footer elements if footer is disabled
-    if(this.footerEnabled) {
-        // Destroy console
-        if(this._elFt) {
-            // Unhook DOM events
-            YAHOO.util.Event.purgeElement(this._elFt, true);
+        // Don't create footer elements if footer is disabled
+        if(this.footerEnabled) {
+            // Destroy console
+            if(this._elFt) {
+                // Unhook DOM events
+                YAHOO.util.Event.purgeElement(this._elFt, true);
 
-            // Remove DOM elements
-            this._elFt.innerHTML = "";
-        }
+                // Remove DOM elements
+                this._elFt.innerHTML = "";
+            }
 
-        this._elFt = this._elContainer.appendChild(document.createElement("div"));
-        this._elFt.className = "yui-log-ft";
+            this._elFt = this._elContainer.appendChild(document.createElement("div"));
+            this._elFt.className = "yui-log-ft";
 
-        this._elBtns = this._elFt.appendChild(document.createElement("div"));
-        this._elBtns.className = "yui-log-btns";
+            this._elBtns = this._elFt.appendChild(document.createElement("div"));
+            this._elBtns.className = "yui-log-btns";
 
-        this._btnPause = document.createElement("input");
-        this._btnPause.type = "button";
-        //this._btnPause.style.fontSize =
-        //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
-        this._btnPause.className = "yui-log-button";
-        this._btnPause.value = "Pause";
-        this._btnPause = this._elBtns.appendChild(this._btnPause);
-        YAHOO.util.Event.addListener(
-            oSelf._btnPause,'click',oSelf._onClickPauseBtn,oSelf);
+            this._btnPause = document.createElement("input");
+            this._btnPause.type = "button";
+            //this._btnPause.style.fontSize =
+            //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
+            this._btnPause.className = "yui-log-button";
+            this._btnPause.value = "Pause";
+            this._btnPause = this._elBtns.appendChild(this._btnPause);
+            YAHOO.util.Event.addListener(
+                oSelf._btnPause,'click',oSelf._onClickPauseBtn,oSelf);
 
-        this._btnClear = document.createElement("input");
-        this._btnClear.type = "button";
-        //this._btnClear.style.fontSize =
-        //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
-        this._btnClear.className = "yui-log-button";
-        this._btnClear.value = "Clear";
-        this._btnClear = this._elBtns.appendChild(this._btnClear);
-        YAHOO.util.Event.addListener(
-            oSelf._btnClear,'click',oSelf._onClickClearBtn,oSelf);
+            this._btnClear = document.createElement("input");
+            this._btnClear.type = "button";
+            //this._btnClear.style.fontSize =
+            //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
+            this._btnClear.className = "yui-log-button";
+            this._btnClear.value = "Clear";
+            this._btnClear = this._elBtns.appendChild(this._btnClear);
+            YAHOO.util.Event.addListener(
+                oSelf._btnClear,'click',oSelf._onClickClearBtn,oSelf);
 
-        this._elCategoryFilters = this._elFt.appendChild(document.createElement("div"));
-        this._elCategoryFilters.className = "yui-log-categoryfilters";
-        this._elSourceFilters = this._elFt.appendChild(document.createElement("div"));
-        this._elSourceFilters.className = "yui-log-sourcefilters";
-    }
-};
+            this._elCategoryFilters = this._elFt.appendChild(document.createElement("div"));
+            this._elCategoryFilters.className = "yui-log-categoryfilters";
+            this._elSourceFilters = this._elFt.appendChild(document.createElement("div"));
+            this._elSourceFilters.className = "yui-log-sourcefilters";
+        }
+    },
 
-/**
- * Initializes Drag and Drop on the header element.
- *
- * @method _initDragDrop
- * @private
- */
-YAHOO.widget.LogReader.prototype._initDragDrop = function() {
-    // If Drag and Drop utility is available...
-    // ...and draggable is true...
-    // ...then make the header draggable
-    if(YAHOO.util.DD && this.draggable && this._elHd) {
-        var ylog_dd = new YAHOO.util.DD(this._elContainer);
-        ylog_dd.setHandleElId(this._elHd.id);
-        //TODO: use class name
-        this._elHd.style.cursor = "move";
-    }
-};
+    /**
+     * Initializes Drag and Drop on the header element.
+     *
+     * @method _initDragDrop
+     * @private
+     */
+    _initDragDrop : function() {
+        // If Drag and Drop utility is available...
+        // ...and draggable is true...
+        // ...then make the header draggable
+        if(YAHOO.util.DD && this.draggable && this._elHd) {
+            var ylog_dd = new YAHOO.util.DD(this._elContainer);
+            ylog_dd.setHandleElId(this._elHd.id);
+            //TODO: use class name
+            this._elHd.style.cursor = "move";
+        }
+    },
 
-/**
- * Initializes category filters.
- *
- * @method _initCategories
- * @private
- */
-YAHOO.widget.LogReader.prototype._initCategories = function() {
-    // Initialize category filters
-    this._categoryFilters = [];
-    var aInitialCategories = YAHOO.widget.Logger.categories;
+    /**
+     * Initializes category filters.
+     *
+     * @method _initCategories
+     * @private
+     */
+    _initCategories : function() {
+        // Initialize category filters
+        this._categoryFilters = [];
+        var aInitialCategories = YAHOO.widget.Logger.categories;
 
-    for(var j=0; j < aInitialCategories.length; j++) {
-        var sCategory = aInitialCategories[j];
+        for(var j=0; j < aInitialCategories.length; j++) {
+            var sCategory = aInitialCategories[j];
 
-        // Add category to the internal array of filters
-        this._categoryFilters.push(sCategory);
+            // Add category to the internal array of filters
+            this._categoryFilters.push(sCategory);
 
-        // Add checkbox element if UI is enabled
-        if(this._elCategoryFilters) {
-            this._createCategoryCheckbox(sCategory);
+            // Add checkbox element if UI is enabled
+            if(this._elCategoryFilters) {
+                this._createCategoryCheckbox(sCategory);
+            }
         }
-    }
-};
+    },
 
-/**
- * Initializes source filters.
- *
- * @method _initSources
- * @private
- */
-YAHOO.widget.LogReader.prototype._initSources = function() {
-    // Initialize source filters
-    this._sourceFilters = [];
-    var aInitialSources = YAHOO.widget.Logger.sources;
+    /**
+     * Initializes source filters.
+     *
+     * @method _initSources
+     * @private
+     */
+    _initSources : function() {
+        // Initialize source filters
+        this._sourceFilters = [];
+        var aInitialSources = YAHOO.widget.Logger.sources;
 
-    for(var j=0; j < aInitialSources.length; j++) {
-        var sSource = aInitialSources[j];
+        for(var j=0; j < aInitialSources.length; j++) {
+            var sSource = aInitialSources[j];
 
-        // Add source to the internal array of filters
-        this._sourceFilters.push(sSource);
+            // Add source to the internal array of filters
+            this._sourceFilters.push(sSource);
 
-        // Add checkbox element if UI is enabled
-        if(this._elSourceFilters) {
-            this._createSourceCheckbox(sSource);
+            // Add checkbox element if UI is enabled
+            if(this._elSourceFilters) {
+                this._createSourceCheckbox(sSource);
+            }
         }
-    }}
-;
+    },
 
-/**
- * Creates the UI for a category filter in the LogReader footer element.
- *
- * @method _createCategoryCheckbox
- * @param sCategory {String} Category name.
- * @private
- */
-YAHOO.widget.LogReader.prototype._createCategoryCheckbox = function(sCategory) {
-    var oSelf = this;
+    /**
+     * Creates the UI for a category filter in the LogReader footer element.
+     *
+     * @method _createCategoryCheckbox
+     * @param sCategory {String} Category name.
+     * @private
+     */
+    _createCategoryCheckbox : function(sCategory) {
+        var oSelf = this;
 
-    if(this._elFt) {
-        var elParent = this._elCategoryFilters;
-        var elFilter = elParent.appendChild(document.createElement("span"));
-        elFilter.className = "yui-log-filtergrp";
-        
-        // Append el at the end so IE 5.5 can set "type" attribute
-        // and THEN set checked property
-        var chkCategory = document.createElement("input");
-        chkCategory.id = "yui-log-filter-" + sCategory + this._sName;
-        chkCategory.className = "yui-log-filter-" + sCategory;
-        chkCategory.type = "checkbox";
-        chkCategory.category = sCategory;
-        chkCategory = elFilter.appendChild(chkCategory);
-        chkCategory.checked = true;
+        if(this._elFt) {
+            var elParent = this._elCategoryFilters;
+            var elFilter = elParent.appendChild(document.createElement("span"));
+            elFilter.className = "yui-log-filtergrp";
+            
+            // Append el at the end so IE 5.5 can set "type" attribute
+            // and THEN set checked property
+            var chkCategory = document.createElement("input");
+            chkCategory.id = "yui-log-filter-" + sCategory + this._sName;
+            chkCategory.className = "yui-log-filter-" + sCategory;
+            chkCategory.type = "checkbox";
+            chkCategory.category = sCategory;
+            chkCategory = elFilter.appendChild(chkCategory);
+            chkCategory.checked = true;
 
-        // Subscribe to the click event
-        YAHOO.util.Event.addListener(chkCategory,'click',oSelf._onCheckCategory,oSelf);
+            // Subscribe to the click event
+            YAHOO.util.Event.addListener(chkCategory,'click',oSelf._onCheckCategory,oSelf);
 
-        // Create and class the text label
-        var lblCategory = elFilter.appendChild(document.createElement("label"));
-        lblCategory.htmlFor = chkCategory.id;
-        lblCategory.className = sCategory;
-        lblCategory.innerHTML = sCategory;
-        
-        this._filterCheckboxes[sCategory] = chkCategory;
-    }
-};
+            // Create and class the text label
+            var lblCategory = elFilter.appendChild(document.createElement("label"));
+            lblCategory.htmlFor = chkCategory.id;
+            lblCategory.className = sCategory;
+            lblCategory.innerHTML = sCategory;
+            
+            this._filterCheckboxes[sCategory] = chkCategory;
+        }
+    },
 
-/**
- * Creates a checkbox in the LogReader footer element to filter by source.
- *
- * @method _createSourceCheckbox
- * @param sSource {String} Source name.
- * @private
- */
-YAHOO.widget.LogReader.prototype._createSourceCheckbox = function(sSource) {
-    var oSelf = this;
+    /**
+     * Creates a checkbox in the LogReader footer element to filter by source.
+     *
+     * @method _createSourceCheckbox
+     * @param sSource {String} Source name.
+     * @private
+     */
+    _createSourceCheckbox : function(sSource) {
+        var oSelf = this;
 
-    if(this._elFt) {
-        var elParent = this._elSourceFilters;
-        var elFilter = elParent.appendChild(document.createElement("span"));
-        elFilter.className = "yui-log-filtergrp";
+        if(this._elFt) {
+            var elParent = this._elSourceFilters;
+            var elFilter = elParent.appendChild(document.createElement("span"));
+            elFilter.className = "yui-log-filtergrp";
 
-        // Append el at the end so IE 5.5 can set "type" attribute
-        // and THEN set checked property
-        var chkSource = document.createElement("input");
-        chkSource.id = "yui-log-filter" + sSource + this._sName;
-        chkSource.className = "yui-log-filter" + sSource;
-        chkSource.type = "checkbox";
-        chkSource.source = sSource;
-        chkSource = elFilter.appendChild(chkSource);
-        chkSource.checked = true;
+            // Append el at the end so IE 5.5 can set "type" attribute
+            // and THEN set checked property
+            var chkSource = document.createElement("input");
+            chkSource.id = "yui-log-filter" + sSource + this._sName;
+            chkSource.className = "yui-log-filter" + sSource;
+            chkSource.type = "checkbox";
+            chkSource.source = sSource;
+            chkSource = elFilter.appendChild(chkSource);
+            chkSource.checked = true;
 
-        // Subscribe to the click event
-        YAHOO.util.Event.addListener(chkSource,'click',oSelf._onCheckSource,oSelf);
+            // Subscribe to the click event
+            YAHOO.util.Event.addListener(chkSource,'click',oSelf._onCheckSource,oSelf);
 
-        // Create and class the text label
-        var lblSource = elFilter.appendChild(document.createElement("label"));
-        lblSource.htmlFor = chkSource.id;
-        lblSource.className = sSource;
-        lblSource.innerHTML = sSource;
-        
-        this._filterCheckboxes[sSource] = chkSource;
-    }
-};
+            // Create and class the text label
+            var lblSource = elFilter.appendChild(document.createElement("label"));
+            lblSource.htmlFor = chkSource.id;
+            lblSource.className = sSource;
+            lblSource.innerHTML = sSource;
+            
+            this._filterCheckboxes[sSource] = chkSource;
+        }
+    },
 
-/**
- * Reprints all log messages in the stack through filters.
- *
- * @method _filterLogs
- * @private
- */
-YAHOO.widget.LogReader.prototype._filterLogs = function() {
-    // Reprint stack with new filters
-    if (this._elConsole !== null) {
-        this.clearConsole();
-        this._printToConsole(YAHOO.widget.Logger.getStack());
-    }
-};
+    /**
+     * Reprints all log messages in the stack through filters.
+     *
+     * @method _filterLogs
+     * @private
+     */
+    _filterLogs : function() {
+        // Reprint stack with new filters
+        if (this._elConsole !== null) {
+            this.clearConsole();
+            this._printToConsole(YAHOO.widget.Logger.getStack());
+        }
+    },
 
-/**
- * Sends buffer of log messages to output and clears buffer.
- *
- * @method _printBuffer
- * @private
- */
-YAHOO.widget.LogReader.prototype._printBuffer = function() {
-    this._timeout = null;
+    /**
+     * Sends buffer of log messages to output and clears buffer.
+     *
+     * @method _printBuffer
+     * @private
+     */
+    _printBuffer : function() {
+        this._timeout = null;
 
-    if(this._elConsole !== null) {
-        var thresholdMax = this.thresholdMax;
-        thresholdMax = (thresholdMax && !isNaN(thresholdMax)) ? thresholdMax : 500;
-        if(this._consoleMsgCount < thresholdMax) {
-            var entries = [];
-            for (var i=0; i<this._buffer.length; i++) {
-                entries[i] = this._buffer[i];
+        if(this._elConsole !== null) {
+            var thresholdMax = this.thresholdMax;
+            thresholdMax = (thresholdMax && !isNaN(thresholdMax)) ? thresholdMax : 500;
+            if(this._consoleMsgCount < thresholdMax) {
+                var entries = [];
+                for (var i=0; i<this._buffer.length; i++) {
+                    entries[i] = this._buffer[i];
+                }
+                this._buffer = [];
+                this._printToConsole(entries);
             }
-            this._buffer = [];
-            this._printToConsole(entries);
+            else {
+                this._filterLogs();
+            }
+            
+            if(!this.newestOnTop) {
+                this._elConsole.scrollTop = this._elConsole.scrollHeight;
+            }
         }
-        else {
-            this._filterLogs();
+    },
+
+    /**
+     * Cycles through an array of log messages, and outputs each one to the console
+     * if its category has not been filtered out.
+     *
+     * @method _printToConsole
+     * @param aEntries {Object[]} Array of LogMsg objects to output to console.
+     * @private
+     */
+    _printToConsole : function(aEntries) {
+        // Manage the number of messages displayed in the console
+        var entriesLen         = aEntries.length,
+            df                 = document.createDocumentFragment(),
+            msgHTML            = [],
+            thresholdMin       = this.thresholdMin,
+            sourceFiltersLen   = this._sourceFilters.length,
+            categoryFiltersLen = this._categoryFilters.length,
+            entriesStartIndex,
+            i, j, msg, before;
+
+        if(isNaN(thresholdMin) || (thresholdMin > this.thresholdMax)) {
+            thresholdMin = 0;
         }
+        entriesStartIndex = (entriesLen > thresholdMin) ? (entriesLen - thresholdMin) : 0;
         
-        if(!this.newestOnTop) {
-            this._elConsole.scrollTop = this._elConsole.scrollHeight;
-        }
-    }
-};
+        // Iterate through all log entries 
+        for(i=entriesStartIndex; i<entriesLen; i++) {
+            // Print only the ones that filter through
+            var okToPrint = false;
+            var okToFilterCats = false;
 
-/**
- * Cycles through an array of log messages, and outputs each one to the console
- * if its category has not been filtered out.
- *
- * @method _printToConsole
- * @param aEntries {Object[]} Array of LogMsg objects to output to console.
- * @private
- */
-YAHOO.widget.LogReader.prototype._printToConsole = function(aEntries) {
-    // Manage the number of messages displayed in the console
-    var entriesLen = aEntries.length;
-    var thresholdMin = this.thresholdMin;
-    if(isNaN(thresholdMin) || (thresholdMin > this.thresholdMax)) {
-        thresholdMin = 0;
-    }
-    var entriesStartIndex = (entriesLen > thresholdMin) ? (entriesLen - thresholdMin) : 0;
-    
-    // Iterate through all log entries 
-    var sourceFiltersLen = this._sourceFilters.length;
-    var categoryFiltersLen = this._categoryFilters.length;
-    for(var i=entriesStartIndex; i<entriesLen; i++) {
-        // Print only the ones that filter through
-        var okToPrint = false;
-        var okToFilterCats = false;
+            // Get log message details
+            var entry = aEntries[i];
+            var source = entry.source;
+            var category = entry.category;
 
-        // Get log message details
-        var entry = aEntries[i];
-        var source = entry.source;
-        var category = entry.category;
-
-        for(var j=0; j<sourceFiltersLen; j++) {
-            if(source == this._sourceFilters[j]) {
-                okToFilterCats = true;
-                break;
-            }
-        }
-        if(okToFilterCats) {
-            for(var k=0; k<categoryFiltersLen; k++) {
-                if(category == this._categoryFilters[k]) {
-                    okToPrint = true;
+            for(j=0; j<sourceFiltersLen; j++) {
+                if(source == this._sourceFilters[j]) {
+                    okToFilterCats = true;
                     break;
                 }
             }
-        }
-        if(okToPrint) {
-            var output = this.formatMsg(entry);
-            if(this.newestOnTop) {
-                this._elConsole.innerHTML = output + this._elConsole.innerHTML;
+            if(okToFilterCats) {
+                for(j=0; j<categoryFiltersLen; j++) {
+                    if(category == this._categoryFilters[j]) {
+                        okToPrint = true;
+                        break;
+                    }
+                }
             }
-            else {
-                this._elConsole.innerHTML += output;
+            if(okToPrint) {
+                msg = this.formatMsg(entry);
+                if (typeof msg === 'string') {
+                    msgHTML[msgHTML.length] = msg;
+                } else {
+                    df.insertBefore(msg, this.newestOnTop ?
+                        df.firstChild || null : null);
+                }
+                this._consoleMsgCount++;
+                this._lastTime = entry.time.getTime();
             }
-            this._consoleMsgCount++;
-            this._lastTime = entry.time.getTime();
         }
-    }
-};
 
+        if (msgHTML.length) {
+            msgHTML.splice(0,0,this._elConsole.innerHTML);
+            this._elConsole.innerHTML = this.newestOnTop ?
+                                            msgHTML.reverse().join('') :
+                                            msgHTML.join('');
+        } else if (df.firstChild) {
+            this._elConsole.insertBefore(df, this.newestOnTop ?
+                        this._elConsole.firstChild || null : null);
+        }
+    },
+
 /////////////////////////////////////////////////////////////////////////////
 //
 // Private event handlers
 //
 /////////////////////////////////////////////////////////////////////////////
 
-/**
- * Handles Logger's categoryCreateEvent.
- *
- * @method _onCategoryCreate
- * @param sType {String} The event.
- * @param aArgs {Object[]} Data passed from event firer.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onCategoryCreate = function(sType, aArgs, oSelf) {
-    var category = aArgs[0];
-    
-    // Add category to the internal array of filters
-    oSelf._categoryFilters.push(category);
+    /**
+     * Handles Logger's categoryCreateEvent.
+     *
+     * @method _onCategoryCreate
+     * @param sType {String} The event.
+     * @param aArgs {Object[]} Data passed from event firer.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onCategoryCreate : function(sType, aArgs, oSelf) {
+        var category = aArgs[0];
+        
+        // Add category to the internal array of filters
+        oSelf._categoryFilters.push(category);
 
-    if(oSelf._elFt) {
-        oSelf._createCategoryCheckbox(category);
-    }
-};
+        if(oSelf._elFt) {
+            oSelf._createCategoryCheckbox(category);
+        }
+    },
 
-/**
- * Handles Logger's sourceCreateEvent.
- *
- * @method _onSourceCreate
- * @param sType {String} The event.
- * @param aArgs {Object[]} Data passed from event firer.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onSourceCreate = function(sType, aArgs, oSelf) {
-    var source = aArgs[0];
-    
-    // Add source to the internal array of filters
-    oSelf._sourceFilters.push(source);
+    /**
+     * Handles Logger's sourceCreateEvent.
+     *
+     * @method _onSourceCreate
+     * @param sType {String} The event.
+     * @param aArgs {Object[]} Data passed from event firer.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onSourceCreate : function(sType, aArgs, oSelf) {
+        var source = aArgs[0];
+        
+        // Add source to the internal array of filters
+        oSelf._sourceFilters.push(source);
 
-    if(oSelf._elFt) {
-        oSelf._createSourceCheckbox(source);
-    }
-};
+        if(oSelf._elFt) {
+            oSelf._createSourceCheckbox(source);
+        }
+    },
 
-/**
- * Handles check events on the category filter checkboxes.
- *
- * @method _onCheckCategory
- * @param v {HTMLEvent} The click event.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onCheckCategory = function(v, oSelf) {
-    var category = this.category;
-    if(!this.checked) {
-        oSelf.hideCategory(category);
-    }
-    else {
-        oSelf.showCategory(category);
-    }
-};
+    /**
+     * Handles check events on the category filter checkboxes.
+     *
+     * @method _onCheckCategory
+     * @param v {HTMLEvent} The click event.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onCheckCategory : function(v, oSelf) {
+        var category = this.category;
+        if(!this.checked) {
+            oSelf.hideCategory(category);
+        }
+        else {
+            oSelf.showCategory(category);
+        }
+    },
 
-/**
- * Handles check events on the category filter checkboxes.
- *
- * @method _onCheckSource
- * @param v {HTMLEvent} The click event.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onCheckSource = function(v, oSelf) {
-    var source = this.source;
-    if(!this.checked) {
-        oSelf.hideSource(source);
-    }
-    else {
-        oSelf.showSource(source);
-    }
-};
+    /**
+     * Handles check events on the category filter checkboxes.
+     *
+     * @method _onCheckSource
+     * @param v {HTMLEvent} The click event.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onCheckSource : function(v, oSelf) {
+        var source = this.source;
+        if(!this.checked) {
+            oSelf.hideSource(source);
+        }
+        else {
+            oSelf.showSource(source);
+        }
+    },
 
-/**
- * Handles click events on the collapse button.
- *
- * @method _onClickCollapseBtn
- * @param v {HTMLEvent} The click event.
- * @param oSelf {Object} The LogReader instance
- * @private
- */
-YAHOO.widget.LogReader.prototype._onClickCollapseBtn = function(v, oSelf) {
-    if(!oSelf.isCollapsed) {
-        oSelf.collapse();
-    }
-    else {
-        oSelf.expand();
-    }
-};
+    /**
+     * Handles click events on the collapse button.
+     *
+     * @method _onClickCollapseBtn
+     * @param v {HTMLEvent} The click event.
+     * @param oSelf {Object} The LogReader instance
+     * @private
+     */
+    _onClickCollapseBtn : function(v, oSelf) {
+        if(!oSelf.isCollapsed) {
+            oSelf.collapse();
+        }
+        else {
+            oSelf.expand();
+        }
+    },
 
-/**
- * Handles click events on the pause button.
- *
- * @method _onClickPauseBtn
- * @param v {HTMLEvent} The click event.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onClickPauseBtn = function(v, oSelf) {
-    if(!oSelf.isPaused) {
-        oSelf.pause();
-    }
-    else {
-        oSelf.resume();
-    }
-};
+    /**
+     * Handles click events on the pause button.
+     *
+     * @method _onClickPauseBtn
+     * @param v {HTMLEvent} The click event.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onClickPauseBtn : function(v, oSelf) {
+        if(!oSelf.isPaused) {
+            oSelf.pause();
+        }
+        else {
+            oSelf.resume();
+        }
+    },
 
-/**
- * Handles click events on the clear button.
- *
- * @method _onClickClearBtn
- * @param v {HTMLEvent} The click event.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onClickClearBtn = function(v, oSelf) {
-    oSelf.clearConsole();
-};
+    /**
+     * Handles click events on the clear button.
+     *
+     * @method _onClickClearBtn
+     * @param v {HTMLEvent} The click event.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onClickClearBtn : function(v, oSelf) {
+        oSelf.clearConsole();
+    },
 
-/**
- * Handles Logger's newLogEvent.
- *
- * @method _onNewLog
- * @param sType {String} The event.
- * @param aArgs {Object[]} Data passed from event firer.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onNewLog = function(sType, aArgs, oSelf) {
-    var logEntry = aArgs[0];
-    oSelf._buffer.push(logEntry);
+    /**
+     * Handles Logger's newLogEvent.
+     *
+     * @method _onNewLog
+     * @param sType {String} The event.
+     * @param aArgs {Object[]} Data passed from event firer.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onNewLog : function(sType, aArgs, oSelf) {
+        var logEntry = aArgs[0];
+        oSelf._buffer.push(logEntry);
 
-    if (oSelf.logReaderEnabled === true && oSelf._timeout === null) {
-        oSelf._timeout = setTimeout(function(){oSelf._printBuffer();}, oSelf.outputBuffer);
+        if (oSelf.logReaderEnabled === true && oSelf._timeout === null) {
+            oSelf._timeout = setTimeout(function(){oSelf._printBuffer();}, oSelf.outputBuffer);
+        }
+    },
+
+    /**
+     * Handles Logger's resetEvent.
+     *
+     * @method _onReset
+     * @param sType {String} The event.
+     * @param aArgs {Object[]} Data passed from event firer.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onReset : function(sType, aArgs, oSelf) {
+        oSelf._filterLogs();
     }
 };
 
-/**
- * Handles Logger's resetEvent.
- *
- * @method _onReset
- * @param sType {String} The event.
- * @param aArgs {Object[]} Data passed from event firer.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onReset = function(sType, aArgs, oSelf) {
-    oSelf._filterLogs();
-};
-
  /**
  * The Logger widget provides a simple way to read or write log messages in
  * JavaScript code. Integration with the YUI Library's debug builds allow
@@ -1935,10 +1983,9 @@
             var output =
                 localTime + " (" +
                 elapsedTime + "ms): " +
-                oEntry.source + ": " +
-                oEntry.msg;
+                oEntry.source + ": ";
 
-            console.log(output);
+            console.log(output, oEntry.msg);
         }
     };
 
@@ -1980,4 +2027,4 @@
 }
 
 
-YAHOO.register("logger", YAHOO.widget.Logger, {version: "2.4.1", build: "742"});
+YAHOO.register("logger", YAHOO.widget.Logger, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/logger/logger-min.js
===================================================================
--- trunk/root/static/yui/logger/logger-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/logger/logger-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,10 +1,9 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-YAHOO.widget.LogMsg=function(A){if(A&&(A.constructor==Object)){for(var B in A){this[B]=A[B];}}};YAHOO.widget.LogMsg.prototype.msg=null;YAHOO.widget.LogMsg.prototype.time=null;YAHOO.widget.LogMsg.prototype.category=null;YAHOO.widget.LogMsg.prototype.source=null;YAHOO.widget.LogMsg.prototype.sourceDetail=null;YAHOO.widget.LogWriter=function(A){if(!A){YAHOO.log("Could not instantiate LogWriter due to invalid source.","error","LogWriter");return ;}this._source=A;};YAHOO.widget.LogWriter.prototype.toString=function(){return"LogWriter "+this._sSource;};YAHOO.widget.LogWriter.prototype.log=function(A,B){YAHOO.widget.Logger.log(A,B,this._source);};YAHOO.widget.LogWriter.prototype.getSource=function(){return this._sSource;};YAHOO.widget.LogWriter.prototype.setSource=function(A){if(!A){YAHOO.log("Could not set source due to invalid source.","error",this.toString());return ;}else{this._sSource=A;}};YAHOO.widget.LogWriter.prototype._source=null;YAHOO.widget.LogReader=function(B,A){this!
 ._sName=YAHOO.widget.LogReader._index;YAHOO.widget.LogReader._index++;this._buffer=[];this._filterCheckboxes={};this._lastTime=YAHOO.widget.Logger.getStartTime();if(A&&(A.constructor==Object)){for(var C in A){this[C]=A[C];}}this._initContainerEl(B);if(!this._elContainer){YAHOO.log("Could not instantiate LogReader due to an invalid container element "+B,"error",this.toString());return ;}this._initHeaderEl();this._initConsoleEl();this._initFooterEl();this._initDragDrop();this._initCategories();this._initSources();YAHOO.widget.Logger.newLogEvent.subscribe(this._onNewLog,this);YAHOO.widget.Logger.logResetEvent.subscribe(this._onReset,this);YAHOO.widget.Logger.categoryCreateEvent.subscribe(this._onCategoryCreate,this);YAHOO.widget.Logger.sourceCreateEvent.subscribe(this._onSourceCreate,this);this._filterLogs();YAHOO.log("LogReader initialized",null,this.toString());};YAHOO.widget.LogReader.prototype.logReaderEnabled=true;YAHOO.widget.LogReader.prototype.width=null;YAHOO.widget.L!
 ogReader.prototype.height=null;YAHOO.widget.LogReader.prototyp!
 e.top=nu
ll;YAHOO.widget.LogReader.prototype.left=null;YAHOO.widget.LogReader.prototype.right=null;YAHOO.widget.LogReader.prototype.bottom=null;YAHOO.widget.LogReader.prototype.fontSize=null;YAHOO.widget.LogReader.prototype.footerEnabled=true;YAHOO.widget.LogReader.prototype.verboseOutput=true;YAHOO.widget.LogReader.prototype.newestOnTop=true;YAHOO.widget.LogReader.prototype.outputBuffer=100;YAHOO.widget.LogReader.prototype.thresholdMax=500;YAHOO.widget.LogReader.prototype.thresholdMin=100;YAHOO.widget.LogReader.prototype.isCollapsed=false;YAHOO.widget.LogReader.prototype.isPaused=false;YAHOO.widget.LogReader.prototype.draggable=true;YAHOO.widget.LogReader.prototype.toString=function(){return"LogReader instance"+this._sName;};YAHOO.widget.LogReader.prototype.pause=function(){this.isPaused=true;this._btnPause.value="Resume";this._timeout=null;this.logReaderEnabled=false;};YAHOO.widget.LogReader.prototype.resume=function(){this.isPaused=false;this._btnPause.value="Pause";this.logReader!
 Enabled=true;this._printBuffer();};YAHOO.widget.LogReader.prototype.hide=function(){this._elContainer.style.display="none";};YAHOO.widget.LogReader.prototype.show=function(){this._elContainer.style.display="block";};YAHOO.widget.LogReader.prototype.collapse=function(){this._elConsole.style.display="none";if(this._elFt){this._elFt.style.display="none";}this._btnCollapse.value="Expand";this.isCollapsed=true;};YAHOO.widget.LogReader.prototype.expand=function(){this._elConsole.style.display="block";if(this._elFt){this._elFt.style.display="block";}this._btnCollapse.value="Collapse";this.isCollapsed=false;};YAHOO.widget.LogReader.prototype.getCheckbox=function(A){return this._filterCheckboxes[A];};YAHOO.widget.LogReader.prototype.getCategories=function(){return this._categoryFilters;};YAHOO.widget.LogReader.prototype.showCategory=function(B){var D=this._categoryFilters;if(D.indexOf){if(D.indexOf(B)>-1){return ;}}else{for(var A=0;A<D.length;A++){if(D[A]===B){return ;}}}this._categ!
 oryFilters.push(B);this._filterLogs();var C=this.getCheckbox(B!
 );if(C){
C.checked=true;}};YAHOO.widget.LogReader.prototype.hideCategory=function(B){var D=this._categoryFilters;for(var A=0;A<D.length;A++){if(B==D[A]){D.splice(A,1);break;}}this._filterLogs();var C=this.getCheckbox(B);if(C){C.checked=false;}};YAHOO.widget.LogReader.prototype.getSources=function(){return this._sourceFilters;};YAHOO.widget.LogReader.prototype.showSource=function(A){var D=this._sourceFilters;if(D.indexOf){if(D.indexOf(A)>-1){return ;}}else{for(var B=0;B<D.length;B++){if(A==D[B]){return ;}}}D.push(A);this._filterLogs();var C=this.getCheckbox(A);if(C){C.checked=true;}};YAHOO.widget.LogReader.prototype.hideSource=function(A){var D=this._sourceFilters;for(var B=0;B<D.length;B++){if(A==D[B]){D.splice(B,1);break;}}this._filterLogs();var C=this.getCheckbox(A);if(C){C.checked=false;}};YAHOO.widget.LogReader.prototype.clearConsole=function(){this._timeout=null;this._buffer=[];this._consoleMsgCount=0;var A=this._elConsole;while(A.hasChildNodes()){A.removeChild(A.firstChild);}};!
 YAHOO.widget.LogReader.prototype.setTitle=function(A){this._title.innerHTML=this.html2Text(A);};YAHOO.widget.LogReader.prototype.getLastTime=function(){return this._lastTime;};YAHOO.widget.LogReader.prototype.formatMsg=function(D){var E=D.category;var L=E.substring(0,4).toUpperCase();var I=D.time;var J;if(I.toLocaleTimeString){J=I.toLocaleTimeString();}else{J=I.toString();}var B=I.getTime();var F=YAHOO.widget.Logger.getStartTime();var C=B-F;var N=B-this.getLastTime();var A=D.source;var M=D.sourceDetail;var K=(M)?A+" "+M:A;var H=this.html2Text(YAHOO.lang.dump(D.msg));var G=(this.verboseOutput)?["<pre class=\"yui-log-verbose\"><p><span class='",E,"'>",L,"</span> ",C,"ms (+",N,") ",J,": ","</p><p>",K,": </p><p>",H,"</p></pre>"]:["<pre><p><span class='",E,"'>",L,"</span> ",C,"ms (+",N,") ",J,": ",K,": ",H,"</p></pre>"];return G.join("");};YAHOO.widget.LogReader.prototype.html2Text=function(A){if(A){A+="";return A.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");
-}return"";};YAHOO.widget.LogReader._index=0;YAHOO.widget.LogReader.prototype._sName=null;YAHOO.widget.LogReader.prototype._buffer=null;YAHOO.widget.LogReader.prototype._consoleMsgCount=0;YAHOO.widget.LogReader.prototype._lastTime=null;YAHOO.widget.LogReader.prototype._timeout=null;YAHOO.widget.LogReader.prototype._filterCheckboxes=null;YAHOO.widget.LogReader.prototype._categoryFilters=null;YAHOO.widget.LogReader.prototype._sourceFilters=null;YAHOO.widget.LogReader.prototype._elContainer=null;YAHOO.widget.LogReader.prototype._elHd=null;YAHOO.widget.LogReader.prototype._elCollapse=null;YAHOO.widget.LogReader.prototype._btnCollapse=null;YAHOO.widget.LogReader.prototype._title=null;YAHOO.widget.LogReader.prototype._elConsole=null;YAHOO.widget.LogReader.prototype._elFt=null;YAHOO.widget.LogReader.prototype._elBtns=null;YAHOO.widget.LogReader.prototype._elCategoryFilters=null;YAHOO.widget.LogReader.prototype._elSourceFilters=null;YAHOO.widget.LogReader.prototype._btnPause=null;YA!
 HOO.widget.LogReader.prototype._btnClear=null;YAHOO.widget.LogReader.prototype._initContainerEl=function(B){B=YAHOO.util.Dom.get(B);if(B&&B.tagName&&(B.tagName.toLowerCase()=="div")){this._elContainer=B;YAHOO.util.Dom.addClass(this._elContainer,"yui-log");}else{this._elContainer=document.body.appendChild(document.createElement("div"));YAHOO.util.Dom.addClass(this._elContainer,"yui-log");YAHOO.util.Dom.addClass(this._elContainer,"yui-log-container");var A=this._elContainer.style;if(this.width){A.width=this.width;}if(this.right){A.right=this.right;}if(this.top){A.top=this.top;}if(this.left){A.left=this.left;A.right="auto";}if(this.bottom){A.bottom=this.bottom;A.top="auto";}if(this.fontSize){A.fontSize=this.fontSize;}if(navigator.userAgent.toLowerCase().indexOf("opera")!=-1){document.body.style+="";}}};YAHOO.widget.LogReader.prototype._initHeaderEl=function(){var A=this;if(this._elHd){YAHOO.util.Event.purgeElement(this._elHd,true);this._elHd.innerHTML="";}this._elHd=this._elCo!
 ntainer.appendChild(document.createElement("div"));this._elHd.!
 id="yui-
log-hd"+this._sName;this._elHd.className="yui-log-hd";this._elCollapse=this._elHd.appendChild(document.createElement("div"));this._elCollapse.className="yui-log-btns";this._btnCollapse=document.createElement("input");this._btnCollapse.type="button";this._btnCollapse.className="yui-log-button";this._btnCollapse.value="Collapse";this._btnCollapse=this._elCollapse.appendChild(this._btnCollapse);YAHOO.util.Event.addListener(A._btnCollapse,"click",A._onClickCollapseBtn,A);this._title=this._elHd.appendChild(document.createElement("h4"));this._title.innerHTML="Logger Console";};YAHOO.widget.LogReader.prototype._initConsoleEl=function(){if(this._elConsole){YAHOO.util.Event.purgeElement(this._elConsole,true);this._elConsole.innerHTML="";}this._elConsole=this._elContainer.appendChild(document.createElement("div"));this._elConsole.className="yui-log-bd";if(this.height){this._elConsole.style.height=this.height;}};YAHOO.widget.LogReader.prototype._initFooterEl=function(){var A=this;if(th!
 is.footerEnabled){if(this._elFt){YAHOO.util.Event.purgeElement(this._elFt,true);this._elFt.innerHTML="";}this._elFt=this._elContainer.appendChild(document.createElement("div"));this._elFt.className="yui-log-ft";this._elBtns=this._elFt.appendChild(document.createElement("div"));this._elBtns.className="yui-log-btns";this._btnPause=document.createElement("input");this._btnPause.type="button";this._btnPause.className="yui-log-button";this._btnPause.value="Pause";this._btnPause=this._elBtns.appendChild(this._btnPause);YAHOO.util.Event.addListener(A._btnPause,"click",A._onClickPauseBtn,A);this._btnClear=document.createElement("input");this._btnClear.type="button";this._btnClear.className="yui-log-button";this._btnClear.value="Clear";this._btnClear=this._elBtns.appendChild(this._btnClear);YAHOO.util.Event.addListener(A._btnClear,"click",A._onClickClearBtn,A);this._elCategoryFilters=this._elFt.appendChild(document.createElement("div"));this._elCategoryFilters.className="yui-log-cat!
 egoryfilters";this._elSourceFilters=this._elFt.appendChild(doc!
 ument.cr
eateElement("div"));this._elSourceFilters.className="yui-log-sourcefilters";}};YAHOO.widget.LogReader.prototype._initDragDrop=function(){if(YAHOO.util.DD&&this.draggable&&this._elHd){var A=new YAHOO.util.DD(this._elContainer);A.setHandleElId(this._elHd.id);this._elHd.style.cursor="move";}};YAHOO.widget.LogReader.prototype._initCategories=function(){this._categoryFilters=[];var C=YAHOO.widget.Logger.categories;for(var A=0;A<C.length;A++){var B=C[A];this._categoryFilters.push(B);if(this._elCategoryFilters){this._createCategoryCheckbox(B);}}};YAHOO.widget.LogReader.prototype._initSources=function(){this._sourceFilters=[];var C=YAHOO.widget.Logger.sources;for(var B=0;B<C.length;B++){var A=C[B];this._sourceFilters.push(A);if(this._elSourceFilters){this._createSourceCheckbox(A);}}};YAHOO.widget.LogReader.prototype._createCategoryCheckbox=function(B){var A=this;if(this._elFt){var E=this._elCategoryFilters;var D=E.appendChild(document.createElement("span"));D.className="yui-log-filt!
 ergrp";var C=document.createElement("input");C.id="yui-log-filter-"+B+this._sName;C.className="yui-log-filter-"+B;C.type="checkbox";C.category=B;C=D.appendChild(C);C.checked=true;YAHOO.util.Event.addListener(C,"click",A._onCheckCategory,A);var F=D.appendChild(document.createElement("label"));F.htmlFor=C.id;F.className=B;F.innerHTML=B;this._filterCheckboxes[B]=C;}};YAHOO.widget.LogReader.prototype._createSourceCheckbox=function(A){var D=this;if(this._elFt){var F=this._elSourceFilters;var E=F.appendChild(document.createElement("span"));E.className="yui-log-filtergrp";var C=document.createElement("input");C.id="yui-log-filter"+A+this._sName;C.className="yui-log-filter"+A;C.type="checkbox";C.source=A;C=E.appendChild(C);C.checked=true;YAHOO.util.Event.addListener(C,"click",D._onCheckSource,D);var B=E.appendChild(document.createElement("label"));B.htmlFor=C.id;B.className=A;B.innerHTML=A;this._filterCheckboxes[A]=C;
-}};YAHOO.widget.LogReader.prototype._filterLogs=function(){if(this._elConsole!==null){this.clearConsole();this._printToConsole(YAHOO.widget.Logger.getStack());}};YAHOO.widget.LogReader.prototype._printBuffer=function(){this._timeout=null;if(this._elConsole!==null){var B=this.thresholdMax;B=(B&&!isNaN(B))?B:500;if(this._consoleMsgCount<B){var A=[];for(var C=0;C<this._buffer.length;C++){A[C]=this._buffer[C];}this._buffer=[];this._printToConsole(A);}else{this._filterLogs();}if(!this.newestOnTop){this._elConsole.scrollTop=this._elConsole.scrollHeight;}}};YAHOO.widget.LogReader.prototype._printToConsole=function(J){var B=J.length;var O=this.thresholdMin;if(isNaN(O)||(O>this.thresholdMax)){O=0;}var L=(B>O)?(B-O):0;var C=this._sourceFilters.length;var M=this._categoryFilters.length;for(var I=L;I<B;I++){var F=false;var K=false;var N=J[I];var A=N.source;var D=N.category;for(var H=0;H<C;H++){if(A==this._sourceFilters[H]){K=true;break;}}if(K){for(var G=0;G<M;G++){if(D==this._categoryF!
 ilters[G]){F=true;break;}}}if(F){var E=this.formatMsg(N);if(this.newestOnTop){this._elConsole.innerHTML=E+this._elConsole.innerHTML;}else{this._elConsole.innerHTML+=E;}this._consoleMsgCount++;this._lastTime=N.time.getTime();}}};YAHOO.widget.LogReader.prototype._onCategoryCreate=function(D,C,A){var B=C[0];A._categoryFilters.push(B);if(A._elFt){A._createCategoryCheckbox(B);}};YAHOO.widget.LogReader.prototype._onSourceCreate=function(D,C,A){var B=C[0];A._sourceFilters.push(B);if(A._elFt){A._createSourceCheckbox(B);}};YAHOO.widget.LogReader.prototype._onCheckCategory=function(A,B){var C=this.category;if(!this.checked){B.hideCategory(C);}else{B.showCategory(C);}};YAHOO.widget.LogReader.prototype._onCheckSource=function(A,B){var C=this.source;if(!this.checked){B.hideSource(C);}else{B.showSource(C);}};YAHOO.widget.LogReader.prototype._onClickCollapseBtn=function(A,B){if(!B.isCollapsed){B.collapse();}else{B.expand();}};YAHOO.widget.LogReader.prototype._onClickPauseBtn=function(A,B)!
 {if(!B.isPaused){B.pause();}else{B.resume();}};YAHOO.widget.Lo!
 gReader.
prototype._onClickClearBtn=function(A,B){B.clearConsole();};YAHOO.widget.LogReader.prototype._onNewLog=function(D,C,A){var B=C[0];A._buffer.push(B);if(A.logReaderEnabled===true&&A._timeout===null){A._timeout=setTimeout(function(){A._printBuffer();},A.outputBuffer);}};YAHOO.widget.LogReader.prototype._onReset=function(C,B,A){A._filterLogs();};if(!YAHOO.widget.Logger){YAHOO.widget.Logger={loggerEnabled:true,_browserConsoleEnabled:false,categories:["info","warn","error","time","window"],sources:["global"],_stack:[],maxStackEntries:2500,_startTime:new Date().getTime(),_lastTime:null,_windowErrorsHandled:false,_origOnWindowError:null};YAHOO.widget.Logger.log=function(B,F,G){if(this.loggerEnabled){if(!F){F="info";}else{F=F.toLocaleLowerCase();if(this._isNewCategory(F)){this._createNewCategory(F);}}var C="global";var A=null;if(G){var D=G.indexOf(" ");if(D>0){C=G.substring(0,D);A=G.substring(D,G.length);}else{C=G;}if(this._isNewSource(C)){this._createNewSource(C);}}var H=new Date();!
 var J=new YAHOO.widget.LogMsg({msg:B,time:H,category:F,source:C,sourceDetail:A});var I=this._stack;var E=this.maxStackEntries;if(E&&!isNaN(E)&&(I.length>=E)){I.shift();}I.push(J);this.newLogEvent.fire(J);if(this._browserConsoleEnabled){this._printToBrowserConsole(J);}return true;}else{return false;}};YAHOO.widget.Logger.reset=function(){this._stack=[];this._startTime=new Date().getTime();this.loggerEnabled=true;this.log("Logger reset");this.logResetEvent.fire();};YAHOO.widget.Logger.getStack=function(){return this._stack;};YAHOO.widget.Logger.getStartTime=function(){return this._startTime;};YAHOO.widget.Logger.disableBrowserConsole=function(){YAHOO.log("Logger output to the function console.log() has been disabled.");this._browserConsoleEnabled=false;};YAHOO.widget.Logger.enableBrowserConsole=function(){this._browserConsoleEnabled=true;YAHOO.log("Logger output to the function console.log() has been enabled.");};YAHOO.widget.Logger.handleWindowErrors=function(){if(!YAHOO.wid!
 get.Logger._windowErrorsHandled){if(window.error){YAHOO.widget!
 .Logger.
_origOnWindowError=window.onerror;}window.onerror=YAHOO.widget.Logger._onWindowError;YAHOO.widget.Logger._windowErrorsHandled=true;YAHOO.log("Logger handling of window.onerror has been enabled.");}else{YAHOO.log("Logger handling of window.onerror had already been enabled.");}};YAHOO.widget.Logger.unhandleWindowErrors=function(){if(YAHOO.widget.Logger._windowErrorsHandled){if(YAHOO.widget.Logger._origOnWindowError){window.onerror=YAHOO.widget.Logger._origOnWindowError;YAHOO.widget.Logger._origOnWindowError=null;}else{window.onerror=null;}YAHOO.widget.Logger._windowErrorsHandled=false;YAHOO.log("Logger handling of window.onerror has been disabled.");}else{YAHOO.log("Logger handling of window.onerror had already been disabled.");}};YAHOO.widget.Logger.categoryCreateEvent=new YAHOO.util.CustomEvent("categoryCreate",this,true);YAHOO.widget.Logger.sourceCreateEvent=new YAHOO.util.CustomEvent("sourceCreate",this,true);YAHOO.widget.Logger.newLogEvent=new YAHOO.util.CustomEvent("newL!
 og",this,true);YAHOO.widget.Logger.logResetEvent=new YAHOO.util.CustomEvent("logReset",this,true);YAHOO.widget.Logger._createNewCategory=function(A){this.categories.push(A);this.categoryCreateEvent.fire(A);};YAHOO.widget.Logger._isNewCategory=function(B){for(var A=0;A<this.categories.length;A++){if(B==this.categories[A]){return false;}}return true;};YAHOO.widget.Logger._createNewSource=function(A){this.sources.push(A);this.sourceCreateEvent.fire(A);};YAHOO.widget.Logger._isNewSource=function(A){if(A){for(var B=0;B<this.sources.length;B++){if(A==this.sources[B]){return false;}}return true;}};YAHOO.widget.Logger._printToBrowserConsole=function(C){if(window.console&&console.log){var E=C.category;var D=C.category.substring(0,4).toUpperCase();var G=C.time;var F;if(G.toLocaleTimeString){F=G.toLocaleTimeString();}else{F=G.toString();}var H=G.getTime();var B=(YAHOO.widget.Logger._lastTime)?(H-YAHOO.widget.Logger._lastTime):0;
-YAHOO.widget.Logger._lastTime=H;var A=F+" ("+B+"ms): "+C.source+": "+C.msg;console.log(A);}};YAHOO.widget.Logger._onWindowError=function(A,C,B){try{YAHOO.widget.Logger.log(A+" ("+C+", line "+B+")","window");if(YAHOO.widget.Logger._origOnWindowError){YAHOO.widget.Logger._origOnWindowError();}}catch(D){return false;}};YAHOO.widget.Logger.log("Logger initialized");}YAHOO.register("logger",YAHOO.widget.Logger,{version:"2.4.1",build:"742"});
\ No newline at end of file
+YAHOO.widget.LogMsg=function(A){this.msg=this.time=this.category=this.source=this.sourceDetail=null;if(A&&(A.constructor==Object)){for(var B in A){this[B]=A[B];}}};YAHOO.widget.LogWriter=function(A){if(!A){YAHOO.log("Could not instantiate LogWriter due to invalid source.","error","LogWriter");return ;}this._source=A;};YAHOO.widget.LogWriter.prototype.toString=function(){return"LogWriter "+this._sSource;};YAHOO.widget.LogWriter.prototype.log=function(A,B){YAHOO.widget.Logger.log(A,B,this._source);};YAHOO.widget.LogWriter.prototype.getSource=function(){return this._sSource;};YAHOO.widget.LogWriter.prototype.setSource=function(A){if(!A){YAHOO.log("Could not set source due to invalid source.","error",this.toString());return ;}else{this._sSource=A;}};YAHOO.widget.LogWriter.prototype._source=null;YAHOO.widget.LogReader=function(B,A){this._sName=YAHOO.widget.LogReader._index;YAHOO.widget.LogReader._index++;this._buffer=[];this._filterCheckboxes={};this._lastTime=YAHOO.widget.Logge!
 r.getStartTime();if(A&&(A.constructor==Object)){for(var C in A){this[C]=A[C];}}this._initContainerEl(B);if(!this._elContainer){YAHOO.log("Could not instantiate LogReader due to an invalid container element "+B,"error",this.toString());return ;}this._initHeaderEl();this._initConsoleEl();this._initFooterEl();this._initDragDrop();this._initCategories();this._initSources();YAHOO.widget.Logger.newLogEvent.subscribe(this._onNewLog,this);YAHOO.widget.Logger.logResetEvent.subscribe(this._onReset,this);YAHOO.widget.Logger.categoryCreateEvent.subscribe(this._onCategoryCreate,this);YAHOO.widget.Logger.sourceCreateEvent.subscribe(this._onSourceCreate,this);this._filterLogs();YAHOO.log("LogReader initialized",null,this.toString());};YAHOO.lang.augmentObject(YAHOO.widget.LogReader,{_index:0,ENTRY_TEMPLATE:(function(){var A=document.createElement("pre");YAHOO.util.Dom.addClass(A,"yui-log-entry");return A;})(),VERBOSE_TEMPLATE:"<span class='{category}'>{label}</span>{totalTime}ms (+{elapse!
 dTime}) {localTime}:</p><p>{sourceAndDetail}</p><p>{message}</!
 p>",BASI
C_TEMPLATE:"<p><span class='{category}'>{label}</span>{totalTime}ms (+{elapsedTime}) {localTime}: {sourceAndDetail}: {message}</p>"});YAHOO.widget.LogReader.prototype={logReaderEnabled:true,width:null,height:null,top:null,left:null,right:null,bottom:null,fontSize:null,footerEnabled:true,verboseOutput:true,entryFormat:null,newestOnTop:true,outputBuffer:100,thresholdMax:500,thresholdMin:100,isCollapsed:false,isPaused:false,draggable:true,toString:function(){return"LogReader instance"+this._sName;},pause:function(){this.isPaused=true;this._btnPause.value="Resume";this._timeout=null;this.logReaderEnabled=false;},resume:function(){this.isPaused=false;this._btnPause.value="Pause";this.logReaderEnabled=true;this._printBuffer();},hide:function(){this._elContainer.style.display="none";},show:function(){this._elContainer.style.display="block";},collapse:function(){this._elConsole.style.display="none";if(this._elFt){this._elFt.style.display="none";}this._btnCollapse.value="Expand";this!
 .isCollapsed=true;},expand:function(){this._elConsole.style.display="block";if(this._elFt){this._elFt.style.display="block";}this._btnCollapse.value="Collapse";this.isCollapsed=false;},getCheckbox:function(A){return this._filterCheckboxes[A];},getCategories:function(){return this._categoryFilters;},showCategory:function(B){var D=this._categoryFilters;if(D.indexOf){if(D.indexOf(B)>-1){return ;}}else{for(var A=0;A<D.length;A++){if(D[A]===B){return ;}}}this._categoryFilters.push(B);this._filterLogs();var C=this.getCheckbox(B);if(C){C.checked=true;}},hideCategory:function(B){var D=this._categoryFilters;for(var A=0;A<D.length;A++){if(B==D[A]){D.splice(A,1);break;}}this._filterLogs();var C=this.getCheckbox(B);if(C){C.checked=false;}},getSources:function(){return this._sourceFilters;},showSource:function(A){var D=this._sourceFilters;if(D.indexOf){if(D.indexOf(A)>-1){return ;}}else{for(var B=0;B<D.length;B++){if(A==D[B]){return ;}}}D.push(A);this._filterLogs();var C=this.getCheckbo!
 x(A);if(C){C.checked=true;}},hideSource:function(A){var D=this!
 ._source
Filters;for(var B=0;B<D.length;B++){if(A==D[B]){D.splice(B,1);break;}}this._filterLogs();var C=this.getCheckbox(A);if(C){C.checked=false;}},clearConsole:function(){this._timeout=null;this._buffer=[];this._consoleMsgCount=0;var A=this._elConsole;A.innerHTML="";},setTitle:function(A){this._title.innerHTML=this.html2Text(A);},getLastTime:function(){return this._lastTime;},formatMsg:function(C){var B=YAHOO.widget.LogReader,A=this.entryFormat||(this.verboseOutput?B.VERBOSE_TEMPLATE:B.BASIC_TEMPLATE),D={category:C.category,label:C.category.substring(0,4).toUpperCase(),sourceAndDetail:C.sourceDetail?C.source+" "+C.sourceDetail:C.source,message:this.html2Text(C.msg||C.message||"")};if(C.time&&C.time.getTime){D.localTime=C.time.toLocaleTimeString?C.time.toLocaleTimeString():C.time.toString();D.elapsedTime=C.time.getTime()-this.getLastTime();D.totalTime=C.time.getTime()-YAHOO.widget.Logger.getStartTime();}var E=B.ENTRY_TEMPLATE.cloneNode(true);if(this.verboseOutput){E.className+=" yui!
 -log-verbose";}E.innerHTML=YAHOO.lang.substitute(A,D);return E;},html2Text:function(A){if(A){A+="";return A.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">");}return"";},_sName:null,_buffer:null,_consoleMsgCount:0,_lastTime:null,_timeout:null,_filterCheckboxes:null,_categoryFilters:null,_sourceFilters:null,_elContainer:null,_elHd:null,_elCollapse:null,_btnCollapse:null,_title:null,_elConsole:null,_elFt:null,_elBtns:null,_elCategoryFilters:null,_elSourceFilters:null,_btnPause:null,_btnClear:null,_initContainerEl:function(B){B=YAHOO.util.Dom.get(B);if(B&&B.tagName&&(B.tagName.toLowerCase()=="div")){this._elContainer=B;YAHOO.util.Dom.addClass(this._elContainer,"yui-log");}else{this._elContainer=document.body.appendChild(document.createElement("div"));YAHOO.util.Dom.addClass(this._elContainer,"yui-log");YAHOO.util.Dom.addClass(this._elContainer,"yui-log-container");var A=this._elContainer.style;
+if(this.width){A.width=this.width;}if(this.right){A.right=this.right;}if(this.top){A.top=this.top;}if(this.left){A.left=this.left;A.right="auto";}if(this.bottom){A.bottom=this.bottom;A.top="auto";}if(this.fontSize){A.fontSize=this.fontSize;}if(navigator.userAgent.toLowerCase().indexOf("opera")!=-1){document.body.style+="";}}},_initHeaderEl:function(){var A=this;if(this._elHd){YAHOO.util.Event.purgeElement(this._elHd,true);this._elHd.innerHTML="";}this._elHd=this._elContainer.appendChild(document.createElement("div"));this._elHd.id="yui-log-hd"+this._sName;this._elHd.className="yui-log-hd";this._elCollapse=this._elHd.appendChild(document.createElement("div"));this._elCollapse.className="yui-log-btns";this._btnCollapse=document.createElement("input");this._btnCollapse.type="button";this._btnCollapse.className="yui-log-button";this._btnCollapse.value="Collapse";this._btnCollapse=this._elCollapse.appendChild(this._btnCollapse);YAHOO.util.Event.addListener(A._btnCollapse,"click"!
 ,A._onClickCollapseBtn,A);this._title=this._elHd.appendChild(document.createElement("h4"));this._title.innerHTML="Logger Console";},_initConsoleEl:function(){if(this._elConsole){YAHOO.util.Event.purgeElement(this._elConsole,true);this._elConsole.innerHTML="";}this._elConsole=this._elContainer.appendChild(document.createElement("div"));this._elConsole.className="yui-log-bd";if(this.height){this._elConsole.style.height=this.height;}},_initFooterEl:function(){var A=this;if(this.footerEnabled){if(this._elFt){YAHOO.util.Event.purgeElement(this._elFt,true);this._elFt.innerHTML="";}this._elFt=this._elContainer.appendChild(document.createElement("div"));this._elFt.className="yui-log-ft";this._elBtns=this._elFt.appendChild(document.createElement("div"));this._elBtns.className="yui-log-btns";this._btnPause=document.createElement("input");this._btnPause.type="button";this._btnPause.className="yui-log-button";this._btnPause.value="Pause";this._btnPause=this._elBtns.appendChild(this._bt!
 nPause);YAHOO.util.Event.addListener(A._btnPause,"click",A._on!
 ClickPau
seBtn,A);this._btnClear=document.createElement("input");this._btnClear.type="button";this._btnClear.className="yui-log-button";this._btnClear.value="Clear";this._btnClear=this._elBtns.appendChild(this._btnClear);YAHOO.util.Event.addListener(A._btnClear,"click",A._onClickClearBtn,A);this._elCategoryFilters=this._elFt.appendChild(document.createElement("div"));this._elCategoryFilters.className="yui-log-categoryfilters";this._elSourceFilters=this._elFt.appendChild(document.createElement("div"));this._elSourceFilters.className="yui-log-sourcefilters";}},_initDragDrop:function(){if(YAHOO.util.DD&&this.draggable&&this._elHd){var A=new YAHOO.util.DD(this._elContainer);A.setHandleElId(this._elHd.id);this._elHd.style.cursor="move";}},_initCategories:function(){this._categoryFilters=[];var C=YAHOO.widget.Logger.categories;for(var A=0;A<C.length;A++){var B=C[A];this._categoryFilters.push(B);if(this._elCategoryFilters){this._createCategoryCheckbox(B);}}},_initSources:function(){this._so!
 urceFilters=[];var C=YAHOO.widget.Logger.sources;for(var B=0;B<C.length;B++){var A=C[B];this._sourceFilters.push(A);if(this._elSourceFilters){this._createSourceCheckbox(A);}}},_createCategoryCheckbox:function(B){var A=this;if(this._elFt){var E=this._elCategoryFilters;var D=E.appendChild(document.createElement("span"));D.className="yui-log-filtergrp";var C=document.createElement("input");C.id="yui-log-filter-"+B+this._sName;C.className="yui-log-filter-"+B;C.type="checkbox";C.category=B;C=D.appendChild(C);C.checked=true;YAHOO.util.Event.addListener(C,"click",A._onCheckCategory,A);var F=D.appendChild(document.createElement("label"));F.htmlFor=C.id;F.className=B;F.innerHTML=B;this._filterCheckboxes[B]=C;}},_createSourceCheckbox:function(A){var D=this;if(this._elFt){var F=this._elSourceFilters;var E=F.appendChild(document.createElement("span"));E.className="yui-log-filtergrp";var C=document.createElement("input");C.id="yui-log-filter"+A+this._sName;C.className="yui-log-filter"+A!
 ;C.type="checkbox";C.source=A;C=E.appendChild(C);C.checked=tru!
 e;YAHOO.
util.Event.addListener(C,"click",D._onCheckSource,D);var B=E.appendChild(document.createElement("label"));B.htmlFor=C.id;B.className=A;B.innerHTML=A;this._filterCheckboxes[A]=C;}},_filterLogs:function(){if(this._elConsole!==null){this.clearConsole();this._printToConsole(YAHOO.widget.Logger.getStack());}},_printBuffer:function(){this._timeout=null;if(this._elConsole!==null){var B=this.thresholdMax;B=(B&&!isNaN(B))?B:500;if(this._consoleMsgCount<B){var A=[];for(var C=0;C<this._buffer.length;C++){A[C]=this._buffer[C];}this._buffer=[];this._printToConsole(A);}else{this._filterLogs();}if(!this.newestOnTop){this._elConsole.scrollTop=this._elConsole.scrollHeight;}}},_printToConsole:function(I){var B=I.length,M=document.createDocumentFragment(),P=[],Q=this.thresholdMin,C=this._sourceFilters.length,N=this._categoryFilters.length,K,H,G,F,L;if(isNaN(Q)||(Q>this.thresholdMax)){Q=0;}K=(B>Q)?(B-Q):0;for(H=K;H<B;H++){var E=false;var J=false;var O=I[H];var A=O.source;var D=O.category;for(G=!
 0;G<C;G++){if(A==this._sourceFilters[G]){J=true;break;}}if(J){for(G=0;G<N;G++){if(D==this._categoryFilters[G]){E=true;break;}}}if(E){F=this.formatMsg(O);if(typeof F==="string"){P[P.length]=F;}else{M.insertBefore(F,this.newestOnTop?M.firstChild||null:null);}this._consoleMsgCount++;this._lastTime=O.time.getTime();}}if(P.length){P.splice(0,0,this._elConsole.innerHTML);this._elConsole.innerHTML=this.newestOnTop?P.reverse().join(""):P.join("");}else{if(M.firstChild){this._elConsole.insertBefore(M,this.newestOnTop?this._elConsole.firstChild||null:null);}}},_onCategoryCreate:function(D,C,A){var B=C[0];A._categoryFilters.push(B);if(A._elFt){A._createCategoryCheckbox(B);}},_onSourceCreate:function(D,C,A){var B=C[0];A._sourceFilters.push(B);if(A._elFt){A._createSourceCheckbox(B);}},_onCheckCategory:function(A,B){var C=this.category;if(!this.checked){B.hideCategory(C);}else{B.showCategory(C);}},_onCheckSource:function(A,B){var C=this.source;
+if(!this.checked){B.hideSource(C);}else{B.showSource(C);}},_onClickCollapseBtn:function(A,B){if(!B.isCollapsed){B.collapse();}else{B.expand();}},_onClickPauseBtn:function(A,B){if(!B.isPaused){B.pause();}else{B.resume();}},_onClickClearBtn:function(A,B){B.clearConsole();},_onNewLog:function(D,C,A){var B=C[0];A._buffer.push(B);if(A.logReaderEnabled===true&&A._timeout===null){A._timeout=setTimeout(function(){A._printBuffer();},A.outputBuffer);}},_onReset:function(C,B,A){A._filterLogs();}};if(!YAHOO.widget.Logger){YAHOO.widget.Logger={loggerEnabled:true,_browserConsoleEnabled:false,categories:["info","warn","error","time","window"],sources:["global"],_stack:[],maxStackEntries:2500,_startTime:new Date().getTime(),_lastTime:null,_windowErrorsHandled:false,_origOnWindowError:null};YAHOO.widget.Logger.log=function(B,F,G){if(this.loggerEnabled){if(!F){F="info";}else{F=F.toLocaleLowerCase();if(this._isNewCategory(F)){this._createNewCategory(F);}}var C="global";var A=null;if(G){var D=!
 G.indexOf(" ");if(D>0){C=G.substring(0,D);A=G.substring(D,G.length);}else{C=G;}if(this._isNewSource(C)){this._createNewSource(C);}}var H=new Date();var J=new YAHOO.widget.LogMsg({msg:B,time:H,category:F,source:C,sourceDetail:A});var I=this._stack;var E=this.maxStackEntries;if(E&&!isNaN(E)&&(I.length>=E)){I.shift();}I.push(J);this.newLogEvent.fire(J);if(this._browserConsoleEnabled){this._printToBrowserConsole(J);}return true;}else{return false;}};YAHOO.widget.Logger.reset=function(){this._stack=[];this._startTime=new Date().getTime();this.loggerEnabled=true;this.log("Logger reset");this.logResetEvent.fire();};YAHOO.widget.Logger.getStack=function(){return this._stack;};YAHOO.widget.Logger.getStartTime=function(){return this._startTime;};YAHOO.widget.Logger.disableBrowserConsole=function(){YAHOO.log("Logger output to the function console.log() has been disabled.");this._browserConsoleEnabled=false;};YAHOO.widget.Logger.enableBrowserConsole=function(){this._browserConsoleEnabl!
 ed=true;YAHOO.log("Logger output to the function console.log()!
  has bee
n enabled.");};YAHOO.widget.Logger.handleWindowErrors=function(){if(!YAHOO.widget.Logger._windowErrorsHandled){if(window.error){YAHOO.widget.Logger._origOnWindowError=window.onerror;}window.onerror=YAHOO.widget.Logger._onWindowError;YAHOO.widget.Logger._windowErrorsHandled=true;YAHOO.log("Logger handling of window.onerror has been enabled.");}else{YAHOO.log("Logger handling of window.onerror had already been enabled.");}};YAHOO.widget.Logger.unhandleWindowErrors=function(){if(YAHOO.widget.Logger._windowErrorsHandled){if(YAHOO.widget.Logger._origOnWindowError){window.onerror=YAHOO.widget.Logger._origOnWindowError;YAHOO.widget.Logger._origOnWindowError=null;}else{window.onerror=null;}YAHOO.widget.Logger._windowErrorsHandled=false;YAHOO.log("Logger handling of window.onerror has been disabled.");}else{YAHOO.log("Logger handling of window.onerror had already been disabled.");}};YAHOO.widget.Logger.categoryCreateEvent=new YAHOO.util.CustomEvent("categoryCreate",this,true);YAHOO.w!
 idget.Logger.sourceCreateEvent=new YAHOO.util.CustomEvent("sourceCreate",this,true);YAHOO.widget.Logger.newLogEvent=new YAHOO.util.CustomEvent("newLog",this,true);YAHOO.widget.Logger.logResetEvent=new YAHOO.util.CustomEvent("logReset",this,true);YAHOO.widget.Logger._createNewCategory=function(A){this.categories.push(A);this.categoryCreateEvent.fire(A);};YAHOO.widget.Logger._isNewCategory=function(B){for(var A=0;A<this.categories.length;A++){if(B==this.categories[A]){return false;}}return true;};YAHOO.widget.Logger._createNewSource=function(A){this.sources.push(A);this.sourceCreateEvent.fire(A);};YAHOO.widget.Logger._isNewSource=function(A){if(A){for(var B=0;B<this.sources.length;B++){if(A==this.sources[B]){return false;}}return true;}};YAHOO.widget.Logger._printToBrowserConsole=function(C){if(window.console&&console.log){var E=C.category;var D=C.category.substring(0,4).toUpperCase();var G=C.time;var F;if(G.toLocaleTimeString){F=G.toLocaleTimeString();}else{F=G.toString();}v!
 ar H=G.getTime();var B=(YAHOO.widget.Logger._lastTime)?(H-YAHO!
 O.widget
.Logger._lastTime):0;YAHOO.widget.Logger._lastTime=H;var A=F+" ("+B+"ms): "+C.source+": ";console.log(A,C.msg);}};YAHOO.widget.Logger._onWindowError=function(A,C,B){try{YAHOO.widget.Logger.log(A+" ("+C+", line "+B+")","window");if(YAHOO.widget.Logger._origOnWindowError){YAHOO.widget.Logger._origOnWindowError();}}catch(D){return false;}};YAHOO.widget.Logger.log("Logger initialized");}YAHOO.register("logger",YAHOO.widget.Logger,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/logger/logger.js
===================================================================
--- trunk/root/static/yui/logger/logger.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/logger/logger.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /****************************************************************************/
 /****************************************************************************/
@@ -15,63 +15,55 @@
  * @constructor
  * @param oConfigs {Object} Object literal of configuration params.
  */
- YAHOO.widget.LogMsg = function(oConfigs) {
+YAHOO.widget.LogMsg = function(oConfigs) {
     // Parse configs
+    /**
+     * Log message.
+     *
+     * @property msg
+     * @type String
+     */
+    this.msg =
+    /**
+     * Log timestamp.
+     *
+     * @property time
+     * @type Date
+     */
+    this.time =
+
+    /**
+     * Log category.
+     *
+     * @property category
+     * @type String
+     */
+    this.category =
+
+    /**
+     * Log source. The first word passed in as the source argument.
+     *
+     * @property source
+     * @type String
+     */
+    this.source =
+
+    /**
+     * Log source detail. The remainder of the string passed in as the source argument, not
+     * including the first word (if any).
+     *
+     * @property sourceDetail
+     * @type String
+     */
+    this.sourceDetail = null;
+
     if (oConfigs && (oConfigs.constructor == Object)) {
         for(var param in oConfigs) {
             this[param] = oConfigs[param];
         }
     }
- };
- 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public member variables
-//
-/////////////////////////////////////////////////////////////////////////////
+};
 
-/**
- * Log message.
- *
- * @property msg
- * @type String
- */
-YAHOO.widget.LogMsg.prototype.msg = null;
- 
-/**
- * Log timestamp.
- *
- * @property time
- * @type Date
- */
-YAHOO.widget.LogMsg.prototype.time = null;
-
-/**
- * Log category.
- *
- * @property category
- * @type String
- */
-YAHOO.widget.LogMsg.prototype.category = null;
-
-/**
- * Log source. The first word passed in as the source argument.
- *
- * @property source
- * @type String
- */
-YAHOO.widget.LogMsg.prototype.source = null;
-
-/**
- * Log source detail. The remainder of the string passed in as the source argument, not
- * including the first word (if any).
- *
- * @property sourceDetail
- * @type String
- */
-YAHOO.widget.LogMsg.prototype.sourceDetail = null;
-
-
 /****************************************************************************/
 /****************************************************************************/
 /****************************************************************************/
@@ -222,1286 +214,1342 @@
 
 /////////////////////////////////////////////////////////////////////////////
 //
+// Static member variables
+//
+/////////////////////////////////////////////////////////////////////////////
+YAHOO.lang.augmentObject(YAHOO.widget.LogReader, {
+    /**
+     * Internal class member to index multiple LogReader instances.
+     *
+     * @property _memberName
+     * @static
+     * @type Number
+     * @default 0
+     * @private
+     */
+    _index : 0,
+
+    /**
+     * Node template for the log entries
+     * @property ENTRY_TEMPLATE
+     * @static
+     * @type {HTMLElement}
+     * @default PRE.yui-log-entry element
+     */
+    ENTRY_TEMPLATE : (function () {
+        var t = document.createElement('pre');
+        YAHOO.util.Dom.addClass(t,'yui-log-entry');
+        return t;
+    })(),
+
+    /**
+     * Template used for innerHTML of verbose entry output.
+     * @property VERBOSE_TEMPLATE
+     * @static
+     * @default "<span class='{category}'>{label}</span>{totalTime}ms (+{elapsedTime}) {localTime}:</p><p>{sourceAndDetail}</p><p>{message}</p>"
+     */
+    VERBOSE_TEMPLATE : "<span class='{category}'>{label}</span>{totalTime}ms (+{elapsedTime}) {localTime}:</p><p>{sourceAndDetail}</p><p>{message}</p>",
+
+    /**
+     * Template used for innerHTML of compact entry output.
+     * @property BASIC_TEMPLATE
+     * @static
+     * @default "<p><span class='{category}'>{label}</span>{totalTime}ms (+{elapsedTime}) {localTime}: {sourceAndDetail}: {message}</p>"
+     */
+    BASIC_TEMPLATE : "<p><span class='{category}'>{label}</span>{totalTime}ms (+{elapsedTime}) {localTime}: {sourceAndDetail}: {message}</p>"
+});
+
+/////////////////////////////////////////////////////////////////////////////
+//
 // Public member variables
 //
 /////////////////////////////////////////////////////////////////////////////
 
-/**
- * Whether or not LogReader is enabled to output log messages.
- *
- * @property logReaderEnabled
- * @type Boolean
- * @default true
- */
-YAHOO.widget.LogReader.prototype.logReaderEnabled = true;
+YAHOO.widget.LogReader.prototype = {
+    /**
+     * Whether or not LogReader is enabled to output log messages.
+     *
+     * @property logReaderEnabled
+     * @type Boolean
+     * @default true
+     */
+    logReaderEnabled : true,
 
-/**
- * Public member to access CSS width of the LogReader container.
- *
- * @property width
- * @type String
- */
-YAHOO.widget.LogReader.prototype.width = null;
+    /**
+     * Public member to access CSS width of the LogReader container.
+     *
+     * @property width
+     * @type String
+     */
+    width : null,
 
-/**
- * Public member to access CSS height of the LogReader container.
- *
- * @property height
- * @type String
- */
-YAHOO.widget.LogReader.prototype.height = null;
+    /**
+     * Public member to access CSS height of the LogReader container.
+     *
+     * @property height
+     * @type String
+     */
+    height : null,
 
-/**
- * Public member to access CSS top position of the LogReader container.
- *
- * @property top
- * @type String
- */
-YAHOO.widget.LogReader.prototype.top = null;
+    /**
+     * Public member to access CSS top position of the LogReader container.
+     *
+     * @property top
+     * @type String
+     */
+    top : null,
 
-/**
- * Public member to access CSS left position of the LogReader container.
- *
- * @property left
- * @type String
- */
-YAHOO.widget.LogReader.prototype.left = null;
+    /**
+     * Public member to access CSS left position of the LogReader container.
+     *
+     * @property left
+     * @type String
+     */
+    left : null,
 
-/**
- * Public member to access CSS right position of the LogReader container.
- *
- * @property right
- * @type String
- */
-YAHOO.widget.LogReader.prototype.right = null;
+    /**
+     * Public member to access CSS right position of the LogReader container.
+     *
+     * @property right
+     * @type String
+     */
+    right : null,
 
-/**
- * Public member to access CSS bottom position of the LogReader container.
- *
- * @property bottom
- * @type String
- */
-YAHOO.widget.LogReader.prototype.bottom = null;
+    /**
+     * Public member to access CSS bottom position of the LogReader container.
+     *
+     * @property bottom
+     * @type String
+     */
+    bottom : null,
 
-/**
- * Public member to access CSS font size of the LogReader container.
- *
- * @property fontSize
- * @type String
- */
-YAHOO.widget.LogReader.prototype.fontSize = null;
+    /**
+     * Public member to access CSS font size of the LogReader container.
+     *
+     * @property fontSize
+     * @type String
+     */
+    fontSize : null,
 
-/**
- * Whether or not the footer UI is enabled for the LogReader.
- *
- * @property footerEnabled
- * @type Boolean
- * @default true
- */
-YAHOO.widget.LogReader.prototype.footerEnabled = true;
+    /**
+     * Whether or not the footer UI is enabled for the LogReader.
+     *
+     * @property footerEnabled
+     * @type Boolean
+     * @default true
+     */
+    footerEnabled : true,
 
-/**
- * Whether or not output is verbose (more readable). Setting to true will make
- * output more compact (less readable).
- *
- * @property verboseOutput
- * @type Boolean
- * @default true
- */
-YAHOO.widget.LogReader.prototype.verboseOutput = true;
+    /**
+     * Whether or not output is verbose (more readable). Setting to true will make
+     * output more compact (less readable).
+     *
+     * @property verboseOutput
+     * @type Boolean
+     * @default true
+     */
+    verboseOutput : true,
 
-/**
- * Whether or not newest message is printed on top.
- *
- * @property newestOnTop
- * @type Boolean
- */
-YAHOO.widget.LogReader.prototype.newestOnTop = true;
+    /**
+     * Custom output format for log messages.  Defaults to null, which falls
+     * back to verboseOutput param deciding between LogReader.VERBOSE_TEMPLATE
+     * and LogReader.BASIC_TEMPLATE.  Use bracketed place holders to mark where
+     * message info should go.  Available place holder names include:
+     * <ul>
+     *  <li>category</li>
+     *  <li>label</li>
+     *  <li>sourceAndDetail</li>
+     *  <li>message</li>
+     *  <li>localTime</li>
+     *  <li>elapsedTime</li>
+     *  <li>totalTime</li>
+     * </ul>
+     *
+     * @property entryFormat
+     * @type String
+     * @default null
+     */
+    entryFormat : null,
 
-/**
- * Output timeout buffer in milliseconds.
- *
- * @property outputBuffer
- * @type Number
- * @default 100
- */
-YAHOO.widget.LogReader.prototype.outputBuffer = 100;
+    /**
+     * Whether or not newest message is printed on top.
+     *
+     * @property newestOnTop
+     * @type Boolean
+     */
+    newestOnTop : true,
 
-/**
- * Maximum number of messages a LogReader console will display.
- *
- * @property thresholdMax
- * @type Number
- * @default 500
- */
-YAHOO.widget.LogReader.prototype.thresholdMax = 500;
+    /**
+     * Output timeout buffer in milliseconds.
+     *
+     * @property outputBuffer
+     * @type Number
+     * @default 100
+     */
+    outputBuffer : 100,
 
-/**
- * When a LogReader console reaches its thresholdMax, it will clear out messages
- * and print out the latest thresholdMin number of messages.
- *
- * @property thresholdMin
- * @type Number
- * @default 100
- */
-YAHOO.widget.LogReader.prototype.thresholdMin = 100;
+    /**
+     * Maximum number of messages a LogReader console will display.
+     *
+     * @property thresholdMax
+     * @type Number
+     * @default 500
+     */
+    thresholdMax : 500,
 
-/**
- * True when LogReader is in a collapsed state, false otherwise.
- *
- * @property isCollapsed
- * @type Boolean
- * @default false
- */
-YAHOO.widget.LogReader.prototype.isCollapsed = false;
+    /**
+     * When a LogReader console reaches its thresholdMax, it will clear out messages
+     * and print out the latest thresholdMin number of messages.
+     *
+     * @property thresholdMin
+     * @type Number
+     * @default 100
+     */
+    thresholdMin : 100,
 
-/**
- * True when LogReader is in a paused state, false otherwise.
- *
- * @property isPaused
- * @type Boolean
- * @default false
- */
-YAHOO.widget.LogReader.prototype.isPaused = false;
+    /**
+     * True when LogReader is in a collapsed state, false otherwise.
+     *
+     * @property isCollapsed
+     * @type Boolean
+     * @default false
+     */
+    isCollapsed : false,
 
-/**
- * Enables draggable LogReader if DragDrop Utility is present.
- *
- * @property draggable
- * @type Boolean
- * @default true
- */
-YAHOO.widget.LogReader.prototype.draggable = true;
+    /**
+     * True when LogReader is in a paused state, false otherwise.
+     *
+     * @property isPaused
+     * @type Boolean
+     * @default false
+     */
+    isPaused : false,
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Public methods
-//
-/////////////////////////////////////////////////////////////////////////////
+    /**
+     * Enables draggable LogReader if DragDrop Utility is present.
+     *
+     * @property draggable
+     * @type Boolean
+     * @default true
+     */
+    draggable : true,
 
- /**
- * Public accessor to the unique name of the LogReader instance.
- *
- * @method toString
- * @return {String} Unique name of the LogReader instance.
- */
-YAHOO.widget.LogReader.prototype.toString = function() {
-    return "LogReader instance" + this._sName;
-};
-/**
- * Pauses output of log messages. While paused, log messages are not lost, but
- * get saved to a buffer and then output upon resume of LogReader.
- *
- * @method pause
- */
-YAHOO.widget.LogReader.prototype.pause = function() {
-    this.isPaused = true;
-    this._btnPause.value = "Resume";
-    this._timeout = null;
-    this.logReaderEnabled = false;
-};
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Public methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
 
-/**
- * Resumes output of log messages, including outputting any log messages that
- * have been saved to buffer while paused.
- *
- * @method resume
- */
-YAHOO.widget.LogReader.prototype.resume = function() {
-    this.isPaused = false;
-    this._btnPause.value = "Pause";
-    this.logReaderEnabled = true;
-    this._printBuffer();
-};
+     /**
+     * Public accessor to the unique name of the LogReader instance.
+     *
+     * @method toString
+     * @return {String} Unique name of the LogReader instance.
+     */
+    toString : function() {
+        return "LogReader instance" + this._sName;
+    },
+    /**
+     * Pauses output of log messages. While paused, log messages are not lost, but
+     * get saved to a buffer and then output upon resume of LogReader.
+     *
+     * @method pause
+     */
+    pause : function() {
+        this.isPaused = true;
+        this._btnPause.value = "Resume";
+        this._timeout = null;
+        this.logReaderEnabled = false;
+    },
 
-/**
- * Hides UI of LogReader. Logging functionality is not disrupted.
- *
- * @method hide
- */
-YAHOO.widget.LogReader.prototype.hide = function() {
-    this._elContainer.style.display = "none";
-};
+    /**
+     * Resumes output of log messages, including outputting any log messages that
+     * have been saved to buffer while paused.
+     *
+     * @method resume
+     */
+    resume : function() {
+        this.isPaused = false;
+        this._btnPause.value = "Pause";
+        this.logReaderEnabled = true;
+        this._printBuffer();
+    },
 
-/**
- * Shows UI of LogReader. Logging functionality is not disrupted.
- *
- * @method show
- */
-YAHOO.widget.LogReader.prototype.show = function() {
-    this._elContainer.style.display = "block";
-};
+    /**
+     * Hides UI of LogReader. Logging functionality is not disrupted.
+     *
+     * @method hide
+     */
+    hide : function() {
+        this._elContainer.style.display = "none";
+    },
 
-/**
- * Collapses UI of LogReader. Logging functionality is not disrupted.
- *
- * @method collapse
- */
-YAHOO.widget.LogReader.prototype.collapse = function() {
-    this._elConsole.style.display = "none";
-    if(this._elFt) {
-        this._elFt.style.display = "none";
-    }
-    this._btnCollapse.value = "Expand";
-    this.isCollapsed = true;
-};
+    /**
+     * Shows UI of LogReader. Logging functionality is not disrupted.
+     *
+     * @method show
+     */
+    show : function() {
+        this._elContainer.style.display = "block";
+    },
 
-/**
- * Expands UI of LogReader. Logging functionality is not disrupted.
- *
- * @method expand
- */
-YAHOO.widget.LogReader.prototype.expand = function() {
-    this._elConsole.style.display = "block";
-    if(this._elFt) {
-        this._elFt.style.display = "block";
-    }
-    this._btnCollapse.value = "Collapse";
-    this.isCollapsed = false;
-};
+    /**
+     * Collapses UI of LogReader. Logging functionality is not disrupted.
+     *
+     * @method collapse
+     */
+    collapse : function() {
+        this._elConsole.style.display = "none";
+        if(this._elFt) {
+            this._elFt.style.display = "none";
+        }
+        this._btnCollapse.value = "Expand";
+        this.isCollapsed = true;
+    },
 
-/**
- * Returns related checkbox element for given filter (i.e., category or source).
- *
- * @method getCheckbox
- * @param {String} Category or source name.
- * @return {Array} Array of all filter checkboxes.
- */
-YAHOO.widget.LogReader.prototype.getCheckbox = function(filter) {
-    return this._filterCheckboxes[filter];
-};
+    /**
+     * Expands UI of LogReader. Logging functionality is not disrupted.
+     *
+     * @method expand
+     */
+    expand : function() {
+        this._elConsole.style.display = "block";
+        if(this._elFt) {
+            this._elFt.style.display = "block";
+        }
+        this._btnCollapse.value = "Collapse";
+        this.isCollapsed = false;
+    },
 
-/**
- * Returns array of enabled categories.
- *
- * @method getCategories
- * @return {String[]} Array of enabled categories.
- */
-YAHOO.widget.LogReader.prototype.getCategories = function() {
-    return this._categoryFilters;
-};
+    /**
+     * Returns related checkbox element for given filter (i.e., category or source).
+     *
+     * @method getCheckbox
+     * @param {String} Category or source name.
+     * @return {Array} Array of all filter checkboxes.
+     */
+    getCheckbox : function(filter) {
+        return this._filterCheckboxes[filter];
+    },
 
-/**
- * Shows log messages associated with given category.
- *
- * @method showCategory
- * @param {String} Category name.
- */
-YAHOO.widget.LogReader.prototype.showCategory = function(sCategory) {
-    var filtersArray = this._categoryFilters;
-    // Don't do anything if category is already enabled
-    // Use Array.indexOf if available...
-    if(filtersArray.indexOf) {
-         if(filtersArray.indexOf(sCategory) >  -1) {
-            return;
-        }
-    }
-    // ...or do it the old-fashioned way
-    else {
-        for(var i=0; i<filtersArray.length; i++) {
-           if(filtersArray[i] === sCategory){
+    /**
+     * Returns array of enabled categories.
+     *
+     * @method getCategories
+     * @return {String[]} Array of enabled categories.
+     */
+    getCategories : function() {
+        return this._categoryFilters;
+    },
+
+    /**
+     * Shows log messages associated with given category.
+     *
+     * @method showCategory
+     * @param {String} Category name.
+     */
+    showCategory : function(sCategory) {
+        var filtersArray = this._categoryFilters;
+        // Don't do anything if category is already enabled
+        // Use Array.indexOf if available...
+        if(filtersArray.indexOf) {
+             if(filtersArray.indexOf(sCategory) >  -1) {
                 return;
             }
         }
-    }
+        // ...or do it the old-fashioned way
+        else {
+            for(var i=0; i<filtersArray.length; i++) {
+               if(filtersArray[i] === sCategory){
+                    return;
+                }
+            }
+        }
 
-    this._categoryFilters.push(sCategory);
-    this._filterLogs();
-    var elCheckbox = this.getCheckbox(sCategory);
-    if(elCheckbox) {
-        elCheckbox.checked = true;
-    }
-};
+        this._categoryFilters.push(sCategory);
+        this._filterLogs();
+        var elCheckbox = this.getCheckbox(sCategory);
+        if(elCheckbox) {
+            elCheckbox.checked = true;
+        }
+    },
 
-/**
- * Hides log messages associated with given category.
- *
- * @method hideCategory
- * @param {String} Category name.
- */
-YAHOO.widget.LogReader.prototype.hideCategory = function(sCategory) {
-    var filtersArray = this._categoryFilters;
-    for(var i=0; i<filtersArray.length; i++) {
-        if(sCategory == filtersArray[i]) {
-            filtersArray.splice(i, 1);
-            break;
+    /**
+     * Hides log messages associated with given category.
+     *
+     * @method hideCategory
+     * @param {String} Category name.
+     */
+    hideCategory : function(sCategory) {
+        var filtersArray = this._categoryFilters;
+        for(var i=0; i<filtersArray.length; i++) {
+            if(sCategory == filtersArray[i]) {
+                filtersArray.splice(i, 1);
+                break;
+            }
         }
-    }
-    this._filterLogs();
-    var elCheckbox = this.getCheckbox(sCategory);
-    if(elCheckbox) {
-        elCheckbox.checked = false;
-    }
-};
+        this._filterLogs();
+        var elCheckbox = this.getCheckbox(sCategory);
+        if(elCheckbox) {
+            elCheckbox.checked = false;
+        }
+    },
 
-/**
- * Returns array of enabled sources.
- *
- * @method getSources
- * @return {Array} Array of enabled sources.
- */
-YAHOO.widget.LogReader.prototype.getSources = function() {
-    return this._sourceFilters;
-};
+    /**
+     * Returns array of enabled sources.
+     *
+     * @method getSources
+     * @return {Array} Array of enabled sources.
+     */
+    getSources : function() {
+        return this._sourceFilters;
+    },
 
-/**
- * Shows log messages associated with given source.
- *
- * @method showSource
- * @param {String} Source name.
- */
-YAHOO.widget.LogReader.prototype.showSource = function(sSource) {
-    var filtersArray = this._sourceFilters;
-    // Don't do anything if category is already enabled
-    // Use Array.indexOf if available...
-    if(filtersArray.indexOf) {
-         if(filtersArray.indexOf(sSource) >  -1) {
-            return;
-        }
-    }
-    // ...or do it the old-fashioned way
-    else {
-        for(var i=0; i<filtersArray.length; i++) {
-           if(sSource == filtersArray[i]){
+    /**
+     * Shows log messages associated with given source.
+     *
+     * @method showSource
+     * @param {String} Source name.
+     */
+    showSource : function(sSource) {
+        var filtersArray = this._sourceFilters;
+        // Don't do anything if category is already enabled
+        // Use Array.indexOf if available...
+        if(filtersArray.indexOf) {
+             if(filtersArray.indexOf(sSource) >  -1) {
                 return;
             }
         }
-    }
-    filtersArray.push(sSource);
-    this._filterLogs();
-    var elCheckbox = this.getCheckbox(sSource);
-    if(elCheckbox) {
-        elCheckbox.checked = true;
-    }
-};
+        // ...or do it the old-fashioned way
+        else {
+            for(var i=0; i<filtersArray.length; i++) {
+               if(sSource == filtersArray[i]){
+                    return;
+                }
+            }
+        }
+        filtersArray.push(sSource);
+        this._filterLogs();
+        var elCheckbox = this.getCheckbox(sSource);
+        if(elCheckbox) {
+            elCheckbox.checked = true;
+        }
+    },
 
-/**
- * Hides log messages associated with given source.
- *
- * @method hideSource
- * @param {String} Source name.
- */
-YAHOO.widget.LogReader.prototype.hideSource = function(sSource) {
-    var filtersArray = this._sourceFilters;
-    for(var i=0; i<filtersArray.length; i++) {
-        if(sSource == filtersArray[i]) {
-            filtersArray.splice(i, 1);
-            break;
+    /**
+     * Hides log messages associated with given source.
+     *
+     * @method hideSource
+     * @param {String} Source name.
+     */
+    hideSource : function(sSource) {
+        var filtersArray = this._sourceFilters;
+        for(var i=0; i<filtersArray.length; i++) {
+            if(sSource == filtersArray[i]) {
+                filtersArray.splice(i, 1);
+                break;
+            }
         }
-    }
-    this._filterLogs();
-    var elCheckbox = this.getCheckbox(sSource);
-    if(elCheckbox) {
-        elCheckbox.checked = false;
-    }
-};
+        this._filterLogs();
+        var elCheckbox = this.getCheckbox(sSource);
+        if(elCheckbox) {
+            elCheckbox.checked = false;
+        }
+    },
 
-/**
- * Does not delete any log messages, but clears all printed log messages from
- * the console. Log messages will be printed out again if user re-filters. The
- * static method YAHOO.widget.Logger.reset() should be called in order to
- * actually delete log messages.
- *
- * @method clearConsole
- */
-YAHOO.widget.LogReader.prototype.clearConsole = function() {
-    // Clear the buffer of any pending messages
-    this._timeout = null;
-    this._buffer = [];
-    this._consoleMsgCount = 0;
+    /**
+     * Does not delete any log messages, but clears all printed log messages from
+     * the console. Log messages will be printed out again if user re-filters. The
+     * static method YAHOO.widget.Logger.reset() should be called in order to
+     * actually delete log messages.
+     *
+     * @method clearConsole
+     */
+    clearConsole : function() {
+        // Clear the buffer of any pending messages
+        this._timeout = null;
+        this._buffer = [];
+        this._consoleMsgCount = 0;
 
-    var elConsole = this._elConsole;
-    while(elConsole.hasChildNodes()) {
-        elConsole.removeChild(elConsole.firstChild);
-    }
-};
+        var elConsole = this._elConsole;
+        elConsole.innerHTML = '';
+    },
 
-/**
- * Updates title to given string.
- *
- * @method setTitle
- * @param sTitle {String} New title.
- */
-YAHOO.widget.LogReader.prototype.setTitle = function(sTitle) {
-    this._title.innerHTML = this.html2Text(sTitle);
-};
+    /**
+     * Updates title to given string.
+     *
+     * @method setTitle
+     * @param sTitle {String} New title.
+     */
+    setTitle : function(sTitle) {
+        this._title.innerHTML = this.html2Text(sTitle);
+    },
 
-/**
- * Gets timestamp of the last log.
- *
- * @method getLastTime
- * @return {Date} Timestamp of the last log.
- */
-YAHOO.widget.LogReader.prototype.getLastTime = function() {
-    return this._lastTime;
-};
+    /**
+     * Gets timestamp of the last log.
+     *
+     * @method getLastTime
+     * @return {Date} Timestamp of the last log.
+     */
+    getLastTime : function() {
+        return this._lastTime;
+    },
 
-/**
- * Formats message string to HTML for output to console.
- *
- * @method formatMsg
- * @param oLogMsg {Object} Log message object.
- * @return {String} HTML-formatted message for output to console.
- */
-YAHOO.widget.LogReader.prototype.formatMsg = function(oLogMsg) {
-    var category = oLogMsg.category;
-    
-    // Label for color-coded display
-    var label = category.substring(0,4).toUpperCase();
+    formatMsg : function (entry) {
+        var Static      = YAHOO.widget.LogReader,
+            entryFormat = this.entryFormat || (this.verboseOutput ?
+                          Static.VERBOSE_TEMPLATE : Static.BASIC_TEMPLATE),
+            info        = {
+                category : entry.category,
 
-    // Calculate the elapsed time to be from the last item that passed through the filter,
-    // not the absolute previous item in the stack
+                // Label for color-coded display
+                label : entry.category.substring(0,4).toUpperCase(),
 
-    var time = oLogMsg.time;
-    var localTime;
-    if (time.toLocaleTimeString) {
-        localTime  = time.toLocaleTimeString();
-    }
-    else {
-        localTime = time.toString();
-    }
+                sourceAndDetail : entry.sourceDetail ?
+                                  entry.source + " " + entry.sourceDetail :
+                                  entry.source,
 
-    var msecs = time.getTime();
-    var startTime = YAHOO.widget.Logger.getStartTime();
-    var totalTime = msecs - startTime;
-    var elapsedTime = msecs - this.getLastTime();
+                // Escape HTML entities in the log message itself for output
+                // to console
+                message : this.html2Text(entry.msg || entry.message || '')
+            };
 
-    var source = oLogMsg.source;
-    var sourceDetail = oLogMsg.sourceDetail;
-    var sourceAndDetail = (sourceDetail) ?
-        source + " " + sourceDetail : source;
-        
-    
-    // Escape HTML entities in the log message itself for output to console
-    //var msg = this.html2Text(oLogMsg.msg); //TODO: delete
-    var msg = this.html2Text(YAHOO.lang.dump(oLogMsg.msg));
+        // Add time info
+        if (entry.time && entry.time.getTime) {
+            info.localTime = entry.time.toLocaleTimeString ?
+                             entry.time.toLocaleTimeString() :
+                             entry.time.toString();
 
-    // Verbose output includes extra line breaks
-    var output =  (this.verboseOutput) ?
-        ["<pre class=\"yui-log-verbose\"><p><span class='", category, "'>", label, "</span> ",
-        totalTime, "ms (+", elapsedTime, ") ",
-        localTime, ": ",
-        "</p><p>",
-        sourceAndDetail,
-        ": </p><p>",
-        msg,
-        "</p></pre>"] :
+            // Calculate the elapsed time to be from the last item that
+            // passed through the filter, not the absolute previous item
+            // in the stack
+            info.elapsedTime = entry.time.getTime() - this.getLastTime();
 
-        ["<pre><p><span class='", category, "'>", label, "</span> ",
-        totalTime, "ms (+", elapsedTime, ") ",
-        localTime, ": ",
-        sourceAndDetail, ": ",
-        msg, "</p></pre>"];
+            info.totalTime = entry.time.getTime() -
+                               YAHOO.widget.Logger.getStartTime();
+        }
 
-    return output.join("");
-};
+        var msg = Static.ENTRY_TEMPLATE.cloneNode(true);
+        if (this.verboseOutput) {
+            msg.className += ' yui-log-verbose';
+        }
 
-/**
- * Converts input chars "<", ">", and "&" to HTML entities.
- *
- * @method html2Text
- * @param sHtml {String} String to convert.
- * @private
- */
-YAHOO.widget.LogReader.prototype.html2Text = function(sHtml) {
-    if(sHtml) {
-        sHtml += "";
-        return sHtml.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
-    }
-    return "";
-};
+        msg.innerHTML = YAHOO.lang.substitute(entryFormat, info);
 
+        return msg;
+    },
+
+    /**
+     * Converts input chars "<", ">", and "&" to HTML entities.
+     *
+     * @method html2Text
+     * @param sHtml {String} String to convert.
+     * @private
+     */
+    html2Text : function(sHtml) {
+        if(sHtml) {
+            sHtml += "";
+            return sHtml.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
+        }
+        return "";
+    },
+
 /////////////////////////////////////////////////////////////////////////////
 //
 // Private member variables
 //
 /////////////////////////////////////////////////////////////////////////////
 
-/**
- * Internal class member to index multiple LogReader instances.
- *
- * @property _memberName
- * @static
- * @type Number
- * @default 0
- * @private
- */
-YAHOO.widget.LogReader._index = 0;
+    /**
+     * Name of LogReader instance.
+     *
+     * @property _sName
+     * @type String
+     * @private
+     */
+    _sName : null,
 
-/**
- * Name of LogReader instance.
- *
- * @property _sName
- * @type String
- * @private
- */
-YAHOO.widget.LogReader.prototype._sName = null;
+    //TODO: remove
+    /**
+     * A class member shared by all LogReaders if a container needs to be
+     * created during instantiation. Will be null if a container element never needs to
+     * be created on the fly, such as when the implementer passes in their own element.
+     *
+     * @property _elDefaultContainer
+     * @type HTMLElement
+     * @private
+     */
+    //YAHOO.widget.LogReader._elDefaultContainer = null;
 
-//TODO: remove
-/**
- * A class member shared by all LogReaders if a container needs to be
- * created during instantiation. Will be null if a container element never needs to
- * be created on the fly, such as when the implementer passes in their own element.
- *
- * @property _elDefaultContainer
- * @type HTMLElement
- * @private
- */
-//YAHOO.widget.LogReader._elDefaultContainer = null;
+    /**
+     * Buffer of log message objects for batch output.
+     *
+     * @property _buffer
+     * @type Object[]
+     * @private
+     */
+    _buffer : null,
 
-/**
- * Buffer of log message objects for batch output.
- *
- * @property _buffer
- * @type Object[]
- * @private
- */
-YAHOO.widget.LogReader.prototype._buffer = null;
+    /**
+     * Number of log messages output to console.
+     *
+     * @property _consoleMsgCount
+     * @type Number
+     * @default 0
+     * @private
+     */
+    _consoleMsgCount : 0,
 
-/**
- * Number of log messages output to console.
- *
- * @property _consoleMsgCount
- * @type Number
- * @default 0
- * @private
- */
-YAHOO.widget.LogReader.prototype._consoleMsgCount = 0;
+    /**
+     * Date of last output log message.
+     *
+     * @property _lastTime
+     * @type Date
+     * @private
+     */
+    _lastTime : null,
 
-/**
- * Date of last output log message.
- *
- * @property _lastTime
- * @type Date
- * @private
- */
-YAHOO.widget.LogReader.prototype._lastTime = null;
+    /**
+     * Batched output timeout ID.
+     *
+     * @property _timeout
+     * @type Number
+     * @private
+     */
+    _timeout : null,
 
-/**
- * Batched output timeout ID.
- *
- * @property _timeout
- * @type Number
- * @private
- */
-YAHOO.widget.LogReader.prototype._timeout = null;
+    /**
+     * Hash of filters and their related checkbox elements.
+     *
+     * @property _filterCheckboxes
+     * @type Object
+     * @private
+     */
+    _filterCheckboxes : null,
 
-/**
- * Hash of filters and their related checkbox elements.
- *
- * @property _filterCheckboxes
- * @type Object
- * @private
- */
-YAHOO.widget.LogReader.prototype._filterCheckboxes = null;
+    /**
+     * Array of filters for log message categories.
+     *
+     * @property _categoryFilters
+     * @type String[]
+     * @private
+     */
+    _categoryFilters : null,
 
-/**
- * Array of filters for log message categories.
- *
- * @property _categoryFilters
- * @type String[]
- * @private
- */
-YAHOO.widget.LogReader.prototype._categoryFilters = null;
+    /**
+     * Array of filters for log message sources.
+     *
+     * @property _sourceFilters
+     * @type String[]
+     * @private
+     */
+    _sourceFilters : null,
 
-/**
- * Array of filters for log message sources.
- *
- * @property _sourceFilters
- * @type String[]
- * @private
- */
-YAHOO.widget.LogReader.prototype._sourceFilters = null;
+    /**
+     * LogReader container element.
+     *
+     * @property _elContainer
+     * @type HTMLElement
+     * @private
+     */
+    _elContainer : null,
 
-/**
- * LogReader container element.
- *
- * @property _elContainer
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elContainer = null;
+    /**
+     * LogReader header element.
+     *
+     * @property _elHd
+     * @type HTMLElement
+     * @private
+     */
+    _elHd : null,
 
-/**
- * LogReader header element.
- *
- * @property _elHd
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elHd = null;
+    /**
+     * LogReader collapse element.
+     *
+     * @property _elCollapse
+     * @type HTMLElement
+     * @private
+     */
+    _elCollapse : null,
 
-/**
- * LogReader collapse element.
- *
- * @property _elCollapse
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elCollapse = null;
+    /**
+     * LogReader collapse button element.
+     *
+     * @property _btnCollapse
+     * @type HTMLElement
+     * @private
+     */
+    _btnCollapse : null,
 
-/**
- * LogReader collapse button element.
- *
- * @property _btnCollapse
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._btnCollapse = null;
+    /**
+     * LogReader title header element.
+     *
+     * @property _title
+     * @type HTMLElement
+     * @private
+     */
+    _title : null,
 
-/**
- * LogReader title header element.
- *
- * @property _title
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._title = null;
+    /**
+     * LogReader console element.
+     *
+     * @property _elConsole
+     * @type HTMLElement
+     * @private
+     */
+    _elConsole : null,
 
-/**
- * LogReader console element.
- *
- * @property _elConsole
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elConsole = null;
+    /**
+     * LogReader footer element.
+     *
+     * @property _elFt
+     * @type HTMLElement
+     * @private
+     */
+    _elFt : null,
 
-/**
- * LogReader footer element.
- *
- * @property _elFt
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elFt = null;
+    /**
+     * LogReader buttons container element.
+     *
+     * @property _elBtns
+     * @type HTMLElement
+     * @private
+     */
+    _elBtns : null,
 
-/**
- * LogReader buttons container element.
- *
- * @property _elBtns
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elBtns = null;
+    /**
+     * Container element for LogReader category filter checkboxes.
+     *
+     * @property _elCategoryFilters
+     * @type HTMLElement
+     * @private
+     */
+    _elCategoryFilters : null,
 
-/**
- * Container element for LogReader category filter checkboxes.
- *
- * @property _elCategoryFilters
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elCategoryFilters = null;
+    /**
+     * Container element for LogReader source filter checkboxes.
+     *
+     * @property _elSourceFilters
+     * @type HTMLElement
+     * @private
+     */
+    _elSourceFilters : null,
 
-/**
- * Container element for LogReader source filter checkboxes.
- *
- * @property _elSourceFilters
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._elSourceFilters = null;
+    /**
+     * LogReader pause button element.
+     *
+     * @property _btnPause
+     * @type HTMLElement
+     * @private
+     */
+    _btnPause : null,
 
-/**
- * LogReader pause button element.
- *
- * @property _btnPause
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._btnPause = null;
+    /**
+     * Clear button element.
+     *
+     * @property _btnClear
+     * @type HTMLElement
+     * @private
+     */
+    _btnClear : null,
 
-/**
- * Clear button element.
- *
- * @property _btnClear
- * @type HTMLElement
- * @private
- */
-YAHOO.widget.LogReader.prototype._btnClear = null;
+    /////////////////////////////////////////////////////////////////////////////
+    //
+    // Private methods
+    //
+    /////////////////////////////////////////////////////////////////////////////
 
-/////////////////////////////////////////////////////////////////////////////
-//
-// Private methods
-//
-/////////////////////////////////////////////////////////////////////////////
+    /**
+     * Initializes the primary container element.
+     *
+     * @method _initContainerEl
+     * @param elContainer {HTMLElement} Container element by reference or string ID.
+     * @private
+     */
+    _initContainerEl : function(elContainer) {
+        // Validate container
+        elContainer = YAHOO.util.Dom.get(elContainer);
+        // Attach to existing container...
+        if(elContainer && elContainer.tagName && (elContainer.tagName.toLowerCase() == "div")) {
+            this._elContainer = elContainer;
+            YAHOO.util.Dom.addClass(this._elContainer,"yui-log");
+        }
+        // ...or create container from scratch
+        else {
+            this._elContainer = document.body.appendChild(document.createElement("div"));
+            //this._elContainer.id = "yui-log" + this._sName;
+            YAHOO.util.Dom.addClass(this._elContainer,"yui-log");
+            YAHOO.util.Dom.addClass(this._elContainer,"yui-log-container");
 
-/**
- * Initializes the primary container element.
- *
- * @method _initContainerEl
- * @param elContainer {HTMLElement} Container element by reference or string ID.
- * @private
- */
-YAHOO.widget.LogReader.prototype._initContainerEl = function(elContainer) {
-    // Validate container
-    elContainer = YAHOO.util.Dom.get(elContainer);
-    // Attach to existing container...
-    if(elContainer && elContainer.tagName && (elContainer.tagName.toLowerCase() == "div")) {
-        this._elContainer = elContainer;
-        YAHOO.util.Dom.addClass(this._elContainer,"yui-log");
-    }
-    // ...or create container from scratch
-    else {
-        this._elContainer = document.body.appendChild(document.createElement("div"));
-        //this._elContainer.id = "yui-log" + this._sName;
-        YAHOO.util.Dom.addClass(this._elContainer,"yui-log");
-        YAHOO.util.Dom.addClass(this._elContainer,"yui-log-container");
+            //YAHOO.widget.LogReader._elDefaultContainer = this._elContainer;
 
-        //YAHOO.widget.LogReader._elDefaultContainer = this._elContainer;
-
-        // If implementer has provided container values, trust and set those
-        var containerStyle = this._elContainer.style;
-        if(this.width) {
-            containerStyle.width = this.width;
+            // If implementer has provided container values, trust and set those
+            var containerStyle = this._elContainer.style;
+            if(this.width) {
+                containerStyle.width = this.width;
+            }
+            if(this.right) {
+                containerStyle.right = this.right;
+            }
+            if(this.top) {
+                containerStyle.top = this.top;
+            }
+             if(this.left) {
+                containerStyle.left = this.left;
+                containerStyle.right = "auto";
+            }
+            if(this.bottom) {
+                containerStyle.bottom = this.bottom;
+                containerStyle.top = "auto";
+            }
+           if(this.fontSize) {
+                containerStyle.fontSize = this.fontSize;
+            }
+            // For Opera
+            if(navigator.userAgent.toLowerCase().indexOf("opera") != -1) {
+                document.body.style += '';
+            }
         }
-        if(this.right) {
-            containerStyle.right = this.right;
-        }
-        if(this.top) {
-            containerStyle.top = this.top;
-        }
-         if(this.left) {
-            containerStyle.left = this.left;
-            containerStyle.right = "auto";
-        }
-        if(this.bottom) {
-            containerStyle.bottom = this.bottom;
-            containerStyle.top = "auto";
-        }
-       if(this.fontSize) {
-            containerStyle.fontSize = this.fontSize;
-        }
-        // For Opera
-        if(navigator.userAgent.toLowerCase().indexOf("opera") != -1) {
-            document.body.style += '';
-        }
-    }
-};
+    },
 
-/**
- * Initializes the header element.
- *
- * @method _initHeaderEl
- * @private
- */
-YAHOO.widget.LogReader.prototype._initHeaderEl = function() {
-    var oSelf = this;
+    /**
+     * Initializes the header element.
+     *
+     * @method _initHeaderEl
+     * @private
+     */
+    _initHeaderEl : function() {
+        var oSelf = this;
 
-    // Destroy header
-    if(this._elHd) {
-        // Unhook DOM events
-        YAHOO.util.Event.purgeElement(this._elHd, true);
+        // Destroy header
+        if(this._elHd) {
+            // Unhook DOM events
+            YAHOO.util.Event.purgeElement(this._elHd, true);
 
-        // Remove DOM elements
-        this._elHd.innerHTML = "";
-    }
-    
-    // Create header
-    this._elHd = this._elContainer.appendChild(document.createElement("div"));
-    this._elHd.id = "yui-log-hd" + this._sName;
-    this._elHd.className = "yui-log-hd";
+            // Remove DOM elements
+            this._elHd.innerHTML = "";
+        }
+        
+        // Create header
+        this._elHd = this._elContainer.appendChild(document.createElement("div"));
+        this._elHd.id = "yui-log-hd" + this._sName;
+        this._elHd.className = "yui-log-hd";
 
-    this._elCollapse = this._elHd.appendChild(document.createElement("div"));
-    this._elCollapse.className = "yui-log-btns";
+        this._elCollapse = this._elHd.appendChild(document.createElement("div"));
+        this._elCollapse.className = "yui-log-btns";
 
-    this._btnCollapse = document.createElement("input");
-    this._btnCollapse.type = "button";
-    //this._btnCollapse.style.fontSize =
-    //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
-    this._btnCollapse.className = "yui-log-button";
-    this._btnCollapse.value = "Collapse";
-    this._btnCollapse = this._elCollapse.appendChild(this._btnCollapse);
-    YAHOO.util.Event.addListener(
-        oSelf._btnCollapse,'click',oSelf._onClickCollapseBtn,oSelf);
+        this._btnCollapse = document.createElement("input");
+        this._btnCollapse.type = "button";
+        //this._btnCollapse.style.fontSize =
+        //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
+        this._btnCollapse.className = "yui-log-button";
+        this._btnCollapse.value = "Collapse";
+        this._btnCollapse = this._elCollapse.appendChild(this._btnCollapse);
+        YAHOO.util.Event.addListener(
+            oSelf._btnCollapse,'click',oSelf._onClickCollapseBtn,oSelf);
 
-    this._title = this._elHd.appendChild(document.createElement("h4"));
-    this._title.innerHTML = "Logger Console";
-};
+        this._title = this._elHd.appendChild(document.createElement("h4"));
+        this._title.innerHTML = "Logger Console";
+    },
 
-/**
- * Initializes the console element.
- *
- * @method _initConsoleEl
- * @private
- */
-YAHOO.widget.LogReader.prototype._initConsoleEl = function() {
-    // Destroy console
-    if(this._elConsole) {
-        // Unhook DOM events
-        YAHOO.util.Event.purgeElement(this._elConsole, true);
+    /**
+     * Initializes the console element.
+     *
+     * @method _initConsoleEl
+     * @private
+     */
+    _initConsoleEl : function() {
+        // Destroy console
+        if(this._elConsole) {
+            // Unhook DOM events
+            YAHOO.util.Event.purgeElement(this._elConsole, true);
 
-        // Remove DOM elements
-        this._elConsole.innerHTML = "";
-    }
+            // Remove DOM elements
+            this._elConsole.innerHTML = "";
+        }
 
-    // Ceate console
-    this._elConsole = this._elContainer.appendChild(document.createElement("div"));
-    this._elConsole.className = "yui-log-bd";
+        // Ceate console
+        this._elConsole = this._elContainer.appendChild(document.createElement("div"));
+        this._elConsole.className = "yui-log-bd";
 
-    // If implementer has provided console, trust and set those
-    if(this.height) {
-        this._elConsole.style.height = this.height;
-    }
-};
+        // If implementer has provided console, trust and set those
+        if(this.height) {
+            this._elConsole.style.height = this.height;
+        }
+    },
 
-/**
- * Initializes the footer element.
- *
- * @method _initFooterEl
- * @private
- */
-YAHOO.widget.LogReader.prototype._initFooterEl = function() {
-    var oSelf = this;
+    /**
+     * Initializes the footer element.
+     *
+     * @method _initFooterEl
+     * @private
+     */
+    _initFooterEl : function() {
+        var oSelf = this;
 
-    // Don't create footer elements if footer is disabled
-    if(this.footerEnabled) {
-        // Destroy console
-        if(this._elFt) {
-            // Unhook DOM events
-            YAHOO.util.Event.purgeElement(this._elFt, true);
+        // Don't create footer elements if footer is disabled
+        if(this.footerEnabled) {
+            // Destroy console
+            if(this._elFt) {
+                // Unhook DOM events
+                YAHOO.util.Event.purgeElement(this._elFt, true);
 
-            // Remove DOM elements
-            this._elFt.innerHTML = "";
-        }
+                // Remove DOM elements
+                this._elFt.innerHTML = "";
+            }
 
-        this._elFt = this._elContainer.appendChild(document.createElement("div"));
-        this._elFt.className = "yui-log-ft";
+            this._elFt = this._elContainer.appendChild(document.createElement("div"));
+            this._elFt.className = "yui-log-ft";
 
-        this._elBtns = this._elFt.appendChild(document.createElement("div"));
-        this._elBtns.className = "yui-log-btns";
+            this._elBtns = this._elFt.appendChild(document.createElement("div"));
+            this._elBtns.className = "yui-log-btns";
 
-        this._btnPause = document.createElement("input");
-        this._btnPause.type = "button";
-        //this._btnPause.style.fontSize =
-        //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
-        this._btnPause.className = "yui-log-button";
-        this._btnPause.value = "Pause";
-        this._btnPause = this._elBtns.appendChild(this._btnPause);
-        YAHOO.util.Event.addListener(
-            oSelf._btnPause,'click',oSelf._onClickPauseBtn,oSelf);
+            this._btnPause = document.createElement("input");
+            this._btnPause.type = "button";
+            //this._btnPause.style.fontSize =
+            //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
+            this._btnPause.className = "yui-log-button";
+            this._btnPause.value = "Pause";
+            this._btnPause = this._elBtns.appendChild(this._btnPause);
+            YAHOO.util.Event.addListener(
+                oSelf._btnPause,'click',oSelf._onClickPauseBtn,oSelf);
 
-        this._btnClear = document.createElement("input");
-        this._btnClear.type = "button";
-        //this._btnClear.style.fontSize =
-        //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
-        this._btnClear.className = "yui-log-button";
-        this._btnClear.value = "Clear";
-        this._btnClear = this._elBtns.appendChild(this._btnClear);
-        YAHOO.util.Event.addListener(
-            oSelf._btnClear,'click',oSelf._onClickClearBtn,oSelf);
+            this._btnClear = document.createElement("input");
+            this._btnClear.type = "button";
+            //this._btnClear.style.fontSize =
+            //    YAHOO.util.Dom.getStyle(this._elContainer,"fontSize");
+            this._btnClear.className = "yui-log-button";
+            this._btnClear.value = "Clear";
+            this._btnClear = this._elBtns.appendChild(this._btnClear);
+            YAHOO.util.Event.addListener(
+                oSelf._btnClear,'click',oSelf._onClickClearBtn,oSelf);
 
-        this._elCategoryFilters = this._elFt.appendChild(document.createElement("div"));
-        this._elCategoryFilters.className = "yui-log-categoryfilters";
-        this._elSourceFilters = this._elFt.appendChild(document.createElement("div"));
-        this._elSourceFilters.className = "yui-log-sourcefilters";
-    }
-};
+            this._elCategoryFilters = this._elFt.appendChild(document.createElement("div"));
+            this._elCategoryFilters.className = "yui-log-categoryfilters";
+            this._elSourceFilters = this._elFt.appendChild(document.createElement("div"));
+            this._elSourceFilters.className = "yui-log-sourcefilters";
+        }
+    },
 
-/**
- * Initializes Drag and Drop on the header element.
- *
- * @method _initDragDrop
- * @private
- */
-YAHOO.widget.LogReader.prototype._initDragDrop = function() {
-    // If Drag and Drop utility is available...
-    // ...and draggable is true...
-    // ...then make the header draggable
-    if(YAHOO.util.DD && this.draggable && this._elHd) {
-        var ylog_dd = new YAHOO.util.DD(this._elContainer);
-        ylog_dd.setHandleElId(this._elHd.id);
-        //TODO: use class name
-        this._elHd.style.cursor = "move";
-    }
-};
+    /**
+     * Initializes Drag and Drop on the header element.
+     *
+     * @method _initDragDrop
+     * @private
+     */
+    _initDragDrop : function() {
+        // If Drag and Drop utility is available...
+        // ...and draggable is true...
+        // ...then make the header draggable
+        if(YAHOO.util.DD && this.draggable && this._elHd) {
+            var ylog_dd = new YAHOO.util.DD(this._elContainer);
+            ylog_dd.setHandleElId(this._elHd.id);
+            //TODO: use class name
+            this._elHd.style.cursor = "move";
+        }
+    },
 
-/**
- * Initializes category filters.
- *
- * @method _initCategories
- * @private
- */
-YAHOO.widget.LogReader.prototype._initCategories = function() {
-    // Initialize category filters
-    this._categoryFilters = [];
-    var aInitialCategories = YAHOO.widget.Logger.categories;
+    /**
+     * Initializes category filters.
+     *
+     * @method _initCategories
+     * @private
+     */
+    _initCategories : function() {
+        // Initialize category filters
+        this._categoryFilters = [];
+        var aInitialCategories = YAHOO.widget.Logger.categories;
 
-    for(var j=0; j < aInitialCategories.length; j++) {
-        var sCategory = aInitialCategories[j];
+        for(var j=0; j < aInitialCategories.length; j++) {
+            var sCategory = aInitialCategories[j];
 
-        // Add category to the internal array of filters
-        this._categoryFilters.push(sCategory);
+            // Add category to the internal array of filters
+            this._categoryFilters.push(sCategory);
 
-        // Add checkbox element if UI is enabled
-        if(this._elCategoryFilters) {
-            this._createCategoryCheckbox(sCategory);
+            // Add checkbox element if UI is enabled
+            if(this._elCategoryFilters) {
+                this._createCategoryCheckbox(sCategory);
+            }
         }
-    }
-};
+    },
 
-/**
- * Initializes source filters.
- *
- * @method _initSources
- * @private
- */
-YAHOO.widget.LogReader.prototype._initSources = function() {
-    // Initialize source filters
-    this._sourceFilters = [];
-    var aInitialSources = YAHOO.widget.Logger.sources;
+    /**
+     * Initializes source filters.
+     *
+     * @method _initSources
+     * @private
+     */
+    _initSources : function() {
+        // Initialize source filters
+        this._sourceFilters = [];
+        var aInitialSources = YAHOO.widget.Logger.sources;
 
-    for(var j=0; j < aInitialSources.length; j++) {
-        var sSource = aInitialSources[j];
+        for(var j=0; j < aInitialSources.length; j++) {
+            var sSource = aInitialSources[j];
 
-        // Add source to the internal array of filters
-        this._sourceFilters.push(sSource);
+            // Add source to the internal array of filters
+            this._sourceFilters.push(sSource);
 
-        // Add checkbox element if UI is enabled
-        if(this._elSourceFilters) {
-            this._createSourceCheckbox(sSource);
+            // Add checkbox element if UI is enabled
+            if(this._elSourceFilters) {
+                this._createSourceCheckbox(sSource);
+            }
         }
-    }}
-;
+    },
 
-/**
- * Creates the UI for a category filter in the LogReader footer element.
- *
- * @method _createCategoryCheckbox
- * @param sCategory {String} Category name.
- * @private
- */
-YAHOO.widget.LogReader.prototype._createCategoryCheckbox = function(sCategory) {
-    var oSelf = this;
+    /**
+     * Creates the UI for a category filter in the LogReader footer element.
+     *
+     * @method _createCategoryCheckbox
+     * @param sCategory {String} Category name.
+     * @private
+     */
+    _createCategoryCheckbox : function(sCategory) {
+        var oSelf = this;
 
-    if(this._elFt) {
-        var elParent = this._elCategoryFilters;
-        var elFilter = elParent.appendChild(document.createElement("span"));
-        elFilter.className = "yui-log-filtergrp";
-        
-        // Append el at the end so IE 5.5 can set "type" attribute
-        // and THEN set checked property
-        var chkCategory = document.createElement("input");
-        chkCategory.id = "yui-log-filter-" + sCategory + this._sName;
-        chkCategory.className = "yui-log-filter-" + sCategory;
-        chkCategory.type = "checkbox";
-        chkCategory.category = sCategory;
-        chkCategory = elFilter.appendChild(chkCategory);
-        chkCategory.checked = true;
+        if(this._elFt) {
+            var elParent = this._elCategoryFilters;
+            var elFilter = elParent.appendChild(document.createElement("span"));
+            elFilter.className = "yui-log-filtergrp";
+            
+            // Append el at the end so IE 5.5 can set "type" attribute
+            // and THEN set checked property
+            var chkCategory = document.createElement("input");
+            chkCategory.id = "yui-log-filter-" + sCategory + this._sName;
+            chkCategory.className = "yui-log-filter-" + sCategory;
+            chkCategory.type = "checkbox";
+            chkCategory.category = sCategory;
+            chkCategory = elFilter.appendChild(chkCategory);
+            chkCategory.checked = true;
 
-        // Subscribe to the click event
-        YAHOO.util.Event.addListener(chkCategory,'click',oSelf._onCheckCategory,oSelf);
+            // Subscribe to the click event
+            YAHOO.util.Event.addListener(chkCategory,'click',oSelf._onCheckCategory,oSelf);
 
-        // Create and class the text label
-        var lblCategory = elFilter.appendChild(document.createElement("label"));
-        lblCategory.htmlFor = chkCategory.id;
-        lblCategory.className = sCategory;
-        lblCategory.innerHTML = sCategory;
-        
-        this._filterCheckboxes[sCategory] = chkCategory;
-    }
-};
+            // Create and class the text label
+            var lblCategory = elFilter.appendChild(document.createElement("label"));
+            lblCategory.htmlFor = chkCategory.id;
+            lblCategory.className = sCategory;
+            lblCategory.innerHTML = sCategory;
+            
+            this._filterCheckboxes[sCategory] = chkCategory;
+        }
+    },
 
-/**
- * Creates a checkbox in the LogReader footer element to filter by source.
- *
- * @method _createSourceCheckbox
- * @param sSource {String} Source name.
- * @private
- */
-YAHOO.widget.LogReader.prototype._createSourceCheckbox = function(sSource) {
-    var oSelf = this;
+    /**
+     * Creates a checkbox in the LogReader footer element to filter by source.
+     *
+     * @method _createSourceCheckbox
+     * @param sSource {String} Source name.
+     * @private
+     */
+    _createSourceCheckbox : function(sSource) {
+        var oSelf = this;
 
-    if(this._elFt) {
-        var elParent = this._elSourceFilters;
-        var elFilter = elParent.appendChild(document.createElement("span"));
-        elFilter.className = "yui-log-filtergrp";
+        if(this._elFt) {
+            var elParent = this._elSourceFilters;
+            var elFilter = elParent.appendChild(document.createElement("span"));
+            elFilter.className = "yui-log-filtergrp";
 
-        // Append el at the end so IE 5.5 can set "type" attribute
-        // and THEN set checked property
-        var chkSource = document.createElement("input");
-        chkSource.id = "yui-log-filter" + sSource + this._sName;
-        chkSource.className = "yui-log-filter" + sSource;
-        chkSource.type = "checkbox";
-        chkSource.source = sSource;
-        chkSource = elFilter.appendChild(chkSource);
-        chkSource.checked = true;
+            // Append el at the end so IE 5.5 can set "type" attribute
+            // and THEN set checked property
+            var chkSource = document.createElement("input");
+            chkSource.id = "yui-log-filter" + sSource + this._sName;
+            chkSource.className = "yui-log-filter" + sSource;
+            chkSource.type = "checkbox";
+            chkSource.source = sSource;
+            chkSource = elFilter.appendChild(chkSource);
+            chkSource.checked = true;
 
-        // Subscribe to the click event
-        YAHOO.util.Event.addListener(chkSource,'click',oSelf._onCheckSource,oSelf);
+            // Subscribe to the click event
+            YAHOO.util.Event.addListener(chkSource,'click',oSelf._onCheckSource,oSelf);
 
-        // Create and class the text label
-        var lblSource = elFilter.appendChild(document.createElement("label"));
-        lblSource.htmlFor = chkSource.id;
-        lblSource.className = sSource;
-        lblSource.innerHTML = sSource;
-        
-        this._filterCheckboxes[sSource] = chkSource;
-    }
-};
+            // Create and class the text label
+            var lblSource = elFilter.appendChild(document.createElement("label"));
+            lblSource.htmlFor = chkSource.id;
+            lblSource.className = sSource;
+            lblSource.innerHTML = sSource;
+            
+            this._filterCheckboxes[sSource] = chkSource;
+        }
+    },
 
-/**
- * Reprints all log messages in the stack through filters.
- *
- * @method _filterLogs
- * @private
- */
-YAHOO.widget.LogReader.prototype._filterLogs = function() {
-    // Reprint stack with new filters
-    if (this._elConsole !== null) {
-        this.clearConsole();
-        this._printToConsole(YAHOO.widget.Logger.getStack());
-    }
-};
+    /**
+     * Reprints all log messages in the stack through filters.
+     *
+     * @method _filterLogs
+     * @private
+     */
+    _filterLogs : function() {
+        // Reprint stack with new filters
+        if (this._elConsole !== null) {
+            this.clearConsole();
+            this._printToConsole(YAHOO.widget.Logger.getStack());
+        }
+    },
 
-/**
- * Sends buffer of log messages to output and clears buffer.
- *
- * @method _printBuffer
- * @private
- */
-YAHOO.widget.LogReader.prototype._printBuffer = function() {
-    this._timeout = null;
+    /**
+     * Sends buffer of log messages to output and clears buffer.
+     *
+     * @method _printBuffer
+     * @private
+     */
+    _printBuffer : function() {
+        this._timeout = null;
 
-    if(this._elConsole !== null) {
-        var thresholdMax = this.thresholdMax;
-        thresholdMax = (thresholdMax && !isNaN(thresholdMax)) ? thresholdMax : 500;
-        if(this._consoleMsgCount < thresholdMax) {
-            var entries = [];
-            for (var i=0; i<this._buffer.length; i++) {
-                entries[i] = this._buffer[i];
+        if(this._elConsole !== null) {
+            var thresholdMax = this.thresholdMax;
+            thresholdMax = (thresholdMax && !isNaN(thresholdMax)) ? thresholdMax : 500;
+            if(this._consoleMsgCount < thresholdMax) {
+                var entries = [];
+                for (var i=0; i<this._buffer.length; i++) {
+                    entries[i] = this._buffer[i];
+                }
+                this._buffer = [];
+                this._printToConsole(entries);
             }
-            this._buffer = [];
-            this._printToConsole(entries);
+            else {
+                this._filterLogs();
+            }
+            
+            if(!this.newestOnTop) {
+                this._elConsole.scrollTop = this._elConsole.scrollHeight;
+            }
         }
-        else {
-            this._filterLogs();
+    },
+
+    /**
+     * Cycles through an array of log messages, and outputs each one to the console
+     * if its category has not been filtered out.
+     *
+     * @method _printToConsole
+     * @param aEntries {Object[]} Array of LogMsg objects to output to console.
+     * @private
+     */
+    _printToConsole : function(aEntries) {
+        // Manage the number of messages displayed in the console
+        var entriesLen         = aEntries.length,
+            df                 = document.createDocumentFragment(),
+            msgHTML            = [],
+            thresholdMin       = this.thresholdMin,
+            sourceFiltersLen   = this._sourceFilters.length,
+            categoryFiltersLen = this._categoryFilters.length,
+            entriesStartIndex,
+            i, j, msg, before;
+
+        if(isNaN(thresholdMin) || (thresholdMin > this.thresholdMax)) {
+            thresholdMin = 0;
         }
+        entriesStartIndex = (entriesLen > thresholdMin) ? (entriesLen - thresholdMin) : 0;
         
-        if(!this.newestOnTop) {
-            this._elConsole.scrollTop = this._elConsole.scrollHeight;
-        }
-    }
-};
+        // Iterate through all log entries 
+        for(i=entriesStartIndex; i<entriesLen; i++) {
+            // Print only the ones that filter through
+            var okToPrint = false;
+            var okToFilterCats = false;
 
-/**
- * Cycles through an array of log messages, and outputs each one to the console
- * if its category has not been filtered out.
- *
- * @method _printToConsole
- * @param aEntries {Object[]} Array of LogMsg objects to output to console.
- * @private
- */
-YAHOO.widget.LogReader.prototype._printToConsole = function(aEntries) {
-    // Manage the number of messages displayed in the console
-    var entriesLen = aEntries.length;
-    var thresholdMin = this.thresholdMin;
-    if(isNaN(thresholdMin) || (thresholdMin > this.thresholdMax)) {
-        thresholdMin = 0;
-    }
-    var entriesStartIndex = (entriesLen > thresholdMin) ? (entriesLen - thresholdMin) : 0;
-    
-    // Iterate through all log entries 
-    var sourceFiltersLen = this._sourceFilters.length;
-    var categoryFiltersLen = this._categoryFilters.length;
-    for(var i=entriesStartIndex; i<entriesLen; i++) {
-        // Print only the ones that filter through
-        var okToPrint = false;
-        var okToFilterCats = false;
+            // Get log message details
+            var entry = aEntries[i];
+            var source = entry.source;
+            var category = entry.category;
 
-        // Get log message details
-        var entry = aEntries[i];
-        var source = entry.source;
-        var category = entry.category;
-
-        for(var j=0; j<sourceFiltersLen; j++) {
-            if(source == this._sourceFilters[j]) {
-                okToFilterCats = true;
-                break;
-            }
-        }
-        if(okToFilterCats) {
-            for(var k=0; k<categoryFiltersLen; k++) {
-                if(category == this._categoryFilters[k]) {
-                    okToPrint = true;
+            for(j=0; j<sourceFiltersLen; j++) {
+                if(source == this._sourceFilters[j]) {
+                    okToFilterCats = true;
                     break;
                 }
             }
-        }
-        if(okToPrint) {
-            var output = this.formatMsg(entry);
-            if(this.newestOnTop) {
-                this._elConsole.innerHTML = output + this._elConsole.innerHTML;
+            if(okToFilterCats) {
+                for(j=0; j<categoryFiltersLen; j++) {
+                    if(category == this._categoryFilters[j]) {
+                        okToPrint = true;
+                        break;
+                    }
+                }
             }
-            else {
-                this._elConsole.innerHTML += output;
+            if(okToPrint) {
+                msg = this.formatMsg(entry);
+                if (typeof msg === 'string') {
+                    msgHTML[msgHTML.length] = msg;
+                } else {
+                    df.insertBefore(msg, this.newestOnTop ?
+                        df.firstChild || null : null);
+                }
+                this._consoleMsgCount++;
+                this._lastTime = entry.time.getTime();
             }
-            this._consoleMsgCount++;
-            this._lastTime = entry.time.getTime();
         }
-    }
-};
 
+        if (msgHTML.length) {
+            msgHTML.splice(0,0,this._elConsole.innerHTML);
+            this._elConsole.innerHTML = this.newestOnTop ?
+                                            msgHTML.reverse().join('') :
+                                            msgHTML.join('');
+        } else if (df.firstChild) {
+            this._elConsole.insertBefore(df, this.newestOnTop ?
+                        this._elConsole.firstChild || null : null);
+        }
+    },
+
 /////////////////////////////////////////////////////////////////////////////
 //
 // Private event handlers
 //
 /////////////////////////////////////////////////////////////////////////////
 
-/**
- * Handles Logger's categoryCreateEvent.
- *
- * @method _onCategoryCreate
- * @param sType {String} The event.
- * @param aArgs {Object[]} Data passed from event firer.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onCategoryCreate = function(sType, aArgs, oSelf) {
-    var category = aArgs[0];
-    
-    // Add category to the internal array of filters
-    oSelf._categoryFilters.push(category);
+    /**
+     * Handles Logger's categoryCreateEvent.
+     *
+     * @method _onCategoryCreate
+     * @param sType {String} The event.
+     * @param aArgs {Object[]} Data passed from event firer.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onCategoryCreate : function(sType, aArgs, oSelf) {
+        var category = aArgs[0];
+        
+        // Add category to the internal array of filters
+        oSelf._categoryFilters.push(category);
 
-    if(oSelf._elFt) {
-        oSelf._createCategoryCheckbox(category);
-    }
-};
+        if(oSelf._elFt) {
+            oSelf._createCategoryCheckbox(category);
+        }
+    },
 
-/**
- * Handles Logger's sourceCreateEvent.
- *
- * @method _onSourceCreate
- * @param sType {String} The event.
- * @param aArgs {Object[]} Data passed from event firer.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onSourceCreate = function(sType, aArgs, oSelf) {
-    var source = aArgs[0];
-    
-    // Add source to the internal array of filters
-    oSelf._sourceFilters.push(source);
+    /**
+     * Handles Logger's sourceCreateEvent.
+     *
+     * @method _onSourceCreate
+     * @param sType {String} The event.
+     * @param aArgs {Object[]} Data passed from event firer.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onSourceCreate : function(sType, aArgs, oSelf) {
+        var source = aArgs[0];
+        
+        // Add source to the internal array of filters
+        oSelf._sourceFilters.push(source);
 
-    if(oSelf._elFt) {
-        oSelf._createSourceCheckbox(source);
-    }
-};
+        if(oSelf._elFt) {
+            oSelf._createSourceCheckbox(source);
+        }
+    },
 
-/**
- * Handles check events on the category filter checkboxes.
- *
- * @method _onCheckCategory
- * @param v {HTMLEvent} The click event.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onCheckCategory = function(v, oSelf) {
-    var category = this.category;
-    if(!this.checked) {
-        oSelf.hideCategory(category);
-    }
-    else {
-        oSelf.showCategory(category);
-    }
-};
+    /**
+     * Handles check events on the category filter checkboxes.
+     *
+     * @method _onCheckCategory
+     * @param v {HTMLEvent} The click event.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onCheckCategory : function(v, oSelf) {
+        var category = this.category;
+        if(!this.checked) {
+            oSelf.hideCategory(category);
+        }
+        else {
+            oSelf.showCategory(category);
+        }
+    },
 
-/**
- * Handles check events on the category filter checkboxes.
- *
- * @method _onCheckSource
- * @param v {HTMLEvent} The click event.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onCheckSource = function(v, oSelf) {
-    var source = this.source;
-    if(!this.checked) {
-        oSelf.hideSource(source);
-    }
-    else {
-        oSelf.showSource(source);
-    }
-};
+    /**
+     * Handles check events on the category filter checkboxes.
+     *
+     * @method _onCheckSource
+     * @param v {HTMLEvent} The click event.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onCheckSource : function(v, oSelf) {
+        var source = this.source;
+        if(!this.checked) {
+            oSelf.hideSource(source);
+        }
+        else {
+            oSelf.showSource(source);
+        }
+    },
 
-/**
- * Handles click events on the collapse button.
- *
- * @method _onClickCollapseBtn
- * @param v {HTMLEvent} The click event.
- * @param oSelf {Object} The LogReader instance
- * @private
- */
-YAHOO.widget.LogReader.prototype._onClickCollapseBtn = function(v, oSelf) {
-    if(!oSelf.isCollapsed) {
-        oSelf.collapse();
-    }
-    else {
-        oSelf.expand();
-    }
-};
+    /**
+     * Handles click events on the collapse button.
+     *
+     * @method _onClickCollapseBtn
+     * @param v {HTMLEvent} The click event.
+     * @param oSelf {Object} The LogReader instance
+     * @private
+     */
+    _onClickCollapseBtn : function(v, oSelf) {
+        if(!oSelf.isCollapsed) {
+            oSelf.collapse();
+        }
+        else {
+            oSelf.expand();
+        }
+    },
 
-/**
- * Handles click events on the pause button.
- *
- * @method _onClickPauseBtn
- * @param v {HTMLEvent} The click event.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onClickPauseBtn = function(v, oSelf) {
-    if(!oSelf.isPaused) {
-        oSelf.pause();
-    }
-    else {
-        oSelf.resume();
-    }
-};
+    /**
+     * Handles click events on the pause button.
+     *
+     * @method _onClickPauseBtn
+     * @param v {HTMLEvent} The click event.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onClickPauseBtn : function(v, oSelf) {
+        if(!oSelf.isPaused) {
+            oSelf.pause();
+        }
+        else {
+            oSelf.resume();
+        }
+    },
 
-/**
- * Handles click events on the clear button.
- *
- * @method _onClickClearBtn
- * @param v {HTMLEvent} The click event.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onClickClearBtn = function(v, oSelf) {
-    oSelf.clearConsole();
-};
+    /**
+     * Handles click events on the clear button.
+     *
+     * @method _onClickClearBtn
+     * @param v {HTMLEvent} The click event.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onClickClearBtn : function(v, oSelf) {
+        oSelf.clearConsole();
+    },
 
-/**
- * Handles Logger's newLogEvent.
- *
- * @method _onNewLog
- * @param sType {String} The event.
- * @param aArgs {Object[]} Data passed from event firer.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onNewLog = function(sType, aArgs, oSelf) {
-    var logEntry = aArgs[0];
-    oSelf._buffer.push(logEntry);
+    /**
+     * Handles Logger's newLogEvent.
+     *
+     * @method _onNewLog
+     * @param sType {String} The event.
+     * @param aArgs {Object[]} Data passed from event firer.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onNewLog : function(sType, aArgs, oSelf) {
+        var logEntry = aArgs[0];
+        oSelf._buffer.push(logEntry);
 
-    if (oSelf.logReaderEnabled === true && oSelf._timeout === null) {
-        oSelf._timeout = setTimeout(function(){oSelf._printBuffer();}, oSelf.outputBuffer);
+        if (oSelf.logReaderEnabled === true && oSelf._timeout === null) {
+            oSelf._timeout = setTimeout(function(){oSelf._printBuffer();}, oSelf.outputBuffer);
+        }
+    },
+
+    /**
+     * Handles Logger's resetEvent.
+     *
+     * @method _onReset
+     * @param sType {String} The event.
+     * @param aArgs {Object[]} Data passed from event firer.
+     * @param oSelf {Object} The LogReader instance.
+     * @private
+     */
+    _onReset : function(sType, aArgs, oSelf) {
+        oSelf._filterLogs();
     }
 };
 
-/**
- * Handles Logger's resetEvent.
- *
- * @method _onReset
- * @param sType {String} The event.
- * @param aArgs {Object[]} Data passed from event firer.
- * @param oSelf {Object} The LogReader instance.
- * @private
- */
-YAHOO.widget.LogReader.prototype._onReset = function(sType, aArgs, oSelf) {
-    oSelf._filterLogs();
-};
-
  /**
  * The Logger widget provides a simple way to read or write log messages in
  * JavaScript code. Integration with the YUI Library's debug builds allow
@@ -1935,10 +1983,9 @@
             var output =
                 localTime + " (" +
                 elapsedTime + "ms): " +
-                oEntry.source + ": " +
-                oEntry.msg;
+                oEntry.source + ": ";
 
-            console.log(output);
+            console.log(output, oEntry.msg);
         }
     };
 
@@ -1980,4 +2027,4 @@
 }
 
 
-YAHOO.register("logger", YAHOO.widget.Logger, {version: "2.4.1", build: "742"});
+YAHOO.register("logger", YAHOO.widget.Logger, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/menu/README
===================================================================
--- trunk/root/static/yui/menu/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/menu/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,43 @@
+*** version 2.5.1 ***
+
+Fixed the following bugs:
+-------------------------
+
++ The "url" configuration property of YAHOO.widget.MenuItem now returns the exact value of the 
+  "href" attribute of its anchor element in Internet Explorer. 
+
++ Clicking on an item in a Menu will no longer cause Firefox to scroll to the top of the window.
+
++ Improved Menu's viewport boundary awareness.
+
+
+
+*** version 2.5.0 ***
+
+Fixed the following bugs:
+-------------------------
+
++ Corrected the paths to all images in the original Menu CSS file so that checked MenuItems now
+  render correctly.
+
++ Clicking on a disabled MenuItem instance will no longer cause the browser to navigate to 
+  the top of the current page.
+
++ Removed the use of the "yui-skin-sam" class name from the Menu core CSS file.
+
++ Scrolling Menus now render correctly in IE 6 and IE 7.
+
++ Submenus are no longer hidden then re-shown when the mouse is moving from a visible submenu back
+  to its parent MenuItem instance.
+
+
+
 *** version 2.4.1 ***
 
-No change
++ No changes
 
+
+
 *** version 2.4.0 ***
 
 
@@ -977,4 +1013,4 @@
   "first-of-type" class
 
 * Changed case of MenuModuleItem class's "subMenuIndicator" property 
-  to "submenuIndicator"
+  to "submenuIndicator"
\ No newline at end of file

Modified: trunk/root/static/yui/menu/assets/menu-core.css
===================================================================
--- trunk/root/static/yui/menu/assets/menu-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/menu/assets/menu-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* Menu & MenuBar styles */
 
@@ -137,7 +137,7 @@
 
 }
 
-.yui-skin-sam .yui-menu-shadow-visible {
+.yui-menu-shadow-visible {
 
     top: 2px;
     right: -3px;

Modified: trunk/root/static/yui/menu/assets/menu.css
===================================================================
--- trunk/root/static/yui/menu/assets/menu.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/menu/assets/menu.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* Menu & MenuBar styles */
 
@@ -137,7 +137,7 @@
 
 }
 
-.yui-skin-sam .yui-menu-shadow-visible {
+.yui-menu-shadow-visible {
 
     top: 2px;
     right: -3px;

Deleted: trunk/root/static/yui/menu/assets/menu_down_arrow_selected.png
===================================================================
(Binary files differ)

Added: trunk/root/static/yui/menu/assets/menuitem_checkbox.png
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/menu/assets/menuitem_checkbox.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/root/static/yui/menu/assets/menuitem_checkbox_disabled.png
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/menu/assets/menuitem_checkbox_disabled.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/root/static/yui/menu/assets/menuitem_checkbox_selected.png
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/menu/assets/menuitem_checkbox_selected.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Deleted: trunk/root/static/yui/menu/assets/menuitem_checked.png
===================================================================
(Binary files differ)

Deleted: trunk/root/static/yui/menu/assets/menuitem_checked_disabled.png
===================================================================
(Binary files differ)

Deleted: trunk/root/static/yui/menu/assets/menuitem_checked_selected.png
===================================================================
(Binary files differ)

Modified: trunk/root/static/yui/menu/assets/skins/sam/menu-skin.css
===================================================================
--- trunk/root/static/yui/menu/assets/skins/sam/menu-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/menu/assets/skins/sam/menu-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* MenuBar style rules */
 

Modified: trunk/root/static/yui/menu/assets/skins/sam/menu.css
===================================================================
--- trunk/root/static/yui/menu/assets/skins/sam/menu.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/menu/assets/skins/sam/menu.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-.yuimenubar{visibility:visible;position:static;}.yuimenu .yuimenu,.yuimenubar .yuimenu{visibility:hidden;position:absolute;top:-10000px;left:-10000px;}.yuimenubar li,.yuimenu li{list-style-type:none;}.yuimenubar ul,.yuimenu ul,.yuimenubar li,.yuimenu li,.yuimenu h6,.yuimenubar h6{margin:0;padding:0;}.yuimenuitemlabel,.yuimenubaritemlabel{text-align:left;white-space:nowrap;}.yuimenubar ul{*zoom:1;}.yuimenubar .yuimenu ul{*zoom:normal;}.yuimenubar>.bd>ul:after{content:".";display:block;clear:both;visibility:hidden;height:0;line-height:0;}.yuimenubaritem{float:left;}.yuimenubaritemlabel,.yuimenuitemlabel{display:block;}.yuimenuitemlabel .helptext{font-style:normal;display:block;margin:-1em 0 0 10em;}.yui-menu-shadow{position:absolute;visibility:hidden;z-index:-1;}.yui-skin-sam .yui-menu-shadow-visible{top:2px;right:-3px;left:-3px;bottom:-3px;visibility:visible;}.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.yuimenu.show-scrollbars,.yuimenubar.show-s!
 crollbars{overflow:visible;}.yuimenu.hide-scrollbars .yui-menu-shadow,.yuimenubar.hide-scrollbars .yui-menu-shadow{overflow:hidden;}.yuimenu.show-scrollbars .yui-menu-shadow,.yuimenubar.show-scrollbars .yui-menu-shadow{overflow:auto;}.yui-skin-sam .yuimenubar{font-size:93%;line-height:2;*line-height:1.9;border:solid 1px #808080;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritem{border-right:solid 1px #ccc;}.yui-skin-sam .yuimenubaritemlabel{padding:0 10px;color:#000;text-decoration:none;cursor:default;border-style:solid;border-color:#808080;border-width:1px 0;*position:relative;margin:-1px 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel{padding-right:20px;*display:inline-block;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu{background:url(menubaritem_submenuindicator.png) right center no-repeat;}.yui-skin-sam .yuimenubaritem-selected{background:url(../../../../assets/skins/sam/sprite.png) rep!
 eat-x 0 -1700px;}.yui-skin-sam .yuimenubaritemlabel-selected{b!
 order-co
lor:#7D98B8;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-selected{border-left-width:1px;margin-left:-1px;*left:-1px;}.yui-skin-sam .yuimenubaritemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu-disabled{background-image:url(menubaritem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenu{font-size:93%;line-height:1.5;*line-height:1.45;}.yui-skin-sam .yuimenubar .yuimenu,.yui-skin-sam .yuimenu .yuimenu{font-size:100%;}.yui-skin-sam .yuimenu .bd{border:solid 1px #808080;background-color:#fff;}.yui-skin-sam .yuimenu ul{padding:3px 0;border-width:1px 0 0 0;border-color:#ccc;border-style:solid;}.yui-skin-sam .yuimenu ul.first-of-type{border-width:0;}.yui-skin-sam .yuimenu h6{font-weight:bold;border-style:solid;border-color:#ccc;border-width:1px 0 0 0;color:#a4a4a4;padding:3px 10px 0 10px;}.yui-skin-sam .yuimenu ul.hastitle,.yui-skin-sam .yuimenu h6.first-of-type{border-width:0;}.yui-skin-sam .yuimenu .yui-menu-body!
 -scrolled{border-color:#ccc #808080;overflow:hidden;}.yui-skin-sam .yuimenu .topscrollbar,.yui-skin-sam .yuimenu .bottomscrollbar{height:16px;border:solid 1px #808080;background:#fff url(../../../../assets/skins/sam/sprite.png) no-repeat 0 0;}.yui-skin-sam .yuimenu .topscrollbar{border-bottom-width:0;background-position:center -950px;}.yui-skin-sam .yuimenu .topscrollbar_disabled{background-position:center -975px;}.yui-skin-sam .yuimenu .bottomscrollbar{border-top-width:0;background-position:center -850px;}.yui-skin-sam .yuimenu .bottomscrollbar_disabled{background-position:center -875px;}.yui-skin-sam .yuimenuitem{_border-bottom:solid 1px #fff;}.yui-skin-sam .yuimenuitemlabel{padding:0 20px;color:#000;text-decoration:none;cursor:default;}.yui-skin-sam .yuimenuitemlabel .helptext{margin-top:-1.5em;*margin-top:-1.45em;}.yui-skin-sam .yuimenuitem-hassubmenu{background-image:url(menuitem_submenuindicator.png);background-position:right center;background-repeat:no-repeat;}.yui-s!
 kin-sam .yuimenuitem-checked{background-image:url(menuitem_che!
 ckbox.pn
g);background-position:left center;background-repeat:no-repeat;}.yui-skin-sam .yui-menu-shadow-visible{background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yuimenuitem-selected{background-color:#B3D4FF;}.yui-skin-sam .yuimenuitemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenuitem-hassubmenu-disabled{background-image:url(menuitem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenuitem-checked-disabled{background-image:url(menuitem_checkbox_disabled.png);}
+.yuimenubar{visibility:visible;position:static;}.yuimenu .yuimenu,.yuimenubar .yuimenu{visibility:hidden;position:absolute;top:-10000px;left:-10000px;}.yuimenubar li,.yuimenu li{list-style-type:none;}.yuimenubar ul,.yuimenu ul,.yuimenubar li,.yuimenu li,.yuimenu h6,.yuimenubar h6{margin:0;padding:0;}.yuimenuitemlabel,.yuimenubaritemlabel{text-align:left;white-space:nowrap;}.yuimenubar ul{*zoom:1;}.yuimenubar .yuimenu ul{*zoom:normal;}.yuimenubar>.bd>ul:after{content:".";display:block;clear:both;visibility:hidden;height:0;line-height:0;}.yuimenubaritem{float:left;}.yuimenubaritemlabel,.yuimenuitemlabel{display:block;}.yuimenuitemlabel .helptext{font-style:normal;display:block;margin:-1em 0 0 10em;}.yui-menu-shadow{position:absolute;visibility:hidden;z-index:-1;}.yui-menu-shadow-visible{top:2px;right:-3px;left:-3px;bottom:-3px;visibility:visible;}.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.yuimenu.show-scrollbars,.yuimenubar.show-scrollbars{over!
 flow:visible;}.yuimenu.hide-scrollbars .yui-menu-shadow,.yuimenubar.hide-scrollbars .yui-menu-shadow{overflow:hidden;}.yuimenu.show-scrollbars .yui-menu-shadow,.yuimenubar.show-scrollbars .yui-menu-shadow{overflow:auto;}.yui-skin-sam .yuimenubar{font-size:93%;line-height:2;*line-height:1.9;border:solid 1px #808080;background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritem{border-right:solid 1px #ccc;}.yui-skin-sam .yuimenubaritemlabel{padding:0 10px;color:#000;text-decoration:none;cursor:default;border-style:solid;border-color:#808080;border-width:1px 0;*position:relative;margin:-1px 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel{padding-right:20px;*display:inline-block;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu{background:url(menubaritem_submenuindicator.png) right center no-repeat;}.yui-skin-sam .yuimenubaritem-selected{background:url(../../../../assets/skins/sam/sprite.png) repeat-x 0 -1700p!
 x;}.yui-skin-sam .yuimenubaritemlabel-selected{border-color:#7!
 D98B8;}.
yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-selected{border-left-width:1px;margin-left:-1px;*left:-1px;}.yui-skin-sam .yuimenubaritemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu-disabled{background-image:url(menubaritem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenu{font-size:93%;line-height:1.5;*line-height:1.45;}.yui-skin-sam .yuimenubar .yuimenu,.yui-skin-sam .yuimenu .yuimenu{font-size:100%;}.yui-skin-sam .yuimenu .bd{border:solid 1px #808080;background-color:#fff;}.yui-skin-sam .yuimenu ul{padding:3px 0;border-width:1px 0 0 0;border-color:#ccc;border-style:solid;}.yui-skin-sam .yuimenu ul.first-of-type{border-width:0;}.yui-skin-sam .yuimenu h6{font-weight:bold;border-style:solid;border-color:#ccc;border-width:1px 0 0 0;color:#a4a4a4;padding:3px 10px 0 10px;}.yui-skin-sam .yuimenu ul.hastitle,.yui-skin-sam .yuimenu h6.first-of-type{border-width:0;}.yui-skin-sam .yuimenu .yui-menu-body-scrolled{bord!
 er-color:#ccc #808080;overflow:hidden;}.yui-skin-sam .yuimenu .topscrollbar,.yui-skin-sam .yuimenu .bottomscrollbar{height:16px;border:solid 1px #808080;background:#fff url(../../../../assets/skins/sam/sprite.png) no-repeat 0 0;}.yui-skin-sam .yuimenu .topscrollbar{border-bottom-width:0;background-position:center -950px;}.yui-skin-sam .yuimenu .topscrollbar_disabled{background-position:center -975px;}.yui-skin-sam .yuimenu .bottomscrollbar{border-top-width:0;background-position:center -850px;}.yui-skin-sam .yuimenu .bottomscrollbar_disabled{background-position:center -875px;}.yui-skin-sam .yuimenuitem{_border-bottom:solid 1px #fff;}.yui-skin-sam .yuimenuitemlabel{padding:0 20px;color:#000;text-decoration:none;cursor:default;}.yui-skin-sam .yuimenuitemlabel .helptext{margin-top:-1.5em;*margin-top:-1.45em;}.yui-skin-sam .yuimenuitem-hassubmenu{background-image:url(menuitem_submenuindicator.png);background-position:right center;background-repeat:no-repeat;}.yui-skin-sam .yuime!
 nuitem-checked{background-image:url(menuitem_checkbox.png);bac!
 kground-
position:left center;background-repeat:no-repeat;}.yui-skin-sam .yui-menu-shadow-visible{background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yuimenuitem-selected{background-color:#B3D4FF;}.yui-skin-sam .yuimenuitemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenuitem-hassubmenu-disabled{background-image:url(menuitem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenuitem-checked-disabled{background-image:url(menuitem_checkbox_disabled.png);}

Modified: trunk/root/static/yui/menu/menu-debug.js
===================================================================
--- trunk/root/static/yui/menu/menu-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/menu/menu-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 
 
@@ -2547,9 +2547,13 @@
         Event.on(this.element, "mousemove", this._onMouseMove, this, true);
 
 
-        this.clearActiveItem();
+		if (!Dom.isAncestor(oItem.element, Event.getRelatedTarget(oEvent))) {
 
+        	this.clearActiveItem();
+        
+        }
 
+
         if (this.parent && this._nSubmenuHideDelayId) {
 
             window.clearTimeout(this._nSubmenuHideDelayId);
@@ -2777,91 +2781,113 @@
 */
 _onClick: function (p_sType, p_aArgs) {
 
-    var oEvent = p_aArgs[0],
-        oItem = p_aArgs[1],
-        oSubmenu,
-        bInMenuAnchor = false,
-        oRoot,
-        sId,
-        sURL,
-        nHashPos,
-        nLen;
+	var Event = YAHOO.util.Event,
+		Dom = YAHOO.util.Dom,
+		oEvent = p_aArgs[0],
+		oItem = p_aArgs[1],
+		oSubmenu,
+		bInMenuAnchor = false,
+		oRoot,
+		sId,
+		sURL,
+		nHashPos,
+		nLen;
 
 
-    if (oItem && !oItem.cfg.getProperty("disabled")) {
+	if (oItem) {
+	
+		if (oItem.cfg.getProperty("disabled")) {
+		
+			Event.preventDefault(oEvent);
 
-        oSubmenu = oItem.cfg.getProperty("submenu");
+		}
+		else {
 
-        
-        /*
-             Check if the URL of the anchor is pointing to an element that is 
-             a child of the menu.
-        */
-        
-        sURL = oItem.cfg.getProperty("url");
+			oSubmenu = oItem.cfg.getProperty("submenu");
+	
+			
+			/*
+				 Check if the URL of the anchor is pointing to an element that is 
+				 a child of the menu.
+			*/
+			
+			sURL = oItem.cfg.getProperty("url");
 
-        
-        if (sURL) {
+		
+			if (sURL) {
+	
+				nHashPos = sURL.indexOf("#");
+	
+				nLen = sURL.length;
+	
+	
+				if (nHashPos != -1) {
+	
+					sURL = sURL.substr(nHashPos, nLen);
+		
+					nLen = sURL.length;
+	
+	
+					if (nLen > 1) {
+	
+						sId = sURL.substr(1, nLen);
+	
+						bInMenuAnchor = Dom.isAncestor(this.element, sId);
+						
+					}
+					else if (nLen === 1) {
+	
+						bInMenuAnchor = true;
+					
+					}
+	
+				}
+			
+			}
 
-            nHashPos = sURL.indexOf("#");
 
-            nLen = sURL.length;
+	
+			if (bInMenuAnchor && !oItem.cfg.getProperty("target")) {
+	
+				Event.preventDefault(oEvent);
+				
 
+				if (UA.webkit) {
+				
+					oItem.focus();
+				
+				}
+				else {
 
-            if (nHashPos != -1) {
+					oItem.focusEvent.fire();
+				
+				}
+			
+			}
+	
+	
+			if (!oSubmenu) {
+	
+				oRoot = this.getRoot();
+				
+				if (oRoot instanceof YAHOO.widget.MenuBar || 
+					oRoot.cfg.getProperty("position") == "static") {
+	
+					oRoot.clearActiveItem();
+	
+				}
+				else {
+	
+					oRoot.hide();
+				
+				}
+	
+			}
+			
+		}
+	
+	}
 
-                sURL = sURL.substr(nHashPos, nLen);
-    
-                nLen = sURL.length;
-
-
-                if (nLen > 1) {
-
-                    sId = sURL.substr(1, nLen);
-
-                    bInMenuAnchor = Dom.isAncestor(this.element, sId);
-                    
-                }
-                else if (nLen === 1) {
-
-                    bInMenuAnchor = true;
-                
-                }
-
-            }
-        
-        }
-
-
-        if (bInMenuAnchor && !oItem.cfg.getProperty("target")) {
-
-            Event.preventDefault(oEvent);
-
-            oItem.focus();
-        
-        }
-
-
-        if (!oSubmenu) {
-
-            oRoot = this.getRoot();
-            
-            if (oRoot instanceof YAHOO.widget.MenuBar || 
-                oRoot.cfg.getProperty("position") == "static") {
-
-                oRoot.clearActiveItem();
-
-            }
-            else {
-
-                oRoot.hide();
-            
-            }
-
-        }
-    
-    }
-
 },
 
 
@@ -4027,107 +4053,38 @@
 */
 enforceConstraints: function (type, args, obj) {
 
-    var oParentMenuItem = this.parent,
-        nViewportOffset = Overlay.VIEWPORT_OFFSET,
-        oElement = this.element,
-        oConfig = this.cfg,
-        pos = args[0],
-        offsetHeight = oElement.offsetHeight,
-        offsetWidth = oElement.offsetWidth,
-        viewPortWidth = Dom.getViewportWidth(),
-        viewPortHeight = Dom.getViewportHeight(),
-        nPadding = (oParentMenuItem && 
-            oParentMenuItem.parent instanceof YAHOO.widget.MenuBar) ? 
-            0 : nViewportOffset,
-        aContext = oConfig.getProperty("context"),
-        oContextElement = aContext ? aContext[0] : null,
-        topConstraint,
-        leftConstraint,
-        bottomConstraint,
-        rightConstraint,
-        scrollX,
-        scrollY,
-        x,
-        y;
-    
+	YAHOO.widget.Menu.superclass.enforceConstraints.apply(this, arguments);
+	
+	var oParent = this.parent,
+		oParentMenu,
+		nParentMenuX,
+		nNewX,
+		nX;
+	
+	
+	if (oParent) {
+	
+		oParentMenu = oParent.parent;
 
-    if (offsetWidth < viewPortWidth) {
+		if (!(oParentMenu instanceof YAHOO.widget.MenuBar)) {
+	
+			nParentMenuX = oParentMenu.cfg.getProperty("x");
+			nX = this.cfg.getProperty("x");
+		
+	
+			if (nX < (nParentMenuX + oParent.element.offsetWidth)) {
 
-        x = pos[0];
-        scrollX = Dom.getDocumentScrollLeft();
-        leftConstraint = scrollX + nPadding;
-        rightConstraint = scrollX + viewPortWidth - offsetWidth - nPadding;
+				nNewX = (nParentMenuX - this.element.offsetWidth);
+			
+				this.cfg.setProperty("x",  nNewX, true);
+				this.cfg.setProperty("xy", [nNewX, (this.cfg.getProperty("y"))], true);
+			
+			}
+		
+		}
+	
+	}
 
-        if (x < nViewportOffset) {
-    
-            x = leftConstraint;
-    
-        } else if ((x + offsetWidth) > viewPortWidth) {
-    
-            if(oContextElement &&
-                ((x - oContextElement.offsetWidth) > offsetWidth)) {
-    
-                if (oParentMenuItem && 
-                    oParentMenuItem.parent instanceof YAHOO.widget.MenuBar) {
-    
-                    x = (x - (offsetWidth - oContextElement.offsetWidth));
-    
-                }
-                else {
-    
-                    x = (x - (oContextElement.offsetWidth + offsetWidth));
-    
-                }
-    
-            }
-            else {
-    
-                x = rightConstraint;
-    
-            }
-    
-        }
-    
-    }
-
-
-    if (offsetHeight < viewPortHeight) {
-
-        y = pos[1];
-        scrollY = Dom.getDocumentScrollTop();
-        topConstraint = scrollY + nPadding;
-        bottomConstraint = scrollY + viewPortHeight - offsetHeight - nPadding;
-
-
-
-        if (y < nViewportOffset) {
-    
-            y = topConstraint;
-    
-        } else if (y > bottomConstraint) {
-    
-            if (oContextElement && (y > offsetHeight)) {
-    
-                y = ((y + oContextElement.offsetHeight) - offsetHeight);
-    
-            }
-            else {
-    
-                y = bottomConstraint;
-                
-
-    
-            }
-    
-        }
-
-    }
-
-
-    oConfig.setProperty("x", x, true);
-    oConfig.setProperty("y", y, true);
-    oConfig.setProperty("xy", [x,y], true);
-
 },
 
 
@@ -4379,7 +4336,8 @@
         fnMouseOut = this._onScrollTargetMouseOut,
         nMinScrollHeight = this.cfg.getProperty("minscrollheight"),
         nHeight,
-        nOffsetWidth;
+        nOffsetWidth,
+        sWidth;
 
 
     if (nMaxHeight !== 0 && nMaxHeight < nMinScrollHeight) {
@@ -4415,25 +4373,37 @@
         offsetParent's "position" property is also set to "absolute."  It is 
         possible to work around this bug by specifying a value for the width 
         property in addition to overflow.
+
+		In IE it is also necessary to give the Menu a width when the scrollbars are 
+		rendered to prevent the Menu from rendering with a width that is 100% of
+		the browser viewport.
     */
 
-    if (UA.gecko && this.parent && this.parent.parent && 
-        this.parent.parent.cfg.getProperty("position") == "dynamic" && 
-        !this.cfg.getProperty("width")) {
+	var bSetWidth = ((UA.gecko && this.parent && this.parent.parent && 
+        this.parent.parent.cfg.getProperty("position") == "dynamic") || UA.ie);
 
-        nOffsetWidth = oElement.offsetWidth;
 
-        /*
-            Measuring the difference of the offsetWidth before and after
-            setting the "width" style attribute allows us to compute the 
-            about of padding and borders applied to the element, which in 
-            turn allows us to set the "width" property correctly.
-        */
-        
-        oElement.style.width = nOffsetWidth + "px";
-        oElement.style.width = 
-                (nOffsetWidth - (oElement.offsetWidth - nOffsetWidth)) + "px";
+    if (bSetWidth) {
 
+		if (!this.cfg.getProperty("width")) {
+
+			nOffsetWidth = oElement.offsetWidth;
+	
+			/*
+				Measuring the difference of the offsetWidth before and after
+				setting the "width" style attribute allows us to compute the 
+				about of padding and borders applied to the element, which in 
+				turn allows us to set the "width" property correctly.
+			*/
+			
+			oElement.style.width = nOffsetWidth + "px";
+	
+			sWidth = (nOffsetWidth - (oElement.offsetWidth - nOffsetWidth)) + "px";
+	
+			this.cfg.setProperty("width", sWidth);
+		
+		}
+
     }
 
 
@@ -4457,7 +4427,6 @@
     nHeight = (nMaxHeight - (oHeader.offsetHeight + oHeader.offsetHeight));
 
 
-
     if (nHeight > 0 && (oBody.offsetHeight > nMaxHeight)) {
 
         Dom.addClass(oBody, "yui-menu-body-scrolled");
@@ -4474,6 +4443,13 @@
     }
     else if (oHeader && oFooter) {
 
+		if (bSetWidth) {
+
+			this.cfg.setProperty("width", "");
+		
+		}
+
+
         this._enableScrollHeader();
         this._enableScrollFooter();
 
@@ -6492,7 +6468,7 @@
 
                     if (oAnchor) {
 
-                        sURL = oAnchor.getAttribute("href");
+                        sURL = oAnchor.getAttribute("href", 2);
                         sTarget = oAnchor.getAttribute("target");
 
                         sText = oAnchor.innerHTML;
@@ -7378,7 +7354,7 @@
         * accompany the text for the menu item.
         * @deprecated Use "text" configuration property to add help text markup.  
         * For example: <code>oMenuItem.cfg.setProperty("text", "Copy <em 
-        * class=\"helptext\">Ctrl + C</em<");</code>
+        * class=\"helptext\">Ctrl + C</em>");</code>
         * @default null
         * @type String|<a href="http://www.w3.org/TR/
         * 2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
@@ -7438,7 +7414,7 @@
         * rendered with emphasis.
         * @deprecated Use "text" configuration property to add emphasis.  
         * For example: <code>oMenuItem.cfg.setProperty("text", "<em>Some 
-        * Text</em<");</code>
+        * Text</em>");</code>
         * @default false
         * @type Boolean
         */
@@ -7460,7 +7436,7 @@
         * rendered with strong emphasis.
         * @deprecated Use "text" configuration property to add strong emphasis.  
         * For example: <code>oMenuItem.cfg.setProperty("text", "<strong> 
-        * Some Text</strong<");</code>
+        * Some Text</strong>");</code>
         * @default false
         * @type Boolean
         */
@@ -9050,4 +9026,4 @@
 }
     
 }); // END YAHOO.lang.extend
-YAHOO.register("menu", YAHOO.widget.Menu, {version: "2.4.1", build: "742"});
+YAHOO.register("menu", YAHOO.widget.Menu, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/menu/menu-min.js
===================================================================
--- trunk/root/static/yui/menu/menu-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/menu/menu-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,16 +1,16 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 (function(){var B=YAHOO.util.Dom,A=YAHOO.util.Event;YAHOO.widget.MenuManager=function(){var N=false,F={},Q={},J={},E={"click":"clickEvent","mousedown":"mouseDownEvent","mouseup":"mouseUpEvent","mouseover":"mouseOverEvent","mouseout":"mouseOutEvent","keydown":"keyDownEvent","keyup":"keyUpEvent","keypress":"keyPressEvent"},K=null;function D(S){var R;if(S&&S.tagName){switch(S.tagName.toUpperCase()){case"DIV":R=S.parentNode;if((B.hasClass(S,"hd")||B.hasClass(S,"bd")||B.hasClass(S,"ft"))&&R&&R.tagName&&R.tagName.toUpperCase()=="DIV"){return R;}else{return S;}break;case"LI":return S;default:R=S.parentNode;if(R){return D(R);}break;}}}function G(V){var R=A.getTarget(V),S=D(R),X,T,U,Z,Y;if(S){T=S.tagName.toUpperCase();if(T=="LI"){U=S.id;if(U&&J[U]){Z=J[U];Y=Z.parent;}}else{if(T=="DIV"){if(S.id){Y=F[S.id];}}}}if(Y){X=E[V.type];if(Z&&!Z.cfg.getProperty("disabled")){Z[X].fire(V);if(V.type=="keyup"||V.type=="mousedown"){if(K!=Z){if(K){K.blurEvent.fire();}Z.focusEvent.fire();}}}Y[X].fire!
 (V,Z);}else{if(V.type=="mousedown"){if(K){K.blurEvent.fire();K=null;}for(var W in Q){if(YAHOO.lang.hasOwnProperty(Q,W)){Y=Q[W];if(Y.cfg.getProperty("clicktohide")&&!(Y instanceof YAHOO.widget.MenuBar)&&Y.cfg.getProperty("position")=="dynamic"){Y.hide();}else{Y.clearActiveItem(true);}}}}else{if(V.type=="keyup"){if(K){K.blurEvent.fire();K=null;}}}}}function P(S,R,T){if(F[T.id]){this.removeMenu(T);}}function M(S,R){var T=R[0];if(T){K=T;}}function H(S,R){K=null;}function C(T,S){var R=S[0],U=this.id;if(R){Q[U]=this;}else{if(Q[U]){delete Q[U];}}}function L(S,R){O(this);}function O(S){var R=S.id;if(R&&J[R]){if(K==S){K=null;}delete J[R];S.destroyEvent.unsubscribe(L);}}function I(S,R){var U=R[0],T;if(U instanceof YAHOO.widget.MenuItem){T=U.id;if(!J[T]){J[T]=U;U.destroyEvent.subscribe(L);}}}return{addMenu:function(S){var R;if(S instanceof YAHOO.widget.Menu&&S.id&&!F[S.id]){F[S.id]=S;if(!N){R=document;A.on(R,"mouseover",G,this,true);A.on(R,"mouseout",G,this,true);A.on(R,"mousedown",G,!
 this,true);A.on(R,"mouseup",G,this,true);A.on(R,"click",G,this!
 ,true);A
.on(R,"keydown",G,this,true);A.on(R,"keyup",G,this,true);A.on(R,"keypress",G,this,true);N=true;}S.cfg.subscribeToConfigEvent("visible",C);S.destroyEvent.subscribe(P,S,this);S.itemAddedEvent.subscribe(I);S.focusEvent.subscribe(M);S.blurEvent.subscribe(H);}},removeMenu:function(U){var S,R,T;if(U){S=U.id;if(F[S]==U){R=U.getItems();if(R&&R.length>0){T=R.length-1;do{O(R[T]);}while(T--);}delete F[S];if(Q[S]==U){delete Q[S];}if(U.cfg){U.cfg.unsubscribeFromConfigEvent("visible",C);}U.destroyEvent.unsubscribe(P,U);U.itemAddedEvent.unsubscribe(I);U.focusEvent.unsubscribe(M);U.blurEvent.unsubscribe(H);}}},hideVisible:function(){var R;for(var S in Q){if(YAHOO.lang.hasOwnProperty(Q,S)){R=Q[S];if(!(R instanceof YAHOO.widget.MenuBar)&&R.cfg.getProperty("position")=="dynamic"){R.hide();}}}},getVisible:function(){return Q;},getMenus:function(){return F;},getMenu:function(S){var R=F[S];if(R){return R;}},getMenuItem:function(R){var S=J[R];if(S){return S;}},getMenuItemGroup:function(U){var S=B.!
 get(U),R,W,V,T;if(S&&S.tagName&&S.tagName.toUpperCase()=="UL"){W=S.firstChild;if(W){R=[];do{T=W.id;if(T){V=this.getMenuItem(T);if(V){R[R.length]=V;}}}while((W=W.nextSibling));if(R.length>0){return R;}}}},getFocusedMenuItem:function(){return K;},getFocusedMenu:function(){if(K){return(K.parent.getRoot());}},toString:function(){return"MenuManager";}};}();})();(function(){YAHOO.widget.Menu=function(O,N){if(N){this.parent=N.parent;this.lazyLoad=N.lazyLoad||N.lazyload;this.itemData=N.itemData||N.itemdata;}YAHOO.widget.Menu.superclass.constructor.call(this,O,N);};function I(N){if(typeof N=="string"){return("dynamic,static".indexOf((N.toLowerCase()))!=-1);}}var C=YAHOO.util.Dom,M=YAHOO.util.Event,D=YAHOO.widget.Module,B=YAHOO.widget.Overlay,F=YAHOO.widget.Menu,K=YAHOO.widget.MenuManager,L=YAHOO.util.CustomEvent,E=YAHOO.lang,H=YAHOO.env.ua,G,A={"MOUSE_OVER":"mouseover","MOUSE_OUT":"mouseout","MOUSE_DOWN":"mousedown","MOUSE_UP":"mouseup","CLICK":"click","KEY_PRESS":"keypress","KEY_DO!
 WN":"keydown","KEY_UP":"keyup","FOCUS":"focus","BLUR":"blur","!
 ITEM_ADD
ED":"itemAdded","ITEM_REMOVED":"itemRemoved"},J={"VISIBLE":{key:"visible",value:false,validator:E.isBoolean},"CONSTRAIN_TO_VIEWPORT":{key:"constraintoviewport",value:true,validator:E.isBoolean,supercedes:["iframe","x","y","xy"]},"POSITION":{key:"position",value:"dynamic",validator:I,supercedes:["visible","iframe"]},"SUBMENU_ALIGNMENT":{key:"submenualignment",value:["tl","tr"],suppressEvent:true},"AUTO_SUBMENU_DISPLAY":{key:"autosubmenudisplay",value:true,validator:E.isBoolean,suppressEvent:true},"SHOW_DELAY":{key:"showdelay",value:250,validator:E.isNumber,suppressEvent:true},"HIDE_DELAY":{key:"hidedelay",value:0,validator:E.isNumber,suppressEvent:true},"SUBMENU_HIDE_DELAY":{key:"submenuhidedelay",value:250,validator:E.isNumber,suppressEvent:true},"CLICK_TO_HIDE":{key:"clicktohide",value:true,validator:E.isBoolean,suppressEvent:true},"CONTAINER":{key:"container",suppressEvent:true},"SCROLL_INCREMENT":{key:"scrollincrement",value:1,validator:E.isNumber,supercedes:["maxheight"]!
 ,suppressEvent:true},"MIN_SCROLL_HEIGHT":{key:"minscrollheight",value:90,validator:E.isNumber,supercedes:["maxheight"],suppressEvent:true},"MAX_HEIGHT":{key:"maxheight",value:0,validator:E.isNumber,supercedes:["iframe"],suppressEvent:true},"CLASS_NAME":{key:"classname",value:null,validator:E.isString,suppressEvent:true},"DISABLED":{key:"disabled",value:false,validator:E.isBoolean,suppressEvent:true}};YAHOO.lang.extend(F,B,{CSS_CLASS_NAME:"yuimenu",ITEM_TYPE:null,GROUP_TITLE_TAG_NAME:"h6",OFF_SCREEN_POSITION:[-10000,-10000],_nHideDelayId:null,_nShowDelayId:null,_nSubmenuHideDelayId:null,_nBodyScrollId:null,_bHideDelayEventHandlersAssigned:false,_bHandledMouseOverEvent:false,_bHandledMouseOutEvent:false,_aGroupTitleElements:null,_aItemGroups:null,_aListElements:null,_nCurrentMouseX:0,_bStopMouseEventHandlers:false,_sClassName:null,lazyLoad:false,itemData:null,activeItem:null,parent:null,srcElement:null,mouseOverEvent:null,mouseOutEvent:null,mouseDownEvent:null,mouseUpEvent:nu!
 ll,clickEvent:null,keyPressEvent:null,keyDownEvent:null,keyUpE!
 vent:nul
l,itemAddedEvent:null,itemRemovedEvent:null,init:function(P,O){this._aItemGroups=[];
 this._aListElements=[];this._aGroupTitleElements=[];if(!this.ITEM_TYPE){this.ITEM_TYPE=YAHOO.widget.MenuItem;}var N;if(typeof P=="string"){N=document.getElementById(P);}else{if(P.tagName){N=P;}}if(N&&N.tagName){switch(N.tagName.toUpperCase()){case"DIV":this.srcElement=N;if(!N.id){N.setAttribute("id",C.generateId());}F.superclass.init.call(this,N);this.beforeInitEvent.fire(F);break;case"SELECT":this.srcElement=N;F.superclass.init.call(this,C.generateId());this.beforeInitEvent.fire(F);break;}}else{F.superclass.init.call(this,P);this.beforeInitEvent.fire(F);}if(this.element){C.addClass(this.element,this.CSS_CLASS_NAME);this.initEvent.subscribe(this._onInit);this.beforeRenderEvent.subscribe(this._onBeforeRender);this.renderEvent.subscribe(this._onRender);this.renderEvent.subscribe(this.onRender);this.beforeShowEvent.subscribe(this._onBeforeShow);this.hideEvent.subscribe(this.positionOffScreen);this.showEvent.subscribe(this._onShow);this.beforeHideEvent.subscribe(this._onBeforeH!
 ide);this.mouseOverEvent.subscribe(this._onMouseOver);this.mouseOutEvent.subscribe(this._onMouseOut);this.clickEvent.subscribe(this._onClick);this.keyDownEvent.subscribe(this._onKeyDown);this.keyPressEvent.subscribe(this._onKeyPress);if(H.gecko||H.webkit){this.cfg.subscribeToConfigEvent("y",this._onYChange);}if(O){this.cfg.applyConfig(O,true);}K.addMenu(this);this.initEvent.fire(F);}},_initSubTree:function(){var O=this.srcElement,N,Q,T,U,S,R,P;if(O){N=(O.tagName&&O.tagName.toUpperCase());if(N=="DIV"){U=this.body.firstChild;if(U){Q=0;T=this.GROUP_TITLE_TAG_NAME.toUpperCase();do{if(U&&U.tagName){switch(U.tagName.toUpperCase()){case T:this._aGroupTitleElements[Q]=U;break;case"UL":this._aListElements[Q]=U;this._aItemGroups[Q]=[];Q++;break;}}}while((U=U.nextSibling));if(this._aListElements[0]){C.addClass(this._aListElements[0],"first-of-type");}}}U=null;if(N){switch(N){case"DIV":S=this._aListElements;R=S.length;if(R>0){P=R-1;do{U=S[P].firstChild;if(U){do{if(U&&U.tagName&&U.tagNa!
 me.toUpperCase()=="LI"){this.addItem(new this.ITEM_TYPE(U,{par!
 ent:this
}),P);}}while((U=U.nextSibling));}}while(P--);}break;case"SELECT":U=O.firstChild;do{if(U&&U.tagName){switch(U.tagName.toUpperCase()){case"OPTGROUP":case"OPTION":this.addItem(new this.ITEM_TYPE(U,{parent:this}));break;}}}while((U=U.nextSibling));break;}}}},_getFirstEnabledItem:function(){var N=this.getItems(),Q=N.length,P;for(var O=0;O<Q;O++){P=N[O];if(P&&!P.cfg.getProperty("disabled")&&P.element.style.display!="none"){return P;}}},_addItemToGroup:function(S,T,W){var U,X,Q,V,R,O,P;function N(Y,Z){return(Y[Z]||N(Y,(Z+1)));}if(T instanceof this.ITEM_TYPE){U=T;U.parent=this;}else{if(typeof T=="string"){U=new this.ITEM_TYPE(T,{parent:this});}else{if(typeof T=="object"){T.parent=this;U=new this.ITEM_TYPE(T.text,T);}}}if(U){if(U.cfg.getProperty("selected")){this.activeItem=U;}X=typeof S=="number"?S:0;Q=this._getItemGroup(X);if(!Q){Q=this._createItemGroup(X);}if(typeof W=="number"){R=(W>=Q.length);if(Q[W]){Q.splice(W,0,U);}else{Q[W]=U;}V=Q[W];if(V){if(R&&(!V.element.parentNode||V.el!
 ement.parentNode.nodeType==11)){this._aListElements[X].appendChild(V.element);}else{O=N(Q,(W+1));if(O&&(!V.element.parentNode||V.element.parentNode.nodeType==11)){this._aListElements[X].insertBefore(V.element,O.element);}}V.parent=this;this._subscribeToItemEvents(V);this._configureSubmenu(V);this._updateItemProperties(X);this.itemAddedEvent.fire(V);this.changeContentEvent.fire();return V;}}else{P=Q.length;Q[P]=U;V=Q[P];if(V){if(!C.isAncestor(this._aListElements[X],V.element)){this._aListElements[X].appendChild(V.element);}V.element.setAttribute("groupindex",X);V.element.setAttribute("index",P);V.parent=this;V.index=P;V.groupIndex=X;this._subscribeToItemEvents(V);this._configureSubmenu(V);if(P===0){C.addClass(V.element,"first-of-type");}this.itemAddedEvent.fire(V);this.changeContentEvent.fire();return V;}}}},_removeItemFromGroupByIndex:function(Q,O){var P=typeof Q=="number"?Q:0,R=this._getItemGroup(P),T,S,N;if(R){T=R.splice(O,1);S=T[0];if(S){this._updateItemProperties(P);if(!
 R.length===0){N=this._aListElements[P];if(this.body&&N){this.b!
 ody.remo
veChild(N);}this._aItemGroups.splice(P,1);this._aListElements.splice(P,1);N=this._aListElements[0];if(N){C.addClass(N,"first-of-type");}}this.itemRemovedEvent.fire(S);this.changeContentEvent.fire();return S;}}},_removeItemFromGroupByValue:function(P,N){var R=this._getItemGroup(P),S,Q,O;if(R){S=R.length;Q=-1;if(S>0){O=S-1;do{if(R[O]==N){Q=O;break;}}while(O--);if(Q>-1){return(this._removeItemFromGroupByIndex(P,Q));}}}},_updateItemProperties:function(O){var P=this._getItemGroup(O),S=P.length,R,Q,N;if(S>0){N=S-1;do{R=P[N];if(R){Q=R.element;R.index=N;R.groupIndex=O;Q.setAttribute("groupindex",O);Q.setAttribute("index",N);C.removeClass(Q,"first-of-type");}}while(N--);if(Q){C.addClass(Q,"first-of-type");}}},_createItemGroup:function(O){var N;if(!this._aItemGroups[O]){this._aItemGroups[O]=[];N=document.createElement("ul");this._aListElements[O]=N;return this._aItemGroups[O];}},_getItemGroup:function(O){var N=((typeof O=="number")?O:0);return this._aItemGroups[N];},_configureSubmenu:!
 function(N){var O=N.cfg.getProperty("submenu");if(O){this.cfg.configChangedEvent.subscribe(this._onParentMenuConfigChange,O,true);this.renderEvent.subscribe(this._onParentMenuRender,O,true);O.beforeShowEvent.subscribe(this._onSubmenuBeforeShow);}},_subscribeToItemEvents:function(N){N.focusEvent.subscribe(this._onMenuItemFocus);N.blurEvent.subscribe(this._onMenuItemBlur);N.destroyEvent.subscribe(this._onMenuItemDestroy,N,this);N.cfg.configChangedEvent.subscribe(this._onMenuItemConfigChange,N,this);},_onVisibleChange:function(P,O){var N=O[0];if(N){C.addClass(this.element,"visible");}else{C.removeClass(this.element,"visible");}},_cancelHideDelay:function(){var N=this.getRoot();if(N._nHideDelayId){window.clearTimeout(N._nHideDelayId);}},_execHideDelay:function(){this._cancelHideDelay();var O=this.getRoot(),P=this;function N(){if(O.activeItem){O.clearActiveItem();}if(O==P&&!(P instanceof YAHOO.widget.MenuBar)&&P.cfg.getProperty("position")=="dynamic"){P.hide();
-}}O._nHideDelayId=window.setTimeout(N,O.cfg.getProperty("hidedelay"));},_cancelShowDelay:function(){var N=this.getRoot();if(N._nShowDelayId){window.clearTimeout(N._nShowDelayId);}},_execShowDelay:function(P){var O=this.getRoot();function N(){if(P.parent.cfg.getProperty("selected")){P.show();}}O._nShowDelayId=window.setTimeout(N,O.cfg.getProperty("showdelay"));},_execSubmenuHideDelay:function(Q,O,N){var P=this;Q._nSubmenuHideDelayId=window.setTimeout(function(){if(P._nCurrentMouseX>(O+10)){Q._nSubmenuHideDelayId=window.setTimeout(function(){Q.hide();},N);}else{Q.hide();}},50);},_disableScrollHeader:function(){if(!this._bHeaderDisabled){C.addClass(this.header,"topscrollbar_disabled");this._bHeaderDisabled=true;}},_disableScrollFooter:function(){if(!this._bFooterDisabled){C.addClass(this.footer,"bottomscrollbar_disabled");this._bFooterDisabled=true;}},_enableScrollHeader:function(){if(this._bHeaderDisabled){C.removeClass(this.header,"topscrollbar_disabled");this._bHeaderDisabl!
 ed=false;}},_enableScrollFooter:function(){if(this._bFooterDisabled){C.removeClass(this.footer,"bottomscrollbar_disabled");this._bFooterDisabled=false;}},_onMouseOver:function(W,R){if(this._bStopMouseEventHandlers){return false;}var X=R[0],V=R[1],N=M.getTarget(X),O,Q,U,P,T,S;if(!this._bHandledMouseOverEvent&&(N==this.element||C.isAncestor(this.element,N))){this._nCurrentMouseX=0;M.on(this.element,"mousemove",this._onMouseMove,this,true);this.clearActiveItem();if(this.parent&&this._nSubmenuHideDelayId){window.clearTimeout(this._nSubmenuHideDelayId);this.parent.cfg.setProperty("selected",true);O=this.parent.parent;O._bHandledMouseOutEvent=true;O._bHandledMouseOverEvent=false;}this._bHandledMouseOverEvent=true;this._bHandledMouseOutEvent=false;}if(V&&!V.handledMouseOverEvent&&!V.cfg.getProperty("disabled")&&(N==V.element||C.isAncestor(V.element,N))){Q=this.cfg.getProperty("showdelay");U=(Q>0);if(U){this._cancelShowDelay();}P=this.activeItem;if(P){P.cfg.setProperty("selected",f!
 alse);}T=V.cfg;T.setProperty("selected",true);if(this.hasFocus!
 ()){V.fo
cus();}if(this.cfg.getProperty("autosubmenudisplay")){S=T.getProperty("submenu");if(S){if(U){this._execShowDelay(S);}else{S.show();}}}V.handledMouseOverEvent=true;V.handledMouseOutEvent=false;}},_onMouseOut:function(V,P){if(this._bStopMouseEventHandlers){return false;}var W=P[0],T=P[1],Q=M.getRelatedTarget(W),U=false,S,R,N,O;if(T&&!T.cfg.getProperty("disabled")){S=T.cfg;R=S.getProperty("submenu");if(R&&(Q==R.element||C.isAncestor(R.element,Q))){U=true;}if(!T.handledMouseOutEvent&&((Q!=T.element&&!C.isAncestor(T.element,Q))||U)){if(!U){T.cfg.setProperty("selected",false);if(R){N=this.cfg.getProperty("submenuhidedelay");O=this.cfg.getProperty("showdelay");if(!(this instanceof YAHOO.widget.MenuBar)&&N>0&&O>=N){this._execSubmenuHideDelay(R,M.getPageX(W),N);}else{R.hide();}}}T.handledMouseOutEvent=true;T.handledMouseOverEvent=false;}}if(!this._bHandledMouseOutEvent&&((Q!=this.element&&!C.isAncestor(this.element,Q))||U)){M.removeListener(this.element,"mousemove",this._onMouseMove)!
 ;this._nCurrentMouseX=M.getPageX(W);this._bHandledMouseOutEvent=true;this._bHandledMouseOverEvent=false;}},_onMouseMove:function(O,N){if(this._bStopMouseEventHandlers){return false;}this._nCurrentMouseX=M.getPageX(O);},_onClick:function(W,P){var X=P[0],S=P[1],Q,U=false,O,N,R,T,V;if(S&&!S.cfg.getProperty("disabled")){Q=S.cfg.getProperty("submenu");R=S.cfg.getProperty("url");if(R){T=R.indexOf("#");V=R.length;if(T!=-1){R=R.substr(T,V);V=R.length;if(V>1){N=R.substr(1,V);U=C.isAncestor(this.element,N);}else{if(V===1){U=true;}}}}if(U&&!S.cfg.getProperty("target")){M.preventDefault(X);S.focus();}if(!Q){O=this.getRoot();if(O instanceof YAHOO.widget.MenuBar||O.cfg.getProperty("position")=="static"){O.clearActiveItem();}else{O.hide();}}}},_onKeyDown:function(b,V){var Y=V[0],X=V[1],f=this,U,Z,O,S,c,N,e,R,a,Q,W,d,T;function P(){f._bStopMouseEventHandlers=true;window.setTimeout(function(){f._bStopMouseEventHandlers=false;},10);}if(X&&!X.cfg.getProperty("disabled")){Z=X.cfg;O=this.parent!
 ;switch(Y.keyCode){case 38:case 40:c=(Y.keyCode==38)?X.getPrev!
 iousEnab
ledSibling():X.getNextEnabledSibling();if(c){this.clearActiveItem();c.cfg.setProperty("selected",true);c.focus();if(this.cfg.getProperty("maxheight")>0){N=this.body;e=N.scrollTop;R=N.offsetHeight;a=this.getItems();Q=a.length-1;W=c.element.offsetTop;if(Y.keyCode==40){if(W>=(R+e)){N.scrollTop=W-R;}else{if(W<=e){N.scrollTop=0;}}if(c==a[Q]){N.scrollTop=c.element.offsetTop;}}else{if(W<=e){N.scrollTop=W-c.element.offsetHeight;}else{if(W>=(e+R)){N.scrollTop=W;}}if(c==a[0]){N.scrollTop=0;}}e=N.scrollTop;d=N.scrollHeight-N.offsetHeight;if(e===0){this._disableScrollHeader();this._enableScrollFooter();}else{if(e==d){this._enableScrollHeader();this._disableScrollFooter();}else{this._enableScrollHeader();this._enableScrollFooter();}}}}M.preventDefault(Y);P();break;case 39:U=Z.getProperty("submenu");if(U){if(!Z.getProperty("selected")){Z.setProperty("selected",true);}U.show();U.setInitialFocus();U.setInitialSelection();}else{S=this.getRoot();if(S instanceof YAHOO.widget.MenuBar){c=S.activ!
 eItem.getNextEnabledSibling();if(c){S.clearActiveItem();c.cfg.setProperty("selected",true);U=c.cfg.getProperty("submenu");if(U){U.show();}c.focus();}}}M.preventDefault(Y);P();break;case 37:if(O){T=O.parent;if(T instanceof YAHOO.widget.MenuBar){c=T.activeItem.getPreviousEnabledSibling();if(c){T.clearActiveItem();c.cfg.setProperty("selected",true);U=c.cfg.getProperty("submenu");if(U){U.show();}c.focus();}}else{this.hide();O.focus();}}M.preventDefault(Y);P();break;}}if(Y.keyCode==27){if(this.cfg.getProperty("position")=="dynamic"){this.hide();if(this.parent){this.parent.focus();}}else{if(this.activeItem){U=this.activeItem.cfg.getProperty("submenu");if(U&&U.cfg.getProperty("visible")){U.hide();this.activeItem.focus();}else{this.activeItem.blur();this.activeItem.cfg.setProperty("selected",false);}}}M.preventDefault(Y);}},_onKeyPress:function(P,O){var N=O[0];if(N.keyCode==40||N.keyCode==38){M.preventDefault(N);}},_onYChange:function(O,N){var Q=this.parent,S,P,R;
-if(Q){S=Q.parent.body.scrollTop;if(S>0){R=(this.cfg.getProperty("y")-S);C.setY(this.element,R);P=this.iframe;if(P){C.setY(P,R);}this.cfg.setProperty("y",R,true);}}},_onScrollTargetMouseOver:function(T,W){this._cancelHideDelay();var P=M.getTarget(T),R=this.body,V=this,Q=this.cfg.getProperty("scrollincrement"),N,O;function U(){var X=R.scrollTop;if(X<N){R.scrollTop=(X+Q);V._enableScrollHeader();}else{R.scrollTop=N;window.clearInterval(V._nBodyScrollId);V._disableScrollFooter();}}function S(){var X=R.scrollTop;if(X>0){R.scrollTop=(X-Q);V._enableScrollFooter();}else{R.scrollTop=0;window.clearInterval(V._nBodyScrollId);V._disableScrollHeader();}}if(C.hasClass(P,"hd")){O=S;}else{N=R.scrollHeight-R.offsetHeight;O=U;}this._nBodyScrollId=window.setInterval(O,10);},_onScrollTargetMouseOut:function(O,N){window.clearInterval(this._nBodyScrollId);this._cancelHideDelay();},_onInit:function(O,N){this.cfg.subscribeToConfigEvent("visible",this._onVisibleChange);var P=!this.parent,Q=this.lazy!
 Load;if(((P&&!Q)||(P&&(this.cfg.getProperty("visible")||this.cfg.getProperty("position")=="static"))||(!P&&!Q))&&this.getItemGroups().length===0){if(this.srcElement){this._initSubTree();}if(this.itemData){this.addItems(this.itemData);}}else{if(Q){this.cfg.fireQueue();}}},_onBeforeRender:function(Q,P){var R=this.element,U=this._aListElements.length,O=true,T=0,N,S;if(U>0){do{N=this._aListElements[T];if(N){if(O){C.addClass(N,"first-of-type");O=false;}if(!C.isAncestor(R,N)){this.appendToBody(N);}S=this._aGroupTitleElements[T];if(S){if(!C.isAncestor(R,S)){N.parentNode.insertBefore(S,N);}C.addClass(N,"hastitle");}}T++;}while(T<U);}},_onRender:function(O,N){if(this.cfg.getProperty("position")=="dynamic"){if(!this.cfg.getProperty("visible")){this.positionOffScreen();}}},_onBeforeShow:function(W,R){var V,O,S,Q,T;if(this.lazyLoad&&this.getItemGroups().length===0){if(this.srcElement){this._initSubTree();}if(this.itemData){if(this.parent&&this.parent.parent&&this.parent.parent.srcEleme!
 nt&&this.parent.parent.srcElement.tagName.toUpperCase()=="SELE!
 CT"){V=t
his.itemData.length;for(O=0;O<V;O++){if(this.itemData[O].tagName){this.addItem((new this.ITEM_TYPE(this.itemData[O])));}}}else{this.addItems(this.itemData);}}T=this.srcElement;if(T){if(T.tagName.toUpperCase()=="SELECT"){if(C.inDocument(T)){this.render(T.parentNode);}else{this.render(this.cfg.getProperty("container"));}}else{this.render();}}else{if(this.parent){this.render(this.parent.element);}else{this.render(this.cfg.getProperty("container"));}}}var P=this.cfg.getProperty("maxheight"),N=this.cfg.getProperty("minscrollheight"),U=this.cfg.getProperty("position")=="dynamic";if(!this.parent&&U){this.cfg.refireEvent("xy");}function X(){this.cfg.setProperty("maxheight",0);this.hideEvent.unsubscribe(X);}if(!(this instanceof YAHOO.widget.MenuBar)&&U){if(P===0){S=C.getViewportHeight();if(this.parent&&this.parent.parent instanceof YAHOO.widget.MenuBar){Q=YAHOO.util.Region.getRegion(this.parent.element);S=(S-Q.bottom);}if(this.element.offsetHeight>=S){P=(S-(B.VIEWPORT_OFFSET*2));if(P!
 <N){P=N;}this.cfg.setProperty("maxheight",P);this.hideEvent.subscribe(X);}}}},_onShow:function(Q,P){var T=this.parent,S,N,O;function R(V){var U;if(V.type=="mousedown"||(V.type=="keydown"&&V.keyCode==27)){U=M.getTarget(V);if(U!=S.element||!C.isAncestor(S.element,U)){S.cfg.setProperty("autosubmenudisplay",false);M.removeListener(document,"mousedown",R);M.removeListener(document,"keydown",R);}}}if(T){S=T.parent;N=S.cfg.getProperty("submenualignment");O=this.cfg.getProperty("submenualignment");if((N[0]!=O[0])&&(N[1]!=O[1])){this.cfg.setProperty("submenualignment",[N[0],N[1]]);}if(!S.cfg.getProperty("autosubmenudisplay")&&(S instanceof YAHOO.widget.MenuBar||S.cfg.getProperty("position")=="static")){S.cfg.setProperty("autosubmenudisplay",true);M.on(document,"mousedown",R);M.on(document,"keydown",R);}}},_onBeforeHide:function(P,O){var N=this.activeItem,R,Q;if(N){R=N.cfg;R.setProperty("selected",false);Q=R.getProperty("submenu");if(Q){Q.hide();}}if(this.getRoot()==this){this.blur()!
 ;}},_onParentMenuConfigChange:function(O,N,R){var P=N[0][0],Q=!
 N[0][1];
switch(P){case"iframe":case"constraintoviewport":case"hidedelay":case"showdelay":case"submenuhidedelay":case"clicktohide":case"effect":case"classname":case"scrollincrement":case"minscrollheight":R.cfg.setProperty(P,Q);break;}},_onParentMenuRender:function(O,N,S){var P=S.parent.parent.cfg,Q={constraintoviewport:P.getProperty("constraintoviewport"),xy:[0,0],clicktohide:P.getProperty("clicktohide"),effect:P.getProperty("effect"),showdelay:P.getProperty("showdelay"),hidedelay:P.getProperty("hidedelay"),submenuhidedelay:P.getProperty("submenuhidedelay"),classname:P.getProperty("classname"),scrollincrement:P.getProperty("scrollincrement"),minscrollheight:P.getProperty("minscrollheight"),iframe:P.getProperty("iframe")},R;S.cfg.applyConfig(Q);if(!this.lazyLoad){R=this.parent.element;if(this.element.parentNode==R){this.render();}else{this.render(R);}}},_onSubmenuBeforeShow:function(P,O){var Q=this.parent,N=Q.parent.cfg.getProperty("submenualignment");if(!this.cfg.getProperty("context!
 ")){this.cfg.setProperty("context",[Q.element,N[0],N[1]]);}else{this.align();}},_onMenuItemFocus:function(O,N){this.parent.focusEvent.fire(this);},_onMenuItemBlur:function(O,N){this.parent.blurEvent.fire(this);},_onMenuItemDestroy:function(P,O,N){this._removeItemFromGroupByValue(N.groupIndex,N);},_onMenuItemConfigChange:function(P,O,N){var R=O[0][0],S=O[0][1],Q;switch(R){case"selected":if(S===true){this.activeItem=N;}break;case"submenu":Q=O[0][1];if(Q){this._configureSubmenu(N);}break;}},enforceConstraints:function(Q,P,W){var j=this.parent,f=B.VIEWPORT_OFFSET,b=this.element,S=this.cfg,T=P[0],R=b.offsetHeight,c=b.offsetWidth,i=C.getViewportWidth(),a=C.getViewportHeight(),Z=(j&&j.parent instanceof YAHOO.widget.MenuBar)?0:f,d=S.getProperty("context"),X=d?d[0]:null,Y,h,O,N,g,e,V,U;if(c<i){V=T[0];g=C.getDocumentScrollLeft();h=g+Z;N=g+i-c-Z;if(V<f){V=h;}else{if((V+c)>i){if(X&&((V-X.offsetWidth)>c)){if(j&&j.parent instanceof YAHOO.widget.MenuBar){V=(V-(c-X.offsetWidth));
-}else{V=(V-(X.offsetWidth+c));}}else{V=N;}}}}if(R<a){U=T[1];e=C.getDocumentScrollTop();Y=e+Z;O=e+a-R-Z;if(U<f){U=Y;}else{if(U>O){if(X&&(U>R)){U=((U+X.offsetHeight)-R);}else{U=O;}}}}S.setProperty("x",V,true);S.setProperty("y",U,true);S.setProperty("xy",[V,U],true);},configVisible:function(P,O,Q){var N,R;if(this.cfg.getProperty("position")=="dynamic"){F.superclass.configVisible.call(this,P,O,Q);}else{N=O[0];R=C.getStyle(this.element,"display");C.setStyle(this.element,"visibility","visible");if(N){if(R!="block"){this.beforeShowEvent.fire();C.setStyle(this.element,"display","block");this.showEvent.fire();}}else{if(R=="block"){this.beforeHideEvent.fire();C.setStyle(this.element,"display","none");this.hideEvent.fire();}}}},configPosition:function(P,O,S){var R=this.element,Q=O[0]=="static"?"static":"absolute",T=this.cfg,N;C.setStyle(R,"position",Q);if(Q=="static"){C.setStyle(R,"display","block");T.setProperty("visible",true);}else{C.setStyle(R,"visibility","hidden");}if(Q=="absolu!
 te"){N=T.getProperty("zindex");if(!N||N===0){N=this.parent?(this.parent.parent.cfg.getProperty("zindex")+1):1;T.setProperty("zindex",N);}}},configIframe:function(O,N,P){if(this.cfg.getProperty("position")=="dynamic"){F.superclass.configIframe.call(this,O,N,P);}},configHideDelay:function(O,N,R){var T=N[0],S=this.mouseOutEvent,P=this.mouseOverEvent,Q=this.keyDownEvent;if(T>0){if(!this._bHideDelayEventHandlersAssigned){S.subscribe(this._execHideDelay);P.subscribe(this._cancelHideDelay);Q.subscribe(this._cancelHideDelay);this._bHideDelayEventHandlersAssigned=true;}}else{S.unsubscribe(this._execHideDelay);P.unsubscribe(this._cancelHideDelay);Q.unsubscribe(this._cancelHideDelay);this._bHideDelayEventHandlersAssigned=false;}},configContainer:function(O,N,Q){var P=N[0];if(typeof P=="string"){this.cfg.setProperty("container",document.getElementById(P),true);}},_setMaxHeight:function(O,N,P){this.cfg.setProperty("maxheight",P);this.renderEvent.unsubscribe(this._setMaxHeight);},configM!
 axHeight:function(Y,T,W){var S=T[0],P=this.element,Q=this.body!
 ,X=this.
header,O=this.footer,V=this._onScrollTargetMouseOver,Z=this._onScrollTargetMouseOut,N=this.cfg.getProperty("minscrollheight"),U,R;if(S!==0&&S<N){S=N;}if(this.lazyLoad&&!Q){this.renderEvent.unsubscribe(this._setMaxHeight);if(S>0){this.renderEvent.subscribe(this._setMaxHeight,S,this);}return ;}C.setStyle(Q,"height","");C.removeClass(Q,"yui-menu-body-scrolled");if(H.gecko&&this.parent&&this.parent.parent&&this.parent.parent.cfg.getProperty("position")=="dynamic"&&!this.cfg.getProperty("width")){R=P.offsetWidth;P.style.width=R+"px";P.style.width=(R-(P.offsetWidth-R))+"px";}if(!X&&!O){this.setHeader(" ");this.setFooter(" ");X=this.header;O=this.footer;C.addClass(X,"topscrollbar");C.addClass(O,"bottomscrollbar");P.insertBefore(X,Q);P.appendChild(O);}U=(S-(X.offsetHeight+X.offsetHeight));if(U>0&&(Q.offsetHeight>S)){C.addClass(Q,"yui-menu-body-scrolled");C.setStyle(Q,"height",(U+"px"));M.on(X,"mouseover",V,this,true);M.on(X,"mouseout",Z,this,true);M.on(O,"mouseover",V,this,t!
 rue);M.on(O,"mouseout",Z,this,true);this._disableScrollHeader();this._enableScrollFooter();}else{if(X&&O){this._enableScrollHeader();this._enableScrollFooter();M.removeListener(X,"mouseover",V);M.removeListener(X,"mouseout",Z);M.removeListener(O,"mouseover",V);M.removeListener(O,"mouseout",Z);P.removeChild(X);P.removeChild(O);this.header=null;this.footer=null;}}this.cfg.refireEvent("iframe");},configClassName:function(P,O,Q){var N=O[0];if(this._sClassName){C.removeClass(this.element,this._sClassName);}C.addClass(this.element,N);this._sClassName=N;},_onItemAdded:function(O,N){var P=N[0];if(P){P.cfg.setProperty("disabled",true);}},configDisabled:function(P,O,S){var R=O[0],N=this.getItems(),T,Q;if(E.isArray(N)){T=N.length;if(T>0){Q=T-1;do{N[Q].cfg.setProperty("disabled",R);}while(Q--);}if(R){this.clearActiveItem(true);C.addClass(this.element,"disabled");this.itemAddedEvent.subscribe(this._onItemAdded);}else{C.removeClass(this.element,"disabled");this.itemAddedEvent.unsubscribe!
 (this._onItemAdded);}}},onRender:function(R,Q){function S(){va!
 r W=this
.element,V=this._shadow;if(V&&W){V.style.width=(W.offsetWidth+6)+"px";V.style.height=(W.offsetHeight+1)+"px";}}function U(){this.element.appendChild(this._shadow);}function O(){C.addClass(this._shadow,"yui-menu-shadow-visible");}function N(){C.removeClass(this._shadow,"yui-menu-shadow-visible");}function T(){var W=this._shadow,V,X;if(!W){V=this.element;X=this;if(!G){G=document.createElement("div");G.className="yui-menu-shadow yui-menu-shadow-visible";}W=G.cloneNode(false);V.appendChild(W);this._shadow=W;this.beforeShowEvent.subscribe(O);this.beforeHideEvent.subscribe(N);if(H.ie){window.setTimeout(function(){S.call(X);X.syncIframe();},0);this.cfg.subscribeToConfigEvent("width",S);this.cfg.subscribeToConfigEvent("height",S);this.cfg.subscribeToConfigEvent("maxheight",S);this.changeContentEvent.subscribe(S);D.textResizeEvent.subscribe(S,X,true);this.destroyEvent.subscribe(function(){D.textResizeEvent.unsubscribe(S,X);});}this.cfg.subscribeToConfigEvent("maxheight",U);}}function!
  P(){T.call(this);this.beforeShowEvent.unsubscribe(P);}if(this.cfg.getProperty("position")=="dynamic"){if(this.cfg.getProperty("visible")){T.call(this);}else{this.beforeShowEvent.subscribe(P);}}},initEvents:function(){F.superclass.initEvents.call(this);var N=L.LIST;this.mouseOverEvent=this.createEvent(A.MOUSE_OVER);this.mouseOverEvent.signature=N;this.mouseOutEvent=this.createEvent(A.MOUSE_OUT);this.mouseOutEvent.signature=N;this.mouseDownEvent=this.createEvent(A.MOUSE_DOWN);this.mouseDownEvent.signature=N;this.mouseUpEvent=this.createEvent(A.MOUSE_UP);this.mouseUpEvent.signature=N;this.clickEvent=this.createEvent(A.CLICK);this.clickEvent.signature=N;this.keyPressEvent=this.createEvent(A.KEY_PRESS);this.keyPressEvent.signature=N;this.keyDownEvent=this.createEvent(A.KEY_DOWN);this.keyDownEvent.signature=N;this.keyUpEvent=this.createEvent(A.KEY_UP);this.keyUpEvent.signature=N;this.focusEvent=this.createEvent(A.FOCUS);
-this.focusEvent.signature=N;this.blurEvent=this.createEvent(A.BLUR);this.blurEvent.signature=N;this.itemAddedEvent=this.createEvent(A.ITEM_ADDED);this.itemAddedEvent.signature=N;this.itemRemovedEvent=this.createEvent(A.ITEM_REMOVED);this.itemRemovedEvent.signature=N;},positionOffScreen:function(){var O=this.iframe,N=this.OFF_SCREEN_POSITION;C.setXY(this.element,N);if(O){C.setXY(O,N);}},getRoot:function(){var O=this.parent,N;if(O){N=O.parent;return N?N.getRoot():this;}else{return this;}},toString:function(){var O="Menu",N=this.id;if(N){O+=(" "+N);}return O;},setItemGroupTitle:function(S,R){var Q,P,O,N;if(typeof S=="string"&&S.length>0){Q=typeof R=="number"?R:0;P=this._aGroupTitleElements[Q];if(P){P.innerHTML=S;}else{P=document.createElement(this.GROUP_TITLE_TAG_NAME);P.innerHTML=S;this._aGroupTitleElements[Q]=P;}O=this._aGroupTitleElements.length-1;do{if(this._aGroupTitleElements[O]){C.removeClass(this._aGroupTitleElements[O],"first-of-type");N=O;}}while(O--);if(N!==null){C.!
 addClass(this._aGroupTitleElements[N],"first-of-type");}this.changeContentEvent.fire();}},addItem:function(N,O){if(N){return this._addItemToGroup(O,N);}},addItems:function(Q,P){var S,N,R,O;if(E.isArray(Q)){S=Q.length;N=[];for(O=0;O<S;O++){R=Q[O];if(R){if(E.isArray(R)){N[N.length]=this.addItems(R,O);}else{N[N.length]=this._addItemToGroup(P,R);}}}if(N.length){return N;}}},insertItem:function(N,O,P){if(N){return this._addItemToGroup(P,N,O);}},removeItem:function(N,O){var P;if(typeof N!="undefined"){if(N instanceof YAHOO.widget.MenuItem){P=this._removeItemFromGroupByValue(O,N);}else{if(typeof N=="number"){P=this._removeItemFromGroupByIndex(O,N);}}if(P){P.destroy();return P;}}},getItems:function(){var P=this._aItemGroups,O,N=[];if(E.isArray(P)){O=P.length;return((O==1)?P[0]:(Array.prototype.concat.apply(N,P)));}},getItemGroups:function(){return this._aItemGroups;},getItem:function(N,O){var P;if(typeof N=="number"){P=this._getItemGroup(O);if(P){return P[N];}}},getSubmenus:functio!
 n(){var O=this.getItems(),S=O.length,N,P,R,Q;if(S>0){N=[];for(!
 Q=0;Q<S;
Q++){R=O[Q];if(R){P=R.cfg.getProperty("submenu");if(P){N[N.length]=P;}}}}return N;},clearContent:function(){var R=this.getItems(),O=R.length,P=this.element,Q=this.body,V=this.header,N=this.footer,U,T,S;if(O>0){S=O-1;do{U=R[S];if(U){T=U.cfg.getProperty("submenu");if(T){this.cfg.configChangedEvent.unsubscribe(this._onParentMenuConfigChange,T);this.renderEvent.unsubscribe(this._onParentMenuRender,T);}this.removeItem(U);}}while(S--);}if(V){M.purgeElement(V);P.removeChild(V);}if(N){M.purgeElement(N);P.removeChild(N);}if(Q){M.purgeElement(Q);Q.innerHTML="";}this.activeItem=null;this._aItemGroups=[];this._aListElements=[];this._aGroupTitleElements=[];this.cfg.setProperty("width",null);},destroy:function(){this.clearContent();this._aItemGroups=null;this._aListElements=null;this._aGroupTitleElements=null;F.superclass.destroy.call(this);},setInitialFocus:function(){var N=this._getFirstEnabledItem();if(N){N.focus();}},setInitialSelection:function(){var N=this._getFirstEnabledItem();if(!
 N){N.cfg.setProperty("selected",true);}},clearActiveItem:function(P){if(this.cfg.getProperty("showdelay")>0){this._cancelShowDelay();}var N=this.activeItem,Q,O;if(N){Q=N.cfg;if(P){N.blur();}Q.setProperty("selected",false);O=Q.getProperty("submenu");if(O){O.hide();}this.activeItem=null;}},focus:function(){if(!this.hasFocus()){this.setInitialFocus();}},blur:function(){var N;if(this.hasFocus()){N=K.getFocusedMenuItem();if(N){N.blur();}}},hasFocus:function(){return(K.getFocusedMenu()==this.getRoot());},subscribe:function(){function Q(V,U,X){var Y=U[0],W=Y.cfg.getProperty("submenu");if(W){W.subscribe.apply(W,X);}}function T(V,U,X){var W=this.cfg.getProperty("submenu");if(W){W.subscribe.apply(W,X);}}F.superclass.subscribe.apply(this,arguments);F.superclass.subscribe.call(this,"itemAdded",Q,arguments);var N=this.getItems(),S,R,O,P;if(N){S=N.length;if(S>0){P=S-1;do{R=N[P];O=R.cfg.getProperty("submenu");if(O){O.subscribe.apply(O,arguments);}else{R.cfg.subscribeToConfigEvent("submenu!
 ",T,arguments);}}while(P--);}}},initDefaultConfig:function(){F!
 .supercl
ass.initDefaultConfig.call(this);var N=this.cfg;N.addProperty(J.VISIBLE.key,{handler:this.configVisible,value:J.VISIBLE.value,validator:J.VISIBLE.validator});N.addProperty(J.CONSTRAIN_TO_VIEWPORT.key,{handler:this.configConstrainToViewport,value:J.CONSTRAIN_TO_VIEWPORT.value,validator:J.CONSTRAIN_TO_VIEWPORT.validator,supercedes:J.CONSTRAIN_TO_VIEWPORT.supercedes});N.addProperty(J.POSITION.key,{handler:this.configPosition,value:J.POSITION.value,validator:J.POSITION.validator,supercedes:J.POSITION.supercedes});N.addProperty(J.SUBMENU_ALIGNMENT.key,{value:J.SUBMENU_ALIGNMENT.value,suppressEvent:J.SUBMENU_ALIGNMENT.suppressEvent});N.addProperty(J.AUTO_SUBMENU_DISPLAY.key,{value:J.AUTO_SUBMENU_DISPLAY.value,validator:J.AUTO_SUBMENU_DISPLAY.validator,suppressEvent:J.AUTO_SUBMENU_DISPLAY.suppressEvent});N.addProperty(J.SHOW_DELAY.key,{value:J.SHOW_DELAY.value,validator:J.SHOW_DELAY.validator,suppressEvent:J.SHOW_DELAY.suppressEvent});N.addProperty(J.HIDE_DELAY.key,{handler:this.co!
 nfigHideDelay,value:J.HIDE_DELAY.value,validator:J.HIDE_DELAY.validator,suppressEvent:J.HIDE_DELAY.suppressEvent});N.addProperty(J.SUBMENU_HIDE_DELAY.key,{value:J.SUBMENU_HIDE_DELAY.value,validator:J.SUBMENU_HIDE_DELAY.validator,suppressEvent:J.SUBMENU_HIDE_DELAY.suppressEvent});N.addProperty(J.CLICK_TO_HIDE.key,{value:J.CLICK_TO_HIDE.value,validator:J.CLICK_TO_HIDE.validator,suppressEvent:J.CLICK_TO_HIDE.suppressEvent});N.addProperty(J.CONTAINER.key,{handler:this.configContainer,value:document.body,suppressEvent:J.CONTAINER.suppressEvent});N.addProperty(J.SCROLL_INCREMENT.key,{value:J.SCROLL_INCREMENT.value,validator:J.SCROLL_INCREMENT.validator,supercedes:J.SCROLL_INCREMENT.supercedes,suppressEvent:J.SCROLL_INCREMENT.suppressEvent});N.addProperty(J.MIN_SCROLL_HEIGHT.key,{value:J.MIN_SCROLL_HEIGHT.value,validator:J.MIN_SCROLL_HEIGHT.validator,supercedes:J.MIN_SCROLL_HEIGHT.supercedes,suppressEvent:J.MIN_SCROLL_HEIGHT.suppressEvent});
-N.addProperty(J.MAX_HEIGHT.key,{handler:this.configMaxHeight,value:J.MAX_HEIGHT.value,validator:J.MAX_HEIGHT.validator,suppressEvent:J.MAX_HEIGHT.suppressEvent,supercedes:J.MAX_HEIGHT.supercedes});N.addProperty(J.CLASS_NAME.key,{handler:this.configClassName,value:J.CLASS_NAME.value,validator:J.CLASS_NAME.validator,supercedes:J.CLASS_NAME.supercedes});N.addProperty(J.DISABLED.key,{handler:this.configDisabled,value:J.DISABLED.value,validator:J.DISABLED.validator,suppressEvent:J.DISABLED.suppressEvent});}});})();(function(){YAHOO.widget.MenuItem=function(K,J){if(K){if(J){this.parent=J.parent;this.value=J.value;this.id=J.id;}this.init(K,J);}};var B=YAHOO.util.Dom,C=YAHOO.widget.Module,E=YAHOO.widget.Menu,H=YAHOO.widget.MenuItem,I=YAHOO.util.CustomEvent,F=YAHOO.lang,D,A={"MOUSE_OVER":"mouseover","MOUSE_OUT":"mouseout","MOUSE_DOWN":"mousedown","MOUSE_UP":"mouseup","CLICK":"click","KEY_PRESS":"keypress","KEY_DOWN":"keydown","KEY_UP":"keyup","ITEM_ADDED":"itemAdded","ITEM_REMOVED":!
 "itemRemoved","FOCUS":"focus","BLUR":"blur","DESTROY":"destroy"},G={"TEXT":{key:"text",value:"",validator:F.isString,suppressEvent:true},"HELP_TEXT":{key:"helptext",supercedes:["text"],suppressEvent:true},"URL":{key:"url",value:"#",suppressEvent:true},"TARGET":{key:"target",suppressEvent:true},"EMPHASIS":{key:"emphasis",value:false,validator:F.isBoolean,suppressEvent:true,supercedes:["text"]},"STRONG_EMPHASIS":{key:"strongemphasis",value:false,validator:F.isBoolean,suppressEvent:true,supercedes:["text"]},"CHECKED":{key:"checked",value:false,validator:F.isBoolean,suppressEvent:true,supercedes:["disabled","selected"]},"SUBMENU":{key:"submenu",suppressEvent:true,supercedes:["disabled","selected"]},"DISABLED":{key:"disabled",value:false,validator:F.isBoolean,suppressEvent:true,supercedes:["text","selected"]},"SELECTED":{key:"selected",value:false,validator:F.isBoolean,suppressEvent:true},"ONCLICK":{key:"onclick",suppressEvent:true},"CLASS_NAME":{key:"classname",value:null,valid!
 ator:F.isString,suppressEvent:true}};H.prototype={CSS_CLASS_NA!
 ME:"yuim
enuitem",CSS_LABEL_CLASS_NAME:"yuimenuitemlabel",SUBMENU_TYPE:null,_oAnchor:null,_oHelpTextEM:null,_oSubmenu:null,_oOnclickAttributeValue:null,_sClassName:null,constructor:H,index:null,groupIndex:null,parent:null,element:null,srcElement:null,value:null,browser:C.prototype.browser,id:null,destroyEvent:null,mouseOverEvent:null,mouseOutEvent:null,mouseDownEvent:null,mouseUpEvent:null,clickEvent:null,keyPressEvent:null,keyDownEvent:null,keyUpEvent:null,focusEvent:null,blurEvent:null,init:function(J,R){if(!this.SUBMENU_TYPE){this.SUBMENU_TYPE=E;}this.cfg=new YAHOO.util.Config(this);this.initDefaultConfig();var O=I.LIST,N=this.cfg,P="#",Q,K,M,L;if(F.isString(J)){this._createRootNodeStructure();N.queueProperty("text",J);}else{if(J&&J.tagName){switch(J.tagName.toUpperCase()){case"OPTION":this._createRootNodeStructure();N.queueProperty("text",J.text);N.queueProperty("disabled",J.disabled);this.value=J.value;this.srcElement=J;break;case"OPTGROUP":this._createRootNodeStructure();N.queu!
 eProperty("text",J.label);N.queueProperty("disabled",J.disabled);this.srcElement=J;this._initSubTree();break;case"LI":Q=B.getFirstChild(J);if(Q){P=Q.getAttribute("href");K=Q.getAttribute("target");M=Q.innerHTML;}this.srcElement=J;this.element=J;this._oAnchor=Q;N.setProperty("text",M,true);N.setProperty("url",P,true);N.setProperty("target",K,true);this._initSubTree();break;}}}if(this.element){L=(this.srcElement||this.element).id;if(!L){L=this.id||B.generateId();this.element.id=L;}this.id=L;B.addClass(this.element,this.CSS_CLASS_NAME);B.addClass(this._oAnchor,this.CSS_LABEL_CLASS_NAME);this.mouseOverEvent=this.createEvent(A.MOUSE_OVER);this.mouseOverEvent.signature=O;this.mouseOutEvent=this.createEvent(A.MOUSE_OUT);this.mouseOutEvent.signature=O;this.mouseDownEvent=this.createEvent(A.MOUSE_DOWN);this.mouseDownEvent.signature=O;this.mouseUpEvent=this.createEvent(A.MOUSE_UP);this.mouseUpEvent.signature=O;this.clickEvent=this.createEvent(A.CLICK);this.clickEvent.signature=O;this!
 .keyPressEvent=this.createEvent(A.KEY_PRESS);this.keyPressEven!
 t.signat
ure=O;this.keyDownEvent=this.createEvent(A.KEY_DOWN);this.keyDownEvent.signature=O;this.keyUpEvent=this.createEvent(A.KEY_UP);this.keyUpEvent.signature=O;this.focusEvent=this.createEvent(A.FOCUS);this.focusEvent.signature=O;this.blurEvent=this.createEvent(A.BLUR);this.blurEvent.signature=O;this.destroyEvent=this.createEvent(A.DESTROY);this.destroyEvent.signature=O;if(R){N.applyConfig(R);}N.fireQueue();}},_createRootNodeStructure:function(){var J,K;if(!D){D=document.createElement("li");D.innerHTML="<a href=\"#\"></a>";}J=D.cloneNode(true);J.className=this.CSS_CLASS_NAME;K=J.firstChild;K.className=this.CSS_LABEL_CLASS_NAME;this.element=J;this._oAnchor=K;},_initSubTree:function(){var P=this.srcElement,L=this.cfg,N,M,K,J,O;if(P.childNodes.length>0){if(this.parent.lazyLoad&&this.parent.srcElement&&this.parent.srcElement.tagName.toUpperCase()=="SELECT"){L.setProperty("submenu",{id:B.generateId(),itemdata:P.childNodes});}else{N=P.firstChild;M=[];do{if(N&&N.tagName){switch(N.tagName!
 .toUpperCase()){case"DIV":L.setProperty("submenu",N);break;case"OPTION":M[M.length]=N;break;}}}while((N=N.nextSibling));K=M.length;if(K>0){J=new this.SUBMENU_TYPE(B.generateId());L.setProperty("submenu",J);for(O=0;O<K;O++){J.addItem((new J.ITEM_TYPE(M[O])));}}}}},configText:function(S,L,N){var K=L[0],M=this.cfg,Q=this._oAnchor,J=M.getProperty("helptext"),R="",O="",P="";if(K){if(J){R="<em class=\"helptext\">"+J+"</em>";}if(M.getProperty("emphasis")){O="<em>";P="</em>";}if(M.getProperty("strongemphasis")){O="<strong>";P="</strong>";}Q.innerHTML=(O+K+P+R);}},configHelpText:function(L,K,J){this.cfg.refireEvent("text");},configURL:function(L,K,J){var N=K[0];if(!N){N="#";}var M=this._oAnchor;if(YAHOO.env.ua.opera){M.removeAttribute("href");}M.setAttribute("href",N);},configTarget:function(M,L,K){var J=L[0],N=this._oAnchor;if(J&&J.length>0){N.setAttribute("target",J);}else{N.removeAttribute("target");}},configEmphasis:function(L,K,J){var N=K[0],M=this.cfg;
-if(N&&M.getProperty("strongemphasis")){M.setProperty("strongemphasis",false);}M.refireEvent("text");},configStrongEmphasis:function(M,L,K){var J=L[0],N=this.cfg;if(J&&N.getProperty("emphasis")){N.setProperty("emphasis",false);}N.refireEvent("text");},configChecked:function(S,M,O){var R=M[0],K=this.element,Q=this._oAnchor,N=this.cfg,J="-checked",L=this.CSS_CLASS_NAME+J,P=this.CSS_LABEL_CLASS_NAME+J;if(R){B.addClass(K,L);B.addClass(Q,P);}else{B.removeClass(K,L);B.removeClass(Q,P);}N.refireEvent("text");if(N.getProperty("disabled")){N.refireEvent("disabled");}if(N.getProperty("selected")){N.refireEvent("selected");}},configDisabled:function(X,R,a){var Z=R[0],L=this.cfg,P=L.getProperty("submenu"),O=L.getProperty("checked"),S=this.element,V=this._oAnchor,U="-disabled",W="-checked"+U,Y="-hassubmenu"+U,M=this.CSS_CLASS_NAME+U,N=this.CSS_LABEL_CLASS_NAME+U,T=this.CSS_CLASS_NAME+W,Q=this.CSS_LABEL_CLASS_NAME+W,K=this.CSS_CLASS_NAME+Y,J=this.CSS_LABEL_CLASS_NAME+Y;if(Z){if(L.getPrope!
 rty("selected")){L.setProperty("selected",false);}B.addClass(S,M);B.addClass(V,N);if(P){B.addClass(S,K);B.addClass(V,J);}if(O){B.addClass(S,T);B.addClass(V,Q);}}else{B.removeClass(S,M);B.removeClass(V,N);if(P){B.removeClass(S,K);B.removeClass(V,J);}if(O){B.removeClass(S,T);B.removeClass(V,Q);}}},configSelected:function(X,R,a){var L=this.cfg,Y=R[0],S=this.element,V=this._oAnchor,O=L.getProperty("checked"),P=L.getProperty("submenu"),U="-selected",W="-checked"+U,Z="-hassubmenu"+U,M=this.CSS_CLASS_NAME+U,N=this.CSS_LABEL_CLASS_NAME+U,T=this.CSS_CLASS_NAME+W,Q=this.CSS_LABEL_CLASS_NAME+W,K=this.CSS_CLASS_NAME+Z,J=this.CSS_LABEL_CLASS_NAME+Z;if(YAHOO.env.ua.opera){V.blur();}if(Y&&!L.getProperty("disabled")){B.addClass(S,M);B.addClass(V,N);if(P){B.addClass(S,K);B.addClass(V,J);}if(O){B.addClass(S,T);B.addClass(V,Q);}}else{B.removeClass(S,M);B.removeClass(V,N);if(P){B.removeClass(S,K);B.removeClass(V,J);}if(O){B.removeClass(S,T);B.removeClass(V,Q);}}if(this.hasFocus()&&YAHOO.env.ua!
 .opera){V.focus();}},_onSubmenuBeforeHide:function(M,L){var N=!
 this.par
ent,J;function K(){N._oAnchor.blur();J.beforeHideEvent.unsubscribe(K);}if(N.hasFocus()){J=N.parent;J.beforeHideEvent.subscribe(K);}},configSubmenu:function(V,O,R){var Q=O[0],P=this.cfg,K=this.element,T=this._oAnchor,N=this.parent&&this.parent.lazyLoad,J="-hassubmenu",L=this.CSS_CLASS_NAME+J,S=this.CSS_LABEL_CLASS_NAME+J,U,W,M;if(Q){if(Q instanceof E){U=Q;U.parent=this;U.lazyLoad=N;}else{if(typeof Q=="object"&&Q.id&&!Q.nodeType){W=Q.id;M=Q;M.lazyload=N;M.parent=this;U=new this.SUBMENU_TYPE(W,M);P.setProperty("submenu",U,true);}else{U=new this.SUBMENU_TYPE(Q,{lazyload:N,parent:this});P.setProperty("submenu",U,true);}}if(U){B.addClass(K,L);B.addClass(T,S);this._oSubmenu=U;if(YAHOO.env.ua.opera){U.beforeHideEvent.subscribe(this._onSubmenuBeforeHide);}}}else{B.removeClass(K,L);B.removeClass(T,S);if(this._oSubmenu){this._oSubmenu.destroy();}}if(P.getProperty("disabled")){P.refireEvent("disabled");}if(P.getProperty("selected")){P.refireEvent("selected");}},configOnClick:function(L,!
 K,J){var M=K[0];if(this._oOnclickAttributeValue&&(this._oOnclickAttributeValue!=M)){this.clickEvent.unsubscribe(this._oOnclickAttributeValue.fn,this._oOnclickAttributeValue.obj);this._oOnclickAttributeValue=null;}if(!this._oOnclickAttributeValue&&typeof M=="object"&&typeof M.fn=="function"){this.clickEvent.subscribe(M.fn,((!YAHOO.lang.isUndefined(M.obj))?M.obj:this),M.scope);this._oOnclickAttributeValue=M;}},configClassName:function(M,L,K){var J=L[0];if(this._sClassName){B.removeClass(this.element,this._sClassName);}B.addClass(this.element,J);this._sClassName=J;},initDefaultConfig:function(){var J=this.cfg;J.addProperty(G.TEXT.key,{handler:this.configText,value:G.TEXT.value,validator:G.TEXT.validator,suppressEvent:G.TEXT.suppressEvent});J.addProperty(G.HELP_TEXT.key,{handler:this.configHelpText,supercedes:G.HELP_TEXT.supercedes,suppressEvent:G.HELP_TEXT.suppressEvent});J.addProperty(G.URL.key,{handler:this.configURL,value:G.URL.value,suppressEvent:G.URL.suppressEvent});J.ad!
 dProperty(G.TARGET.key,{handler:this.configTarget,suppressEven!
 t:G.TARG
ET.suppressEvent});J.addProperty(G.EMPHASIS.key,{handler:this.configEmphasis,value:G.EMPHASIS.value,validator:G.EMPHASIS.validator,suppressEvent:G.EMPHASIS.suppressEvent,supercedes:G.EMPHASIS.supercedes});J.addProperty(G.STRONG_EMPHASIS.key,{handler:this.configStrongEmphasis,value:G.STRONG_EMPHASIS.value,validator:G.STRONG_EMPHASIS.validator,suppressEvent:G.STRONG_EMPHASIS.suppressEvent,supercedes:G.STRONG_EMPHASIS.supercedes});J.addProperty(G.CHECKED.key,{handler:this.configChecked,value:G.CHECKED.value,validator:G.CHECKED.validator,suppressEvent:G.CHECKED.suppressEvent,supercedes:G.CHECKED.supercedes});J.addProperty(G.DISABLED.key,{handler:this.configDisabled,value:G.DISABLED.value,validator:G.DISABLED.validator,suppressEvent:G.DISABLED.suppressEvent});J.addProperty(G.SELECTED.key,{handler:this.configSelected,value:G.SELECTED.value,validator:G.SELECTED.validator,suppressEvent:G.SELECTED.suppressEvent});J.addProperty(G.SUBMENU.key,{handler:this.configSubmenu,supercedes:G.SU!
 BMENU.supercedes,suppressEvent:G.SUBMENU.suppressEvent});J.addProperty(G.ONCLICK.key,{handler:this.configOnClick,suppressEvent:G.ONCLICK.suppressEvent});J.addProperty(G.CLASS_NAME.key,{handler:this.configClassName,value:G.CLASS_NAME.value,validator:G.CLASS_NAME.validator,suppressEvent:G.CLASS_NAME.suppressEvent});},getNextEnabledSibling:function(){var L,O,J,N,M;function K(P,Q){return P[Q]||K(P,(Q+1));}if(this.parent instanceof E){L=this.groupIndex;O=this.parent.getItemGroups();if(this.index<(O[L].length-1)){J=K(O[L],(this.index+1));}else{if(L<(O.length-1)){N=L+1;}else{N=0;}M=K(O,N);J=K(M,0);}return(J.cfg.getProperty("disabled")||J.element.style.display=="none")?J.getNextEnabledSibling():J;}},getPreviousEnabledSibling:function(){var N,P,K,J,M;function O(Q,R){return Q[R]||O(Q,(R-1));}function L(Q,R){return Q[R]?R:L(Q,(R+1));}if(this.parent instanceof E){N=this.groupIndex;P=this.parent.getItemGroups();if(this.index>L(P[N],0)){K=O(P[N],(this.index-1));
-}else{if(N>L(P,0)){J=N-1;}else{J=P.length-1;}M=O(P,J);K=O(M,(M.length-1));}return(K.cfg.getProperty("disabled")||K.element.style.display=="none")?K.getPreviousEnabledSibling():K;}},focus:function(){var N=this.parent,M=this._oAnchor,J=N.activeItem,L=this;function K(){try{if(YAHOO.env.ua.ie&&!document.hasFocus()){return ;}if(J){J.blurEvent.fire();}M.focus();L.focusEvent.fire();}catch(O){}}if(!this.cfg.getProperty("disabled")&&N&&N.cfg.getProperty("visible")&&this.element.style.display!="none"){window.setTimeout(K,0);}},blur:function(){var K=this.parent;if(!this.cfg.getProperty("disabled")&&K&&K.cfg.getProperty("visible")){var J=this;window.setTimeout(function(){try{J._oAnchor.blur();J.blurEvent.fire();}catch(L){}},0);}},hasFocus:function(){return(YAHOO.widget.MenuManager.getFocusedMenuItem()==this);},destroy:function(){var L=this.element,K,J;if(L){K=this.cfg.getProperty("submenu");if(K){K.destroy();}this.mouseOverEvent.unsubscribeAll();this.mouseOutEvent.unsubscribeAll();this!
 .mouseDownEvent.unsubscribeAll();this.mouseUpEvent.unsubscribeAll();this.clickEvent.unsubscribeAll();this.keyPressEvent.unsubscribeAll();this.keyDownEvent.unsubscribeAll();this.keyUpEvent.unsubscribeAll();this.focusEvent.unsubscribeAll();this.blurEvent.unsubscribeAll();this.cfg.configChangedEvent.unsubscribeAll();J=L.parentNode;if(J){J.removeChild(L);this.destroyEvent.fire();}this.destroyEvent.unsubscribeAll();}},toString:function(){var K="MenuItem",J=this.id;if(J){K+=(" "+J);}return K;}};F.augmentProto(H,YAHOO.util.EventProvider);})();(function(){YAHOO.widget.ContextMenu=function(G,F){YAHOO.widget.ContextMenu.superclass.constructor.call(this,G,F);};var B=YAHOO.util.Event,E=YAHOO.widget.ContextMenu,D={"TRIGGER_CONTEXT_MENU":"triggerContextMenu","CONTEXT_MENU":(YAHOO.env.ua.opera?"mousedown":"contextmenu"),"CLICK":"click"},C={"TRIGGER":{key:"trigger",suppressEvent:true}};function A(G,F,H){this.cfg.setProperty("xy",H);this.beforeShowEvent.unsubscribe(A,H);}YAHOO.lang.extend(E!
 ,YAHOO.widget.Menu,{_oTrigger:null,_bCancelled:false,contextEv!
 entTarge
t:null,triggerContextMenuEvent:null,init:function(G,F){E.superclass.init.call(this,G);this.beforeInitEvent.fire(E);if(F){this.cfg.applyConfig(F,true);}this.initEvent.fire(E);},initEvents:function(){E.superclass.initEvents.call(this);this.triggerContextMenuEvent=this.createEvent(D.TRIGGER_CONTEXT_MENU);this.triggerContextMenuEvent.signature=YAHOO.util.CustomEvent.LIST;},cancel:function(){this._bCancelled=true;},_removeEventHandlers:function(){var F=this._oTrigger;if(F){B.removeListener(F,D.CONTEXT_MENU,this._onTriggerContextMenu);if(YAHOO.env.ua.opera){B.removeListener(F,D.CLICK,this._onTriggerClick);}}},_onTriggerClick:function(G,F){if(G.ctrlKey){B.stopEvent(G);}},_onTriggerContextMenu:function(H,F){if(H.type=="mousedown"&&!H.ctrlKey){return ;}var G;B.stopEvent(H);this.contextEventTarget=B.getTarget(H);this.triggerContextMenuEvent.fire(H);YAHOO.widget.MenuManager.hideVisible();if(!this._bCancelled){G=B.getXY(H);if(!YAHOO.util.Dom.inDocument(this.element)){this.beforeShowEven!
 t.subscribe(A,G);}else{this.cfg.setProperty("xy",G);}this.show();}this._bCancelled=false;},toString:function(){var G="ContextMenu",F=this.id;if(F){G+=(" "+F);}return G;},initDefaultConfig:function(){E.superclass.initDefaultConfig.call(this);this.cfg.addProperty(C.TRIGGER.key,{handler:this.configTrigger,suppressEvent:C.TRIGGER.suppressEvent});},destroy:function(){this._removeEventHandlers();E.superclass.destroy.call(this);},configTrigger:function(G,F,I){var H=F[0];if(H){if(this._oTrigger){this._removeEventHandlers();}this._oTrigger=H;B.on(H,D.CONTEXT_MENU,this._onTriggerContextMenu,this,true);if(YAHOO.env.ua.opera){B.on(H,D.CLICK,this._onTriggerClick,this,true);}}else{this._removeEventHandlers();}}});}());YAHOO.widget.ContextMenuItem=YAHOO.widget.MenuItem;(function(){YAHOO.widget.MenuBar=function(F,E){YAHOO.widget.MenuBar.superclass.constructor.call(this,F,E);};function D(E){if(typeof E=="string"){return("dynamic,static".indexOf((E.toLowerCase()))!=-1);}}var B=YAHOO.util.Eve!
 nt,A=YAHOO.widget.MenuBar,C={"POSITION":{key:"position",value:!
 "static"
,validator:D,supercedes:["visible"]},"SUBMENU_ALIGNMENT":{key:"submenualignment",value:["tl","bl"],suppressEvent:true},"AUTO_SUBMENU_DISPLAY":{key:"autosubmenudisplay",value:false,validator:YAHOO.lang.isBoolean,suppressEvent:true}};YAHOO.lang.extend(A,YAHOO.widget.Menu,{init:function(F,E){if(!this.ITEM_TYPE){this.ITEM_TYPE=YAHOO.widget.MenuBarItem;}A.superclass.init.call(this,F);this.beforeInitEvent.fire(A);if(E){this.cfg.applyConfig(E,true);}this.initEvent.fire(A);},CSS_CLASS_NAME:"yuimenubar",_onKeyDown:function(G,F,K){var E=F[0],L=F[1],I,J,H;if(L&&!L.cfg.getProperty("disabled")){J=L.cfg;switch(E.keyCode){case 37:case 39:if(L==this.activeItem&&!J.getProperty("selected")){J.setProperty("selected",true);}else{H=(E.keyCode==37)?L.getPreviousEnabledSibling():L.getNextEnabledSibling();if(H){this.clearActiveItem();H.cfg.setProperty("selected",true);if(this.cfg.getProperty("autosubmenudisplay")){I=H.cfg.getProperty("submenu");if(I){I.show();}}H.focus();}}B.preventDefault(E);break!
 ;case 40:if(this.activeItem!=L){this.clearActiveItem();J.setProperty("selected",true);L.focus();}I=J.getProperty("submenu");if(I){if(I.cfg.getProperty("visible")){I.setInitialSelection();I.setInitialFocus();}else{I.show();}}B.preventDefault(E);break;}}if(E.keyCode==27&&this.activeItem){I=this.activeItem.cfg.getProperty("submenu");if(I&&I.cfg.getProperty("visible")){I.hide();this.activeItem.focus();}else{this.activeItem.cfg.setProperty("selected",false);this.activeItem.blur();}B.preventDefault(E);}},_onClick:function(L,G,J){A.superclass._onClick.call(this,L,G,J);var K=G[1],M,E,F,H,I;if(K&&!K.cfg.getProperty("disabled")){M=G[0];E=B.getTarget(M);F=this.activeItem;H=this.cfg;if(F&&F!=K){this.clearActiveItem();}K.cfg.setProperty("selected",true);I=K.cfg.getProperty("submenu");if(I){if(I.cfg.getProperty("visible")){I.hide();}else{I.show();}}}},toString:function(){var F="MenuBar",E=this.id;if(E){F+=(" "+E);}return F;
-},initDefaultConfig:function(){A.superclass.initDefaultConfig.call(this);var E=this.cfg;E.addProperty(C.POSITION.key,{handler:this.configPosition,value:C.POSITION.value,validator:C.POSITION.validator,supercedes:C.POSITION.supercedes});E.addProperty(C.SUBMENU_ALIGNMENT.key,{value:C.SUBMENU_ALIGNMENT.value,suppressEvent:C.SUBMENU_ALIGNMENT.suppressEvent});E.addProperty(C.AUTO_SUBMENU_DISPLAY.key,{value:C.AUTO_SUBMENU_DISPLAY.value,validator:C.AUTO_SUBMENU_DISPLAY.validator,suppressEvent:C.AUTO_SUBMENU_DISPLAY.suppressEvent});}});}());YAHOO.widget.MenuBarItem=function(B,A){YAHOO.widget.MenuBarItem.superclass.constructor.call(this,B,A);};YAHOO.lang.extend(YAHOO.widget.MenuBarItem,YAHOO.widget.MenuItem,{init:function(B,A){if(!this.SUBMENU_TYPE){this.SUBMENU_TYPE=YAHOO.widget.Menu;}YAHOO.widget.MenuBarItem.superclass.init.call(this,B);var C=this.cfg;if(A){C.applyConfig(A,true);}C.fireQueue();},CSS_CLASS_NAME:"yuimenubaritem",CSS_LABEL_CLASS_NAME:"yuimenubaritemlabel",toString:fun!
 ction(){var A="MenuBarItem";if(this.cfg&&this.cfg.getProperty("text")){A+=(": "+this.cfg.getProperty("text"));}return A;}});YAHOO.register("menu",YAHOO.widget.Menu,{version:"2.4.1",build:"742"});
\ No newline at end of file
+}}O._nHideDelayId=window.setTimeout(N,O.cfg.getProperty("hidedelay"));},_cancelShowDelay:function(){var N=this.getRoot();if(N._nShowDelayId){window.clearTimeout(N._nShowDelayId);}},_execShowDelay:function(P){var O=this.getRoot();function N(){if(P.parent.cfg.getProperty("selected")){P.show();}}O._nShowDelayId=window.setTimeout(N,O.cfg.getProperty("showdelay"));},_execSubmenuHideDelay:function(Q,O,N){var P=this;Q._nSubmenuHideDelayId=window.setTimeout(function(){if(P._nCurrentMouseX>(O+10)){Q._nSubmenuHideDelayId=window.setTimeout(function(){Q.hide();},N);}else{Q.hide();}},50);},_disableScrollHeader:function(){if(!this._bHeaderDisabled){C.addClass(this.header,"topscrollbar_disabled");this._bHeaderDisabled=true;}},_disableScrollFooter:function(){if(!this._bFooterDisabled){C.addClass(this.footer,"bottomscrollbar_disabled");this._bFooterDisabled=true;}},_enableScrollHeader:function(){if(this._bHeaderDisabled){C.removeClass(this.header,"topscrollbar_disabled");this._bHeaderDisabl!
 ed=false;}},_enableScrollFooter:function(){if(this._bFooterDisabled){C.removeClass(this.footer,"bottomscrollbar_disabled");this._bFooterDisabled=false;}},_onMouseOver:function(W,R){if(this._bStopMouseEventHandlers){return false;}var X=R[0],V=R[1],N=M.getTarget(X),O,Q,U,P,T,S;if(!this._bHandledMouseOverEvent&&(N==this.element||C.isAncestor(this.element,N))){this._nCurrentMouseX=0;M.on(this.element,"mousemove",this._onMouseMove,this,true);if(!C.isAncestor(V.element,M.getRelatedTarget(X))){this.clearActiveItem();}if(this.parent&&this._nSubmenuHideDelayId){window.clearTimeout(this._nSubmenuHideDelayId);this.parent.cfg.setProperty("selected",true);O=this.parent.parent;O._bHandledMouseOutEvent=true;O._bHandledMouseOverEvent=false;}this._bHandledMouseOverEvent=true;this._bHandledMouseOutEvent=false;}if(V&&!V.handledMouseOverEvent&&!V.cfg.getProperty("disabled")&&(N==V.element||C.isAncestor(V.element,N))){Q=this.cfg.getProperty("showdelay");U=(Q>0);if(U){this._cancelShowDelay();}P=!
 this.activeItem;if(P){P.cfg.setProperty("selected",false);}T=V!
 .cfg;T.s
etProperty("selected",true);if(this.hasFocus()){V.focus();}if(this.cfg.getProperty("autosubmenudisplay")){S=T.getProperty("submenu");if(S){if(U){this._execShowDelay(S);}else{S.show();}}}V.handledMouseOverEvent=true;V.handledMouseOutEvent=false;}},_onMouseOut:function(V,P){if(this._bStopMouseEventHandlers){return false;}var W=P[0],T=P[1],Q=M.getRelatedTarget(W),U=false,S,R,N,O;if(T&&!T.cfg.getProperty("disabled")){S=T.cfg;R=S.getProperty("submenu");if(R&&(Q==R.element||C.isAncestor(R.element,Q))){U=true;}if(!T.handledMouseOutEvent&&((Q!=T.element&&!C.isAncestor(T.element,Q))||U)){if(!U){T.cfg.setProperty("selected",false);if(R){N=this.cfg.getProperty("submenuhidedelay");O=this.cfg.getProperty("showdelay");if(!(this instanceof YAHOO.widget.MenuBar)&&N>0&&O>=N){this._execSubmenuHideDelay(R,M.getPageX(W),N);}else{R.hide();}}}T.handledMouseOutEvent=true;T.handledMouseOverEvent=false;}}if(!this._bHandledMouseOutEvent&&((Q!=this.element&&!C.isAncestor(this.element,Q))||U)){M.remove!
 Listener(this.element,"mousemove",this._onMouseMove);this._nCurrentMouseX=M.getPageX(W);this._bHandledMouseOutEvent=true;this._bHandledMouseOverEvent=false;}},_onMouseMove:function(O,N){if(this._bStopMouseEventHandlers){return false;}this._nCurrentMouseX=M.getPageX(O);},_onClick:function(Y,Q){var W=YAHOO.util.Event,P=YAHOO.util.Dom,Z=Q[0],T=Q[1],R,V=false,O,N,S,U,X;if(T){if(T.cfg.getProperty("disabled")){W.preventDefault(Z);}else{R=T.cfg.getProperty("submenu");S=T.cfg.getProperty("url");if(S){U=S.indexOf("#");X=S.length;if(U!=-1){S=S.substr(U,X);X=S.length;if(X>1){N=S.substr(1,X);V=P.isAncestor(this.element,N);}else{if(X===1){V=true;}}}}if(V&&!T.cfg.getProperty("target")){W.preventDefault(Z);if(H.webkit){T.focus();}else{T.focusEvent.fire();}}if(!R){O=this.getRoot();if(O instanceof YAHOO.widget.MenuBar||O.cfg.getProperty("position")=="static"){O.clearActiveItem();}else{O.hide();}}}}},_onKeyDown:function(b,V){var Y=V[0],X=V[1],f=this,U,Z,O,S,c,N,e,R,a,Q,W,d,T;function P(){f._!
 bStopMouseEventHandlers=true;window.setTimeout(function(){f._b!
 StopMous
eEventHandlers=false;},10);}if(X&&!X.cfg.getProperty("disabled")){Z=X.cfg;O=this.parent;switch(Y.keyCode){case 38:case 40:c=(Y.keyCode==38)?X.getPreviousEnabledSibling():X.getNextEnabledSibling();if(c){this.clearActiveItem();c.cfg.setProperty("selected",true);c.focus();if(this.cfg.getProperty("maxheight")>0){N=this.body;e=N.scrollTop;R=N.offsetHeight;a=this.getItems();Q=a.length-1;W=c.element.offsetTop;if(Y.keyCode==40){if(W>=(R+e)){N.scrollTop=W-R;}else{if(W<=e){N.scrollTop=0;}}if(c==a[Q]){N.scrollTop=c.element.offsetTop;}}else{if(W<=e){N.scrollTop=W-c.element.offsetHeight;}else{if(W>=(e+R)){N.scrollTop=W;}}if(c==a[0]){N.scrollTop=0;}}e=N.scrollTop;d=N.scrollHeight-N.offsetHeight;if(e===0){this._disableScrollHeader();this._enableScrollFooter();}else{if(e==d){this._enableScrollHeader();this._disableScrollFooter();}else{this._enableScrollHeader();this._enableScrollFooter();}}}}M.preventDefault(Y);P();break;case 39:U=Z.getProperty("submenu");if(U){if(!Z.getProperty("selected")!
 ){Z.setProperty("selected",true);}U.show();U.setInitialFocus();U.setInitialSelection();}else{S=this.getRoot();if(S instanceof YAHOO.widget.MenuBar){c=S.activeItem.getNextEnabledSibling();if(c){S.clearActiveItem();c.cfg.setProperty("selected",true);U=c.cfg.getProperty("submenu");if(U){U.show();}c.focus();}}}M.preventDefault(Y);P();break;case 37:if(O){T=O.parent;if(T instanceof YAHOO.widget.MenuBar){c=T.activeItem.getPreviousEnabledSibling();if(c){T.clearActiveItem();c.cfg.setProperty("selected",true);U=c.cfg.getProperty("submenu");if(U){U.show();}c.focus();}}else{this.hide();O.focus();}}M.preventDefault(Y);P();break;}}if(Y.keyCode==27){if(this.cfg.getProperty("position")=="dynamic"){this.hide();if(this.parent){this.parent.focus();}}else{if(this.activeItem){U=this.activeItem.cfg.getProperty("submenu");if(U&&U.cfg.getProperty("visible")){U.hide();this.activeItem.focus();}else{this.activeItem.blur();this.activeItem.cfg.setProperty("selected",false);
+}}}M.preventDefault(Y);}},_onKeyPress:function(P,O){var N=O[0];if(N.keyCode==40||N.keyCode==38){M.preventDefault(N);}},_onYChange:function(O,N){var Q=this.parent,S,P,R;if(Q){S=Q.parent.body.scrollTop;if(S>0){R=(this.cfg.getProperty("y")-S);C.setY(this.element,R);P=this.iframe;if(P){C.setY(P,R);}this.cfg.setProperty("y",R,true);}}},_onScrollTargetMouseOver:function(T,W){this._cancelHideDelay();var P=M.getTarget(T),R=this.body,V=this,Q=this.cfg.getProperty("scrollincrement"),N,O;function U(){var X=R.scrollTop;if(X<N){R.scrollTop=(X+Q);V._enableScrollHeader();}else{R.scrollTop=N;window.clearInterval(V._nBodyScrollId);V._disableScrollFooter();}}function S(){var X=R.scrollTop;if(X>0){R.scrollTop=(X-Q);V._enableScrollFooter();}else{R.scrollTop=0;window.clearInterval(V._nBodyScrollId);V._disableScrollHeader();}}if(C.hasClass(P,"hd")){O=S;}else{N=R.scrollHeight-R.offsetHeight;O=U;}this._nBodyScrollId=window.setInterval(O,10);},_onScrollTargetMouseOut:function(O,N){window.clearInter!
 val(this._nBodyScrollId);this._cancelHideDelay();},_onInit:function(O,N){this.cfg.subscribeToConfigEvent("visible",this._onVisibleChange);var P=!this.parent,Q=this.lazyLoad;if(((P&&!Q)||(P&&(this.cfg.getProperty("visible")||this.cfg.getProperty("position")=="static"))||(!P&&!Q))&&this.getItemGroups().length===0){if(this.srcElement){this._initSubTree();}if(this.itemData){this.addItems(this.itemData);}}else{if(Q){this.cfg.fireQueue();}}},_onBeforeRender:function(Q,P){var R=this.element,U=this._aListElements.length,O=true,T=0,N,S;if(U>0){do{N=this._aListElements[T];if(N){if(O){C.addClass(N,"first-of-type");O=false;}if(!C.isAncestor(R,N)){this.appendToBody(N);}S=this._aGroupTitleElements[T];if(S){if(!C.isAncestor(R,S)){N.parentNode.insertBefore(S,N);}C.addClass(N,"hastitle");}}T++;}while(T<U);}},_onRender:function(O,N){if(this.cfg.getProperty("position")=="dynamic"){if(!this.cfg.getProperty("visible")){this.positionOffScreen();}}},_onBeforeShow:function(W,R){var V,O,S,Q,T;if(th!
 is.lazyLoad&&this.getItemGroups().length===0){if(this.srcEleme!
 nt){this
._initSubTree();}if(this.itemData){if(this.parent&&this.parent.parent&&this.parent.parent.srcElement&&this.parent.parent.srcElement.tagName.toUpperCase()=="SELECT"){V=this.itemData.length;for(O=0;O<V;O++){if(this.itemData[O].tagName){this.addItem((new this.ITEM_TYPE(this.itemData[O])));}}}else{this.addItems(this.itemData);}}T=this.srcElement;if(T){if(T.tagName.toUpperCase()=="SELECT"){if(C.inDocument(T)){this.render(T.parentNode);}else{this.render(this.cfg.getProperty("container"));}}else{this.render();}}else{if(this.parent){this.render(this.parent.element);}else{this.render(this.cfg.getProperty("container"));}}}var P=this.cfg.getProperty("maxheight"),N=this.cfg.getProperty("minscrollheight"),U=this.cfg.getProperty("position")=="dynamic";if(!this.parent&&U){this.cfg.refireEvent("xy");}function X(){this.cfg.setProperty("maxheight",0);this.hideEvent.unsubscribe(X);}if(!(this instanceof YAHOO.widget.MenuBar)&&U){if(P===0){S=C.getViewportHeight();if(this.parent&&this.parent.pare!
 nt instanceof YAHOO.widget.MenuBar){Q=YAHOO.util.Region.getRegion(this.parent.element);S=(S-Q.bottom);}if(this.element.offsetHeight>=S){P=(S-(B.VIEWPORT_OFFSET*2));if(P<N){P=N;}this.cfg.setProperty("maxheight",P);this.hideEvent.subscribe(X);}}}},_onShow:function(Q,P){var T=this.parent,S,N,O;function R(V){var U;if(V.type=="mousedown"||(V.type=="keydown"&&V.keyCode==27)){U=M.getTarget(V);if(U!=S.element||!C.isAncestor(S.element,U)){S.cfg.setProperty("autosubmenudisplay",false);M.removeListener(document,"mousedown",R);M.removeListener(document,"keydown",R);}}}if(T){S=T.parent;N=S.cfg.getProperty("submenualignment");O=this.cfg.getProperty("submenualignment");if((N[0]!=O[0])&&(N[1]!=O[1])){this.cfg.setProperty("submenualignment",[N[0],N[1]]);}if(!S.cfg.getProperty("autosubmenudisplay")&&(S instanceof YAHOO.widget.MenuBar||S.cfg.getProperty("position")=="static")){S.cfg.setProperty("autosubmenudisplay",true);M.on(document,"mousedown",R);M.on(document,"keydown",R);}}},_onBeforeHid!
 e:function(P,O){var N=this.activeItem,R,Q;if(N){R=N.cfg;R.setP!
 roperty(
"selected",false);Q=R.getProperty("submenu");if(Q){Q.hide();}}if(this.getRoot()==this){this.blur();}},_onParentMenuConfigChange:function(O,N,R){var P=N[0][0],Q=N[0][1];switch(P){case"iframe":case"constraintoviewport":case"hidedelay":case"showdelay":case"submenuhidedelay":case"clicktohide":case"effect":case"classname":case"scrollincrement":case"minscrollheight":R.cfg.setProperty(P,Q);break;}},_onParentMenuRender:function(O,N,S){var P=S.parent.parent.cfg,Q={constraintoviewport:P.getProperty("constraintoviewport"),xy:[0,0],clicktohide:P.getProperty("clicktohide"),effect:P.getProperty("effect"),showdelay:P.getProperty("showdelay"),hidedelay:P.getProperty("hidedelay"),submenuhidedelay:P.getProperty("submenuhidedelay"),classname:P.getProperty("classname"),scrollincrement:P.getProperty("scrollincrement"),minscrollheight:P.getProperty("minscrollheight"),iframe:P.getProperty("iframe")},R;S.cfg.applyConfig(Q);if(!this.lazyLoad){R=this.parent.element;if(this.element.parentNode==R){this!
 .render();}else{this.render(R);}}},_onSubmenuBeforeShow:function(P,O){var Q=this.parent,N=Q.parent.cfg.getProperty("submenualignment");if(!this.cfg.getProperty("context")){this.cfg.setProperty("context",[Q.element,N[0],N[1]]);}else{this.align();}},_onMenuItemFocus:function(O,N){this.parent.focusEvent.fire(this);},_onMenuItemBlur:function(O,N){this.parent.blurEvent.fire(this);},_onMenuItemDestroy:function(P,O,N){this._removeItemFromGroupByValue(N.groupIndex,N);},_onMenuItemConfigChange:function(P,O,N){var R=O[0][0],S=O[0][1],Q;switch(R){case"selected":if(S===true){this.activeItem=N;}break;case"submenu":Q=O[0][1];if(Q){this._configureSubmenu(N);}break;}},enforceConstraints:function(P,N,T){YAHOO.widget.Menu.superclass.enforceConstraints.apply(this,arguments);var S=this.parent,O,R,Q,U;if(S){O=S.parent;if(!(O instanceof YAHOO.widget.MenuBar)){R=O.cfg.getProperty("x");U=this.cfg.getProperty("x");if(U<(R+S.element.offsetWidth)){Q=(R-this.element.offsetWidth);
+this.cfg.setProperty("x",Q,true);this.cfg.setProperty("xy",[Q,(this.cfg.getProperty("y"))],true);}}}},configVisible:function(P,O,Q){var N,R;if(this.cfg.getProperty("position")=="dynamic"){F.superclass.configVisible.call(this,P,O,Q);}else{N=O[0];R=C.getStyle(this.element,"display");C.setStyle(this.element,"visibility","visible");if(N){if(R!="block"){this.beforeShowEvent.fire();C.setStyle(this.element,"display","block");this.showEvent.fire();}}else{if(R=="block"){this.beforeHideEvent.fire();C.setStyle(this.element,"display","none");this.hideEvent.fire();}}}},configPosition:function(P,O,S){var R=this.element,Q=O[0]=="static"?"static":"absolute",T=this.cfg,N;C.setStyle(R,"position",Q);if(Q=="static"){C.setStyle(R,"display","block");T.setProperty("visible",true);}else{C.setStyle(R,"visibility","hidden");}if(Q=="absolute"){N=T.getProperty("zindex");if(!N||N===0){N=this.parent?(this.parent.parent.cfg.getProperty("zindex")+1):1;T.setProperty("zindex",N);}}},configIframe:function(O,!
 N,P){if(this.cfg.getProperty("position")=="dynamic"){F.superclass.configIframe.call(this,O,N,P);}},configHideDelay:function(O,N,R){var T=N[0],S=this.mouseOutEvent,P=this.mouseOverEvent,Q=this.keyDownEvent;if(T>0){if(!this._bHideDelayEventHandlersAssigned){S.subscribe(this._execHideDelay);P.subscribe(this._cancelHideDelay);Q.subscribe(this._cancelHideDelay);this._bHideDelayEventHandlersAssigned=true;}}else{S.unsubscribe(this._execHideDelay);P.unsubscribe(this._cancelHideDelay);Q.unsubscribe(this._cancelHideDelay);this._bHideDelayEventHandlersAssigned=false;}},configContainer:function(O,N,Q){var P=N[0];if(typeof P=="string"){this.cfg.setProperty("container",document.getElementById(P),true);}},_setMaxHeight:function(O,N,P){this.cfg.setProperty("maxheight",P);this.renderEvent.unsubscribe(this._setMaxHeight);},configMaxHeight:function(a,U,X){var T=U[0],Q=this.element,R=this.body,Y=this.header,O=this.footer,W=this._onScrollTargetMouseOver,b=this._onScrollTargetMouseOut,N=this.cfg!
 .getProperty("minscrollheight"),V,S,P;if(T!==0&&T<N){T=N;}if(t!
 his.lazy
Load&&!R){this.renderEvent.unsubscribe(this._setMaxHeight);if(T>0){this.renderEvent.subscribe(this._setMaxHeight,T,this);}return ;}C.setStyle(R,"height","");C.removeClass(R,"yui-menu-body-scrolled");var Z=((H.gecko&&this.parent&&this.parent.parent&&this.parent.parent.cfg.getProperty("position")=="dynamic")||H.ie);if(Z){if(!this.cfg.getProperty("width")){S=Q.offsetWidth;Q.style.width=S+"px";P=(S-(Q.offsetWidth-S))+"px";this.cfg.setProperty("width",P);}}if(!Y&&!O){this.setHeader(" ");this.setFooter(" ");Y=this.header;O=this.footer;C.addClass(Y,"topscrollbar");C.addClass(O,"bottomscrollbar");Q.insertBefore(Y,R);Q.appendChild(O);}V=(T-(Y.offsetHeight+Y.offsetHeight));if(V>0&&(R.offsetHeight>T)){C.addClass(R,"yui-menu-body-scrolled");C.setStyle(R,"height",(V+"px"));M.on(Y,"mouseover",W,this,true);M.on(Y,"mouseout",b,this,true);M.on(O,"mouseover",W,this,true);M.on(O,"mouseout",b,this,true);this._disableScrollHeader();this._enableScrollFooter();}else{if(Y&&O){if(Z){this.cfg!
 .setProperty("width","");}this._enableScrollHeader();this._enableScrollFooter();M.removeListener(Y,"mouseover",W);M.removeListener(Y,"mouseout",b);M.removeListener(O,"mouseover",W);M.removeListener(O,"mouseout",b);Q.removeChild(Y);Q.removeChild(O);this.header=null;this.footer=null;}}this.cfg.refireEvent("iframe");},configClassName:function(P,O,Q){var N=O[0];if(this._sClassName){C.removeClass(this.element,this._sClassName);}C.addClass(this.element,N);this._sClassName=N;},_onItemAdded:function(O,N){var P=N[0];if(P){P.cfg.setProperty("disabled",true);}},configDisabled:function(P,O,S){var R=O[0],N=this.getItems(),T,Q;if(E.isArray(N)){T=N.length;if(T>0){Q=T-1;do{N[Q].cfg.setProperty("disabled",R);}while(Q--);}if(R){this.clearActiveItem(true);C.addClass(this.element,"disabled");this.itemAddedEvent.subscribe(this._onItemAdded);}else{C.removeClass(this.element,"disabled");this.itemAddedEvent.unsubscribe(this._onItemAdded);}}},onRender:function(R,Q){function S(){var W=this.element,V!
 =this._shadow;if(V&&W){V.style.width=(W.offsetWidth+6)+"px";V.!
 style.he
ight=(W.offsetHeight+1)+"px";}}function U(){this.element.appendChild(this._shadow);}function O(){C.addClass(this._shadow,"yui-menu-shadow-visible");}function N(){C.removeClass(this._shadow,"yui-menu-shadow-visible");}function T(){var W=this._shadow,V,X;if(!W){V=this.element;X=this;if(!G){G=document.createElement("div");G.className="yui-menu-shadow yui-menu-shadow-visible";}W=G.cloneNode(false);V.appendChild(W);this._shadow=W;this.beforeShowEvent.subscribe(O);this.beforeHideEvent.subscribe(N);if(H.ie){window.setTimeout(function(){S.call(X);X.syncIframe();},0);this.cfg.subscribeToConfigEvent("width",S);this.cfg.subscribeToConfigEvent("height",S);this.cfg.subscribeToConfigEvent("maxheight",S);this.changeContentEvent.subscribe(S);D.textResizeEvent.subscribe(S,X,true);this.destroyEvent.subscribe(function(){D.textResizeEvent.unsubscribe(S,X);});}this.cfg.subscribeToConfigEvent("maxheight",U);}}function P(){T.call(this);this.beforeShowEvent.unsubscribe(P);}if(this.cfg.getProperty("!
 position")=="dynamic"){if(this.cfg.getProperty("visible")){T.call(this);}else{this.beforeShowEvent.subscribe(P);}}},initEvents:function(){F.superclass.initEvents.call(this);var N=L.LIST;this.mouseOverEvent=this.createEvent(A.MOUSE_OVER);this.mouseOverEvent.signature=N;this.mouseOutEvent=this.createEvent(A.MOUSE_OUT);this.mouseOutEvent.signature=N;this.mouseDownEvent=this.createEvent(A.MOUSE_DOWN);this.mouseDownEvent.signature=N;this.mouseUpEvent=this.createEvent(A.MOUSE_UP);this.mouseUpEvent.signature=N;this.clickEvent=this.createEvent(A.CLICK);this.clickEvent.signature=N;this.keyPressEvent=this.createEvent(A.KEY_PRESS);this.keyPressEvent.signature=N;this.keyDownEvent=this.createEvent(A.KEY_DOWN);this.keyDownEvent.signature=N;this.keyUpEvent=this.createEvent(A.KEY_UP);this.keyUpEvent.signature=N;this.focusEvent=this.createEvent(A.FOCUS);this.focusEvent.signature=N;this.blurEvent=this.createEvent(A.BLUR);this.blurEvent.signature=N;
+this.itemAddedEvent=this.createEvent(A.ITEM_ADDED);this.itemAddedEvent.signature=N;this.itemRemovedEvent=this.createEvent(A.ITEM_REMOVED);this.itemRemovedEvent.signature=N;},positionOffScreen:function(){var O=this.iframe,N=this.OFF_SCREEN_POSITION;C.setXY(this.element,N);if(O){C.setXY(O,N);}},getRoot:function(){var O=this.parent,N;if(O){N=O.parent;return N?N.getRoot():this;}else{return this;}},toString:function(){var O="Menu",N=this.id;if(N){O+=(" "+N);}return O;},setItemGroupTitle:function(S,R){var Q,P,O,N;if(typeof S=="string"&&S.length>0){Q=typeof R=="number"?R:0;P=this._aGroupTitleElements[Q];if(P){P.innerHTML=S;}else{P=document.createElement(this.GROUP_TITLE_TAG_NAME);P.innerHTML=S;this._aGroupTitleElements[Q]=P;}O=this._aGroupTitleElements.length-1;do{if(this._aGroupTitleElements[O]){C.removeClass(this._aGroupTitleElements[O],"first-of-type");N=O;}}while(O--);if(N!==null){C.addClass(this._aGroupTitleElements[N],"first-of-type");}this.changeContentEvent.fire();}},addIt!
 em:function(N,O){if(N){return this._addItemToGroup(O,N);}},addItems:function(Q,P){var S,N,R,O;if(E.isArray(Q)){S=Q.length;N=[];for(O=0;O<S;O++){R=Q[O];if(R){if(E.isArray(R)){N[N.length]=this.addItems(R,O);}else{N[N.length]=this._addItemToGroup(P,R);}}}if(N.length){return N;}}},insertItem:function(N,O,P){if(N){return this._addItemToGroup(P,N,O);}},removeItem:function(N,O){var P;if(typeof N!="undefined"){if(N instanceof YAHOO.widget.MenuItem){P=this._removeItemFromGroupByValue(O,N);}else{if(typeof N=="number"){P=this._removeItemFromGroupByIndex(O,N);}}if(P){P.destroy();return P;}}},getItems:function(){var P=this._aItemGroups,O,N=[];if(E.isArray(P)){O=P.length;return((O==1)?P[0]:(Array.prototype.concat.apply(N,P)));}},getItemGroups:function(){return this._aItemGroups;},getItem:function(N,O){var P;if(typeof N=="number"){P=this._getItemGroup(O);if(P){return P[N];}}},getSubmenus:function(){var O=this.getItems(),S=O.length,N,P,R,Q;if(S>0){N=[];for(Q=0;Q<S;Q++){R=O[Q];if(R){P=R.cfg!
 .getProperty("submenu");if(P){N[N.length]=P;}}}}return N;},cle!
 arConten
t:function(){var R=this.getItems(),O=R.length,P=this.element,Q=this.body,V=this.header,N=this.footer,U,T,S;if(O>0){S=O-1;do{U=R[S];if(U){T=U.cfg.getProperty("submenu");if(T){this.cfg.configChangedEvent.unsubscribe(this._onParentMenuConfigChange,T);this.renderEvent.unsubscribe(this._onParentMenuRender,T);}this.removeItem(U);}}while(S--);}if(V){M.purgeElement(V);P.removeChild(V);}if(N){M.purgeElement(N);P.removeChild(N);}if(Q){M.purgeElement(Q);Q.innerHTML="";}this.activeItem=null;this._aItemGroups=[];this._aListElements=[];this._aGroupTitleElements=[];this.cfg.setProperty("width",null);},destroy:function(){this.clearContent();this._aItemGroups=null;this._aListElements=null;this._aGroupTitleElements=null;F.superclass.destroy.call(this);},setInitialFocus:function(){var N=this._getFirstEnabledItem();if(N){N.focus();}},setInitialSelection:function(){var N=this._getFirstEnabledItem();if(N){N.cfg.setProperty("selected",true);}},clearActiveItem:function(P){if(this.cfg.getProperty("s!
 howdelay")>0){this._cancelShowDelay();}var N=this.activeItem,Q,O;if(N){Q=N.cfg;if(P){N.blur();}Q.setProperty("selected",false);O=Q.getProperty("submenu");if(O){O.hide();}this.activeItem=null;}},focus:function(){if(!this.hasFocus()){this.setInitialFocus();}},blur:function(){var N;if(this.hasFocus()){N=K.getFocusedMenuItem();if(N){N.blur();}}},hasFocus:function(){return(K.getFocusedMenu()==this.getRoot());},subscribe:function(){function Q(V,U,X){var Y=U[0],W=Y.cfg.getProperty("submenu");if(W){W.subscribe.apply(W,X);}}function T(V,U,X){var W=this.cfg.getProperty("submenu");if(W){W.subscribe.apply(W,X);}}F.superclass.subscribe.apply(this,arguments);F.superclass.subscribe.call(this,"itemAdded",Q,arguments);var N=this.getItems(),S,R,O,P;if(N){S=N.length;if(S>0){P=S-1;do{R=N[P];O=R.cfg.getProperty("submenu");if(O){O.subscribe.apply(O,arguments);}else{R.cfg.subscribeToConfigEvent("submenu",T,arguments);}}while(P--);}}},initDefaultConfig:function(){F.superclass.initDefaultConfig.cal!
 l(this);var N=this.cfg;N.addProperty(J.VISIBLE.key,{handler:th!
 is.confi
gVisible,value:J.VISIBLE.value,validator:J.VISIBLE.validator});N.addProperty(J.CONSTRAIN_TO_VIEWPORT.key,{handler:this.configConstrainToViewport,value:J.CONSTRAIN_TO_VIEWPORT.value,validator:J.CONSTRAIN_TO_VIEWPORT.validator,supercedes:J.CONSTRAIN_TO_VIEWPORT.supercedes});N.addProperty(J.POSITION.key,{handler:this.configPosition,value:J.POSITION.value,validator:J.POSITION.validator,supercedes:J.POSITION.supercedes});N.addProperty(J.SUBMENU_ALIGNMENT.key,{value:J.SUBMENU_ALIGNMENT.value,suppressEvent:J.SUBMENU_ALIGNMENT.suppressEvent});N.addProperty(J.AUTO_SUBMENU_DISPLAY.key,{value:J.AUTO_SUBMENU_DISPLAY.value,validator:J.AUTO_SUBMENU_DISPLAY.validator,suppressEvent:J.AUTO_SUBMENU_DISPLAY.suppressEvent});N.addProperty(J.SHOW_DELAY.key,{value:J.SHOW_DELAY.value,validator:J.SHOW_DELAY.validator,suppressEvent:J.SHOW_DELAY.suppressEvent});N.addProperty(J.HIDE_DELAY.key,{handler:this.configHideDelay,value:J.HIDE_DELAY.value,validator:J.HIDE_DELAY.validator,suppressEvent:J.HIDE_DE!
 LAY.suppressEvent});N.addProperty(J.SUBMENU_HIDE_DELAY.key,{value:J.SUBMENU_HIDE_DELAY.value,validator:J.SUBMENU_HIDE_DELAY.validator,suppressEvent:J.SUBMENU_HIDE_DELAY.suppressEvent});N.addProperty(J.CLICK_TO_HIDE.key,{value:J.CLICK_TO_HIDE.value,validator:J.CLICK_TO_HIDE.validator,suppressEvent:J.CLICK_TO_HIDE.suppressEvent});N.addProperty(J.CONTAINER.key,{handler:this.configContainer,value:document.body,suppressEvent:J.CONTAINER.suppressEvent});N.addProperty(J.SCROLL_INCREMENT.key,{value:J.SCROLL_INCREMENT.value,validator:J.SCROLL_INCREMENT.validator,supercedes:J.SCROLL_INCREMENT.supercedes,suppressEvent:J.SCROLL_INCREMENT.suppressEvent});N.addProperty(J.MIN_SCROLL_HEIGHT.key,{value:J.MIN_SCROLL_HEIGHT.value,validator:J.MIN_SCROLL_HEIGHT.validator,supercedes:J.MIN_SCROLL_HEIGHT.supercedes,suppressEvent:J.MIN_SCROLL_HEIGHT.suppressEvent});N.addProperty(J.MAX_HEIGHT.key,{handler:this.configMaxHeight,value:J.MAX_HEIGHT.value,validator:J.MAX_HEIGHT.validator,suppressEvent:J.!
 MAX_HEIGHT.suppressEvent,supercedes:J.MAX_HEIGHT.supercedes});
+N.addProperty(J.CLASS_NAME.key,{handler:this.configClassName,value:J.CLASS_NAME.value,validator:J.CLASS_NAME.validator,supercedes:J.CLASS_NAME.supercedes});N.addProperty(J.DISABLED.key,{handler:this.configDisabled,value:J.DISABLED.value,validator:J.DISABLED.validator,suppressEvent:J.DISABLED.suppressEvent});}});})();(function(){YAHOO.widget.MenuItem=function(K,J){if(K){if(J){this.parent=J.parent;this.value=J.value;this.id=J.id;}this.init(K,J);}};var B=YAHOO.util.Dom,C=YAHOO.widget.Module,E=YAHOO.widget.Menu,H=YAHOO.widget.MenuItem,I=YAHOO.util.CustomEvent,F=YAHOO.lang,D,A={"MOUSE_OVER":"mouseover","MOUSE_OUT":"mouseout","MOUSE_DOWN":"mousedown","MOUSE_UP":"mouseup","CLICK":"click","KEY_PRESS":"keypress","KEY_DOWN":"keydown","KEY_UP":"keyup","ITEM_ADDED":"itemAdded","ITEM_REMOVED":"itemRemoved","FOCUS":"focus","BLUR":"blur","DESTROY":"destroy"},G={"TEXT":{key:"text",value:"",validator:F.isString,suppressEvent:true},"HELP_TEXT":{key:"helptext",supercedes:["text"],suppressEven!
 t:true},"URL":{key:"url",value:"#",suppressEvent:true},"TARGET":{key:"target",suppressEvent:true},"EMPHASIS":{key:"emphasis",value:false,validator:F.isBoolean,suppressEvent:true,supercedes:["text"]},"STRONG_EMPHASIS":{key:"strongemphasis",value:false,validator:F.isBoolean,suppressEvent:true,supercedes:["text"]},"CHECKED":{key:"checked",value:false,validator:F.isBoolean,suppressEvent:true,supercedes:["disabled","selected"]},"SUBMENU":{key:"submenu",suppressEvent:true,supercedes:["disabled","selected"]},"DISABLED":{key:"disabled",value:false,validator:F.isBoolean,suppressEvent:true,supercedes:["text","selected"]},"SELECTED":{key:"selected",value:false,validator:F.isBoolean,suppressEvent:true},"ONCLICK":{key:"onclick",suppressEvent:true},"CLASS_NAME":{key:"classname",value:null,validator:F.isString,suppressEvent:true}};H.prototype={CSS_CLASS_NAME:"yuimenuitem",CSS_LABEL_CLASS_NAME:"yuimenuitemlabel",SUBMENU_TYPE:null,_oAnchor:null,_oHelpTextEM:null,_oSubmenu:null,_oOnclickAttr!
 ibuteValue:null,_sClassName:null,constructor:H,index:null,grou!
 pIndex:n
ull,parent:null,element:null,srcElement:null,value:null,browser:C.prototype.browser,id:null,destroyEvent:null,mouseOverEvent:null,mouseOutEvent:null,mouseDownEvent:null,mouseUpEvent:null,clickEvent:null,keyPressEvent:null,keyDownEvent:null,keyUpEvent:null,focusEvent:null,blurEvent:null,init:function(J,R){if(!this.SUBMENU_TYPE){this.SUBMENU_TYPE=E;}this.cfg=new YAHOO.util.Config(this);this.initDefaultConfig();var O=I.LIST,N=this.cfg,P="#",Q,K,M,L;if(F.isString(J)){this._createRootNodeStructure();N.queueProperty("text",J);}else{if(J&&J.tagName){switch(J.tagName.toUpperCase()){case"OPTION":this._createRootNodeStructure();N.queueProperty("text",J.text);N.queueProperty("disabled",J.disabled);this.value=J.value;this.srcElement=J;break;case"OPTGROUP":this._createRootNodeStructure();N.queueProperty("text",J.label);N.queueProperty("disabled",J.disabled);this.srcElement=J;this._initSubTree();break;case"LI":Q=B.getFirstChild(J);if(Q){P=Q.getAttribute("href",2);K=Q.getAttribute("target"!
 );M=Q.innerHTML;}this.srcElement=J;this.element=J;this._oAnchor=Q;N.setProperty("text",M,true);N.setProperty("url",P,true);N.setProperty("target",K,true);this._initSubTree();break;}}}if(this.element){L=(this.srcElement||this.element).id;if(!L){L=this.id||B.generateId();this.element.id=L;}this.id=L;B.addClass(this.element,this.CSS_CLASS_NAME);B.addClass(this._oAnchor,this.CSS_LABEL_CLASS_NAME);this.mouseOverEvent=this.createEvent(A.MOUSE_OVER);this.mouseOverEvent.signature=O;this.mouseOutEvent=this.createEvent(A.MOUSE_OUT);this.mouseOutEvent.signature=O;this.mouseDownEvent=this.createEvent(A.MOUSE_DOWN);this.mouseDownEvent.signature=O;this.mouseUpEvent=this.createEvent(A.MOUSE_UP);this.mouseUpEvent.signature=O;this.clickEvent=this.createEvent(A.CLICK);this.clickEvent.signature=O;this.keyPressEvent=this.createEvent(A.KEY_PRESS);this.keyPressEvent.signature=O;this.keyDownEvent=this.createEvent(A.KEY_DOWN);this.keyDownEvent.signature=O;this.keyUpEvent=this.createEvent(A.KEY_UP)!
 ;this.keyUpEvent.signature=O;this.focusEvent=this.createEvent(!
 A.FOCUS)
;this.focusEvent.signature=O;this.blurEvent=this.createEvent(A.BLUR);this.blurEvent.signature=O;this.destroyEvent=this.createEvent(A.DESTROY);this.destroyEvent.signature=O;if(R){N.applyConfig(R);}N.fireQueue();}},_createRootNodeStructure:function(){var J,K;if(!D){D=document.createElement("li");D.innerHTML='<a href="#"></a>';}J=D.cloneNode(true);J.className=this.CSS_CLASS_NAME;K=J.firstChild;K.className=this.CSS_LABEL_CLASS_NAME;this.element=J;this._oAnchor=K;},_initSubTree:function(){var P=this.srcElement,L=this.cfg,N,M,K,J,O;if(P.childNodes.length>0){if(this.parent.lazyLoad&&this.parent.srcElement&&this.parent.srcElement.tagName.toUpperCase()=="SELECT"){L.setProperty("submenu",{id:B.generateId(),itemdata:P.childNodes});}else{N=P.firstChild;M=[];do{if(N&&N.tagName){switch(N.tagName.toUpperCase()){case"DIV":L.setProperty("submenu",N);break;case"OPTION":M[M.length]=N;break;}}}while((N=N.nextSibling));K=M.length;if(K>0){J=new this.SUBMENU_TYPE(B.generateId());L.setProperty("sub!
 menu",J);for(O=0;O<K;O++){J.addItem((new J.ITEM_TYPE(M[O])));}}}}},configText:function(S,L,N){var K=L[0],M=this.cfg,Q=this._oAnchor,J=M.getProperty("helptext"),R="",O="",P="";if(K){if(J){R='<em class="helptext">'+J+"</em>";}if(M.getProperty("emphasis")){O="<em>";P="</em>";}if(M.getProperty("strongemphasis")){O="<strong>";P="</strong>";}Q.innerHTML=(O+K+P+R);}},configHelpText:function(L,K,J){this.cfg.refireEvent("text");},configURL:function(L,K,J){var N=K[0];if(!N){N="#";}var M=this._oAnchor;if(YAHOO.env.ua.opera){M.removeAttribute("href");}M.setAttribute("href",N);},configTarget:function(M,L,K){var J=L[0],N=this._oAnchor;if(J&&J.length>0){N.setAttribute("target",J);}else{N.removeAttribute("target");}},configEmphasis:function(L,K,J){var N=K[0],M=this.cfg;if(N&&M.getProperty("strongemphasis")){M.setProperty("strongemphasis",false);}M.refireEvent("text");},configStrongEmphasis:function(M,L,K){var J=L[0],N=this.cfg;
+if(J&&N.getProperty("emphasis")){N.setProperty("emphasis",false);}N.refireEvent("text");},configChecked:function(S,M,O){var R=M[0],K=this.element,Q=this._oAnchor,N=this.cfg,J="-checked",L=this.CSS_CLASS_NAME+J,P=this.CSS_LABEL_CLASS_NAME+J;if(R){B.addClass(K,L);B.addClass(Q,P);}else{B.removeClass(K,L);B.removeClass(Q,P);}N.refireEvent("text");if(N.getProperty("disabled")){N.refireEvent("disabled");}if(N.getProperty("selected")){N.refireEvent("selected");}},configDisabled:function(X,R,a){var Z=R[0],L=this.cfg,P=L.getProperty("submenu"),O=L.getProperty("checked"),S=this.element,V=this._oAnchor,U="-disabled",W="-checked"+U,Y="-hassubmenu"+U,M=this.CSS_CLASS_NAME+U,N=this.CSS_LABEL_CLASS_NAME+U,T=this.CSS_CLASS_NAME+W,Q=this.CSS_LABEL_CLASS_NAME+W,K=this.CSS_CLASS_NAME+Y,J=this.CSS_LABEL_CLASS_NAME+Y;if(Z){if(L.getProperty("selected")){L.setProperty("selected",false);}B.addClass(S,M);B.addClass(V,N);if(P){B.addClass(S,K);B.addClass(V,J);}if(O){B.addClass(S,T);B.addClass(V,Q);}}!
 else{B.removeClass(S,M);B.removeClass(V,N);if(P){B.removeClass(S,K);B.removeClass(V,J);}if(O){B.removeClass(S,T);B.removeClass(V,Q);}}},configSelected:function(X,R,a){var L=this.cfg,Y=R[0],S=this.element,V=this._oAnchor,O=L.getProperty("checked"),P=L.getProperty("submenu"),U="-selected",W="-checked"+U,Z="-hassubmenu"+U,M=this.CSS_CLASS_NAME+U,N=this.CSS_LABEL_CLASS_NAME+U,T=this.CSS_CLASS_NAME+W,Q=this.CSS_LABEL_CLASS_NAME+W,K=this.CSS_CLASS_NAME+Z,J=this.CSS_LABEL_CLASS_NAME+Z;if(YAHOO.env.ua.opera){V.blur();}if(Y&&!L.getProperty("disabled")){B.addClass(S,M);B.addClass(V,N);if(P){B.addClass(S,K);B.addClass(V,J);}if(O){B.addClass(S,T);B.addClass(V,Q);}}else{B.removeClass(S,M);B.removeClass(V,N);if(P){B.removeClass(S,K);B.removeClass(V,J);}if(O){B.removeClass(S,T);B.removeClass(V,Q);}}if(this.hasFocus()&&YAHOO.env.ua.opera){V.focus();}},_onSubmenuBeforeHide:function(M,L){var N=this.parent,J;function K(){N._oAnchor.blur();J.beforeHideEvent.unsubscribe(K);}if(N.hasFocus()){J=N!
 .parent;J.beforeHideEvent.subscribe(K);}},configSubmenu:functi!
 on(V,O,R
){var Q=O[0],P=this.cfg,K=this.element,T=this._oAnchor,N=this.parent&&this.parent.lazyLoad,J="-hassubmenu",L=this.CSS_CLASS_NAME+J,S=this.CSS_LABEL_CLASS_NAME+J,U,W,M;if(Q){if(Q instanceof E){U=Q;U.parent=this;U.lazyLoad=N;}else{if(typeof Q=="object"&&Q.id&&!Q.nodeType){W=Q.id;M=Q;M.lazyload=N;M.parent=this;U=new this.SUBMENU_TYPE(W,M);P.setProperty("submenu",U,true);}else{U=new this.SUBMENU_TYPE(Q,{lazyload:N,parent:this});P.setProperty("submenu",U,true);}}if(U){B.addClass(K,L);B.addClass(T,S);this._oSubmenu=U;if(YAHOO.env.ua.opera){U.beforeHideEvent.subscribe(this._onSubmenuBeforeHide);}}}else{B.removeClass(K,L);B.removeClass(T,S);if(this._oSubmenu){this._oSubmenu.destroy();}}if(P.getProperty("disabled")){P.refireEvent("disabled");}if(P.getProperty("selected")){P.refireEvent("selected");}},configOnClick:function(L,K,J){var M=K[0];if(this._oOnclickAttributeValue&&(this._oOnclickAttributeValue!=M)){this.clickEvent.unsubscribe(this._oOnclickAttributeValue.fn,this._oOnclickAtt!
 ributeValue.obj);this._oOnclickAttributeValue=null;}if(!this._oOnclickAttributeValue&&typeof M=="object"&&typeof M.fn=="function"){this.clickEvent.subscribe(M.fn,((!YAHOO.lang.isUndefined(M.obj))?M.obj:this),M.scope);this._oOnclickAttributeValue=M;}},configClassName:function(M,L,K){var J=L[0];if(this._sClassName){B.removeClass(this.element,this._sClassName);}B.addClass(this.element,J);this._sClassName=J;},initDefaultConfig:function(){var J=this.cfg;J.addProperty(G.TEXT.key,{handler:this.configText,value:G.TEXT.value,validator:G.TEXT.validator,suppressEvent:G.TEXT.suppressEvent});J.addProperty(G.HELP_TEXT.key,{handler:this.configHelpText,supercedes:G.HELP_TEXT.supercedes,suppressEvent:G.HELP_TEXT.suppressEvent});J.addProperty(G.URL.key,{handler:this.configURL,value:G.URL.value,suppressEvent:G.URL.suppressEvent});J.addProperty(G.TARGET.key,{handler:this.configTarget,suppressEvent:G.TARGET.suppressEvent});J.addProperty(G.EMPHASIS.key,{handler:this.configEmphasis,value:G.EMPHAS!
 IS.value,validator:G.EMPHASIS.validator,suppressEvent:G.EMPHAS!
 IS.suppr
essEvent,supercedes:G.EMPHASIS.supercedes});J.addProperty(G.STRONG_EMPHASIS.key,{handler:this.configStrongEmphasis,value:G.STRONG_EMPHASIS.value,validator:G.STRONG_EMPHASIS.validator,suppressEvent:G.STRONG_EMPHASIS.suppressEvent,supercedes:G.STRONG_EMPHASIS.supercedes});J.addProperty(G.CHECKED.key,{handler:this.configChecked,value:G.CHECKED.value,validator:G.CHECKED.validator,suppressEvent:G.CHECKED.suppressEvent,supercedes:G.CHECKED.supercedes});J.addProperty(G.DISABLED.key,{handler:this.configDisabled,value:G.DISABLED.value,validator:G.DISABLED.validator,suppressEvent:G.DISABLED.suppressEvent});J.addProperty(G.SELECTED.key,{handler:this.configSelected,value:G.SELECTED.value,validator:G.SELECTED.validator,suppressEvent:G.SELECTED.suppressEvent});J.addProperty(G.SUBMENU.key,{handler:this.configSubmenu,supercedes:G.SUBMENU.supercedes,suppressEvent:G.SUBMENU.suppressEvent});J.addProperty(G.ONCLICK.key,{handler:this.configOnClick,suppressEvent:G.ONCLICK.suppressEvent});J.addPro!
 perty(G.CLASS_NAME.key,{handler:this.configClassName,value:G.CLASS_NAME.value,validator:G.CLASS_NAME.validator,suppressEvent:G.CLASS_NAME.suppressEvent});},getNextEnabledSibling:function(){var L,O,J,N,M;function K(P,Q){return P[Q]||K(P,(Q+1));}if(this.parent instanceof E){L=this.groupIndex;O=this.parent.getItemGroups();if(this.index<(O[L].length-1)){J=K(O[L],(this.index+1));}else{if(L<(O.length-1)){N=L+1;}else{N=0;}M=K(O,N);J=K(M,0);}return(J.cfg.getProperty("disabled")||J.element.style.display=="none")?J.getNextEnabledSibling():J;}},getPreviousEnabledSibling:function(){var N,P,K,J,M;function O(Q,R){return Q[R]||O(Q,(R-1));}function L(Q,R){return Q[R]?R:L(Q,(R+1));}if(this.parent instanceof E){N=this.groupIndex;P=this.parent.getItemGroups();if(this.index>L(P[N],0)){K=O(P[N],(this.index-1));}else{if(N>L(P,0)){J=N-1;}else{J=P.length-1;}M=O(P,J);K=O(M,(M.length-1));}return(K.cfg.getProperty("disabled")||K.element.style.display=="none")?K.getPreviousEnabledSibling():K;
+}},focus:function(){var N=this.parent,M=this._oAnchor,J=N.activeItem,L=this;function K(){try{if(YAHOO.env.ua.ie&&!document.hasFocus()){return ;}if(J){J.blurEvent.fire();}M.focus();L.focusEvent.fire();}catch(O){}}if(!this.cfg.getProperty("disabled")&&N&&N.cfg.getProperty("visible")&&this.element.style.display!="none"){window.setTimeout(K,0);}},blur:function(){var K=this.parent;if(!this.cfg.getProperty("disabled")&&K&&K.cfg.getProperty("visible")){var J=this;window.setTimeout(function(){try{J._oAnchor.blur();J.blurEvent.fire();}catch(L){}},0);}},hasFocus:function(){return(YAHOO.widget.MenuManager.getFocusedMenuItem()==this);},destroy:function(){var L=this.element,K,J;if(L){K=this.cfg.getProperty("submenu");if(K){K.destroy();}this.mouseOverEvent.unsubscribeAll();this.mouseOutEvent.unsubscribeAll();this.mouseDownEvent.unsubscribeAll();this.mouseUpEvent.unsubscribeAll();this.clickEvent.unsubscribeAll();this.keyPressEvent.unsubscribeAll();this.keyDownEvent.unsubscribeAll();this.k!
 eyUpEvent.unsubscribeAll();this.focusEvent.unsubscribeAll();this.blurEvent.unsubscribeAll();this.cfg.configChangedEvent.unsubscribeAll();J=L.parentNode;if(J){J.removeChild(L);this.destroyEvent.fire();}this.destroyEvent.unsubscribeAll();}},toString:function(){var K="MenuItem",J=this.id;if(J){K+=(" "+J);}return K;}};F.augmentProto(H,YAHOO.util.EventProvider);})();(function(){YAHOO.widget.ContextMenu=function(G,F){YAHOO.widget.ContextMenu.superclass.constructor.call(this,G,F);};var B=YAHOO.util.Event,E=YAHOO.widget.ContextMenu,D={"TRIGGER_CONTEXT_MENU":"triggerContextMenu","CONTEXT_MENU":(YAHOO.env.ua.opera?"mousedown":"contextmenu"),"CLICK":"click"},C={"TRIGGER":{key:"trigger",suppressEvent:true}};function A(G,F,H){this.cfg.setProperty("xy",H);this.beforeShowEvent.unsubscribe(A,H);}YAHOO.lang.extend(E,YAHOO.widget.Menu,{_oTrigger:null,_bCancelled:false,contextEventTarget:null,triggerContextMenuEvent:null,init:function(G,F){E.superclass.init.call(this,G);this.beforeInitEvent.f!
 ire(E);if(F){this.cfg.applyConfig(F,true);}this.initEvent.fire!
 (E);},in
itEvents:function(){E.superclass.initEvents.call(this);this.triggerContextMenuEvent=this.createEvent(D.TRIGGER_CONTEXT_MENU);this.triggerContextMenuEvent.signature=YAHOO.util.CustomEvent.LIST;},cancel:function(){this._bCancelled=true;},_removeEventHandlers:function(){var F=this._oTrigger;if(F){B.removeListener(F,D.CONTEXT_MENU,this._onTriggerContextMenu);if(YAHOO.env.ua.opera){B.removeListener(F,D.CLICK,this._onTriggerClick);}}},_onTriggerClick:function(G,F){if(G.ctrlKey){B.stopEvent(G);}},_onTriggerContextMenu:function(H,F){if(H.type=="mousedown"&&!H.ctrlKey){return ;}var G;B.stopEvent(H);this.contextEventTarget=B.getTarget(H);this.triggerContextMenuEvent.fire(H);YAHOO.widget.MenuManager.hideVisible();if(!this._bCancelled){G=B.getXY(H);if(!YAHOO.util.Dom.inDocument(this.element)){this.beforeShowEvent.subscribe(A,G);}else{this.cfg.setProperty("xy",G);}this.show();}this._bCancelled=false;},toString:function(){var G="ContextMenu",F=this.id;if(F){G+=(" "+F);}return G;},initDefa!
 ultConfig:function(){E.superclass.initDefaultConfig.call(this);this.cfg.addProperty(C.TRIGGER.key,{handler:this.configTrigger,suppressEvent:C.TRIGGER.suppressEvent});},destroy:function(){this._removeEventHandlers();E.superclass.destroy.call(this);},configTrigger:function(G,F,I){var H=F[0];if(H){if(this._oTrigger){this._removeEventHandlers();}this._oTrigger=H;B.on(H,D.CONTEXT_MENU,this._onTriggerContextMenu,this,true);if(YAHOO.env.ua.opera){B.on(H,D.CLICK,this._onTriggerClick,this,true);}}else{this._removeEventHandlers();}}});}());YAHOO.widget.ContextMenuItem=YAHOO.widget.MenuItem;(function(){YAHOO.widget.MenuBar=function(F,E){YAHOO.widget.MenuBar.superclass.constructor.call(this,F,E);};function D(E){if(typeof E=="string"){return("dynamic,static".indexOf((E.toLowerCase()))!=-1);}}var B=YAHOO.util.Event,A=YAHOO.widget.MenuBar,C={"POSITION":{key:"position",value:"static",validator:D,supercedes:["visible"]},"SUBMENU_ALIGNMENT":{key:"submenualignment",value:["tl","bl"],suppressE!
 vent:true},"AUTO_SUBMENU_DISPLAY":{key:"autosubmenudisplay",va!
 lue:fals
e,validator:YAHOO.lang.isBoolean,suppressEvent:true}};YAHOO.lang.extend(A,YAHOO.widget.Menu,{init:function(F,E){if(!this.ITEM_TYPE){this.ITEM_TYPE=YAHOO.widget.MenuBarItem;}A.superclass.init.call(this,F);this.beforeInitEvent.fire(A);if(E){this.cfg.applyConfig(E,true);}this.initEvent.fire(A);},CSS_CLASS_NAME:"yuimenubar",_onKeyDown:function(G,F,K){var E=F[0],L=F[1],I,J,H;if(L&&!L.cfg.getProperty("disabled")){J=L.cfg;switch(E.keyCode){case 37:case 39:if(L==this.activeItem&&!J.getProperty("selected")){J.setProperty("selected",true);}else{H=(E.keyCode==37)?L.getPreviousEnabledSibling():L.getNextEnabledSibling();if(H){this.clearActiveItem();H.cfg.setProperty("selected",true);if(this.cfg.getProperty("autosubmenudisplay")){I=H.cfg.getProperty("submenu");if(I){I.show();}}H.focus();}}B.preventDefault(E);break;case 40:if(this.activeItem!=L){this.clearActiveItem();J.setProperty("selected",true);L.focus();}I=J.getProperty("submenu");if(I){if(I.cfg.getProperty("visible")){I.setInitialSel!
 ection();I.setInitialFocus();}else{I.show();}}B.preventDefault(E);break;}}if(E.keyCode==27&&this.activeItem){I=this.activeItem.cfg.getProperty("submenu");if(I&&I.cfg.getProperty("visible")){I.hide();this.activeItem.focus();}else{this.activeItem.cfg.setProperty("selected",false);this.activeItem.blur();}B.preventDefault(E);}},_onClick:function(L,G,J){A.superclass._onClick.call(this,L,G,J);var K=G[1],M,E,F,H,I;if(K&&!K.cfg.getProperty("disabled")){M=G[0];E=B.getTarget(M);F=this.activeItem;H=this.cfg;if(F&&F!=K){this.clearActiveItem();}K.cfg.setProperty("selected",true);I=K.cfg.getProperty("submenu");if(I){if(I.cfg.getProperty("visible")){I.hide();}else{I.show();}}}},toString:function(){var F="MenuBar",E=this.id;if(E){F+=(" "+E);}return F;},initDefaultConfig:function(){A.superclass.initDefaultConfig.call(this);var E=this.cfg;E.addProperty(C.POSITION.key,{handler:this.configPosition,value:C.POSITION.value,validator:C.POSITION.validator,supercedes:C.POSITION.supercedes});
+E.addProperty(C.SUBMENU_ALIGNMENT.key,{value:C.SUBMENU_ALIGNMENT.value,suppressEvent:C.SUBMENU_ALIGNMENT.suppressEvent});E.addProperty(C.AUTO_SUBMENU_DISPLAY.key,{value:C.AUTO_SUBMENU_DISPLAY.value,validator:C.AUTO_SUBMENU_DISPLAY.validator,suppressEvent:C.AUTO_SUBMENU_DISPLAY.suppressEvent});}});}());YAHOO.widget.MenuBarItem=function(B,A){YAHOO.widget.MenuBarItem.superclass.constructor.call(this,B,A);};YAHOO.lang.extend(YAHOO.widget.MenuBarItem,YAHOO.widget.MenuItem,{init:function(B,A){if(!this.SUBMENU_TYPE){this.SUBMENU_TYPE=YAHOO.widget.Menu;}YAHOO.widget.MenuBarItem.superclass.init.call(this,B);var C=this.cfg;if(A){C.applyConfig(A,true);}C.fireQueue();},CSS_CLASS_NAME:"yuimenubaritem",CSS_LABEL_CLASS_NAME:"yuimenubaritemlabel",toString:function(){var A="MenuBarItem";if(this.cfg&&this.cfg.getProperty("text")){A+=(": "+this.cfg.getProperty("text"));}return A;}});YAHOO.register("menu",YAHOO.widget.Menu,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/menu/menu.js
===================================================================
--- trunk/root/static/yui/menu/menu.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/menu/menu.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 
 
@@ -2505,9 +2505,13 @@
         Event.on(this.element, "mousemove", this._onMouseMove, this, true);
 
 
-        this.clearActiveItem();
+		if (!Dom.isAncestor(oItem.element, Event.getRelatedTarget(oEvent))) {
 
+        	this.clearActiveItem();
+        
+        }
 
+
         if (this.parent && this._nSubmenuHideDelayId) {
 
             window.clearTimeout(this._nSubmenuHideDelayId);
@@ -2735,91 +2739,113 @@
 */
 _onClick: function (p_sType, p_aArgs) {
 
-    var oEvent = p_aArgs[0],
-        oItem = p_aArgs[1],
-        oSubmenu,
-        bInMenuAnchor = false,
-        oRoot,
-        sId,
-        sURL,
-        nHashPos,
-        nLen;
+	var Event = YAHOO.util.Event,
+		Dom = YAHOO.util.Dom,
+		oEvent = p_aArgs[0],
+		oItem = p_aArgs[1],
+		oSubmenu,
+		bInMenuAnchor = false,
+		oRoot,
+		sId,
+		sURL,
+		nHashPos,
+		nLen;
 
 
-    if (oItem && !oItem.cfg.getProperty("disabled")) {
+	if (oItem) {
+	
+		if (oItem.cfg.getProperty("disabled")) {
+		
+			Event.preventDefault(oEvent);
 
-        oSubmenu = oItem.cfg.getProperty("submenu");
+		}
+		else {
 
-        
-        /*
-             Check if the URL of the anchor is pointing to an element that is 
-             a child of the menu.
-        */
-        
-        sURL = oItem.cfg.getProperty("url");
+			oSubmenu = oItem.cfg.getProperty("submenu");
+	
+			
+			/*
+				 Check if the URL of the anchor is pointing to an element that is 
+				 a child of the menu.
+			*/
+			
+			sURL = oItem.cfg.getProperty("url");
 
-        
-        if (sURL) {
+		
+			if (sURL) {
+	
+				nHashPos = sURL.indexOf("#");
+	
+				nLen = sURL.length;
+	
+	
+				if (nHashPos != -1) {
+	
+					sURL = sURL.substr(nHashPos, nLen);
+		
+					nLen = sURL.length;
+	
+	
+					if (nLen > 1) {
+	
+						sId = sURL.substr(1, nLen);
+	
+						bInMenuAnchor = Dom.isAncestor(this.element, sId);
+						
+					}
+					else if (nLen === 1) {
+	
+						bInMenuAnchor = true;
+					
+					}
+	
+				}
+			
+			}
 
-            nHashPos = sURL.indexOf("#");
 
-            nLen = sURL.length;
+	
+			if (bInMenuAnchor && !oItem.cfg.getProperty("target")) {
+	
+				Event.preventDefault(oEvent);
+				
 
+				if (UA.webkit) {
+				
+					oItem.focus();
+				
+				}
+				else {
 
-            if (nHashPos != -1) {
+					oItem.focusEvent.fire();
+				
+				}
+			
+			}
+	
+	
+			if (!oSubmenu) {
+	
+				oRoot = this.getRoot();
+				
+				if (oRoot instanceof YAHOO.widget.MenuBar || 
+					oRoot.cfg.getProperty("position") == "static") {
+	
+					oRoot.clearActiveItem();
+	
+				}
+				else {
+	
+					oRoot.hide();
+				
+				}
+	
+			}
+			
+		}
+	
+	}
 
-                sURL = sURL.substr(nHashPos, nLen);
-    
-                nLen = sURL.length;
-
-
-                if (nLen > 1) {
-
-                    sId = sURL.substr(1, nLen);
-
-                    bInMenuAnchor = Dom.isAncestor(this.element, sId);
-                    
-                }
-                else if (nLen === 1) {
-
-                    bInMenuAnchor = true;
-                
-                }
-
-            }
-        
-        }
-
-
-        if (bInMenuAnchor && !oItem.cfg.getProperty("target")) {
-
-            Event.preventDefault(oEvent);
-
-            oItem.focus();
-        
-        }
-
-
-        if (!oSubmenu) {
-
-            oRoot = this.getRoot();
-            
-            if (oRoot instanceof YAHOO.widget.MenuBar || 
-                oRoot.cfg.getProperty("position") == "static") {
-
-                oRoot.clearActiveItem();
-
-            }
-            else {
-
-                oRoot.hide();
-            
-            }
-
-        }
-    
-    }
-
 },
 
 
@@ -3985,107 +4011,38 @@
 */
 enforceConstraints: function (type, args, obj) {
 
-    var oParentMenuItem = this.parent,
-        nViewportOffset = Overlay.VIEWPORT_OFFSET,
-        oElement = this.element,
-        oConfig = this.cfg,
-        pos = args[0],
-        offsetHeight = oElement.offsetHeight,
-        offsetWidth = oElement.offsetWidth,
-        viewPortWidth = Dom.getViewportWidth(),
-        viewPortHeight = Dom.getViewportHeight(),
-        nPadding = (oParentMenuItem && 
-            oParentMenuItem.parent instanceof YAHOO.widget.MenuBar) ? 
-            0 : nViewportOffset,
-        aContext = oConfig.getProperty("context"),
-        oContextElement = aContext ? aContext[0] : null,
-        topConstraint,
-        leftConstraint,
-        bottomConstraint,
-        rightConstraint,
-        scrollX,
-        scrollY,
-        x,
-        y;
-    
+	YAHOO.widget.Menu.superclass.enforceConstraints.apply(this, arguments);
+	
+	var oParent = this.parent,
+		oParentMenu,
+		nParentMenuX,
+		nNewX,
+		nX;
+	
+	
+	if (oParent) {
+	
+		oParentMenu = oParent.parent;
 
-    if (offsetWidth < viewPortWidth) {
+		if (!(oParentMenu instanceof YAHOO.widget.MenuBar)) {
+	
+			nParentMenuX = oParentMenu.cfg.getProperty("x");
+			nX = this.cfg.getProperty("x");
+		
+	
+			if (nX < (nParentMenuX + oParent.element.offsetWidth)) {
 
-        x = pos[0];
-        scrollX = Dom.getDocumentScrollLeft();
-        leftConstraint = scrollX + nPadding;
-        rightConstraint = scrollX + viewPortWidth - offsetWidth - nPadding;
+				nNewX = (nParentMenuX - this.element.offsetWidth);
+			
+				this.cfg.setProperty("x",  nNewX, true);
+				this.cfg.setProperty("xy", [nNewX, (this.cfg.getProperty("y"))], true);
+			
+			}
+		
+		}
+	
+	}
 
-        if (x < nViewportOffset) {
-    
-            x = leftConstraint;
-    
-        } else if ((x + offsetWidth) > viewPortWidth) {
-    
-            if(oContextElement &&
-                ((x - oContextElement.offsetWidth) > offsetWidth)) {
-    
-                if (oParentMenuItem && 
-                    oParentMenuItem.parent instanceof YAHOO.widget.MenuBar) {
-    
-                    x = (x - (offsetWidth - oContextElement.offsetWidth));
-    
-                }
-                else {
-    
-                    x = (x - (oContextElement.offsetWidth + offsetWidth));
-    
-                }
-    
-            }
-            else {
-    
-                x = rightConstraint;
-    
-            }
-    
-        }
-    
-    }
-
-
-    if (offsetHeight < viewPortHeight) {
-
-        y = pos[1];
-        scrollY = Dom.getDocumentScrollTop();
-        topConstraint = scrollY + nPadding;
-        bottomConstraint = scrollY + viewPortHeight - offsetHeight - nPadding;
-
-
-
-        if (y < nViewportOffset) {
-    
-            y = topConstraint;
-    
-        } else if (y > bottomConstraint) {
-    
-            if (oContextElement && (y > offsetHeight)) {
-    
-                y = ((y + oContextElement.offsetHeight) - offsetHeight);
-    
-            }
-            else {
-    
-                y = bottomConstraint;
-                
-
-    
-            }
-    
-        }
-
-    }
-
-
-    oConfig.setProperty("x", x, true);
-    oConfig.setProperty("y", y, true);
-    oConfig.setProperty("xy", [x,y], true);
-
 },
 
 
@@ -4337,7 +4294,8 @@
         fnMouseOut = this._onScrollTargetMouseOut,
         nMinScrollHeight = this.cfg.getProperty("minscrollheight"),
         nHeight,
-        nOffsetWidth;
+        nOffsetWidth,
+        sWidth;
 
 
     if (nMaxHeight !== 0 && nMaxHeight < nMinScrollHeight) {
@@ -4373,25 +4331,37 @@
         offsetParent's "position" property is also set to "absolute."  It is 
         possible to work around this bug by specifying a value for the width 
         property in addition to overflow.
+
+		In IE it is also necessary to give the Menu a width when the scrollbars are 
+		rendered to prevent the Menu from rendering with a width that is 100% of
+		the browser viewport.
     */
 
-    if (UA.gecko && this.parent && this.parent.parent && 
-        this.parent.parent.cfg.getProperty("position") == "dynamic" && 
-        !this.cfg.getProperty("width")) {
+	var bSetWidth = ((UA.gecko && this.parent && this.parent.parent && 
+        this.parent.parent.cfg.getProperty("position") == "dynamic") || UA.ie);
 
-        nOffsetWidth = oElement.offsetWidth;
 
-        /*
-            Measuring the difference of the offsetWidth before and after
-            setting the "width" style attribute allows us to compute the 
-            about of padding and borders applied to the element, which in 
-            turn allows us to set the "width" property correctly.
-        */
-        
-        oElement.style.width = nOffsetWidth + "px";
-        oElement.style.width = 
-                (nOffsetWidth - (oElement.offsetWidth - nOffsetWidth)) + "px";
+    if (bSetWidth) {
 
+		if (!this.cfg.getProperty("width")) {
+
+			nOffsetWidth = oElement.offsetWidth;
+	
+			/*
+				Measuring the difference of the offsetWidth before and after
+				setting the "width" style attribute allows us to compute the 
+				about of padding and borders applied to the element, which in 
+				turn allows us to set the "width" property correctly.
+			*/
+			
+			oElement.style.width = nOffsetWidth + "px";
+	
+			sWidth = (nOffsetWidth - (oElement.offsetWidth - nOffsetWidth)) + "px";
+	
+			this.cfg.setProperty("width", sWidth);
+		
+		}
+
     }
 
 
@@ -4415,7 +4385,6 @@
     nHeight = (nMaxHeight - (oHeader.offsetHeight + oHeader.offsetHeight));
 
 
-
     if (nHeight > 0 && (oBody.offsetHeight > nMaxHeight)) {
 
         Dom.addClass(oBody, "yui-menu-body-scrolled");
@@ -4432,6 +4401,13 @@
     }
     else if (oHeader && oFooter) {
 
+		if (bSetWidth) {
+
+			this.cfg.setProperty("width", "");
+		
+		}
+
+
         this._enableScrollHeader();
         this._enableScrollFooter();
 
@@ -6445,7 +6421,7 @@
 
                     if (oAnchor) {
 
-                        sURL = oAnchor.getAttribute("href");
+                        sURL = oAnchor.getAttribute("href", 2);
                         sTarget = oAnchor.getAttribute("target");
 
                         sText = oAnchor.innerHTML;
@@ -7331,7 +7307,7 @@
         * accompany the text for the menu item.
         * @deprecated Use "text" configuration property to add help text markup.  
         * For example: <code>oMenuItem.cfg.setProperty("text", "Copy <em 
-        * class=\"helptext\">Ctrl + C</em<");</code>
+        * class=\"helptext\">Ctrl + C</em>");</code>
         * @default null
         * @type String|<a href="http://www.w3.org/TR/
         * 2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-58190037">
@@ -7391,7 +7367,7 @@
         * rendered with emphasis.
         * @deprecated Use "text" configuration property to add emphasis.  
         * For example: <code>oMenuItem.cfg.setProperty("text", "<em>Some 
-        * Text</em<");</code>
+        * Text</em>");</code>
         * @default false
         * @type Boolean
         */
@@ -7413,7 +7389,7 @@
         * rendered with strong emphasis.
         * @deprecated Use "text" configuration property to add strong emphasis.  
         * For example: <code>oMenuItem.cfg.setProperty("text", "<strong> 
-        * Some Text</strong<");</code>
+        * Some Text</strong>");</code>
         * @default false
         * @type Boolean
         */
@@ -9003,4 +8979,4 @@
 }
     
 }); // END YAHOO.lang.extend
-YAHOO.register("menu", YAHOO.widget.Menu, {version: "2.4.1", build: "742"});
+YAHOO.register("menu", YAHOO.widget.Menu, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/profiler/README
===================================================================
--- trunk/root/static/yui/profiler/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/profiler/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +1,9 @@
 YUI Library - Profiler - Release Notes
 
-2.4.1
+2.4.1 - 2.5.1
 
-No change
+  * No changes.
 
 2.4.0
 
-  * Beta release
+  * Beta release.

Modified: trunk/root/static/yui/profiler/profiler-beta-debug.js
===================================================================
--- trunk/root/static/yui/profiler/profiler-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/profiler/profiler-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 YAHOO.namespace("tool");
 
@@ -378,4 +378,4 @@
 
 };
 
-YAHOO.register("profiler", YAHOO.tool.Profiler, {version: "2.4.1", build: "742"});
+YAHOO.register("profiler", YAHOO.tool.Profiler, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/profiler/profiler-beta-min.js
===================================================================
--- trunk/root/static/yui/profiler/profiler-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/profiler/profiler-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-YAHOO.namespace("tool");YAHOO.tool.Profiler={_container:new Object(),_report:new Object(),_saveData:function(B,C){var A=this._report[B];A.calls++;A.points.push(C);if(A.calls>1){A.avg=((A.avg*(A.calls-1))+C)/A.calls;A.min=Math.min(A.min,C);A.max=Math.max(A.max,C);}else{A.avg=C;A.min=C;A.max=C;}},getAverage:function(A){return this._report[A].avg;},getCallCount:function(A){return this._report[A].calls;},getMax:function(A){return this._report[A].max;},getMin:function(A){return this._report[A].min;},getFunctionReport:function(A){return this._report[A];},getFullReport:function(C){C=C||function(){return true;};if(YAHOO.lang.isFunction(C)){var A={};for(var B in this._report){if(C(this._report[B])){A[B]=this._report[B];}}return A;}},registerConstructor:function(B,A){this.registerFunction(B,A,true);},registerFunction:function(name,owner,registerPrototype){var funcName=(name.indexOf(".")>-1?name.substring(name.lastIndexOf(".")+1):name);if(!YAHOO.lang.isObject(owner)){owner=eval(name.s!
 ubstring(0,name.lastIndexOf(".")));}var method=owner[funcName];var prototype=method.prototype;if(YAHOO.lang.isFunction(method)&&!method.__yuiProfiled){this._container[name]=method;owner[funcName]=function(){var start=new Date();var retval=method.apply(this,arguments);var stop=new Date();YAHOO.tool.Profiler._saveData(name,stop-start);return retval;};YAHOO.lang.augmentObject(owner[funcName],method);owner[funcName].__yuiProfiled=true;owner[funcName].prototype=prototype;this._container[name].__yuiOwner=owner;this._container[name].__yuiFuncName=funcName;if(registerPrototype){this.registerObject(name+".prototype",prototype);}this._report[name]={calls:0,max:0,min:0,avg:0,points:[]};}return method;},registerObject:function(name,object,recurse){object=(YAHOO.lang.isObject(object)?object:eval(name));this._container[name]=object;for(var prop in object){if(typeof object[prop]=="function"){if(prop!="constructor"&&prop!="superclass"){this.registerFunction(name+"."+prop,object);}}else{if(!
 typeof object[prop]=="object"&&recurse){this.registerObject(na!
 me+"."+p
rop,object[prop],recurse);}}}},unregisterConstructor:function(A){if(YAHOO.lang.isFunction(this._container[A])){this.unregisterFunction(A,true);}},unregisterFunction:function(B,C){if(YAHOO.lang.isFunction(this._container[B])){if(C){this.unregisterObject(B+".prototype",this._container[B].prototype);}var A=this._container[B].__yuiOwner;var D=this._container[B].__yuiFuncName;delete this._container[B].__yuiOwner;delete this._container[B].__yuiFuncName;A[D]=this._container[B];delete this._container[B];delete this._report[B];}},unregisterObject:function(A,B){if(YAHOO.lang.isObject(this._container[A])){object=this._container[A];for(var C in object){if(typeof object[C]=="function"){this.unregisterFunction(A+"."+C);}else{if(typeof object[C]=="object"&&B){this.unregisterObject(A+"."+C,B);}}}delete this._container[A];}}};YAHOO.register("profiler",YAHOO.tool.Profiler,{version:"2.4.1",build:"742"});
\ No newline at end of file
+YAHOO.namespace("tool");YAHOO.tool.Profiler={_container:new Object(),_report:new Object(),_saveData:function(B,C){var A=this._report[B];A.calls++;A.points.push(C);if(A.calls>1){A.avg=((A.avg*(A.calls-1))+C)/A.calls;A.min=Math.min(A.min,C);A.max=Math.max(A.max,C);}else{A.avg=C;A.min=C;A.max=C;}},getAverage:function(A){return this._report[A].avg;},getCallCount:function(A){return this._report[A].calls;},getMax:function(A){return this._report[A].max;},getMin:function(A){return this._report[A].min;},getFunctionReport:function(A){return this._report[A];},getFullReport:function(C){C=C||function(){return true;};if(YAHOO.lang.isFunction(C)){var A={};for(var B in this._report){if(C(this._report[B])){A[B]=this._report[B];}}return A;}},registerConstructor:function(B,A){this.registerFunction(B,A,true);},registerFunction:function(name,owner,registerPrototype){var funcName=(name.indexOf(".")>-1?name.substring(name.lastIndexOf(".")+1):name);if(!YAHOO.lang.isObject(owner)){owner=eval(name.s!
 ubstring(0,name.lastIndexOf(".")));}var method=owner[funcName];var prototype=method.prototype;if(YAHOO.lang.isFunction(method)&&!method.__yuiProfiled){this._container[name]=method;owner[funcName]=function(){var start=new Date();var retval=method.apply(this,arguments);var stop=new Date();YAHOO.tool.Profiler._saveData(name,stop-start);return retval;};YAHOO.lang.augmentObject(owner[funcName],method);owner[funcName].__yuiProfiled=true;owner[funcName].prototype=prototype;this._container[name].__yuiOwner=owner;this._container[name].__yuiFuncName=funcName;if(registerPrototype){this.registerObject(name+".prototype",prototype);}this._report[name]={calls:0,max:0,min:0,avg:0,points:[]};}return method;},registerObject:function(name,object,recurse){object=(YAHOO.lang.isObject(object)?object:eval(name));this._container[name]=object;for(var prop in object){if(typeof object[prop]=="function"){if(prop!="constructor"&&prop!="superclass"){this.registerFunction(name+"."+prop,object);}}else{if(!
 typeof object[prop]=="object"&&recurse){this.registerObject(na!
 me+"."+p
rop,object[prop],recurse);}}}},unregisterConstructor:function(A){if(YAHOO.lang.isFunction(this._container[A])){this.unregisterFunction(A,true);}},unregisterFunction:function(B,C){if(YAHOO.lang.isFunction(this._container[B])){if(C){this.unregisterObject(B+".prototype",this._container[B].prototype);}var A=this._container[B].__yuiOwner;var D=this._container[B].__yuiFuncName;delete this._container[B].__yuiOwner;delete this._container[B].__yuiFuncName;A[D]=this._container[B];delete this._container[B];delete this._report[B];}},unregisterObject:function(A,B){if(YAHOO.lang.isObject(this._container[A])){object=this._container[A];for(var C in object){if(typeof object[C]=="function"){this.unregisterFunction(A+"."+C);}else{if(typeof object[C]=="object"&&B){this.unregisterObject(A+"."+C,B);}}}delete this._container[A];}}};YAHOO.register("profiler",YAHOO.tool.Profiler,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/profiler/profiler-beta.js
===================================================================
--- trunk/root/static/yui/profiler/profiler-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/profiler/profiler-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 YAHOO.namespace("tool");
 
@@ -378,4 +378,4 @@
 
 };
 
-YAHOO.register("profiler", YAHOO.tool.Profiler, {version: "2.4.1", build: "742"});
+YAHOO.register("profiler", YAHOO.tool.Profiler, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/profilerviewer/README
===================================================================
--- trunk/root/static/yui/profilerviewer/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/profilerviewer/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,9 @@
+ProfilerViewer Control -- Release Notes
+
+2.5.1
+
+  * No changes.
+
+2.5.0
+
+  * Beta release
\ No newline at end of file

Added: trunk/root/static/yui/profilerviewer/assets/skins/sam/asc.gif
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/profilerviewer/assets/skins/sam/asc.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/root/static/yui/profilerviewer/assets/skins/sam/desc.gif
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/profilerviewer/assets/skins/sam/desc.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/root/static/yui/profilerviewer/assets/skins/sam/header_background.png
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/profilerviewer/assets/skins/sam/header_background.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/root/static/yui/profilerviewer/assets/skins/sam/profilerviewer.css
===================================================================
--- trunk/root/static/yui/profilerviewer/assets/skins/sam/profilerviewer.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/profilerviewer/assets/skins/sam/profilerviewer.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+.yui-skin-sam .yui-pv{background-color:#4a4a4a;font:arial;position:relative;width:99%;z-index:1000;margin-bottom:1em;overflow:hidden;}.yui-skin-sam .yui-pv .hd{background:url(header_background.png) repeat-x;min-height:30px;overflow:hidden;zoom:1;padding:2px 0;}.yui-skin-sam .yui-pv .hd h4{padding:8px 10px;margin:0;font:bold 14px arial;color:#fff;}.yui-skin-sam .yui-pv .hd a{background:#3f6bc3;font:bold 11px arial;color:#fff;padding:4px;margin:3px 10px 0 0;border:1px solid #3f567d;cursor:pointer;display:block;float:right;}.yui-skin-sam .yui-pv .hd span{display:none;}.yui-skin-sam .yui-pv .hd span.yui-pv-busy{height:18px;width:18px;background:url(wait.gif) no-repeat;overflow:hidden;display:block;float:right;margin:4px 10px 0 0;}.yui-skin-sam .yui-pv .hd:after,.yui-pv .bd:after,.yui-skin-sam .yui-pv-chartlegend dl:after{content:'.';visibility:hidden;clear:left;height:0;display:block;}.yui-skin-sam .yui-pv .bd{position:relative;zoom:1;overflow-x:auto;overflow-y:hidden;}.yui-ski!
 n-sam .yui-pv .yui-pv-table{padding:0 10px;margin:5px 0 10px 0;}.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-bd td{color:#eeee5c;font:12px arial;}.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-odd{background:#929292;}.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-even{background:#58637a;}.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-even td.yui-dt-asc,.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-even td.yui-dt-desc{background:#384970;}.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-odd td.yui-dt-asc,.yui-skin-sam .yui-pv .yui-pv-table tr.yui-dt-odd td.yui-dt-desc{background:#6F6E6E;}.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-hd th{background-image:none;background:#2E2D2D;}.yui-skin-sam .yui-pv th.yui-dt-asc .yui-dt-liner{background:transparent url(asc.gif) no-repeat scroll right center;}.yui-skin-sam .yui-pv th.yui-dt-desc .yui-dt-liner{background:transparent url(desc.gif) no-repeat scroll right center;}.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-hd th a{color:#fff;font:bold 1!
 2px arial;}.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-hd th.y!
 ui-dt-as
c,.yui-skin-sam .yui-pv .yui-pv-table .yui-dt-hd th.yui-dt-desc{background:#333;}.yui-skin-sam .yui-pv-chartcontainer{padding:0 10px;}.yui-skin-sam .yui-pv-chart{height:250px;clear:right;margin:5px 0 0 0;color:#fff;}.yui-skin-sam .yui-pv-chartlegend div{float:right;margin:0 0 0 10px;_width:250px;}.yui-skin-sam .yui-pv-chartlegend dl{border:1px solid #999;padding:.2em 0 .2em .5em;zoom:1;margin:5px 0;}.yui-skin-sam .yui-pv-chartlegend dt{float:left;display:block;height:.7em;width:.7em;padding:0;}.yui-skin-sam .yui-pv-chartlegend dd{float:left;display:block;color:#fff;margin:0 1em 0 .5em;padding:0;font:11px arial;}.yui-skin-sam .yui-pv-minimized{height:35px;}.yui-skin-sam .yui-pv-minimized .bd{top:-3000px;}.yui-skin-sam .yui-pv-minimized .hd a.yui-pv-refresh{display:none;}

Added: trunk/root/static/yui/profilerviewer/assets/skins/sam/wait.gif
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/profilerviewer/assets/skins/sam/wait.gif
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/root/static/yui/profilerviewer/profilerviewer-beta-debug.js
===================================================================
--- trunk/root/static/yui/profilerviewer/profilerviewer-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/profilerviewer/profilerviewer-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,1227 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+(function() {
+
+    /**
+     * The ProfilerViewer module provides a graphical display for viewing
+	 * the output of the YUI Profiler <http://developer.yahoo.com/yui/profiler>.
+     * @module profilerviewer
+     * @requires yahoo, dom, event, element, profiler, yuiloader
+     */
+
+    /**
+     * A widget to view YUI Profiler output.
+     * @namespace YAHOO.widget
+     * @class ProfilerViewer
+     * @extends YAHOO.util.Element
+     * @constructor
+     * @param {HTMLElement | String | Object} el(optional) The html 
+     * element into which the ProfileViewer should be rendered. 
+     * An element will be created if none provided.
+     * @param {Object} attr (optional) A key map of the ProfilerViewer's 
+     * initial attributes.  Ignored if first arg is an attributes object.
+     */
+    YAHOO.widget.ProfilerViewer = function(el, attr) {
+        attr = attr || {};
+        if (arguments.length == 1 && !YAHOO.lang.isString(el) && !el.nodeName) {
+            attr = el;
+            el = attr.element || null;
+        }
+        if (!el && !attr.element) {
+            el = this._createProfilerViewerElement();
+        }
+
+    	YAHOO.widget.ProfilerViewer.superclass.constructor.call(this, el, attr); 
+		
+		this._init();
+		
+		YAHOO.log("ProfilerViewer instantiated.", "info", "ProfilerViewer");
+    };
+
+    YAHOO.extend(YAHOO.widget.ProfilerViewer, YAHOO.util.Element);
+	
+	// Static members of YAHOO.widget.ProfilerViewer:
+	YAHOO.lang.augmentObject(YAHOO.widget.ProfilerViewer, {
+		/**
+		 * Classname for ProfilerViewer containing element.
+		 * @static
+		 * @property CLASS
+		 * @type string
+		 * @public
+		 * @default "yui-pv"
+		 */
+		CLASS: 'yui-pv',
+	
+		/**
+		 * Classname for ProfilerViewer button dashboard. 
+		 * @static
+		 * @property CLASS_DASHBOARD
+		 * @type string
+		 * @public
+		 * @default "yui-pv-dashboard"
+		 */
+		CLASS_DASHBOARD: 'yui-pv-dashboard',
+
+		/**
+		 * Classname for the "refresh data" button. 
+		 * @static
+		 * @property CLASS_REFRESH
+		 * @type string
+		 * @public
+		 * @default "yui-pv-refresh"
+		 */
+		CLASS_REFRESH: 'yui-pv-refresh',
+
+		/**
+		 * Classname for busy indicator in the dashboard. 
+		 * @static
+		 * @property CLASS_BUSY
+		 * @type string
+		 * @public
+		 * @default "yui-pv-busy"
+		 */
+		CLASS_BUSY: 'yui-pv-busy',
+	
+		/**
+		 * Classname for element containing the chart and chart
+		 * legend elements.
+		 * @static
+		 * @property CLASS_CHART_CONTAINER
+		 * @type string
+		 * @public
+		 * @default "yui-pv-chartcontainer"
+		 */
+		CLASS_CHART_CONTAINER: 'yui-pv-chartcontainer',
+	
+		/**
+		 * Classname for element containing the chart.
+		 * @static
+		 * @property CLASS_CHART
+		 * @type string
+		 * @public
+		 * @default "yui-pv-chart"
+		 */
+		CLASS_CHART: 'yui-pv-chart',
+		
+		/**
+		 * Classname for element containing the chart's legend. 
+		 * @static
+		 * @property CLASS_CHART_LEGEND
+		 * @type string
+		 * @public
+		 * @default "yui-pv-chartlegend"
+		 */
+		CLASS_CHART_LEGEND: 'yui-pv-chartlegend',
+		
+		/**
+		 * Classname for element containing the datatable. 
+		 * @static
+		 * @property CLASS_TABLE
+		 * @type string
+		 * @public
+		 * @default "yui-pv-table"
+		 */
+		CLASS_TABLE: 'yui-pv-table',
+		
+		/**
+		 * Strings used in the UI.
+		 * @static
+		 * @property STRINGS
+		 * @object
+		 * @public
+		 * @default English language strings for UI.
+		 */
+		STRINGS: {
+			title: "YUI Profiler (beta)",
+			buttons: {
+				viewprofiler: "View Profiler Data",
+				hideprofiler: "Hide Profiler Report",
+				showchart: "Show Chart",
+				hidechart: "Hide Chart",
+				refreshdata: "Refresh Data"
+			},
+			colHeads: {
+				//key: [column head label, width in pixels]
+				fn: ["Function/Method", null], //must auto-size
+				calls: ["Calls", 40],
+				avg: ["Average", 80],
+				min: ["Shortest", 70],
+				max: ["Longest", 70],
+				total: ["Total Time", 70],
+				pct: ["Percent", 70]
+			},
+			millisecondsAbbrev: "ms",
+			initMessage: "initialiazing chart...",
+			installFlashMessage: "Unable to load Flash content. The YUI Charts Control requires Flash Player 9.0.45 or higher. You can download the latest version of Flash Player from the <a href='http://www.adobe.com/go/getflashplayer'>Adobe Flash Player Download Center</a>."
+		},
+
+		/**
+		 * Function used to format numbers in milliseconds
+		 * for chart; must be publicly accessible, per Charts spec.
+		 * @static
+		 * @property timeAxisLabelFunction
+		 * @type function
+		 * @private
+		 */
+		timeAxisLabelFunction: function(n) {
+			var a = (n === Math.floor(n)) ? n : (Math.round(n*1000))/1000;
+			return (a + " " + YAHOO.widget.ProfilerViewer.STRINGS.millisecondsAbbrev);
+		},
+
+		/**
+		 * Function used to format percent numbers for chart; must
+		 * be publicly accessible, per Charts spec.
+		 * @static
+		 * @property percentAxisLabelFunction
+		 * @type function
+		 * @private
+		 */
+		percentAxisLabelFunction: function(n) {
+			var a = (n === Math.floor(n)) ? n : (Math.round(n*100))/100;
+			return (a + "%");
+		}
+		
+	
+	},true);
+	
+
+	//
+	// STANDARD SHORTCUTS
+	//
+    var Dom = YAHOO.util.Dom;
+    var Event = YAHOO.util.Event;
+	var Profiler = YAHOO.tool.Profiler;
+	var PV = YAHOO.widget.ProfilerViewer;
+	var proto = PV.prototype;
+
+
+	//
+	// PUBLIC METHODS
+	//
+	
+	 /**
+     * Refreshes the data displayed in the ProfilerViewer. When called,
+	 * this will invoke a refresh of the DataTable and (if displayed)
+	 * the Chart.
+     * @method refreshData
+     * @return void
+	 * @public
+     */	
+	proto.refreshData = function() {
+		YAHOO.log("Data refresh requested via refreshData method.", "info", "ProfilerViewer");
+		this.fireEvent("dataRefreshEvent");
+	};
+
+	 /**
+     * Returns the element containing the console's header.
+     * @method getHeadEl
+     * @return HTMLElement
+	 * @public
+     */	
+	proto.getHeadEl = function() {
+		YAHOO.log("Head element requested via getHeadEl.", "info", "ProfilerViewer");
+		return (this._headEl) ? Dom.get(this._headEl) : false;
+	};
+
+	 /**
+     * Returns the element containing the console's body, including
+	 * the chart and the datatable..
+     * @method getBodyEl
+     * @return HTMLElement
+	 * @public
+     */	
+	proto.getBodyEl = function() {
+		YAHOO.log("Body element requested via getBodyEl.", "info", "ProfilerViewer");
+		return (this._bodyEl) ? Dom.get(this._bodyEl) : false;
+	};
+
+	 /**
+     * Returns the element containing the console's chart.
+     * @method getChartEl
+     * @return HTMLElement
+	 * @public
+     */	
+	proto.getChartEl = function() {
+		YAHOO.log("Chart element requested via getChartEl.", "info", "ProfilerViewer");
+		return (this._chartEl) ? Dom.get(this._chartEl) : false;
+	};
+
+	 /**
+     * Returns the element containing the console's dataTable.
+     * @method getTableEl
+     * @return HTMLElement
+	 * @public
+     */	
+	proto.getTableEl = function() {
+		YAHOO.log("DataTable element requested via getTableEl.", "info", "ProfilerViewer");
+		return (this._tableEl) ? Dom.get(this._tableEl) : false;
+	};
+
+	 /**
+     * Returns the element containing the console's DataTable
+	 * instance.
+     * @method getDataTable
+     * @return YAHOO.widget.DataTable
+	 * @public
+     */	
+	proto.getDataTable = function() {
+		YAHOO.log("DataTable instance requested via getDataTable.", "info", "ProfilerViewer");
+		return this._dataTable;
+	};
+
+	 /**
+     * Returns the element containing the console's Chart instance.
+     * @method getChart
+     * @return YAHOO.widget.BarChart
+	 * @public
+     */	
+	proto.getChart = function() {
+		YAHOO.log("Chart instance requested via getChart.", "info", "ProfilerViewer");
+		return this._chart;
+	};
+
+
+    //
+    // PRIVATE PROPERTIES
+    //
+    proto._rendered = false;
+	proto._headEl = null;
+	proto._bodyEl = null;
+	proto._toggleVisibleEl = null;
+	proto._busyEl = null;
+	proto._busy = false;
+	
+	proto._tableEl = null;
+	proto._dataTable = null;
+
+	proto._chartEl = null;
+	proto._chartLegendEl = null;
+	proto._chartElHeight = 250;
+	proto._chart = null;
+	proto._chartInitialized = false;
+
+    //
+    // PRIVATE METHODS
+    //
+
+	proto._init = function() {
+		/**
+		 * CUSTOM EVENTS
+		 **/
+		
+		/**
+		 * Fired when a data refresh is requested. No arguments are passed
+		 * with this event.
+		 *
+		 * @event refreshDataEvent
+		 */
+		this.createEvent("dataRefreshEvent");
+		
+		/**
+		 * Fired when the viewer canvas first renders. No arguments are passed
+		 * with this event.
+		 *
+		 * @event renderEvent
+		 */
+		this.createEvent("renderEvent");
+
+		this.on("dataRefreshEvent", this._refreshDataTable, this, true);
+		
+		this._initLauncherDOM();
+		
+		if(this.get("showChart")) {
+			this.on("sortedByChange", this._refreshChart);
+		}
+
+		YAHOO.log("ProfilerViewer instance initialization complete.", "info", "ProfilerViewer");
+	};
+
+	/**
+	 * If no element is passed in, create it as the first element
+	 * in the document.
+	 * @method _createProfilerViewerElement
+	 * @return HTMLElement
+	 * @private
+	 */
+	proto._createProfilerViewerElement = function() {
+		YAHOO.log("Creating root element...", "info", "ProfilerViewer");
+
+		var el = document.createElement("div");
+		document.body.insertBefore(el, document.body.firstChild);
+		Dom.addClass(el, this.SKIN_CLASS);
+		Dom.addClass(el, PV.CLASS);
+		YAHOO.log(el);
+		return el;
+	};
+			
+    /**
+     * Provides a readable name for the ProfilerViewer instance.
+     * @method toString
+     * @return String
+	 * @private
+	 */
+    proto.toString = function() {
+        return "ProfilerViewer " + (this.get('id') || this.get('tagName'));
+    };
+
+    /**
+     * Toggles visibility of the viewer canvas.
+     * @method _toggleVisible
+     * @return void
+	 * @private
+     */	
+	proto._toggleVisible = function() {
+		YAHOO.log("Toggling visibility to " + !this.get("visible") + ".", "info", "ProfilerViewer");
+		
+		var newVis = (this.get("visible")) ? false : true;
+		this.set("visible", newVis);
+    };
+
+    /**
+     * Shows the viewer canvas.
+     * @method show
+     * @return void
+	 * @private
+     */	
+	 proto._show = function() {
+	 	if(!this._busy) {
+			this._setBusyState(true);
+			if(!this._rendered) {
+				var loader = new YAHOO.util.YUILoader();
+				if (this.get("base")) {
+					loader.base = this.get("base");
+				}
+				
+				var modules = ["datatable"];
+				if(this.get("showChart")) {
+					modules.push("charts");
+				}
+				
+				loader.insert({ require: modules,
+								onSuccess: function() {
+									this._render();
+								},
+								scope: this});
+			} else {
+				var el = this.get("element");
+				Dom.removeClass(el, "yui-pv-minimized");
+				this._toggleVisibleEl.innerHTML = PV.STRINGS.buttons.hideprofiler;
+				
+				//The Flash Charts component can't be set to display:none,
+				//and even after positioning it offscreen the screen
+				//may fail to repaint in some browsers.  Adding an empty
+				//style rule to the console body can help force a repaint:
+				Dom.addClass(el, "yui-pv-null");
+				Dom.removeClass(el, "yui-pv-null");
+				
+				//Always refresh data when changing to visible:
+				this.refreshData();
+			}
+		}
+    };
+
+    /**
+     * Hides the viewer canvas.
+     * @method hide
+     * @return void
+	 * @private
+     */	
+	proto._hide = function() {
+		this._toggleVisibleEl.innerHTML = PV.STRINGS.buttons.viewprofiler;
+		Dom.addClass(this.get("element"), "yui-pv-minimized");
+    };
+	
+	/**
+	 * Render the viewer canvas
+	 * @method _render
+	 * @return void
+	 * @private
+	 */
+	proto._render = function() {
+		YAHOO.log("Beginning to render ProfilerViewer canvas...", "info", "ProfilerViewer");
+		
+		Dom.removeClass(this.get("element"), "yui-pv-minimized");
+		
+		this._initViewerDOM();
+		this._initDataTable();
+		if(this.get("showChart")) {
+			this._initChartDOM();
+			this._initChart();
+		}
+		this._rendered = true;
+		this._toggleVisibleEl.innerHTML = PV.STRINGS.buttons.hideprofiler;
+		
+		this.fireEvent("renderEvent");
+
+		YAHOO.log("ProfilerViewer rendering complete...", "info", "ProfilerViewer");
+	};
+	
+	/**
+	 * Set up the DOM structure for the ProfilerViewer launcher.
+	 * @method _initLauncherDOM
+	 * @private
+	 */
+	proto._initLauncherDOM = function() {
+		YAHOO.log("Creating the launcher...", "info", "ProfilerViewer");
+		
+		var el = this.get("element");
+		Dom.addClass(el, PV.CLASS);
+		Dom.addClass(el, "yui-pv-minimized");
+
+		this._headEl = document.createElement("div");
+		Dom.addClass(this._headEl, "hd");
+		
+		var s = PV.STRINGS.buttons;
+		var b = (this.get("visible")) ? s.hideprofiler : s.viewprofiler;
+		
+		this._toggleVisibleEl = this._createButton(b, this._headEl);
+		
+		this._refreshEl = this._createButton(s.refreshdata, this._headEl);
+		Dom.addClass(this._refreshEl, PV.CLASS_REFRESH);
+		
+		this._busyEl = document.createElement("span");
+		this._headEl.appendChild(this._busyEl);
+
+		var title = document.createElement("h4");
+		title.innerHTML = PV.STRINGS.title;
+		this._headEl.appendChild(title);
+		
+		el.appendChild(this._headEl);
+		
+		Event.on(this._toggleVisibleEl, "click", this._toggleVisible, this, true);
+		Event.on(this._refreshEl, "click", function() {
+			if(!this._busy) {
+				this._setBusyState(true);
+				this.fireEvent("dataRefreshEvent");
+			}
+		}, this, true);
+	};
+
+	/**
+	 * Set up the DOM structure for the ProfilerViewer canvas,
+	 * including the holder for the DataTable.
+	 * @method _initViewerDOM
+	 * @private
+	 */
+	proto._initViewerDOM = function() {
+		YAHOO.log("Creating DOM structure for viewer...", "info", "ProfilerViewer");
+		
+		var el = this.get("element");
+		this._bodyEl = document.createElement("div");
+		Dom.addClass(this._bodyEl, "bd");
+	 	this._tableEl = document.createElement("div");
+		Dom.addClass(this._tableEl, PV.CLASS_TABLE);
+		this._bodyEl.appendChild(this._tableEl);
+		el.appendChild(this._bodyEl);
+	};
+
+	/**
+	 * Set up the DOM structure for the ProfilerViewer canvas.
+	 * @method _initChartDOM
+	 * @private
+	 */
+	proto._initChartDOM = function() {
+		YAHOO.log("Adding DOM structure for chart...", "info", "ProfilerViewer");
+		
+		this._chartContainer = document.createElement("div");
+		Dom.addClass(this._chartContainer, PV.CLASS_CHART_CONTAINER);
+		
+		var chl = document.createElement("div");
+		Dom.addClass(chl, PV.CLASS_CHART_LEGEND);
+		
+		var chw = document.createElement("div");
+
+		this._chartLegendEl = document.createElement("dl");
+		this._chartLegendEl.innerHTML = "<dd>" + PV.STRINGS.initMessage + "</dd>";
+		
+		this._chartEl = document.createElement("div");
+		Dom.addClass(this._chartEl, PV.CLASS_CHART);
+		
+		var msg = document.createElement("p");
+		msg.innerHTML = PV.STRINGS.installFlashMessage;
+		this._chartEl.appendChild(msg);
+		
+		this._chartContainer.appendChild(chl);
+		chl.appendChild(chw);
+		chw.appendChild(this._chartLegendEl);
+		this._chartContainer.appendChild(this._chartEl);
+		this._bodyEl.insertBefore(this._chartContainer,this._tableEl);
+	};
+
+
+	/**
+	 * Create anchor elements for use as buttons. Args: label
+	 * is text to appear on the face of the button, parentEl
+	 * is the el to which the anchor will be attached, position
+	 * is true for inserting as the first node and false for
+	 * inserting as the last node of the parentEl.
+	 * @method _createButton
+	 * @private
+	 */	
+	proto._createButton = function(label, parentEl, position) {
+		var b = document.createElement("a");
+		b.innerHTML = b.title = label;
+		if(parentEl) {
+			if(!position) {
+				parentEl.appendChild(b);
+			} else {
+				parentEl.insertBefore(b, parentEl.firstChild);	
+			}
+		}
+		return b;
+	};
+	
+	/**
+	 * Set's console busy state.
+	 * @method _setBusyState
+	 * @private
+	 **/
+	proto._setBusyState = function(b) {
+		if(b) {
+			Dom.addClass(this._busyEl, PV.CLASS_BUSY);
+			this._busy = true;
+		} else {
+			Dom.removeClass(this._busyEl, PV.CLASS_BUSY);
+			this._busy = false;
+		}
+	};
+
+	/**
+	 * Generages a sorting function based on current sortedBy
+	 * values.
+	 * @method _createProfilerViewerElement
+	 * @private
+	 **/
+	proto._genSortFunction = function(key, dir) {
+		var by = key;
+		var direction = dir;
+		return function(a, b) {
+			if (direction == YAHOO.widget.DataTable.CLASS_ASC) {
+				return a[by] - b[by];	
+			} else {
+				return ((a[by] - b[by]) * -1);
+			}
+		};
+	};
+
+	/**
+	 * Utility function for array sums.
+	 * @method _arraySum
+	 * @private
+	 **/	
+	 var _arraySum = function(arr){
+		var ct = 0;
+		for(var i = 0; i < arr.length; ct+=arr[i++]){}
+		return ct;
+	};
+	
+	/**
+	 * Retrieves data from Profiler, filtering and sorting as needed
+	 * based on current widget state.  Adds calculated percentage
+	 * column and function name to data returned by Profiler.
+	 * @method _getProfilerData
+	 * @private
+	 **/
+	proto._getProfilerData = function() {
+		YAHOO.log("Profiler data requested from function DataSource.", "info", "ProfilerViewer");
+		
+		var obj = Profiler.getFullReport();
+		var arr = [];
+		var totalTime = 0;
+		for (name in obj) {
+    		if (YAHOO.lang.hasOwnProperty(obj, name)) {
+				var r = obj[name];
+				var o = {};
+				o.fn = name; //add function name to record
+				o.points = r.points.slice(); //copy live array
+				o.calls = r.calls;
+				o.min = r.min;
+				o.max = r.max;
+				o.avg = r.avg;
+				o.total = _arraySum(o.points);
+				o.points = r.points;
+				var f = this.get("filter");
+				if((!f) || (f(o))) {
+					arr.push(o);
+					totalTime += o.total;
+				}
+			}
+		}
+		
+		//add calculated percentage column
+		for (var i = 0, j = arr.length; i < j; i++) {
+			arr[i].pct = (totalTime) ? (arr[i].total * 100) / totalTime : 0;	
+		}
+
+		var sortedBy = this.get("sortedBy");
+		var key = sortedBy.key;
+		var dir = sortedBy.dir;		
+
+		arr.sort(this._genSortFunction(key, dir));
+		
+		YAHOO.log("Returning data from DataSource: " + YAHOO.lang.dump(arr), "info", "ProfilerViewer");
+		
+		return arr;
+	};
+	
+	/**
+	 * Set up the DataTable.
+	 * @method _initDataTable
+	 * @private
+	 */
+	proto._initDataTable = function() {
+		YAHOO.log("Creating DataTable instance...", "info", "ProfilerViewer");
+		
+		var self = this;
+		
+		//Set up the JS Function DataSource, pulling data from
+		//the Profiler.
+		this._dataSource = new YAHOO.util.DataSource(
+			function() {
+				return self._getProfilerData.call(self);	
+			},
+			{
+				responseType: YAHOO.util.DataSource.TYPE_JSARRAY,
+				maxCacheEntries: 0
+			}
+		);
+		var ds = this._dataSource;
+
+		ds.responseSchema =
+		{
+			fields: [ "fn", "avg", "calls", "max", "min", "total", "pct", "points"]
+		};
+		
+		//Set up the DataTable.
+		var formatTimeValue = function(elCell, oRecord, oColumn, oData) {
+			var a = (oData === Math.floor(oData)) ? oData : (Math.round(oData*1000))/1000;
+			elCell.innerHTML = a + " " + PV.STRINGS.millisecondsAbbrev;
+		};
+
+		var formatPercent = function(elCell, oRecord, oColumn, oData) {
+			var a = (oData === Math.floor(oData)) ? oData : (Math.round(oData*100))/100;
+			elCell.innerHTML = a + "%";
+		};
+		
+		var a = YAHOO.widget.DataTable.CLASS_ASC;
+		var d = YAHOO.widget.DataTable.CLASS_DESC;
+		var c = PV.STRINGS.colHeads;
+		var f = formatTimeValue;
+		
+		var cols = [
+			{key:"fn", sortable:true, label: c.fn[0],
+				sortOptions: {defaultDir:a}, 
+				resizeable: (YAHOO.util.DragDrop) ? true : false,
+				minWidth:c.fn[1]},
+			{key:"calls", sortable:true, label: c.calls[0],
+				sortOptions: {defaultDir:d},
+				width:c.calls[1]},
+			{key:"avg", sortable:true, label: c.avg[0],
+				sortOptions: {defaultDir:d},
+				formatter:f,
+				width:c.avg[1]},
+			{key:"min", sortable:true, label: c.min[0],
+				sortOptions: {defaultDir:a},
+				formatter:f,
+				width:c.min[1]}, 
+			{key:"max", sortable:true, label: c.max[0],
+				sortOptions: {defaultDir:d},
+				formatter:f,
+				width:c.max[1]},
+			{key:"total", sortable:true, label: c.total[0],
+				sortOptions: {defaultDir:d},
+				formatter:f,
+				width:c.total[1]},
+			{key:"pct", sortable:true, label: c.pct[0],
+				sortOptions: {defaultDir:d}, 
+				formatter:formatPercent,
+				width:c.pct[1]}
+		];
+
+		this._dataTable = new YAHOO.widget.DataTable(this._tableEl, cols, ds, {
+			scrollable:true,
+			height:this.get("tableHeight"),
+			initialRequest:null,
+			sortedBy: {
+				key: "total",
+				dir: YAHOO.widget.DataTable.CLASS_DESC
+			}
+		});
+		var dt = this._dataTable;
+
+		//Wire up DataTable events to drive the rest of the UI.
+		dt.subscribe("sortedByChange", this._sortedByChange, this, true);
+		dt.subscribe("renderEvent", this._dataTableRenderHandler, this, true);
+		dt.subscribe("initEvent", this._dataTableRenderHandler, this, true);
+		Event.on(this._tableEl.getElementsByTagName("th"), "click", this._thClickHandler, this, true);
+		YAHOO.log("DataTable initialized.", "info", "ProfilerViewer");
+	};
+		
+	/**
+	 * Proxy the sort event in DataTable into the ProfilerViewer
+	 * attribute.
+	 * @method _sortedByChange
+	 * @private
+	 **/
+	proto._sortedByChange = function(o) {
+		YAHOO.log("Relaying DataTable sortedBy value change; new key: " + o.newValue.key + "; new direction: " + o.newValue.dir + ".", "info", "ProfilerViewer");
+		this.set("sortedBy", {key: o.newValue.key, dir:o.newValue.dir});
+	};
+
+	/**
+	 * Proxy the render event in DataTable into the ProfilerViewer
+	 * attribute.
+	 * @method _dataTableRenderHandler
+	 * @private
+	 **/
+	proto._dataTableRenderHandler = function(o) {
+		YAHOO.log("DataTable's render event has fired.", "info", "ProfilerViewer");
+		this._setBusyState(false);
+	};
+	
+	/**
+	 * Event handler for clicks on the DataTable's sortable column
+	 * heads.
+	 * @method _thClickHandler
+	 * @private
+	 **/
+	proto._thClickHandler = function(o) {
+		YAHOO.log("DataTable's header row was clicked for sorting.", "info", "ProfilerViewer");
+		this._setBusyState(true);
+	};
+
+	/**
+	 * Refresh DataTable, getting new data from Profiler.
+	 * @method _refreshDataTable
+	 * @private
+	 **/
+	proto._refreshDataTable = function(args) {
+		YAHOO.log("Beginning to refresh DataTable contents...", "info", "ProfilerViewer");
+		var dt = this._dataTable;
+		dt.getDataSource().sendRequest("", dt.onDataReturnInitializeTable, dt);
+		YAHOO.log("DataTable refresh complete.", "info", "ProfilerViewer");
+	};
+
+	/**
+	 * Refresh chart, getting new data from table.
+	 * @method _refreshChart
+	 * @private
+	 **/
+	proto._refreshChart = function() {
+		YAHOO.log("Beginning to refresh Chart contents...", "info", "ProfilerViewer");
+		
+		switch (this.get("sortedBy").key) {
+			case "fn":
+				/*Keep the same data on the chart, but force update to 
+				  reflect new sort order on function/method name: */
+				this._chart.set("dataSource", this._chart.get("dataSource"));
+				
+				/*no further action necessary; chart redraws*/
+				return;
+			case "calls":
+				/*Null out the xAxis formatting before redrawing chart.*/
+				this._chart.set("xAxis", this._chartAxisDefinitionPlain);
+				break;
+			case "pct":
+				this._chart.set("xAxis", this._chartAxisDefinitionPercent);
+				break;
+			default:
+				/*Set the default xAxis; redraw legend; set the new series definition.*/
+				this._chart.set("xAxis", this._chartAxisDefinitionTime);
+				break;
+		}
+		
+		this._drawChartLegend();
+		this._chart.set("series", this._getSeriesDef(this.get("sortedBy").key));
+
+		YAHOO.log("Chart refresh complete.", "info", "ProfilerViewer");
+	};
+	
+	/**
+	 * Get data for the Chart from DataTable recordset
+	 * @method _getChartData
+	 * @private
+	 */
+	proto._getChartData = function() {
+		YAHOO.log("Getting data for chart from function DataSource.", "info", "ProfilerViewer");
+		var records = this._dataTable.getRecordSet().getRecords(0, this.get("maxChartFunctions"));
+		var arr = [];
+		for (var i = records.length - 1; i>-1; i--) {
+			arr.push(records[i].getData());	
+		}
+		YAHOO.log("Returning data to Chart: " + YAHOO.lang.dump(arr), "info", "ProfilerViewer");
+		return arr;
+	};
+	
+	/**
+	 * Build series definition based on current configuration attributes.
+	 * @method _getSeriesDef
+	 * @private
+	 */
+	proto._getSeriesDef = function(field) {
+		var sd = this.get("chartSeriesDefinitions")[field];
+		var arr = [];
+		for(var i = 0, j = sd.group.length; i<j; i++) {
+			var c = this.get("chartSeriesDefinitions")[sd.group[i]];
+			arr.push(
+				{displayName:c.displayName,
+				 xField:c.xField,
+				 style: {color:c.style.color, size:c.style.size}
+				}
+			);
+		}
+		
+		YAHOO.log("Returning new series definition to chart: " + YAHOO.lang.dump(arr), "info", "ProfilerViewer");
+		return arr;
+	};
+	
+	/**
+	 * Set up the Chart.
+	 * @method _initChart
+	 * @private
+	 */
+	proto._initChart = function() {
+		YAHOO.log("Initializing chart...", "info", "ProfilerViewer");
+		
+		this._sizeChartCanvas();
+		
+		YAHOO.widget.Chart.SWFURL = this.get("swfUrl");
+
+		var self = this;
+
+		//Create DataSource based on records currently displayed
+		//at the top of the sort list in the DataTable.
+		var ds = new YAHOO.util.DataSource(
+			//force the jsfunction DataSource to run in the scope of
+			//the ProfilerViewer, not in the YAHOO.util.DataSource scope:
+			function() {
+				return self._getChartData.call(self);
+			}, 
+			{
+				responseType: YAHOO.util.DataSource.TYPE_JSARRAY,
+				maxCacheEntries: 0
+			}
+		);
+
+		ds.responseSchema =
+		{
+			fields: [ "fn", "avg", "calls", "max", "min", "total", "pct" ]
+		};
+		
+		ds.subscribe('responseEvent', this._sizeChartCanvas, this, true);
+		
+		//Set up the chart itself.
+		this._chartAxisDefinitionTime = new YAHOO.widget.NumericAxis();
+		this._chartAxisDefinitionTime.labelFunction = "YAHOO.widget.ProfilerViewer.timeAxisLabelFunction";
+		
+		this._chartAxisDefinitionPercent = new YAHOO.widget.NumericAxis();
+		this._chartAxisDefinitionPercent.labelFunction = "YAHOO.widget.ProfilerViewer.percentAxisLabelFunction";
+
+		this._chartAxisDefinitionPlain = new YAHOO.widget.NumericAxis();
+		
+		this._chart = new YAHOO.widget.BarChart( this._chartEl, ds,
+		{
+			yField: "fn",
+			series: this._getSeriesDef(this.get("sortedBy").key),
+			style: this.get("chartStyle"),
+			xAxis: this._chartAxisDefinitionTime
+		} );
+		
+		this._drawChartLegend();
+		this._chartInitialized = true;
+		this._dataTable.unsubscribe("initEvent", this._initChart, this);
+		this._dataTable.subscribe("initEvent", this._refreshChart, this, true);
+		
+		YAHOO.log("Chart initialization complete.", "info", "ProfilerViewer");
+	};
+	
+	/**
+	 * Set up the Chart's legend
+	 * @method _drawChartLegend
+	 * @private
+	 **/
+	proto._drawChartLegend = function() {
+		YAHOO.log("Drawing chart legend...", "info", "ProfilerViewer");
+		var seriesDefs = this.get("chartSeriesDefinitions");
+		var currentDef = seriesDefs[this.get("sortedBy").key];
+		var l = this._chartLegendEl;
+		l.innerHTML = "";
+		for(var i = 0, j = currentDef.group.length; i<j; i++) {
+			var c = seriesDefs[currentDef.group[i]];
+			var dt = document.createElement("dt");
+			Dom.setStyle(dt, "backgroundColor", "#" + c.style.color);
+			var dd = document.createElement("dd");
+			dd.innerHTML = c.displayName;
+			l.appendChild(dt);
+			l.appendChild(dd);
+		}
+	};
+	
+	/**
+	 * Resize the chart's canvas if based on number of records
+	 * returned from the chart's datasource.
+	 * @method _sizeChartCanvas
+	 * @private
+	 **/
+	proto._sizeChartCanvas = function(o) {
+		YAHOO.log("Resizing chart canvas...", "info", "ProfilerViewer");
+		var bars = (o) ? o.response.length : this.get("maxChartFunctions");
+		var s = (bars * 36) + 34;
+		if (s != parseInt(this._chartElHeight, 10)) {
+			this._chartElHeight = s;
+			Dom.setStyle(this._chartEl, "height", s + "px");
+		}
+	};
+
+    /**
+     * setAttributeConfigs TabView specific properties.
+     * @method initAttributes
+     * @param {Object} attr Hash of initial attributes
+	 * @method initAttributes
+	 * @private
+     */
+    proto.initAttributes = function(attr) {
+		YAHOO.log("Initializing attributes...", "info", "ProfilerViewer");
+        YAHOO.widget.ProfilerViewer.superclass.initAttributes.call(this, attr);
+        /**
+         * The YUI Loader base path from which to pull YUI files needed
+		 * in the rendering of the ProfilerViewer canvas.  Passed directly
+		 * to YUI Loader.  Leave blank to draw files from
+		 * yui.yahooapis.com.
+         * @attribute base
+         * @type string
+		 * @default ""
+         */
+        this.setAttributeConfig('base', {
+            value: attr.base
+        });
+
+        /**
+         * The height of the DataTable.  The table will scroll
+		 * vertically if the content overflows the specified
+		 * height.
+         * @attribute tableHeight
+         * @type string
+		 * @default "15em"
+         */
+        this.setAttributeConfig('tableHeight', {
+            value: attr.tableHeight || "15em",
+			method: function(s) {
+				if(this._dataTable) {
+					this._dataTable.set("height", s);
+				}
+			}
+        });
+		
+        /**
+         * The default column key to sort by.  Valid keys are: fn, calls,
+		 * avg, min, max, total.  Valid dir values are: 
+		 * YAHOO.widget.DataTable.CLASS_ASC and
+		 * YAHOO.widget.DataTable.CLASS_DESC (or their
+		 * string equivalents).
+         * @attribute sortedBy
+         * @type string
+		 * @default {key:"total", dir:"yui-dt-desc"}
+         */
+        this.setAttributeConfig('sortedBy', {
+            value: attr.sortedBy || {key:"total", dir:"yui-dt-desc"}
+        });
+
+        /**
+         * A filter function to use in selecting functions that will
+		 * appear in the ProfilerViewer report.  The function is passed
+		 * a function report object and should return a boolean indicating
+		 * whether that function should be included in the ProfilerViewer
+		 * display.  The argument is structured as follows:
+		 *
+		 * {
+		 *	 	fn: <str function name>,
+		 *		calls : <n number of calls>,
+		 *		avg : <n average call duration>,
+		 *		max: <n duration of longest call>,
+		 *		min: <n duration of shortest call>,
+		 *		total: <n total time of all calls>
+		 *		points : <array time in ms of each call>
+		 *	}
+		 *
+		 * For example, you would use the follwing filter function to 
+		 * return only functions that have been called at least once:
+		 * 
+		 * 	function(o) {
+		 *		return (o.calls > 0);
+		 *	}
+		 *
+         * @attribute filter
+         * @type function
+		 * @default null
+         */
+        this.setAttributeConfig('filter', {
+            value: attr.filter || null,
+			validator: YAHOO.lang.isFunction
+        });
+
+		/**
+		 * The path to the YUI Charts swf file; must be a full URI
+		 * or a path relative to the page being profiled. Changes at runtime
+		 * not supported; pass this value in at instantiation.
+		 * @attribute swfUrl
+		 * @type string
+		 * @default "http://yui.yahooapis.com/2.5.0/build/charts/assets/charts.swf"
+		 */
+		this.setAttributeConfig('swfUrl', {
+			value: attr.swfUrl || "http://yui.yahooapis.com/2.5.0/build/charts/assets/charts.swf"
+		});
+
+        /**
+         * The maximum number of functions to profile in the chart. The
+		 * greater the number of functions, the greater the height of the
+		 * chart canvas.
+		 * height.
+         * @attribute maxChartFunctions
+         * @type int
+		 * @default 6
+         */
+        this.setAttributeConfig('maxChartFunctions', {
+            value: attr.maxChartFunctions || 6,
+			method: function(s) {
+				if(this._rendered) {
+					this._sizeChartCanvas();
+				}
+			},
+			validator: YAHOO.lang.isNumber
+        });
+		
+        /**
+         * The style object that defines the chart's visual presentation.
+		 * Conforms to the style attribute passed to the Charts Control
+		 * constructor.  See Charts Control User's Guide for more information
+		 * on how to format this object.
+         * @attribute chartStyle
+         * @type obj
+		 * @default See JS source for default definitions.
+         */
+        this.setAttributeConfig('chartStyle', {
+            value: 	attr.chartStyle || {
+				font:
+					{
+						name: "Arial",
+						color: 0xeeee5c,
+						size: 12
+					},
+					background:
+					{
+						color: "6e6e63"
+					}
+				},
+			method: function() {
+					if(this._rendered && this.get("showChart")) {
+						this._refreshChart();
+					}
+				}
+        });
+		
+        /**
+         * The series definition information to use when charting
+		 * specific fields on the chart.  displayName, xField,
+		 * and style members are used to construct the series
+		 * definition; the "group" member is the array of fields
+		 * that should be charted when the table is sorted by a
+		 * given field.
+         * @attribute chartSeriesDefinitions
+         * @type obj
+		 * @default See JS source for full default definitions.
+         */
+        this.setAttributeConfig('chartSeriesDefinitions', {
+            value: 	attr.chartSeriesDefinitions ||  {
+						total: {
+							displayName: PV.STRINGS.colHeads.total[0],
+							xField: "total",
+							style: {color:"4d95dd", size:20},
+							group: ["total"]
+						},
+						calls: {		
+							displayName: PV.STRINGS.colHeads.calls[0],
+							xField: "calls",
+							style: {color:"edff9f", size:20},
+							group: ["calls"]
+						},
+						avg: {
+							displayName: PV.STRINGS.colHeads.avg[0],
+							xField: "avg",
+							style: {color:"209daf", size:9},
+							group: ["avg", "min", "max"]
+						},
+						min: {
+							displayName: PV.STRINGS.colHeads.min[0],
+							xField: "min",
+							style: {color:"b6ecf4", size:9},
+							group: ["avg", "min", "max"]
+						},
+						max: {
+							displayName: PV.STRINGS.colHeads.max[0],
+							xField: "max",
+							style: {color:"29c7de", size:9},
+							group: ["avg", "min", "max"]
+						},
+						pct: {
+							displayName: PV.STRINGS.colHeads.pct[0],
+							xField: "pct",
+							style: {color:"C96EDB", size:20},
+							group: ["pct"]
+						}
+				},
+			method: function() {
+					if(this._rendered && this.get("showChart")) {
+						this._refreshChart();
+					}
+				}
+        });
+		
+        /**
+         * The default visibility setting for the viewer canvas. If true,
+		 * the viewer will load all necessary files and render itself
+		 * immediately upon instantiation; otherwise, the viewer will
+		 * load only minimal resources until the user toggles visibility
+		 * via the UI.
+         * @attribute visible
+         * @type boolean
+		 * @default false
+         */
+        this.setAttributeConfig('visible', {
+            value: attr.visible || false,
+			validator: YAHOO.lang.isBoolean,
+			method: function(b) {
+				if(b) {
+					this._show();
+				} else {
+					if (this._rendered) {
+						this._hide();
+					}
+				}
+			}
+        });
+
+        /**
+         * The default visibility setting for the chart.
+         * @attribute showChart
+         * @type boolean
+		 * @default true
+         */
+        this.setAttributeConfig('showChart', {
+            value: attr.showChart || true,
+			validator: YAHOO.lang.isBoolean,
+			writeOnce: true
+			
+        });
+		
+		YAHOO.widget.ProfilerViewer.superclass.initAttributes.call(this, attr);
+		
+		YAHOO.log("Attributes initialized.", "info", "ProfilerViewer");
+    };
+	
+})();
+YAHOO.register("profilerviewer", YAHOO.widget.ProfilerViewer, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/profilerviewer/profilerviewer-beta-min.js
===================================================================
--- trunk/root/static/yui/profilerviewer/profilerviewer-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/profilerviewer/profilerviewer-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,9 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+(function(){YAHOO.widget.ProfilerViewer=function(H,G){G=G||{};if(arguments.length==1&&!YAHOO.lang.isString(H)&&!H.nodeName){G=H;H=G.element||null;}if(!H&&!G.element){H=this._createProfilerViewerElement();}YAHOO.widget.ProfilerViewer.superclass.constructor.call(this,H,G);this._init();};YAHOO.extend(YAHOO.widget.ProfilerViewer,YAHOO.util.Element);YAHOO.lang.augmentObject(YAHOO.widget.ProfilerViewer,{CLASS:"yui-pv",CLASS_DASHBOARD:"yui-pv-dashboard",CLASS_REFRESH:"yui-pv-refresh",CLASS_BUSY:"yui-pv-busy",CLASS_CHART_CONTAINER:"yui-pv-chartcontainer",CLASS_CHART:"yui-pv-chart",CLASS_CHART_LEGEND:"yui-pv-chartlegend",CLASS_TABLE:"yui-pv-table",STRINGS:{title:"YUI Profiler (beta)",buttons:{viewprofiler:"View Profiler Data",hideprofiler:"Hide Profiler Report",showchart:"Show Chart",hidechart:"Hide Chart",refreshdata:"Refresh Data"},colHeads:{fn:["Function/Method",null],calls:["Calls",40],avg:["Average",80],min:["Shortest",70],max:["Longest",70],total:["Total Time",70],pct:["Percen!
 t",70]},millisecondsAbbrev:"ms",initMessage:"initialiazing chart...",installFlashMessage:"Unable to load Flash content. The YUI Charts Control requires Flash Player 9.0.45 or higher. You can download the latest version of Flash Player from the <a href='http://www.adobe.com/go/getflashplayer'>Adobe Flash Player Download Center</a>."},timeAxisLabelFunction:function(H){var G=(H===Math.floor(H))?H:(Math.round(H*1000))/1000;return(G+" "+YAHOO.widget.ProfilerViewer.STRINGS.millisecondsAbbrev);},percentAxisLabelFunction:function(H){var G=(H===Math.floor(H))?H:(Math.round(H*100))/100;return(G+"%");}},true);var C=YAHOO.util.Dom;var A=YAHOO.util.Event;var B=YAHOO.tool.Profiler;var E=YAHOO.widget.ProfilerViewer;var D=E.prototype;D.refreshData=function(){this.fireEvent("dataRefreshEvent");};D.getHeadEl=function(){return(this._headEl)?C.get(this._headEl):false;};D.getBodyEl=function(){return(this._bodyEl)?C.get(this._bodyEl):false;};D.getChartEl=function(){return(this._chartEl)?C.get(th!
 is._chartEl):false;};D.getTableEl=function(){return(this._tabl!
 eEl)?C.g
et(this._tableEl):false;};D.getDataTable=function(){return this._dataTable;};D.getChart=function(){return this._chart;};D._rendered=false;D._headEl=null;D._bodyEl=null;D._toggleVisibleEl=null;D._busyEl=null;D._busy=false;D._tableEl=null;D._dataTable=null;D._chartEl=null;D._chartLegendEl=null;D._chartElHeight=250;D._chart=null;D._chartInitialized=false;D._init=function(){this.createEvent("dataRefreshEvent");this.createEvent("renderEvent");this.on("dataRefreshEvent",this._refreshDataTable,this,true);this._initLauncherDOM();if(this.get("showChart")){this.on("sortedByChange",this._refreshChart);}};D._createProfilerViewerElement=function(){var G=document.createElement("div");document.body.insertBefore(G,document.body.firstChild);C.addClass(G,this.SKIN_CLASS);C.addClass(G,E.CLASS);return G;};D.toString=function(){return"ProfilerViewer "+(this.get("id")||this.get("tagName"));};D._toggleVisible=function(){var G=(this.get("visible"))?false:true;this.set("visible",G);};D._show=functio!
 n(){if(!this._busy){this._setBusyState(true);if(!this._rendered){var G=new YAHOO.util.YUILoader();if(this.get("base")){G.base=this.get("base");}var H=["datatable"];if(this.get("showChart")){H.push("charts");}G.insert({require:H,onSuccess:function(){this._render();},scope:this});}else{var I=this.get("element");C.removeClass(I,"yui-pv-minimized");this._toggleVisibleEl.innerHTML=E.STRINGS.buttons.hideprofiler;C.addClass(I,"yui-pv-null");C.removeClass(I,"yui-pv-null");this.refreshData();}}};D._hide=function(){this._toggleVisibleEl.innerHTML=E.STRINGS.buttons.viewprofiler;C.addClass(this.get("element"),"yui-pv-minimized");};D._render=function(){C.removeClass(this.get("element"),"yui-pv-minimized");this._initViewerDOM();this._initDataTable();if(this.get("showChart")){this._initChartDOM();this._initChart();}this._rendered=true;this._toggleVisibleEl.innerHTML=E.STRINGS.buttons.hideprofiler;this.fireEvent("renderEvent");};D._initLauncherDOM=function(){var I=this.get("element");C.add!
 Class(I,E.CLASS);C.addClass(I,"yui-pv-minimized");this._headEl!
 =documen
t.createElement("div");C.addClass(this._headEl,"hd");var H=E.STRINGS.buttons;var G=(this.get("visible"))?H.hideprofiler:H.viewprofiler;this._toggleVisibleEl=this._createButton(G,this._headEl);this._refreshEl=this._createButton(H.refreshdata,this._headEl);C.addClass(this._refreshEl,E.CLASS_REFRESH);this._busyEl=document.createElement("span");this._headEl.appendChild(this._busyEl);var J=document.createElement("h4");J.innerHTML=E.STRINGS.title;this._headEl.appendChild(J);I.appendChild(this._headEl);A.on(this._toggleVisibleEl,"click",this._toggleVisible,this,true);A.on(this._refreshEl,"click",function(){if(!this._busy){this._setBusyState(true);this.fireEvent("dataRefreshEvent");}},this,true);};D._initViewerDOM=function(){var G=this.get("element");this._bodyEl=document.createElement("div");C.addClass(this._bodyEl,"bd");this._tableEl=document.createElement("div");C.addClass(this._tableEl,E.CLASS_TABLE);this._bodyEl.appendChild(this._tableEl);G.appendChild(this._bodyEl);};D._initCh!
 artDOM=function(){this._chartContainer=document.createElement("div");C.addClass(this._chartContainer,E.CLASS_CHART_CONTAINER);var H=document.createElement("div");C.addClass(H,E.CLASS_CHART_LEGEND);var G=document.createElement("div");this._chartLegendEl=document.createElement("dl");this._chartLegendEl.innerHTML="<dd>"+E.STRINGS.initMessage+"</dd>";this._chartEl=document.createElement("div");C.addClass(this._chartEl,E.CLASS_CHART);var I=document.createElement("p");I.innerHTML=E.STRINGS.installFlashMessage;this._chartEl.appendChild(I);this._chartContainer.appendChild(H);H.appendChild(G);G.appendChild(this._chartLegendEl);this._chartContainer.appendChild(this._chartEl);this._bodyEl.insertBefore(this._chartContainer,this._tableEl);};D._createButton=function(I,J,H){var G=document.createElement("a");G.innerHTML=G.title=I;if(J){if(!H){J.appendChild(G);}else{J.insertBefore(G,J.firstChild);}}return G;};D._setBusyState=function(G){if(G){C.addClass(this._busyEl,E.CLASS_BUSY);
+this._busy=true;}else{C.removeClass(this._busyEl,E.CLASS_BUSY);this._busy=false;}};D._genSortFunction=function(H,G){var J=H;var I=G;return function(L,K){if(I==YAHOO.widget.DataTable.CLASS_ASC){return L[J]-K[J];}else{return((L[J]-K[J])*-1);}};};var F=function(G){var I=0;for(var H=0;H<G.length;I+=G[H++]){}return I;};D._getProfilerData=function(){var L=B.getFullReport();var N=[];var H=0;for(name in L){if(YAHOO.lang.hasOwnProperty(L,name)){var G=L[name];var I={};I.fn=name;I.points=G.points.slice();I.calls=G.calls;I.min=G.min;I.max=G.max;I.avg=G.avg;I.total=F(I.points);I.points=G.points;var P=this.get("filter");if((!P)||(P(I))){N.push(I);H+=I.total;}}}for(var M=0,K=N.length;M<K;M++){N[M].pct=(H)?(N[M].total*100)/H:0;}var O=this.get("sortedBy");var Q=O.key;var J=O.dir;N.sort(this._genSortFunction(Q,J));return N;};D._initDataTable=function(){var P=this;this._dataSource=new YAHOO.util.DataSource(function(){return P._getProfilerData.call(P);},{responseType:YAHOO.util.DataSource.TYPE!
 _JSARRAY,maxCacheEntries:0});var H=this._dataSource;H.responseSchema={fields:["fn","avg","calls","max","min","total","pct","points"]};var O=function(S,R,T,U){var Q=(U===Math.floor(U))?U:(Math.round(U*1000))/1000;S.innerHTML=Q+" "+E.STRINGS.millisecondsAbbrev;};var N=function(S,R,T,U){var Q=(U===Math.floor(U))?U:(Math.round(U*100))/100;S.innerHTML=Q+"%";};var M=YAHOO.widget.DataTable.CLASS_ASC;var J=YAHOO.widget.DataTable.CLASS_DESC;var K=E.STRINGS.colHeads;var I=O;var L=[{key:"fn",sortable:true,label:K.fn[0],sortOptions:{defaultDir:M},resizeable:(YAHOO.util.DragDrop)?true:false,minWidth:K.fn[1]},{key:"calls",sortable:true,label:K.calls[0],sortOptions:{defaultDir:J},width:K.calls[1]},{key:"avg",sortable:true,label:K.avg[0],sortOptions:{defaultDir:J},formatter:I,width:K.avg[1]},{key:"min",sortable:true,label:K.min[0],sortOptions:{defaultDir:M},formatter:I,width:K.min[1]},{key:"max",sortable:true,label:K.max[0],sortOptions:{defaultDir:J},formatter:I,width:K.max[1]},{key:"total!
 ",sortable:true,label:K.total[0],sortOptions:{defaultDir:J},fo!
 rmatter:
I,width:K.total[1]},{key:"pct",sortable:true,label:K.pct[0],sortOptions:{defaultDir:J},formatter:N,width:K.pct[1]}];this._dataTable=new YAHOO.widget.DataTable(this._tableEl,L,H,{scrollable:true,height:this.get("tableHeight"),initialRequest:null,sortedBy:{key:"total",dir:YAHOO.widget.DataTable.CLASS_DESC}});var G=this._dataTable;G.subscribe("sortedByChange",this._sortedByChange,this,true);G.subscribe("renderEvent",this._dataTableRenderHandler,this,true);G.subscribe("initEvent",this._dataTableRenderHandler,this,true);A.on(this._tableEl.getElementsByTagName("th"),"click",this._thClickHandler,this,true);};D._sortedByChange=function(G){this.set("sortedBy",{key:G.newValue.key,dir:G.newValue.dir});};D._dataTableRenderHandler=function(G){this._setBusyState(false);};D._thClickHandler=function(G){this._setBusyState(true);};D._refreshDataTable=function(G){var H=this._dataTable;H.getDataSource().sendRequest("",H.onDataReturnInitializeTable,H);};D._refreshChart=function(){switch(this.get!
 ("sortedBy").key){case"fn":this._chart.set("dataSource",this._chart.get("dataSource"));return ;case"calls":this._chart.set("xAxis",this._chartAxisDefinitionPlain);break;case"pct":this._chart.set("xAxis",this._chartAxisDefinitionPercent);break;default:this._chart.set("xAxis",this._chartAxisDefinitionTime);break;}this._drawChartLegend();this._chart.set("series",this._getSeriesDef(this.get("sortedBy").key));};D._getChartData=function(){var H=this._dataTable.getRecordSet().getRecords(0,this.get("maxChartFunctions"));var G=[];for(var I=H.length-1;I>-1;I--){G.push(H[I].getData());}return G;};D._getSeriesDef=function(K){var J=this.get("chartSeriesDefinitions")[K];var G=[];for(var I=0,H=J.group.length;I<H;I++){var L=this.get("chartSeriesDefinitions")[J.group[I]];G.push({displayName:L.displayName,xField:L.xField,style:{color:L.style.color,size:L.style.size}});}return G;};D._initChart=function(){this._sizeChartCanvas();YAHOO.widget.Chart.SWFURL=this.get("swfUrl");var G=this;var H=new!
  YAHOO.util.DataSource(function(){return G._getChartData.call(!
 G);},{re
sponseType:YAHOO.util.DataSource.TYPE_JSARRAY,maxCacheEntries:0});H.responseSchema={fields:["fn","avg","calls","max","min","total","pct"]};H.subscribe("responseEvent",this._sizeChartCanvas,this,true);this._chartAxisDefinitionTime=new YAHOO.widget.NumericAxis();this._chartAxisDefinitionTime.labelFunction="YAHOO.widget.ProfilerViewer.timeAxisLabelFunction";this._chartAxisDefinitionPercent=new YAHOO.widget.NumericAxis();this._chartAxisDefinitionPercent.labelFunction="YAHOO.widget.ProfilerViewer.percentAxisLabelFunction";this._chartAxisDefinitionPlain=new YAHOO.widget.NumericAxis();this._chart=new YAHOO.widget.BarChart(this._chartEl,H,{yField:"fn",series:this._getSeriesDef(this.get("sortedBy").key),style:this.get("chartStyle"),xAxis:this._chartAxisDefinitionTime});this._drawChartLegend();this._chartInitialized=true;this._dataTable.unsubscribe("initEvent",this._initChart,this);this._dataTable.subscribe("initEvent",this._refreshChart,this,true);};D._drawChartLegend=function(){var !
 M=this.get("chartSeriesDefinitions");var I=M[this.get("sortedBy").key];var H=this._chartLegendEl;H.innerHTML="";for(var K=0,J=I.group.length;K<J;K++){var N=M[I.group[K]];var L=document.createElement("dt");C.setStyle(L,"backgroundColor","#"+N.style.color);var G=document.createElement("dd");G.innerHTML=N.displayName;H.appendChild(L);H.appendChild(G);}};D._sizeChartCanvas=function(I){var G=(I)?I.response.length:this.get("maxChartFunctions");var H=(G*36)+34;if(H!=parseInt(this._chartElHeight,10)){this._chartElHeight=H;C.setStyle(this._chartEl,"height",H+"px");}};D.initAttributes=function(G){YAHOO.widget.ProfilerViewer.superclass.initAttributes.call(this,G);this.setAttributeConfig("base",{value:G.base});this.setAttributeConfig("tableHeight",{value:G.tableHeight||"15em",method:function(H){if(this._dataTable){this._dataTable.set("height",H);}}});this.setAttributeConfig("sortedBy",{value:G.sortedBy||{key:"total",dir:"yui-dt-desc"}});
+this.setAttributeConfig("filter",{value:G.filter||null,validator:YAHOO.lang.isFunction});this.setAttributeConfig("swfUrl",{value:G.swfUrl||"http://yui.yahooapis.com/2.5.0/build/charts/assets/charts.swf"});this.setAttributeConfig("maxChartFunctions",{value:G.maxChartFunctions||6,method:function(H){if(this._rendered){this._sizeChartCanvas();}},validator:YAHOO.lang.isNumber});this.setAttributeConfig("chartStyle",{value:G.chartStyle||{font:{name:"Arial",color:15658588,size:12},background:{color:"6e6e63"}},method:function(){if(this._rendered&&this.get("showChart")){this._refreshChart();}}});this.setAttributeConfig("chartSeriesDefinitions",{value:G.chartSeriesDefinitions||{total:{displayName:E.STRINGS.colHeads.total[0],xField:"total",style:{color:"4d95dd",size:20},group:["total"]},calls:{displayName:E.STRINGS.colHeads.calls[0],xField:"calls",style:{color:"edff9f",size:20},group:["calls"]},avg:{displayName:E.STRINGS.colHeads.avg[0],xField:"avg",style:{color:"209daf",size:9},group:!
 ["avg","min","max"]},min:{displayName:E.STRINGS.colHeads.min[0],xField:"min",style:{color:"b6ecf4",size:9},group:["avg","min","max"]},max:{displayName:E.STRINGS.colHeads.max[0],xField:"max",style:{color:"29c7de",size:9},group:["avg","min","max"]},pct:{displayName:E.STRINGS.colHeads.pct[0],xField:"pct",style:{color:"C96EDB",size:20},group:["pct"]}},method:function(){if(this._rendered&&this.get("showChart")){this._refreshChart();}}});this.setAttributeConfig("visible",{value:G.visible||false,validator:YAHOO.lang.isBoolean,method:function(H){if(H){this._show();}else{if(this._rendered){this._hide();}}}});this.setAttributeConfig("showChart",{value:G.showChart||true,validator:YAHOO.lang.isBoolean,writeOnce:true});YAHOO.widget.ProfilerViewer.superclass.initAttributes.call(this,G);};})();YAHOO.register("profilerviewer",YAHOO.widget.ProfilerViewer,{version:"2.5.1",build:"984"});
\ No newline at end of file

Added: trunk/root/static/yui/profilerviewer/profilerviewer-beta.js
===================================================================
--- trunk/root/static/yui/profilerviewer/profilerviewer-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/profilerviewer/profilerviewer-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,1190 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+(function() {
+
+    /**
+     * The ProfilerViewer module provides a graphical display for viewing
+	 * the output of the YUI Profiler <http://developer.yahoo.com/yui/profiler>.
+     * @module profilerviewer
+     * @requires yahoo, dom, event, element, profiler, yuiloader
+     */
+
+    /**
+     * A widget to view YUI Profiler output.
+     * @namespace YAHOO.widget
+     * @class ProfilerViewer
+     * @extends YAHOO.util.Element
+     * @constructor
+     * @param {HTMLElement | String | Object} el(optional) The html 
+     * element into which the ProfileViewer should be rendered. 
+     * An element will be created if none provided.
+     * @param {Object} attr (optional) A key map of the ProfilerViewer's 
+     * initial attributes.  Ignored if first arg is an attributes object.
+     */
+    YAHOO.widget.ProfilerViewer = function(el, attr) {
+        attr = attr || {};
+        if (arguments.length == 1 && !YAHOO.lang.isString(el) && !el.nodeName) {
+            attr = el;
+            el = attr.element || null;
+        }
+        if (!el && !attr.element) {
+            el = this._createProfilerViewerElement();
+        }
+
+    	YAHOO.widget.ProfilerViewer.superclass.constructor.call(this, el, attr); 
+		
+		this._init();
+		
+    };
+
+    YAHOO.extend(YAHOO.widget.ProfilerViewer, YAHOO.util.Element);
+	
+	// Static members of YAHOO.widget.ProfilerViewer:
+	YAHOO.lang.augmentObject(YAHOO.widget.ProfilerViewer, {
+		/**
+		 * Classname for ProfilerViewer containing element.
+		 * @static
+		 * @property CLASS
+		 * @type string
+		 * @public
+		 * @default "yui-pv"
+		 */
+		CLASS: 'yui-pv',
+	
+		/**
+		 * Classname for ProfilerViewer button dashboard. 
+		 * @static
+		 * @property CLASS_DASHBOARD
+		 * @type string
+		 * @public
+		 * @default "yui-pv-dashboard"
+		 */
+		CLASS_DASHBOARD: 'yui-pv-dashboard',
+
+		/**
+		 * Classname for the "refresh data" button. 
+		 * @static
+		 * @property CLASS_REFRESH
+		 * @type string
+		 * @public
+		 * @default "yui-pv-refresh"
+		 */
+		CLASS_REFRESH: 'yui-pv-refresh',
+
+		/**
+		 * Classname for busy indicator in the dashboard. 
+		 * @static
+		 * @property CLASS_BUSY
+		 * @type string
+		 * @public
+		 * @default "yui-pv-busy"
+		 */
+		CLASS_BUSY: 'yui-pv-busy',
+	
+		/**
+		 * Classname for element containing the chart and chart
+		 * legend elements.
+		 * @static
+		 * @property CLASS_CHART_CONTAINER
+		 * @type string
+		 * @public
+		 * @default "yui-pv-chartcontainer"
+		 */
+		CLASS_CHART_CONTAINER: 'yui-pv-chartcontainer',
+	
+		/**
+		 * Classname for element containing the chart.
+		 * @static
+		 * @property CLASS_CHART
+		 * @type string
+		 * @public
+		 * @default "yui-pv-chart"
+		 */
+		CLASS_CHART: 'yui-pv-chart',
+		
+		/**
+		 * Classname for element containing the chart's legend. 
+		 * @static
+		 * @property CLASS_CHART_LEGEND
+		 * @type string
+		 * @public
+		 * @default "yui-pv-chartlegend"
+		 */
+		CLASS_CHART_LEGEND: 'yui-pv-chartlegend',
+		
+		/**
+		 * Classname for element containing the datatable. 
+		 * @static
+		 * @property CLASS_TABLE
+		 * @type string
+		 * @public
+		 * @default "yui-pv-table"
+		 */
+		CLASS_TABLE: 'yui-pv-table',
+		
+		/**
+		 * Strings used in the UI.
+		 * @static
+		 * @property STRINGS
+		 * @object
+		 * @public
+		 * @default English language strings for UI.
+		 */
+		STRINGS: {
+			title: "YUI Profiler (beta)",
+			buttons: {
+				viewprofiler: "View Profiler Data",
+				hideprofiler: "Hide Profiler Report",
+				showchart: "Show Chart",
+				hidechart: "Hide Chart",
+				refreshdata: "Refresh Data"
+			},
+			colHeads: {
+				//key: [column head label, width in pixels]
+				fn: ["Function/Method", null], //must auto-size
+				calls: ["Calls", 40],
+				avg: ["Average", 80],
+				min: ["Shortest", 70],
+				max: ["Longest", 70],
+				total: ["Total Time", 70],
+				pct: ["Percent", 70]
+			},
+			millisecondsAbbrev: "ms",
+			initMessage: "initialiazing chart...",
+			installFlashMessage: "Unable to load Flash content. The YUI Charts Control requires Flash Player 9.0.45 or higher. You can download the latest version of Flash Player from the <a href='http://www.adobe.com/go/getflashplayer'>Adobe Flash Player Download Center</a>."
+		},
+
+		/**
+		 * Function used to format numbers in milliseconds
+		 * for chart; must be publicly accessible, per Charts spec.
+		 * @static
+		 * @property timeAxisLabelFunction
+		 * @type function
+		 * @private
+		 */
+		timeAxisLabelFunction: function(n) {
+			var a = (n === Math.floor(n)) ? n : (Math.round(n*1000))/1000;
+			return (a + " " + YAHOO.widget.ProfilerViewer.STRINGS.millisecondsAbbrev);
+		},
+
+		/**
+		 * Function used to format percent numbers for chart; must
+		 * be publicly accessible, per Charts spec.
+		 * @static
+		 * @property percentAxisLabelFunction
+		 * @type function
+		 * @private
+		 */
+		percentAxisLabelFunction: function(n) {
+			var a = (n === Math.floor(n)) ? n : (Math.round(n*100))/100;
+			return (a + "%");
+		}
+		
+	
+	},true);
+	
+
+	//
+	// STANDARD SHORTCUTS
+	//
+    var Dom = YAHOO.util.Dom;
+    var Event = YAHOO.util.Event;
+	var Profiler = YAHOO.tool.Profiler;
+	var PV = YAHOO.widget.ProfilerViewer;
+	var proto = PV.prototype;
+
+
+	//
+	// PUBLIC METHODS
+	//
+	
+	 /**
+     * Refreshes the data displayed in the ProfilerViewer. When called,
+	 * this will invoke a refresh of the DataTable and (if displayed)
+	 * the Chart.
+     * @method refreshData
+     * @return void
+	 * @public
+     */	
+	proto.refreshData = function() {
+		this.fireEvent("dataRefreshEvent");
+	};
+
+	 /**
+     * Returns the element containing the console's header.
+     * @method getHeadEl
+     * @return HTMLElement
+	 * @public
+     */	
+	proto.getHeadEl = function() {
+		return (this._headEl) ? Dom.get(this._headEl) : false;
+	};
+
+	 /**
+     * Returns the element containing the console's body, including
+	 * the chart and the datatable..
+     * @method getBodyEl
+     * @return HTMLElement
+	 * @public
+     */	
+	proto.getBodyEl = function() {
+		return (this._bodyEl) ? Dom.get(this._bodyEl) : false;
+	};
+
+	 /**
+     * Returns the element containing the console's chart.
+     * @method getChartEl
+     * @return HTMLElement
+	 * @public
+     */	
+	proto.getChartEl = function() {
+		return (this._chartEl) ? Dom.get(this._chartEl) : false;
+	};
+
+	 /**
+     * Returns the element containing the console's dataTable.
+     * @method getTableEl
+     * @return HTMLElement
+	 * @public
+     */	
+	proto.getTableEl = function() {
+		return (this._tableEl) ? Dom.get(this._tableEl) : false;
+	};
+
+	 /**
+     * Returns the element containing the console's DataTable
+	 * instance.
+     * @method getDataTable
+     * @return YAHOO.widget.DataTable
+	 * @public
+     */	
+	proto.getDataTable = function() {
+		return this._dataTable;
+	};
+
+	 /**
+     * Returns the element containing the console's Chart instance.
+     * @method getChart
+     * @return YAHOO.widget.BarChart
+	 * @public
+     */	
+	proto.getChart = function() {
+		return this._chart;
+	};
+
+
+    //
+    // PRIVATE PROPERTIES
+    //
+    proto._rendered = false;
+	proto._headEl = null;
+	proto._bodyEl = null;
+	proto._toggleVisibleEl = null;
+	proto._busyEl = null;
+	proto._busy = false;
+	
+	proto._tableEl = null;
+	proto._dataTable = null;
+
+	proto._chartEl = null;
+	proto._chartLegendEl = null;
+	proto._chartElHeight = 250;
+	proto._chart = null;
+	proto._chartInitialized = false;
+
+    //
+    // PRIVATE METHODS
+    //
+
+	proto._init = function() {
+		/**
+		 * CUSTOM EVENTS
+		 **/
+		
+		/**
+		 * Fired when a data refresh is requested. No arguments are passed
+		 * with this event.
+		 *
+		 * @event refreshDataEvent
+		 */
+		this.createEvent("dataRefreshEvent");
+		
+		/**
+		 * Fired when the viewer canvas first renders. No arguments are passed
+		 * with this event.
+		 *
+		 * @event renderEvent
+		 */
+		this.createEvent("renderEvent");
+
+		this.on("dataRefreshEvent", this._refreshDataTable, this, true);
+		
+		this._initLauncherDOM();
+		
+		if(this.get("showChart")) {
+			this.on("sortedByChange", this._refreshChart);
+		}
+
+	};
+
+	/**
+	 * If no element is passed in, create it as the first element
+	 * in the document.
+	 * @method _createProfilerViewerElement
+	 * @return HTMLElement
+	 * @private
+	 */
+	proto._createProfilerViewerElement = function() {
+
+		var el = document.createElement("div");
+		document.body.insertBefore(el, document.body.firstChild);
+		Dom.addClass(el, this.SKIN_CLASS);
+		Dom.addClass(el, PV.CLASS);
+		return el;
+	};
+			
+    /**
+     * Provides a readable name for the ProfilerViewer instance.
+     * @method toString
+     * @return String
+	 * @private
+	 */
+    proto.toString = function() {
+        return "ProfilerViewer " + (this.get('id') || this.get('tagName'));
+    };
+
+    /**
+     * Toggles visibility of the viewer canvas.
+     * @method _toggleVisible
+     * @return void
+	 * @private
+     */	
+	proto._toggleVisible = function() {
+		
+		var newVis = (this.get("visible")) ? false : true;
+		this.set("visible", newVis);
+    };
+
+    /**
+     * Shows the viewer canvas.
+     * @method show
+     * @return void
+	 * @private
+     */	
+	 proto._show = function() {
+	 	if(!this._busy) {
+			this._setBusyState(true);
+			if(!this._rendered) {
+				var loader = new YAHOO.util.YUILoader();
+				if (this.get("base")) {
+					loader.base = this.get("base");
+				}
+				
+				var modules = ["datatable"];
+				if(this.get("showChart")) {
+					modules.push("charts");
+				}
+				
+				loader.insert({ require: modules,
+								onSuccess: function() {
+									this._render();
+								},
+								scope: this});
+			} else {
+				var el = this.get("element");
+				Dom.removeClass(el, "yui-pv-minimized");
+				this._toggleVisibleEl.innerHTML = PV.STRINGS.buttons.hideprofiler;
+				
+				//The Flash Charts component can't be set to display:none,
+				//and even after positioning it offscreen the screen
+				//may fail to repaint in some browsers.  Adding an empty
+				//style rule to the console body can help force a repaint:
+				Dom.addClass(el, "yui-pv-null");
+				Dom.removeClass(el, "yui-pv-null");
+				
+				//Always refresh data when changing to visible:
+				this.refreshData();
+			}
+		}
+    };
+
+    /**
+     * Hides the viewer canvas.
+     * @method hide
+     * @return void
+	 * @private
+     */	
+	proto._hide = function() {
+		this._toggleVisibleEl.innerHTML = PV.STRINGS.buttons.viewprofiler;
+		Dom.addClass(this.get("element"), "yui-pv-minimized");
+    };
+	
+	/**
+	 * Render the viewer canvas
+	 * @method _render
+	 * @return void
+	 * @private
+	 */
+	proto._render = function() {
+		
+		Dom.removeClass(this.get("element"), "yui-pv-minimized");
+		
+		this._initViewerDOM();
+		this._initDataTable();
+		if(this.get("showChart")) {
+			this._initChartDOM();
+			this._initChart();
+		}
+		this._rendered = true;
+		this._toggleVisibleEl.innerHTML = PV.STRINGS.buttons.hideprofiler;
+		
+		this.fireEvent("renderEvent");
+
+	};
+	
+	/**
+	 * Set up the DOM structure for the ProfilerViewer launcher.
+	 * @method _initLauncherDOM
+	 * @private
+	 */
+	proto._initLauncherDOM = function() {
+		
+		var el = this.get("element");
+		Dom.addClass(el, PV.CLASS);
+		Dom.addClass(el, "yui-pv-minimized");
+
+		this._headEl = document.createElement("div");
+		Dom.addClass(this._headEl, "hd");
+		
+		var s = PV.STRINGS.buttons;
+		var b = (this.get("visible")) ? s.hideprofiler : s.viewprofiler;
+		
+		this._toggleVisibleEl = this._createButton(b, this._headEl);
+		
+		this._refreshEl = this._createButton(s.refreshdata, this._headEl);
+		Dom.addClass(this._refreshEl, PV.CLASS_REFRESH);
+		
+		this._busyEl = document.createElement("span");
+		this._headEl.appendChild(this._busyEl);
+
+		var title = document.createElement("h4");
+		title.innerHTML = PV.STRINGS.title;
+		this._headEl.appendChild(title);
+		
+		el.appendChild(this._headEl);
+		
+		Event.on(this._toggleVisibleEl, "click", this._toggleVisible, this, true);
+		Event.on(this._refreshEl, "click", function() {
+			if(!this._busy) {
+				this._setBusyState(true);
+				this.fireEvent("dataRefreshEvent");
+			}
+		}, this, true);
+	};
+
+	/**
+	 * Set up the DOM structure for the ProfilerViewer canvas,
+	 * including the holder for the DataTable.
+	 * @method _initViewerDOM
+	 * @private
+	 */
+	proto._initViewerDOM = function() {
+		
+		var el = this.get("element");
+		this._bodyEl = document.createElement("div");
+		Dom.addClass(this._bodyEl, "bd");
+	 	this._tableEl = document.createElement("div");
+		Dom.addClass(this._tableEl, PV.CLASS_TABLE);
+		this._bodyEl.appendChild(this._tableEl);
+		el.appendChild(this._bodyEl);
+	};
+
+	/**
+	 * Set up the DOM structure for the ProfilerViewer canvas.
+	 * @method _initChartDOM
+	 * @private
+	 */
+	proto._initChartDOM = function() {
+		
+		this._chartContainer = document.createElement("div");
+		Dom.addClass(this._chartContainer, PV.CLASS_CHART_CONTAINER);
+		
+		var chl = document.createElement("div");
+		Dom.addClass(chl, PV.CLASS_CHART_LEGEND);
+		
+		var chw = document.createElement("div");
+
+		this._chartLegendEl = document.createElement("dl");
+		this._chartLegendEl.innerHTML = "<dd>" + PV.STRINGS.initMessage + "</dd>";
+		
+		this._chartEl = document.createElement("div");
+		Dom.addClass(this._chartEl, PV.CLASS_CHART);
+		
+		var msg = document.createElement("p");
+		msg.innerHTML = PV.STRINGS.installFlashMessage;
+		this._chartEl.appendChild(msg);
+		
+		this._chartContainer.appendChild(chl);
+		chl.appendChild(chw);
+		chw.appendChild(this._chartLegendEl);
+		this._chartContainer.appendChild(this._chartEl);
+		this._bodyEl.insertBefore(this._chartContainer,this._tableEl);
+	};
+
+
+	/**
+	 * Create anchor elements for use as buttons. Args: label
+	 * is text to appear on the face of the button, parentEl
+	 * is the el to which the anchor will be attached, position
+	 * is true for inserting as the first node and false for
+	 * inserting as the last node of the parentEl.
+	 * @method _createButton
+	 * @private
+	 */	
+	proto._createButton = function(label, parentEl, position) {
+		var b = document.createElement("a");
+		b.innerHTML = b.title = label;
+		if(parentEl) {
+			if(!position) {
+				parentEl.appendChild(b);
+			} else {
+				parentEl.insertBefore(b, parentEl.firstChild);	
+			}
+		}
+		return b;
+	};
+	
+	/**
+	 * Set's console busy state.
+	 * @method _setBusyState
+	 * @private
+	 **/
+	proto._setBusyState = function(b) {
+		if(b) {
+			Dom.addClass(this._busyEl, PV.CLASS_BUSY);
+			this._busy = true;
+		} else {
+			Dom.removeClass(this._busyEl, PV.CLASS_BUSY);
+			this._busy = false;
+		}
+	};
+
+	/**
+	 * Generages a sorting function based on current sortedBy
+	 * values.
+	 * @method _createProfilerViewerElement
+	 * @private
+	 **/
+	proto._genSortFunction = function(key, dir) {
+		var by = key;
+		var direction = dir;
+		return function(a, b) {
+			if (direction == YAHOO.widget.DataTable.CLASS_ASC) {
+				return a[by] - b[by];	
+			} else {
+				return ((a[by] - b[by]) * -1);
+			}
+		};
+	};
+
+	/**
+	 * Utility function for array sums.
+	 * @method _arraySum
+	 * @private
+	 **/	
+	 var _arraySum = function(arr){
+		var ct = 0;
+		for(var i = 0; i < arr.length; ct+=arr[i++]){}
+		return ct;
+	};
+	
+	/**
+	 * Retrieves data from Profiler, filtering and sorting as needed
+	 * based on current widget state.  Adds calculated percentage
+	 * column and function name to data returned by Profiler.
+	 * @method _getProfilerData
+	 * @private
+	 **/
+	proto._getProfilerData = function() {
+		
+		var obj = Profiler.getFullReport();
+		var arr = [];
+		var totalTime = 0;
+		for (name in obj) {
+    		if (YAHOO.lang.hasOwnProperty(obj, name)) {
+				var r = obj[name];
+				var o = {};
+				o.fn = name; //add function name to record
+				o.points = r.points.slice(); //copy live array
+				o.calls = r.calls;
+				o.min = r.min;
+				o.max = r.max;
+				o.avg = r.avg;
+				o.total = _arraySum(o.points);
+				o.points = r.points;
+				var f = this.get("filter");
+				if((!f) || (f(o))) {
+					arr.push(o);
+					totalTime += o.total;
+				}
+			}
+		}
+		
+		//add calculated percentage column
+		for (var i = 0, j = arr.length; i < j; i++) {
+			arr[i].pct = (totalTime) ? (arr[i].total * 100) / totalTime : 0;	
+		}
+
+		var sortedBy = this.get("sortedBy");
+		var key = sortedBy.key;
+		var dir = sortedBy.dir;		
+
+		arr.sort(this._genSortFunction(key, dir));
+		
+		
+		return arr;
+	};
+	
+	/**
+	 * Set up the DataTable.
+	 * @method _initDataTable
+	 * @private
+	 */
+	proto._initDataTable = function() {
+		
+		var self = this;
+		
+		//Set up the JS Function DataSource, pulling data from
+		//the Profiler.
+		this._dataSource = new YAHOO.util.DataSource(
+			function() {
+				return self._getProfilerData.call(self);	
+			},
+			{
+				responseType: YAHOO.util.DataSource.TYPE_JSARRAY,
+				maxCacheEntries: 0
+			}
+		);
+		var ds = this._dataSource;
+
+		ds.responseSchema =
+		{
+			fields: [ "fn", "avg", "calls", "max", "min", "total", "pct", "points"]
+		};
+		
+		//Set up the DataTable.
+		var formatTimeValue = function(elCell, oRecord, oColumn, oData) {
+			var a = (oData === Math.floor(oData)) ? oData : (Math.round(oData*1000))/1000;
+			elCell.innerHTML = a + " " + PV.STRINGS.millisecondsAbbrev;
+		};
+
+		var formatPercent = function(elCell, oRecord, oColumn, oData) {
+			var a = (oData === Math.floor(oData)) ? oData : (Math.round(oData*100))/100;
+			elCell.innerHTML = a + "%";
+		};
+		
+		var a = YAHOO.widget.DataTable.CLASS_ASC;
+		var d = YAHOO.widget.DataTable.CLASS_DESC;
+		var c = PV.STRINGS.colHeads;
+		var f = formatTimeValue;
+		
+		var cols = [
+			{key:"fn", sortable:true, label: c.fn[0],
+				sortOptions: {defaultDir:a}, 
+				resizeable: (YAHOO.util.DragDrop) ? true : false,
+				minWidth:c.fn[1]},
+			{key:"calls", sortable:true, label: c.calls[0],
+				sortOptions: {defaultDir:d},
+				width:c.calls[1]},
+			{key:"avg", sortable:true, label: c.avg[0],
+				sortOptions: {defaultDir:d},
+				formatter:f,
+				width:c.avg[1]},
+			{key:"min", sortable:true, label: c.min[0],
+				sortOptions: {defaultDir:a},
+				formatter:f,
+				width:c.min[1]}, 
+			{key:"max", sortable:true, label: c.max[0],
+				sortOptions: {defaultDir:d},
+				formatter:f,
+				width:c.max[1]},
+			{key:"total", sortable:true, label: c.total[0],
+				sortOptions: {defaultDir:d},
+				formatter:f,
+				width:c.total[1]},
+			{key:"pct", sortable:true, label: c.pct[0],
+				sortOptions: {defaultDir:d}, 
+				formatter:formatPercent,
+				width:c.pct[1]}
+		];
+
+		this._dataTable = new YAHOO.widget.DataTable(this._tableEl, cols, ds, {
+			scrollable:true,
+			height:this.get("tableHeight"),
+			initialRequest:null,
+			sortedBy: {
+				key: "total",
+				dir: YAHOO.widget.DataTable.CLASS_DESC
+			}
+		});
+		var dt = this._dataTable;
+
+		//Wire up DataTable events to drive the rest of the UI.
+		dt.subscribe("sortedByChange", this._sortedByChange, this, true);
+		dt.subscribe("renderEvent", this._dataTableRenderHandler, this, true);
+		dt.subscribe("initEvent", this._dataTableRenderHandler, this, true);
+		Event.on(this._tableEl.getElementsByTagName("th"), "click", this._thClickHandler, this, true);
+	};
+		
+	/**
+	 * Proxy the sort event in DataTable into the ProfilerViewer
+	 * attribute.
+	 * @method _sortedByChange
+	 * @private
+	 **/
+	proto._sortedByChange = function(o) {
+		this.set("sortedBy", {key: o.newValue.key, dir:o.newValue.dir});
+	};
+
+	/**
+	 * Proxy the render event in DataTable into the ProfilerViewer
+	 * attribute.
+	 * @method _dataTableRenderHandler
+	 * @private
+	 **/
+	proto._dataTableRenderHandler = function(o) {
+		this._setBusyState(false);
+	};
+	
+	/**
+	 * Event handler for clicks on the DataTable's sortable column
+	 * heads.
+	 * @method _thClickHandler
+	 * @private
+	 **/
+	proto._thClickHandler = function(o) {
+		this._setBusyState(true);
+	};
+
+	/**
+	 * Refresh DataTable, getting new data from Profiler.
+	 * @method _refreshDataTable
+	 * @private
+	 **/
+	proto._refreshDataTable = function(args) {
+		var dt = this._dataTable;
+		dt.getDataSource().sendRequest("", dt.onDataReturnInitializeTable, dt);
+	};
+
+	/**
+	 * Refresh chart, getting new data from table.
+	 * @method _refreshChart
+	 * @private
+	 **/
+	proto._refreshChart = function() {
+		
+		switch (this.get("sortedBy").key) {
+			case "fn":
+				/*Keep the same data on the chart, but force update to 
+				  reflect new sort order on function/method name: */
+				this._chart.set("dataSource", this._chart.get("dataSource"));
+				
+				/*no further action necessary; chart redraws*/
+				return;
+			case "calls":
+				/*Null out the xAxis formatting before redrawing chart.*/
+				this._chart.set("xAxis", this._chartAxisDefinitionPlain);
+				break;
+			case "pct":
+				this._chart.set("xAxis", this._chartAxisDefinitionPercent);
+				break;
+			default:
+				/*Set the default xAxis; redraw legend; set the new series definition.*/
+				this._chart.set("xAxis", this._chartAxisDefinitionTime);
+				break;
+		}
+		
+		this._drawChartLegend();
+		this._chart.set("series", this._getSeriesDef(this.get("sortedBy").key));
+
+	};
+	
+	/**
+	 * Get data for the Chart from DataTable recordset
+	 * @method _getChartData
+	 * @private
+	 */
+	proto._getChartData = function() {
+		var records = this._dataTable.getRecordSet().getRecords(0, this.get("maxChartFunctions"));
+		var arr = [];
+		for (var i = records.length - 1; i>-1; i--) {
+			arr.push(records[i].getData());	
+		}
+		return arr;
+	};
+	
+	/**
+	 * Build series definition based on current configuration attributes.
+	 * @method _getSeriesDef
+	 * @private
+	 */
+	proto._getSeriesDef = function(field) {
+		var sd = this.get("chartSeriesDefinitions")[field];
+		var arr = [];
+		for(var i = 0, j = sd.group.length; i<j; i++) {
+			var c = this.get("chartSeriesDefinitions")[sd.group[i]];
+			arr.push(
+				{displayName:c.displayName,
+				 xField:c.xField,
+				 style: {color:c.style.color, size:c.style.size}
+				}
+			);
+		}
+		
+		return arr;
+	};
+	
+	/**
+	 * Set up the Chart.
+	 * @method _initChart
+	 * @private
+	 */
+	proto._initChart = function() {
+		
+		this._sizeChartCanvas();
+		
+		YAHOO.widget.Chart.SWFURL = this.get("swfUrl");
+
+		var self = this;
+
+		//Create DataSource based on records currently displayed
+		//at the top of the sort list in the DataTable.
+		var ds = new YAHOO.util.DataSource(
+			//force the jsfunction DataSource to run in the scope of
+			//the ProfilerViewer, not in the YAHOO.util.DataSource scope:
+			function() {
+				return self._getChartData.call(self);
+			}, 
+			{
+				responseType: YAHOO.util.DataSource.TYPE_JSARRAY,
+				maxCacheEntries: 0
+			}
+		);
+
+		ds.responseSchema =
+		{
+			fields: [ "fn", "avg", "calls", "max", "min", "total", "pct" ]
+		};
+		
+		ds.subscribe('responseEvent', this._sizeChartCanvas, this, true);
+		
+		//Set up the chart itself.
+		this._chartAxisDefinitionTime = new YAHOO.widget.NumericAxis();
+		this._chartAxisDefinitionTime.labelFunction = "YAHOO.widget.ProfilerViewer.timeAxisLabelFunction";
+		
+		this._chartAxisDefinitionPercent = new YAHOO.widget.NumericAxis();
+		this._chartAxisDefinitionPercent.labelFunction = "YAHOO.widget.ProfilerViewer.percentAxisLabelFunction";
+
+		this._chartAxisDefinitionPlain = new YAHOO.widget.NumericAxis();
+		
+		this._chart = new YAHOO.widget.BarChart( this._chartEl, ds,
+		{
+			yField: "fn",
+			series: this._getSeriesDef(this.get("sortedBy").key),
+			style: this.get("chartStyle"),
+			xAxis: this._chartAxisDefinitionTime
+		} );
+		
+		this._drawChartLegend();
+		this._chartInitialized = true;
+		this._dataTable.unsubscribe("initEvent", this._initChart, this);
+		this._dataTable.subscribe("initEvent", this._refreshChart, this, true);
+		
+	};
+	
+	/**
+	 * Set up the Chart's legend
+	 * @method _drawChartLegend
+	 * @private
+	 **/
+	proto._drawChartLegend = function() {
+		var seriesDefs = this.get("chartSeriesDefinitions");
+		var currentDef = seriesDefs[this.get("sortedBy").key];
+		var l = this._chartLegendEl;
+		l.innerHTML = "";
+		for(var i = 0, j = currentDef.group.length; i<j; i++) {
+			var c = seriesDefs[currentDef.group[i]];
+			var dt = document.createElement("dt");
+			Dom.setStyle(dt, "backgroundColor", "#" + c.style.color);
+			var dd = document.createElement("dd");
+			dd.innerHTML = c.displayName;
+			l.appendChild(dt);
+			l.appendChild(dd);
+		}
+	};
+	
+	/**
+	 * Resize the chart's canvas if based on number of records
+	 * returned from the chart's datasource.
+	 * @method _sizeChartCanvas
+	 * @private
+	 **/
+	proto._sizeChartCanvas = function(o) {
+		var bars = (o) ? o.response.length : this.get("maxChartFunctions");
+		var s = (bars * 36) + 34;
+		if (s != parseInt(this._chartElHeight, 10)) {
+			this._chartElHeight = s;
+			Dom.setStyle(this._chartEl, "height", s + "px");
+		}
+	};
+
+    /**
+     * setAttributeConfigs TabView specific properties.
+     * @method initAttributes
+     * @param {Object} attr Hash of initial attributes
+	 * @method initAttributes
+	 * @private
+     */
+    proto.initAttributes = function(attr) {
+        YAHOO.widget.ProfilerViewer.superclass.initAttributes.call(this, attr);
+        /**
+         * The YUI Loader base path from which to pull YUI files needed
+		 * in the rendering of the ProfilerViewer canvas.  Passed directly
+		 * to YUI Loader.  Leave blank to draw files from
+		 * yui.yahooapis.com.
+         * @attribute base
+         * @type string
+		 * @default ""
+         */
+        this.setAttributeConfig('base', {
+            value: attr.base
+        });
+
+        /**
+         * The height of the DataTable.  The table will scroll
+		 * vertically if the content overflows the specified
+		 * height.
+         * @attribute tableHeight
+         * @type string
+		 * @default "15em"
+         */
+        this.setAttributeConfig('tableHeight', {
+            value: attr.tableHeight || "15em",
+			method: function(s) {
+				if(this._dataTable) {
+					this._dataTable.set("height", s);
+				}
+			}
+        });
+		
+        /**
+         * The default column key to sort by.  Valid keys are: fn, calls,
+		 * avg, min, max, total.  Valid dir values are: 
+		 * YAHOO.widget.DataTable.CLASS_ASC and
+		 * YAHOO.widget.DataTable.CLASS_DESC (or their
+		 * string equivalents).
+         * @attribute sortedBy
+         * @type string
+		 * @default {key:"total", dir:"yui-dt-desc"}
+         */
+        this.setAttributeConfig('sortedBy', {
+            value: attr.sortedBy || {key:"total", dir:"yui-dt-desc"}
+        });
+
+        /**
+         * A filter function to use in selecting functions that will
+		 * appear in the ProfilerViewer report.  The function is passed
+		 * a function report object and should return a boolean indicating
+		 * whether that function should be included in the ProfilerViewer
+		 * display.  The argument is structured as follows:
+		 *
+		 * {
+		 *	 	fn: <str function name>,
+		 *		calls : <n number of calls>,
+		 *		avg : <n average call duration>,
+		 *		max: <n duration of longest call>,
+		 *		min: <n duration of shortest call>,
+		 *		total: <n total time of all calls>
+		 *		points : <array time in ms of each call>
+		 *	}
+		 *
+		 * For example, you would use the follwing filter function to 
+		 * return only functions that have been called at least once:
+		 * 
+		 * 	function(o) {
+		 *		return (o.calls > 0);
+		 *	}
+		 *
+         * @attribute filter
+         * @type function
+		 * @default null
+         */
+        this.setAttributeConfig('filter', {
+            value: attr.filter || null,
+			validator: YAHOO.lang.isFunction
+        });
+
+		/**
+		 * The path to the YUI Charts swf file; must be a full URI
+		 * or a path relative to the page being profiled. Changes at runtime
+		 * not supported; pass this value in at instantiation.
+		 * @attribute swfUrl
+		 * @type string
+		 * @default "http://yui.yahooapis.com/2.5.0/build/charts/assets/charts.swf"
+		 */
+		this.setAttributeConfig('swfUrl', {
+			value: attr.swfUrl || "http://yui.yahooapis.com/2.5.0/build/charts/assets/charts.swf"
+		});
+
+        /**
+         * The maximum number of functions to profile in the chart. The
+		 * greater the number of functions, the greater the height of the
+		 * chart canvas.
+		 * height.
+         * @attribute maxChartFunctions
+         * @type int
+		 * @default 6
+         */
+        this.setAttributeConfig('maxChartFunctions', {
+            value: attr.maxChartFunctions || 6,
+			method: function(s) {
+				if(this._rendered) {
+					this._sizeChartCanvas();
+				}
+			},
+			validator: YAHOO.lang.isNumber
+        });
+		
+        /**
+         * The style object that defines the chart's visual presentation.
+		 * Conforms to the style attribute passed to the Charts Control
+		 * constructor.  See Charts Control User's Guide for more information
+		 * on how to format this object.
+         * @attribute chartStyle
+         * @type obj
+		 * @default See JS source for default definitions.
+         */
+        this.setAttributeConfig('chartStyle', {
+            value: 	attr.chartStyle || {
+				font:
+					{
+						name: "Arial",
+						color: 0xeeee5c,
+						size: 12
+					},
+					background:
+					{
+						color: "6e6e63"
+					}
+				},
+			method: function() {
+					if(this._rendered && this.get("showChart")) {
+						this._refreshChart();
+					}
+				}
+        });
+		
+        /**
+         * The series definition information to use when charting
+		 * specific fields on the chart.  displayName, xField,
+		 * and style members are used to construct the series
+		 * definition; the "group" member is the array of fields
+		 * that should be charted when the table is sorted by a
+		 * given field.
+         * @attribute chartSeriesDefinitions
+         * @type obj
+		 * @default See JS source for full default definitions.
+         */
+        this.setAttributeConfig('chartSeriesDefinitions', {
+            value: 	attr.chartSeriesDefinitions ||  {
+						total: {
+							displayName: PV.STRINGS.colHeads.total[0],
+							xField: "total",
+							style: {color:"4d95dd", size:20},
+							group: ["total"]
+						},
+						calls: {		
+							displayName: PV.STRINGS.colHeads.calls[0],
+							xField: "calls",
+							style: {color:"edff9f", size:20},
+							group: ["calls"]
+						},
+						avg: {
+							displayName: PV.STRINGS.colHeads.avg[0],
+							xField: "avg",
+							style: {color:"209daf", size:9},
+							group: ["avg", "min", "max"]
+						},
+						min: {
+							displayName: PV.STRINGS.colHeads.min[0],
+							xField: "min",
+							style: {color:"b6ecf4", size:9},
+							group: ["avg", "min", "max"]
+						},
+						max: {
+							displayName: PV.STRINGS.colHeads.max[0],
+							xField: "max",
+							style: {color:"29c7de", size:9},
+							group: ["avg", "min", "max"]
+						},
+						pct: {
+							displayName: PV.STRINGS.colHeads.pct[0],
+							xField: "pct",
+							style: {color:"C96EDB", size:20},
+							group: ["pct"]
+						}
+				},
+			method: function() {
+					if(this._rendered && this.get("showChart")) {
+						this._refreshChart();
+					}
+				}
+        });
+		
+        /**
+         * The default visibility setting for the viewer canvas. If true,
+		 * the viewer will load all necessary files and render itself
+		 * immediately upon instantiation; otherwise, the viewer will
+		 * load only minimal resources until the user toggles visibility
+		 * via the UI.
+         * @attribute visible
+         * @type boolean
+		 * @default false
+         */
+        this.setAttributeConfig('visible', {
+            value: attr.visible || false,
+			validator: YAHOO.lang.isBoolean,
+			method: function(b) {
+				if(b) {
+					this._show();
+				} else {
+					if (this._rendered) {
+						this._hide();
+					}
+				}
+			}
+        });
+
+        /**
+         * The default visibility setting for the chart.
+         * @attribute showChart
+         * @type boolean
+		 * @default true
+         */
+        this.setAttributeConfig('showChart', {
+            value: attr.showChart || true,
+			validator: YAHOO.lang.isBoolean,
+			writeOnce: true
+			
+        });
+		
+		YAHOO.widget.ProfilerViewer.superclass.initAttributes.call(this, attr);
+		
+    };
+	
+})();
+YAHOO.register("profilerviewer", YAHOO.widget.ProfilerViewer, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/reset/README
===================================================================
--- trunk/root/static/yui/reset/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/reset/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +1,13 @@
 YUI Library - Reset - Release Notes
 
-Version 2.4.1
+Version 2.5.1
 
-No change
+  * No changes.
 
+Version 2.5.0
+
+  * Added input,textarea,select{*font-size:100%;} to enable resizing on IE
+
 Version 2.4.0
 
   * Moved background and default font color to HTML from BODY
@@ -42,4 +46,4 @@
 
 Version 0.10.0
 
-  * Initial release.
+  * Initial release.
\ No newline at end of file

Modified: trunk/root/static/yui/reset/reset-min.css
===================================================================
--- trunk/root/static/yui/reset/reset-min.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/reset/reset-min.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;font-variant:normal;}sup {vertical-align:text-top;}sub {vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}legend{color:#000;}
\ No newline at end of file
+html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;font-variant:normal;}sup {vertical-align:text-top;}sub {vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}
\ No newline at end of file

Modified: trunk/root/static/yui/reset/reset.css
===================================================================
--- trunk/root/static/yui/reset/reset.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/reset/reset.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 html{color:#000;background:#FFF;}
 body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}
@@ -18,5 +18,7 @@
 sup {vertical-align:text-top;}
 sub {vertical-align:text-bottom;}
 input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}
+/*to enable resizing for IE*/
+input,textarea,select{*font-size:100%;}
 /*because legend doesn't inherit in IE */
 legend{color:#000;}
\ No newline at end of file

Modified: trunk/root/static/yui/reset-fonts/reset-fonts.css
===================================================================
--- trunk/root/static/yui/reset-fonts/reset-fonts.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/reset-fonts/reset-fonts.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;font-variant:normal;}sup {vertical-align:text-top;}sub {vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}legend{color:#000;}body {font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}
+html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;font-variant:normal;}sup {vertical-align:text-top;}sub {vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}body {font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}

Modified: trunk/root/static/yui/reset-fonts-grids/reset-fonts-grids.css
===================================================================
--- trunk/root/static/yui/reset-fonts-grids/reset-fonts-grids.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/reset-fonts-grids/reset-fonts-grids.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;font-variant:normal;}sup {vertical-align:text-top;}sub {vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}legend{color:#000;}body {font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}
-body{text-align:center;}#ft{clear:both;}#doc,#doc2,#doc3,#doc4,.yui-t1,.yui-t2,.yui-t3,.yui-t4,.yui-t5,.yui-t6,.yui-t7{margin:auto;text-align:left;width:57.69em;*width:56.301em;min-width:750px;}#doc2{width:73.074em;*width:71.313em;}#doc3{margin:auto 10px;width:auto;}#doc4{width:74.923em;*width:73.117em;}.yui-b{position:relative;}.yui-b{_position:static;}#yui-main .yui-b{position:static;}#yui-main{width:100%;}.yui-t1 #yui-main,.yui-t2 #yui-main,.yui-t3 #yui-main{float:right;margin-left:-25em;}.yui-t4 #yui-main,.yui-t5 #yui-main,.yui-t6 #yui-main{float:left;margin-right:-25em;}.yui-t1 .yui-b{float:left;width:12.3207em;*width:12.0106em;}.yui-t1 #yui-main .yui-b{margin-left:13.3207em;*margin-left:13.0106em;}.yui-t2 .yui-b{float:left;width:13.8456em;*width:13.512em;}.yui-t2 #yui-main .yui-b{margin-left:14.8456em;*margin-left:14.512em;}.yui-t3 .yui-b{float:left;width:23.0759em;*width:22.52em;}.yui-t3 #yui-main .yui-b{margin-left:24.0759em;*margin-left:23.52em;}.yui-t4 .yui-b{floa!
 t:right;width:13.8456em;*width:13.512em;}.yui-t4 #yui-main .yui-b{margin-right:14.8456em;*margin-right:14.512em;}.yui-t5 .yui-b{float:right;width:18.4608em;*width:18.016em;}.yui-t5 #yui-main .yui-b{margin-right:19.4608em;*margin-right:19.016em;}.yui-t6 .yui-b{float:right;width:23.0759em;*width:22.52em;}.yui-t6 #yui-main .yui-b{margin-right:24.0759em;*margin-right:23.52em;}.yui-t7 #yui-main .yui-b{display:block;margin:0 0 1em 0;}#yui-main .yui-b{float:none;width:auto;}.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gb .yui-u,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{float:left;margin-left:2%;width:32%;}.yui-gb .yui-gb .yui-u,.yui-gb .yui-gc .yui-u{*margin-left:1.8%;_margin-left:4%;}.yui-g .yui-gb .yui-u{_margin-left:.8%;}.yui-gb .yui-u{float:right;}.yui-gb div.first{margin-left:0;float:left;}.yui-g .yui-gb div.first,.yui-gb .yui-gb div.first{*margin-right:0;*width:32%;_width:31.7%;}.yui-gb .yui-gc d!
 iv.first,.yui-gb .yui-gd div.first{*margin-right:0;}.yui-gb .y!
 ui-gd .y
ui-u{*width:66%;_width:61.2%;}.yui-gb .yui-gd div.first{*width:31%;_width:29.5%;}.yui-g .yui-gc .yui-u,.yui-gb .yui-gc .yui-u{width:32%;_float:right;margin-right:0;_margin-left:0;}.yui-gb .yui-gc div.first{width:66%;*float:left;*margin-left:0;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf .yui-u{margin:0;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf,.yui-gc .yui-u,.yui-gd .yui-g,.yui-g .yui-gc .yui-u,.yui-ge .yui-u,.yui-ge .yui-g,.yui-gf .yui-g,.yui-gf .yui-u{float:right;}.yui-g .yui-gc div.first,.yui-g .yui-ge div.first,.yui-g div.first,.yui-gc div.first,.yui-gc div.first div.first,.yui-gd div.first,.yui-ge div.first,.yui-gf div.first{float:left;}.yui-g .yui-g .yui-u,.yui-gb .yui-g .yui-u,.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u,.yui-ge .yui-g .yui-u,.yui-gf .yui-g .yui-u{width:49%;*width:48.1%;*margin-left:0;}.yui-g .yui-g div.first{*margin:0;}.yui-gb .yui-g div.first{*margin-right:4%;_margin-right:1.3%;}.yui-gb .yui-gb!
  .yui-u{_margin-left:.7%;}.yui-gb .yui-g div.first,.yui-gb .yui-gb div.first{*margin-left:0;}.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u{*width:48.1%;*margin-left:0;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf{width:49.1%;}.yui-g .yui-gb div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first{margin-left:0;}.yui-g .yui-gc div.first,.yui-gc div.first,.yui-gd .yui-g,.yui-gd .yui-u{width:66%;}.yui-gd div.first,.yui-gb .yui-gd div.first{width:32%;}.yui-g .yui-gd div.first{_width:29.9%;}.yui-ge .yui-u,.yui-ge .yui-g,.yui-gf div.first{width:24%;}.yui-gb .yui-ge div.yui-u,.yui-gb .yui-gf div.yui-u{float:right;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf div.first {float:left;}.yui-ge div.first,.yui-gf .yui-g,.yui-gf .yui-u{width:74.2%;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf div.first{*width:24%;_width:20%;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf .yui-u{*width:73.5%;_width:65.5%;}#bd:after,.yui-g:after,.yui-gb:after!
 ,.yui-gc:after,.yui-gd:after,.yui-ge:after,.yui-gf:after{conte!
 nt:".";d
isplay:block;height:0;clear:both;visibility:hidden;}#bd,.yui-g,.yui-gb,.yui-gc,.yui-gd,.yui-ge,.yui-gf{zoom:1;}.yui-gb .yui-u{float:left;}
\ No newline at end of file
+html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;font-variant:normal;}sup {vertical-align:text-top;}sub {vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}body {font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}
+body{text-align:center;}#ft{clear:both;}#doc,#doc2,#doc3,#doc4,.yui-t1,.yui-t2,.yui-t3,.yui-t4,.yui-t5,.yui-t6,.yui-t7{margin:auto;text-align:left;width:57.69em;*width:56.25em;min-width:750px;}#doc2{width:73.076em;*width:71.25em;}#doc3{margin:auto 10px;width:auto;}#doc4{width:74.923em;*width:73.05em;}.yui-b{position:relative;}.yui-b{_position:static;}#yui-main .yui-b{position:static;}#yui-main{width:100%;}.yui-t1 #yui-main,.yui-t2 #yui-main,.yui-t3 #yui-main{float:right;margin-left:-25em;}.yui-t4 #yui-main,.yui-t5 #yui-main,.yui-t6 #yui-main{float:left;margin-right:-25em;}.yui-t1 .yui-b{float:left;width:12.30769em;*width:12.00em;}.yui-t1 #yui-main .yui-b{margin-left:13.30769em;*margin-left:13.05em;}.yui-t2 .yui-b{float:left;width:13.8461em;*width:13.50em;}.yui-t2 #yui-main .yui-b{margin-left:14.8461em;*margin-left:14.55em;}.yui-t3 .yui-b{float:left;width:23.0769em;*width:22.50em;}.yui-t3 #yui-main .yui-b{margin-left:24.0769em;*margin-left:23.62em;}.yui-t4 .yui-b{float:right!
 ;width:13.8456em;*width:13.50em;}.yui-t4 #yui-main .yui-b{margin-right:14.8456em;*margin-right:14.55em;}.yui-t5 .yui-b{float:right;width:18.4615em;*width:18.00em;}.yui-t5 #yui-main .yui-b{margin-right:19.4615em;*margin-right:19.125em;}.yui-t6 .yui-b{float:right;width:23.0769em;*width:22.50em;}.yui-t6 #yui-main .yui-b{margin-right:24.0769em;*margin-right:23.62em;}.yui-t7 #yui-main .yui-b{display:block;margin:0 0 1em 0;}#yui-main .yui-b{float:none;width:auto;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf,.yui-gc .yui-u,.yui-gd .yui-g,.yui-g .yui-gc .yui-u,.yui-ge .yui-u,.yui-ge .yui-g,.yui-gf .yui-g,.yui-gf .yui-u{float:right;}.yui-g div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first,.yui-ge div.first,.yui-gf div.first,.y!
 ui-g .yui-gc div.first,.yui-g .yui-ge div.first,.yui-gc div.fi!
 rst div.
first{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf{width:49.1%;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{width:32%;margin-left:1.99%;}.yui-gb .yui-u{*margin-left:1.9%;*width:31.9%;}.yui-gc div.first,.yui-gd .yui-u{width:66%;}.yui-gd div.first{width:32%;}.yui-ge div.first,.yui-gf .yui-u{width:74.2%;}.yui-ge .yui-u,.yui-gf div.first{width:24%;}.yui-g .yui-gb div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first{margin-left:0;}.yui-g .yui-g .yui-u,.yui-gb .yui-g .yui-u,.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u,.yui-ge .yui-g .yui-u,.yui-gf .yui-g .yui-u{width:49%;*width:48.1%;*margin-left:0;}.yui-g .yui-gb div.first,.yui-gb .yui-gb div.first{*margin-right:0;*width:32%;_width:31.7%;}.yui-g .yui-gc div.first,.yui-gd .yui-g{width:66%;}.yui-gb .yui-g div.first{*margin!
 -right:4%;_margin-right:1.3%;}.yui-gb .yui-gc div.first,.yui-gb .yui-gd div.first{*margin-right:0;}.yui-gb .yui-gb .yui-u,.yui-gb .yui-gc .yui-u{*margin-left:1.8%;_margin-left:4%;}.yui-g .yui-gb .yui-u{_margin-left:1.0%;}.yui-gb .yui-gd .yui-u{*width:66%;_width:61.2%;}.yui-gb .yui-gd div.first{*width:31%;_width:29.5%;}.yui-g .yui-gc .yui-u,.yui-gb .yui-gc .yui-u{width:32%;_float:right;margin-right:0;_margin-left:0;}.yui-gb .yui-gc div.first{width:66%;*float:left;*margin-left:0;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf .yui-u{margin:0;}.yui-gb .yui-gb .yui-u{_margin-left:.7%;}.yui-gb .yui-g div.first,.yui-gb .yui-gb div.first{*margin-left:0;}.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u{*width:48.1%;*margin-left:0;}s .yui-gb .yui-gd div.first{width:32%;}.yui-g .yui-gd div.first{_width:29.9%;}.yui-ge .yui-g{width:24%;}.yui-gf .yui-g{width:74.2%;}.yui-gb .yui-ge div.yui-u,.yui-gb .yui-gf div.yui-u{float:right;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf div.first{float:left;}.yui-gb!
  .yui-ge .yui-u,.yui-gb .yui-gf div.first{*width:24%;_width:20!
 %;}.yui-
gb .yui-ge div.first,.yui-gb .yui-gf .yui-u{*width:73.5%;_width:65.5%;}.yui-ge div.first .yui-gd .yui-u{width:65%;}.yui-ge div.first .yui-gd div.first{width:32%;}#bd:after,.yui-g:after,.yui-gb:after,.yui-gc:after,.yui-gd:after,.yui-ge:after,.yui-gf:after{content:".";display:block;height:0;clear:both;visibility:hidden;}#bd,.yui-g,.yui-gb,.yui-gc,.yui-gd,.yui-ge,.yui-gf{zoom:1;}
\ No newline at end of file

Added: trunk/root/static/yui/resize/README
===================================================================
--- trunk/root/static/yui/resize/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/resize/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,9 @@
+**** version 2.5.1 ***
+    
+    Bug Fixes
+        * 1766923 - [SF 1899888] Resize.destroy() not removing status
+        * 1784371 - Status div tracks on resize cancel
+
+**** version 2.5.0 ***
+
+Initial Release

Added: trunk/root/static/yui/resize/assets/resize-core.css
===================================================================
--- trunk/root/static/yui/resize/assets/resize-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/resize/assets/resize-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,173 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+.yui-resize {
+    position: relative;
+    zoom: 1;
+    z-index: 0;
+}
+.yui-resize-wrap {
+    zoom: 1;
+}
+
+.yui-draggable {
+    cursor: move;
+}
+
+.yui-resize .yui-resize-handle {
+    position: absolute;
+    z-index: 1;
+    font-size: 0;
+    margin: 0;
+    padding: 0;
+    zoom: 1;
+    height: 1px;
+    width: 1px;
+}
+.yui-resize .yui-resize-handle-br {
+    height: 5px;
+    width: 5px;
+    bottom: 0;
+    right: 0;
+    cursor: se-resize;
+    z-index: 2;
+    zoom: 1;
+}
+
+.yui-resize .yui-resize-handle-bl {
+    height: 5px;
+    width: 5px;
+    bottom: 0;
+    left: 0;
+    cursor: sw-resize;
+    z-index: 2;
+    zoom: 1;
+}
+
+.yui-resize .yui-resize-handle-tl {
+    height: 5px;
+    width: 5px;
+    top: 0;
+    left: 0;
+    cursor: nw-resize;
+    z-index: 2;
+    zoom: 1;
+}
+
+.yui-resize .yui-resize-handle-tr {
+    height: 5px;
+    width: 5px;
+    top: 0;
+    right: 0;
+    cursor: ne-resize;
+    z-index: 2;
+    zoom: 1;
+}
+
+.yui-resize .yui-resize-handle-r {
+    width: 5px;
+    height: 100%;
+    top: 0;
+    right: 0;
+    cursor: e-resize;
+    zoom: 1;
+}
+
+.yui-resize .yui-resize-handle-l {
+    height: 100%;
+    width: 5px;
+    top: 0;
+    left: 0;
+    cursor: w-resize;
+    zoom: 1;
+}
+
+.yui-resize .yui-resize-handle-b {
+    width: 100%;
+    height: 5px;
+    bottom: 0;
+    right: 0;
+    cursor: s-resize;
+    zoom: 1;
+}
+.yui-resize .yui-resize-handle-t {
+    width: 100%;
+    height: 5px;
+    top: 0;
+    right: 0;
+    cursor: n-resize;
+    zoom: 1;
+}
+.yui-resize-proxy {
+    position: absolute;
+    border: 1px dashed #000;
+    visibility: hidden;
+    z-index: 1000;
+}
+
+.yui-resize-hover .yui-resize-handle,
+.yui-resize-hidden .yui-resize-handle {
+    opacity: 0;
+    filter: alpha(opacity=0);
+}
+.yui-resize-ghost {
+    opacity: .5;
+    filter: alpha(opacity=50);
+}
+
+.yui-resize-knob .yui-resize-handle {
+    height: 6px;
+    width: 6px;
+}
+.yui-resize-knob .yui-resize-handle-tr {
+    right: -3px;
+    top: -3px;
+}
+.yui-resize-knob .yui-resize-handle-tl {
+    left: -3px;
+    top: -3px;
+}
+.yui-resize-knob .yui-resize-handle-bl {
+    left: -3px;
+    bottom: -3px;
+}
+.yui-resize-knob .yui-resize-handle-br {
+    right: -3px;
+    bottom: -3px;
+}
+.yui-resize-knob .yui-resize-handle-t {
+    left: 45%;
+    top: -3px;
+}
+.yui-resize-knob .yui-resize-handle-r {
+    right: -3px;
+    top: 45%;
+}
+.yui-resize-knob .yui-resize-handle-l {
+    left: -3px;
+    top: 45%;
+}
+.yui-resize-knob .yui-resize-handle-b {
+    left: 45%;
+    bottom: -3px;
+}
+
+.yui-resize-status {
+    position: absolute;
+    top: -999px;
+    left: -999px;
+    padding: 2px;
+    font-size: 80%;
+    display: none;
+    zoom: 1; /* IE hasLayout */
+    z-index: 9999;
+}
+.yui-resize-status strong, .yui-resize-status em {
+    font-weight: normal;
+    font-style: normal;
+    padding: 1px;
+    zoom: 1;
+}

Added: trunk/root/static/yui/resize/assets/skins/sam/layout_sprite.png
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/resize/assets/skins/sam/layout_sprite.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/root/static/yui/resize/assets/skins/sam/resize-skin.css
===================================================================
--- trunk/root/static/yui/resize/assets/skins/sam/resize-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/resize/assets/skins/sam/resize-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,128 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/* Give the handle a background color */
+.yui-skin-sam .yui-resize .yui-resize-handle {
+    background-color: #F2F2F2;
+}
+/* Give the active handle a different color */
+.yui-skin-sam .yui-resize .yui-resize-handle-active {
+    background-color: #7D98B8;
+    zoom: 1;
+}
+.yui-skin-sam .yui-resize .yui-resize-handle-l,
+.yui-skin-sam .yui-resize .yui-resize-handle-r,
+.yui-skin-sam .yui-resize .yui-resize-handle-l-active,
+.yui-skin-sam .yui-resize .yui-resize-handle-r-active {
+    height: 100%;
+}
+/* Give a border to the 8-way knob style handles */
+.yui-skin-sam .yui-resize-knob .yui-resize-handle {
+    border: 1px solid #808080;
+}
+/* Show the active handle when hovered */
+.yui-skin-sam .yui-resize-hover .yui-resize-handle-active {
+    opacity: 1;
+    filter: alpha(opacity=100);
+}
+
+/* Style the resize proxy */
+.yui-skin-sam .yui-resize-proxy {
+    border: 1px dashed #426FD9;
+}
+
+/* Style the status box similar to a tooltip */
+.yui-skin-sam .yui-resize-status {
+    border: 1px solid #A6982B;
+    border-top: 1px solid #D4C237;
+    background-color: #FFEE69
+}
+
+
+/* Style the content of the status box */
+.yui-skin-sam .yui-resize-status strong, .yui-skin-sam .yui-resize-status em {
+    float: left;
+    display: block;
+    clear: both;
+    padding: 1px;
+    text-align: center;
+}
+
+/* Setup the gripper */
+.yui-skin-sam .yui-resize .yui-resize-handle-inner-r,
+.yui-skin-sam .yui-resize .yui-resize-handle-inner-l {
+    background: transparent url( layout_sprite.png) no-repeat 0 -5px;
+    height: 16px;
+    width: 5px;
+    position: absolute;
+    top: 45%;
+}
+
+/* Setup the gripper */
+.yui-skin-sam .yui-resize .yui-resize-handle-inner-t,
+.yui-skin-sam .yui-resize .yui-resize-handle-inner-b {
+    background: transparent url(layout_sprite.png) no-repeat -20px 0;
+    height: 5px;
+    width: 16px;
+    position: absolute;
+    left: 50%;
+}
+
+/* Bottom Right Gripper */
+.yui-skin-sam .yui-resize .yui-resize-handle-br {
+    background-image: url( layout_sprite.png );
+    background-repeat: no-repeat;
+    background-position: -22px -62px;
+}
+
+/* Top Right Gripper */
+.yui-skin-sam .yui-resize .yui-resize-handle-tr {
+    background-image: url( layout_sprite.png );
+    background-repeat: no-repeat;
+    background-position: -22px -42px;
+}
+
+/* Top Left Gripper */
+.yui-skin-sam .yui-resize .yui-resize-handle-tl {
+    background-image: url( layout_sprite.png );
+    background-repeat: no-repeat;
+    background-position: -22px -82px;
+}
+
+/* Bottom Left Gripper */
+.yui-skin-sam .yui-resize .yui-resize-handle-bl {
+    background-image: url( layout_sprite.png );
+    background-repeat: no-repeat;
+    background-position: -22px -23px;
+}
+
+/* Remove the background image from the 8-way knobs */
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-t,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-r,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-b,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-l,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-tl,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-tr,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-bl,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-br,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-t,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-r,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-b,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-l,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-tl,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-tr,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-bl,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-br {
+    background-image: none;
+}
+
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-l,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-r,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-l-active,
+.yui-skin-sam .yui-resize-knob .yui-resize-handle-r-active {
+    height: 6px;
+    width: 6px;
+}

Added: trunk/root/static/yui/resize/assets/skins/sam/resize.css
===================================================================
--- trunk/root/static/yui/resize/assets/skins/sam/resize.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/resize/assets/skins/sam/resize.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,7 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+.yui-resize{position:relative;zoom:1;z-index:0;}.yui-resize-wrap{zoom:1;}.yui-draggable{cursor:move;}.yui-resize .yui-resize-handle{position:absolute;z-index:1;font-size:0;margin:0;padding:0;zoom:1;height:1px;width:1px;}.yui-resize .yui-resize-handle-br{height:5px;width:5px;bottom:0;right:0;cursor:se-resize;z-index:2;zoom:1;}.yui-resize .yui-resize-handle-bl{height:5px;width:5px;bottom:0;left:0;cursor:sw-resize;z-index:2;zoom:1;}.yui-resize .yui-resize-handle-tl{height:5px;width:5px;top:0;left:0;cursor:nw-resize;z-index:2;zoom:1;}.yui-resize .yui-resize-handle-tr{height:5px;width:5px;top:0;right:0;cursor:ne-resize;z-index:2;zoom:1;}.yui-resize .yui-resize-handle-r{width:5px;height:100%;top:0;right:0;cursor:e-resize;zoom:1;}.yui-resize .yui-resize-handle-l{height:100%;width:5px;top:0;left:0;cursor:w-resize;zoom:1;}.yui-resize .yui-resize-handle-b{width:100%;height:5px;bottom:0;right:0;cursor:s-resize;zoom:1;}.yui-resize .yui-resize-handle-t{width:100%;height:5px;top:0;right:!
 0;cursor:n-resize;zoom:1;}.yui-resize-proxy{position:absolute;border:1px dashed #000;visibility:hidden;z-index:1000;}.yui-resize-hover .yui-resize-handle,.yui-resize-hidden .yui-resize-handle{opacity:0;filter:alpha(opacity=0);}.yui-resize-ghost{opacity:.5;filter:alpha(opacity=50);}.yui-resize-knob .yui-resize-handle{height:6px;width:6px;}.yui-resize-knob .yui-resize-handle-tr{right:-3px;top:-3px;}.yui-resize-knob .yui-resize-handle-tl{left:-3px;top:-3px;}.yui-resize-knob .yui-resize-handle-bl{left:-3px;bottom:-3px;}.yui-resize-knob .yui-resize-handle-br{right:-3px;bottom:-3px;}.yui-resize-knob .yui-resize-handle-t{left:45%;top:-3px;}.yui-resize-knob .yui-resize-handle-r{right:-3px;top:45%;}.yui-resize-knob .yui-resize-handle-l{left:-3px;top:45%;}.yui-resize-knob .yui-resize-handle-b{left:45%;bottom:-3px;}.yui-resize-status{position:absolute;top:-999px;left:-999px;padding:2px;font-size:80%;display:none;zoom:1;z-index:9999;}.yui-resize-status strong,.yui-resize-status em{font!
 -weight:normal;font-style:normal;padding:1px;zoom:1;}.yui-skin!
 -sam .yu
i-resize .yui-resize-handle{background-color:#F2F2F2;}.yui-skin-sam .yui-resize .yui-resize-handle-active{background-color:#7D98B8;zoom:1;}.yui-skin-sam .yui-resize .yui-resize-handle-l,.yui-skin-sam .yui-resize .yui-resize-handle-r,.yui-skin-sam .yui-resize .yui-resize-handle-l-active,.yui-skin-sam .yui-resize .yui-resize-handle-r-active{height:100%;}.yui-skin-sam .yui-resize-knob .yui-resize-handle{border:1px solid #808080;}.yui-skin-sam .yui-resize-hover .yui-resize-handle-active{opacity:1;filter:alpha(opacity=100);}.yui-skin-sam .yui-resize-proxy{border:1px dashed #426FD9;}.yui-skin-sam .yui-resize-status{border:1px solid #A6982B;border-top:1px solid #D4C237;background-color:#FFEE69}.yui-skin-sam .yui-resize-status strong,.yui-skin-sam .yui-resize-status em{float:left;display:block;clear:both;padding:1px;text-align:center;}.yui-skin-sam .yui-resize .yui-resize-handle-inner-r,.yui-skin-sam .yui-resize .yui-resize-handle-inner-l{background:transparent url( layout_sprite.pn!
 g) no-repeat 0 -5px;height:16px;width:5px;position:absolute;top:45%;}.yui-skin-sam .yui-resize .yui-resize-handle-inner-t,.yui-skin-sam .yui-resize .yui-resize-handle-inner-b{background:transparent url(layout_sprite.png) no-repeat -20px 0;height:5px;width:16px;position:absolute;left:50%;}.yui-skin-sam .yui-resize .yui-resize-handle-br{background-image:url( layout_sprite.png );background-repeat:no-repeat;background-position:-22px -62px;}.yui-skin-sam .yui-resize .yui-resize-handle-tr{background-image:url( layout_sprite.png );background-repeat:no-repeat;background-position:-22px -42px;}.yui-skin-sam .yui-resize .yui-resize-handle-tl{background-image:url( layout_sprite.png );background-repeat:no-repeat;background-position:-22px -82px;}.yui-skin-sam .yui-resize .yui-resize-handle-bl{background-image:url( layout_sprite.png );background-repeat:no-repeat;background-position:-22px -23px;}.yui-skin-sam .yui-resize-knob .yui-resize-handle-t,.yui-skin-sam .yui-resize-knob .yui-resize-!
 handle-r,.yui-skin-sam .yui-resize-knob .yui-resize-handle-b,.!
 yui-skin
-sam .yui-resize-knob .yui-resize-handle-l,.yui-skin-sam .yui-resize-knob .yui-resize-handle-tl,.yui-skin-sam .yui-resize-knob .yui-resize-handle-tr,.yui-skin-sam .yui-resize-knob .yui-resize-handle-bl,.yui-skin-sam .yui-resize-knob .yui-resize-handle-br,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-t,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-r,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-b,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-l,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-tl,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-tr,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-bl,.yui-skin-sam .yui-resize-knob .yui-resize-handle-inner-br{background-image:none;}.yui-skin-sam .yui-resize-knob .yui-resize-handle-l,.yui-skin-sam .yui-resize-knob .yui-resize-handle-r,.yui-skin-sam .yui-resize-knob .yui-resize-handle-l-active,.yui-skin-sam .yui-resize-knob .yui-resize-handle-r-active{height:6px;width:6px;}

Added: trunk/root/static/yui/resize/resize-beta-debug.js
===================================================================
--- trunk/root/static/yui/resize/resize-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/resize/resize-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,1650 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * @description <p>Makes an element resizable</p>
+ * @namespace YAHOO.util
+ * @requires yahoo, dom, dragdrop, element, event
+ * @optional animation
+ * @module resize
+ * @beta
+ */
+(function() {
+var D = YAHOO.util.Dom,
+    Event = YAHOO.util.Event,
+    Lang = YAHOO.lang;
+
+    /**
+     * @constructor
+     * @class Resize
+     * @extends YAHOO.util.Element
+     * @description <p>Makes an element resizable</p>
+     * @param {String/HTMLElement} el The element to make resizable.
+     * @param {Object} attrs Object liternal containing configuration parameters.
+    */
+
+    var Resize = function(el, config) {
+        YAHOO.log('Creating Resize Object', 'info', 'Resize');
+        var oConfig = {
+            element: el,
+            attributes: config || {}
+        };
+
+        Resize.superclass.constructor.call(this, oConfig.element, oConfig.attributes);    
+    };
+
+    /**
+    * @private
+    * @static
+    * @property _instances
+    * @description Internal hash table for all resize instances
+    * @type Object
+    */ 
+    Resize._instances = {};
+    /**
+    * @static
+    * @method getResizeById 
+    * @description Get's a resize object by the HTML id of the element associated with the Resize object.
+    * @return {Object} The Resize Object
+    */ 
+    Resize.getResizeById = function(id) {
+        if (Resize._instances[id]) {
+            return Resize._instances[id];
+        }
+        YAHOO.log('No Instance Found', 'error', 'Resize');
+        return false;
+    };
+
+    YAHOO.extend(Resize, YAHOO.util.Element, {
+        /**
+        * @private
+        * @property CSS_RESIZE
+        * @description Base CSS class name
+        * @type String
+        */ 
+        CSS_RESIZE: 'yui-resize',
+        /**
+        * @private
+        * @property CSS_DRAG
+        * @description Class name added when dragging is enabled
+        * @type String
+        */ 
+        CSS_DRAG: 'yui-draggable',
+        /**
+        * @private
+        * @property CSS_HOVER
+        * @description Class name used for hover only handles
+        * @type String
+        */ 
+        CSS_HOVER: 'yui-resize-hover',
+        /**
+        * @private
+        * @property CSS_PROXY
+        * @description Class name given to the proxy element
+        * @type String
+        */ 
+        CSS_PROXY: 'yui-resize-proxy',
+        /**
+        * @private
+        * @property CSS_WRAP
+        * @description Class name given to the wrap element
+        * @type String
+        */ 
+        CSS_WRAP: 'yui-resize-wrap',
+        /**
+        * @private
+        * @property CSS_KNOB
+        * @description Class name used to make the knob style handles
+        * @type String
+        */ 
+        CSS_KNOB: 'yui-resize-knob',
+        /**
+        * @private
+        * @property CSS_HIDDEN
+        * @description Class name given to the wrap element to make all handles hidden
+        * @type String
+        */ 
+        CSS_HIDDEN: 'yui-resize-hidden',
+        /**
+        * @private
+        * @property CSS_HANDLE
+        * @description Class name given to all handles, used as a base for single handle names as well.. Handle "t" will get this.CSS_HANDLE + '-t' as well as this.CSS_HANDLE
+        * @type String
+        */ 
+        CSS_HANDLE: 'yui-resize-handle',
+        /**
+        * @private
+        * @property CSS_STATUS
+        * @description Class name given to the status element
+        * @type String
+        */ 
+        CSS_STATUS: 'yui-resize-status',
+        /**
+        * @private
+        * @property CSS_GHOST
+        * @description Class name given to the wrap element when the ghost property is active
+        * @type String
+        */ 
+        CSS_GHOST: 'yui-resize-ghost',
+        /**
+        * @private
+        * @property CSS_RESIZING
+        * @description Class name given to the wrap element when a resize action is taking place.
+        * @type String
+        */ 
+        CSS_RESIZING: 'yui-resize-resizing',
+        /**
+        * @private
+        * @property _resizeEvent
+        * @description The mouse event used to resize with
+        * @type Event
+        */ 
+        _resizeEvent: null,
+        /**
+        * @private
+        * @property dd
+        * @description The <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> instance used if draggable is true
+        * @type Object
+        */ 
+        dd: null,
+        /** 
+        * @private
+        * @property browser
+        * @description A copy of the YAHOO.env.ua property
+        * @type Object
+        */
+        browser: YAHOO.env.ua,
+        /** 
+        * @private
+        * @property _positioned
+        * @description A flag to show if the element is absolutely positioned
+        * @type Boolean
+        */
+        _positioned: null,
+        /** 
+        * @private
+        * @property _dds
+        * @description An Object containing references to all of the <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> instances used for the resize handles
+        * @type Object
+        */
+        _dds: null,
+        /** 
+        * @private
+        * @property _wrap
+        * @description The HTML reference of the element wrapper
+        * @type HTMLElement
+        */
+        _wrap: null,
+        /** 
+        * @private
+        * @property _proxy
+        * @description The HTML reference of the element proxy
+        * @type HTMLElement
+        */
+        _proxy: null,
+        /** 
+        * @private
+        * @property _handles
+        * @description An object containing references to all of the resize handles.
+        * @type Object
+        */
+        _handles: null,
+        /** 
+        * @private
+        * @property _currentHandle
+        * @description The string identifier of the currently active handle. e.g. 'r', 'br', 'tl'
+        * @type String
+        */
+        _currentHandle: null,
+        /** 
+        * @private
+        * @property _currentDD
+        * @description A link to the currently active DD object
+        * @type Object
+        */
+        _currentDD: null,
+        /** 
+        * @private
+        * @property _cache
+        * @description An lookup table containing key information for the element being resized. e.g. height, width, x position, y position, etc..
+        * @type Object
+        */
+        _cache: null,
+        /** 
+        * @private
+        * @property _active
+        * @description Flag to show if the resize is active. Used for events.
+        * @type Boolean
+        */
+        _active: null,
+        /** 
+        * @private
+        * @method _createProxy
+        * @description Creates the proxy element if the proxy config is true
+        */
+        _createProxy: function() {
+            if (this.get('proxy')) {
+                YAHOO.log('Creating the Proxy Element', 'info', 'Resize');
+                this._proxy = document.createElement('div');
+                this._proxy.className = this.CSS_PROXY;
+                this._proxy.style.height = this.get('element').clientHeight + 'px';
+                this._proxy.style.width = this.get('element').clientWidth + 'px';
+                this._wrap.parentNode.appendChild(this._proxy);
+            } else {
+                YAHOO.log('No proxy element, turn off animate config option', 'info', 'Resize');
+                this.set('animate', false);
+            }
+        },
+        /** 
+        * @private
+        * @method _createWrap
+        * @description Creates the wrap element if the wrap config is true. It will auto wrap the following element types: img, textarea, input, iframe, select
+        */
+        _createWrap: function() {
+            YAHOO.log('Create the wrap element', 'info', 'Resize');
+            this._positioned = false;
+            //Force wrap for elements that can't have children 
+            switch (this.get('element').tagName.toLowerCase()) {
+                case 'img':
+                case 'textarea':
+                case 'input':
+                case 'iframe':
+                case 'select':
+                    this.set('wrap', true);
+                    YAHOO.log('Auto-wrapping the element (' + this.get('element').tagName.toLowerCase() + ')', 'warn', 'Resize');
+                    break;
+            }
+            if (this.get('wrap')) {
+                YAHOO.log('Creating the wrap element', 'info', 'Resize');
+                this._wrap = document.createElement('div');
+                this._wrap.id = this.get('element').id + '_wrap';
+                this._wrap.className = this.CSS_WRAP;
+                D.setStyle(this._wrap, 'width', this.get('width'));
+                D.setStyle(this._wrap, 'height', this.get('height'));
+                D.setStyle(this._wrap, 'z-index', this.getStyle('z-index'));
+                this.setStyle('z-index', 0);
+                var pos = D.getStyle(this.get('element'), 'position');
+                D.setStyle(this._wrap, 'position', ((pos == 'static') ? 'relative' : pos));
+                D.setStyle(this._wrap, 'top', D.getStyle(this.get('element'), 'top'));
+                D.setStyle(this._wrap, 'left', D.getStyle(this.get('element'), 'left'));
+                if (D.getStyle(this.get('element'), 'position') == 'absolute') {
+                    this._positioned = true;
+                    YAHOO.log('The element is positioned absolute', 'info', 'Resize');
+                    D.setStyle(this.get('element'), 'position', 'relative');
+                    D.setStyle(this.get('element'), 'top', '0');
+                    D.setStyle(this.get('element'), 'left', '0');
+                }
+                var par = this.get('element').parentNode;
+                par.replaceChild(this._wrap, this.get('element'));
+                this._wrap.appendChild(this.get('element'));
+            } else {
+                this._wrap = this.get('element');
+                if (D.getStyle(this._wrap, 'position') == 'absolute') {
+                    this._positioned = true;
+                }
+            }
+            if (this.get('draggable')) {
+                this._setupDragDrop();
+            }
+            if (this.get('hover')) {
+                D.addClass(this._wrap, this.CSS_HOVER);
+            }
+            if (this.get('knobHandles')) {
+                D.addClass(this._wrap, this.CSS_KNOB);
+            }
+            if (this.get('hiddenHandles')) {
+                D.addClass(this._wrap, this.CSS_HIDDEN);
+            }
+            D.addClass(this._wrap, this.CSS_RESIZE);
+        },
+        /** 
+        * @private
+        * @method _setupDragDrop
+        * @description Setup the <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> instance on the element
+        */
+        _setupDragDrop: function() {
+            YAHOO.log('Setting up the dragdrop instance on the element', 'info', 'Resize');
+            D.addClass(this._wrap, this.CSS_DRAG);
+            this.dd = new YAHOO.util.DD(this._wrap, this.get('id') + '-resize', { dragOnly: true });
+            this.dd.on('dragEvent', function() {
+                this.fireEvent('dragEvent', arguments);
+            }, this, true);
+        },
+        /** 
+        * @private
+        * @method _createHandles
+        * @description Creates the handles as specified in the config
+        */
+        _createHandles: function() {
+            YAHOO.log('Creating the handles', 'info', 'Resize');
+            this._handles = {};
+            this._dds = {};
+            var h = this.get('handles');
+            for (var i = 0; i < h.length; i++) {
+                YAHOO.log('Creating handle position: ' + h[i], 'info', 'Resize');
+                this._handles[h[i]] = document.createElement('div');
+                this._handles[h[i]].id = D.generateId(this._handles[h[i]]);
+                this._handles[h[i]].className = this.CSS_HANDLE + ' ' + this.CSS_HANDLE + '-' + h[i];
+                var k = document.createElement('div');
+                k.className = this.CSS_HANDLE + '-inner-' + h[i];
+                this._handles[h[i]].appendChild(k);
+                this._wrap.appendChild(this._handles[h[i]]);
+                Event.on(this._handles[h[i]], 'mouseover', this._handleMouseOver, this, true);
+                Event.on(this._handles[h[i]], 'mouseout', this._handleMouseOut, this, true);
+                this._dds[h[i]] = new YAHOO.util.DragDrop(this._handles[h[i]], this.get('id') + '-handle-' + h);
+                this._dds[h[i]].setPadding(15, 15, 15, 15);
+                this._dds[h[i]].on('startDragEvent', this._handleStartDrag, this._dds[h[i]], this);
+                this._dds[h[i]].on('mouseDownEvent', this._handleMouseDown, this._dds[h[i]], this);
+            }
+            YAHOO.log('Creating the Status box', 'info', 'Resize');
+            this._status = document.createElement('span');
+            this._status.className = this.CSS_STATUS;
+            document.body.insertBefore(this._status, document.body.firstChild);
+        },
+        /** 
+        * @private
+        * @method _ieSelectFix
+        * @description The function we use as the onselectstart handler when we start a drag in Internet Explorer
+        */
+        _ieSelectFix: function() {
+            return false;
+        },
+        /** 
+        * @private
+        * @property _ieSelectBack
+        * @description We will hold a copy of the current "onselectstart" method on this property, and reset it after we are done using it.
+        */
+        _ieSelectBack: null,
+        /** 
+        * @private
+        * @method _setAutoRatio
+        * @param {Event} ev A mouse event.
+        * @description This method checks to see if the "autoRatio" config is set. If it is, we will check to see if the "Shift Key" is pressed. If so, we will set the config ratio to true.
+        */
+        _setAutoRatio: function(ev) {
+            if (this.get('autoRatio')) {
+                YAHOO.log('Setting up AutoRatio', 'info', 'Resize');
+                if (ev && ev.shiftKey) {
+                    //Shift Pressed
+                    YAHOO.log('Shift key presses, turning on ratio', 'info', 'Resize');
+                    this.set('ratio', true);
+                } else {
+                    YAHOO.log('Resetting ratio back to default', 'info', 'Resize');
+                    this.set('ratio', this._configs.ratio._initialConfig.value);
+                }
+            }
+        },
+        /** 
+        * @private
+        * @method _handleMouseDown
+        * @param {Event} ev A mouse event.
+        * @description This method preps the autoRatio on MouseDown.
+        */
+        _handleMouseDown: function(ev) {
+            if (D.getStyle(this._wrap, 'position') == 'absolute') {
+                this._positioned = true;
+            }
+            if (ev) {
+                this._setAutoRatio(ev);
+            }
+            if (this.browser.ie) {
+                this._ieSelectBack = document.body.onselectstart;
+                document.body.onselectstart = this._ieSelectFix;
+            }
+        },
+        /** 
+        * @private
+        * @method _handleMouseOver
+        * @param {Event} ev A mouse event.
+        * @description Adds CSS class names to the handles
+        */
+        _handleMouseOver: function(ev) {
+            //Internet Explorer needs this
+            D.removeClass(this._wrap, this.CSS_RESIZE);
+            if (this.get('hover')) {
+                D.removeClass(this._wrap, this.CSS_HOVER);
+            }
+            var tar = Event.getTarget(ev);
+            if (!D.hasClass(tar, this.CSS_HANDLE)) {
+                tar = tar.parentNode;
+            }
+            if (D.hasClass(tar, this.CSS_HANDLE) && !this._active) {
+                D.addClass(tar, this.CSS_HANDLE + '-active');
+                for (var i in this._handles) {
+                    if (Lang.hasOwnProperty(this._handles, i)) {
+                        if (this._handles[i] == tar) {
+                            D.addClass(tar, this.CSS_HANDLE + '-' + i + '-active');
+                            break;
+                        }
+                    }
+                }
+            }
+
+            //Internet Explorer needs this
+            D.addClass(this._wrap, this.CSS_RESIZE);
+        },
+        /** 
+        * @private
+        * @method _handleMouseOut
+        * @param {Event} ev A mouse event.
+        * @description Removes CSS class names to the handles
+        */
+        _handleMouseOut: function(ev) {
+            //Internet Explorer needs this
+            D.removeClass(this._wrap, this.CSS_RESIZE);
+            if (this.get('hover') && !this._active) {
+                D.addClass(this._wrap, this.CSS_HOVER);
+            }
+            var tar = Event.getTarget(ev);
+            if (!D.hasClass(tar, this.CSS_HANDLE)) {
+                tar = tar.parentNode;
+            }
+            if (D.hasClass(tar, this.CSS_HANDLE) && !this._active) {
+                D.removeClass(tar, this.CSS_HANDLE + '-active');
+                for (var i in this._handles) {
+                    if (Lang.hasOwnProperty(this._handles, i)) {
+                        if (this._handles[i] == tar) {
+                            D.removeClass(tar, this.CSS_HANDLE + '-' + i + '-active');
+                            break;
+                        }
+                    }
+                }
+            }
+            //Internet Explorer needs this
+            D.addClass(this._wrap, this.CSS_RESIZE);
+        },
+        /** 
+        * @private
+        * @method _handleStartDrag
+        * @param {Object} args The args passed from the CustomEvent.
+        * @param {Object} dd The <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> object we are working with.
+        * @description Resizes the proxy, sets up the <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> handlers, updates the status div and preps the cache
+        */
+        _handleStartDrag: function(args, dd) {
+            YAHOO.log('startDrag', 'info', 'Resize');
+            var tar = dd.getDragEl();
+            if (D.hasClass(tar, this.CSS_HANDLE)) {
+                if (D.getStyle(this._wrap, 'position') == 'absolute') {
+                    this._positioned = true;
+                }
+                this._active = true;
+                this._currentDD = dd;
+                if (this._proxy) {
+                    YAHOO.log('Activate proxy element', 'info', 'Resize');
+                    this._proxy.style.visibility = 'visible';
+                    this._proxy.style.zIndex = '1000';
+                    this._proxy.style.height = this.get('element').clientHeight + 'px';
+                    this._proxy.style.width = this.get('element').clientWidth + 'px';
+                }
+
+                for (var i in this._handles) {
+                    if (Lang.hasOwnProperty(this._handles, i)) {
+                        if (this._handles[i] == tar) {
+                            this._currentHandle = i;
+                            var handle = '_handle_for_' + i;
+                            D.addClass(tar, this.CSS_HANDLE + '-' + i + '-active');
+                            dd.on('dragEvent', this[handle], this, true);
+                            dd.on('mouseUpEvent', this._handleMouseUp, this, true);
+                            YAHOO.log('Adding DragEvents to: ' + i, 'info', 'Resize');
+                            break;
+                        }
+                    }
+                }
+
+
+                D.addClass(tar, this.CSS_HANDLE + '-active');
+
+                if (this.get('proxy')) {
+                    YAHOO.log('Posiiton Proxy Element', 'info', 'Resize');
+                    var xy = D.getXY(this.get('element'));
+                    D.setXY(this._proxy, xy);
+                    if (this.get('ghost')) {
+                        YAHOO.log('Add Ghost Class', 'info', 'Resize');
+                        this.addClass(this.CSS_GHOST);
+                    }
+                }
+                D.addClass(this._wrap, this.CSS_RESIZING);
+                this._setCache();
+                this._updateStatus(this._cache.height, this._cache.width, this._cache.top, this._cache.left);
+                YAHOO.log('Firing startResize Event', 'info', 'Resize');
+                this.fireEvent('startResize', { type: 'startresize', target: this});
+            }
+        },
+        /** 
+        * @private
+        * @method _setCache
+        * @description Sets up the this._cache hash table.
+        */
+        _setCache: function() {
+            YAHOO.log('Setting up property cache', 'info', 'Resize');
+            this._cache.xy = D.getXY(this._wrap);
+            D.setXY(this._wrap, this._cache.xy);
+            this._cache.height = this.get('clientHeight');
+            this._cache.width = this.get('clientWidth');
+            this._cache.start.height = this._cache.height;
+            this._cache.start.width = this._cache.width;
+            this._cache.start.top = this._cache.xy[1];
+            this._cache.start.left = this._cache.xy[0];
+            this._cache.top = this._cache.xy[1];
+            this._cache.left = this._cache.xy[0];
+            this.set('height', this._cache.height, true);
+            this.set('width', this._cache.width, true);
+        },
+        /** 
+        * @private
+        * @method _handleMouseUp
+        * @param {Event} ev A mouse event.
+        * @description Cleans up listeners, hides proxy element and removes class names.
+        */
+        _handleMouseUp: function(ev) {
+            this._active = false;
+
+            var handle = '_handle_for_' + this._currentHandle;
+            this._currentDD.unsubscribe('dragEvent', this[handle], this, true);
+            this._currentDD.unsubscribe('mouseUpEvent', this._handleMouseUp, this, true);
+
+            if (this._proxy) {
+                YAHOO.log('Hide Proxy Element', 'info', 'Resize');
+                this._proxy.style.visibility = 'hidden';
+                this._proxy.style.zIndex = '-1';
+                if (this.get('setSize')) {
+                    YAHOO.log('Setting Size', 'info', 'Resize');
+                    this.resize(ev, this._cache.height, this._cache.width, this._cache.top, this._cache.left, true);
+                } else {
+                    YAHOO.log('Firing Resize Event', 'info', 'Resize');
+                    this.fireEvent('resize', { ev: 'resize', target: this, height: this._cache.height, width: this._cache.width, top: this._cache.top, left: this._cache.left });
+                }
+
+                if (this.get('ghost')) {
+                    YAHOO.log('Removing Ghost Class', 'info', 'Resize');
+                    this.removeClass(this.CSS_GHOST);
+                }
+            }
+
+            if (this.get('hover')) {
+                D.addClass(this._wrap, this.CSS_HOVER);
+            }
+            if (this._status) {
+                D.setStyle(this._status, 'display', 'none');
+            }
+            if (this.browser.ie) {
+                YAHOO.log('Resetting IE onselectstart function', 'info', 'Resize');
+                document.body.onselectstart = this._ieSelectBack;
+            }
+
+            if (this.browser.ie) {
+                D.removeClass(this._wrap, this.CSS_RESIZE);
+            }
+
+            for (var i in this._handles) {
+                if (Lang.hasOwnProperty(this._handles, i)) {
+                    D.removeClass(this._handles[i], this.CSS_HANDLE + '-active');
+                }
+            }
+            if (this.get('hover') && !this._active) {
+                D.addClass(this._wrap, this.CSS_HOVER);
+            }
+            D.removeClass(this._wrap, this.CSS_RESIZING);
+
+            D.removeClass(this._handles[this._currentHandle], this.CSS_HANDLE + '-' + this._currentHandle + '-active');
+            D.removeClass(this._handles[this._currentHandle], this.CSS_HANDLE + '-active');
+
+            if (this.browser.ie) {
+                D.addClass(this._wrap, this.CSS_RESIZE);
+            }
+
+            this._resizeEvent = null;
+            this._currentHandle = null;
+        },
+        /** 
+        * @private
+        * @method _setRatio
+        * @param {Number} h The height offset.
+        * @param {Number} w The with offset.
+        * @param {Number} t The top offset.
+        * @param {Number} l The left offset.
+        * @description Using the Height, Width, Top & Left, it recalcuates them based on the original element size.
+        * @return {Array} The new Height, Width, Top & Left settings
+        */
+        _setRatio: function(h, w, t, l) {
+            YAHOO.log('Setting Ratio', 'info', 'Resize');
+            var oh = h, ow = w;
+            if (this.get('ratio')) {
+                var orgH = this._cache.height,
+                    orgW = this._cache.width,
+                    nh = parseInt(this.get('height'), 10),
+                    nw = parseInt(this.get('width'), 10),
+                    maxH = this.get('maxHeight'),
+                    minH = this.get('minHeight'),
+                    maxW = this.get('maxWidth'),
+                    minW = this.get('minWidth');
+
+                switch (this._currentHandle) {
+                    case 'l':
+                        h = nh * (w / nw);
+                        h = Math.min(Math.max(minH, h), maxH);                        
+                        w = nw * (h / nh);
+                        t = (this._cache.start.top - (-((nh - h) / 2)));
+                        l = (this._cache.start.left - (-((nw - w))));
+                        break;
+                    case 'r':
+                        h = nh * (w / nw);
+                        h = Math.min(Math.max(minH, h), maxH);                        
+                        w = nw * (h / nh);
+                        t = (this._cache.start.top - (-((nh - h) / 2)));
+                        break;
+                    case 't':
+                        w = nw * (h / nh);
+                        h = nh * (w / nw);
+                        l = (this._cache.start.left - (-((nw - w) / 2)));
+                        t = (this._cache.start.top - (-((nh - h))));
+                        break;
+                    case 'b':
+                        w = nw * (h / nh);
+                        h = nh * (w / nw);
+                        l = (this._cache.start.left - (-((nw - w) / 2)));
+                        break;
+                    case 'bl':
+                        h = nh * (w / nw);
+                        w = nw * (h / nh);
+                        l = (this._cache.start.left - (-((nw - w))));
+                        break;
+                    case 'br':
+                        h = nh * (w / nw);
+                        w = nw * (h / nh);
+                        break;
+                    case 'tl':
+                        h = nh * (w / nw);
+                        w = nw * (h / nh);
+                        l = (this._cache.start.left - (-((nw - w))));
+                        t = (this._cache.start.top - (-((nh - h))));
+                        break;
+                    case 'tr':
+                        h = nh * (w / nw);
+                        w = nw * (h / nh);
+                        l = (this._cache.start.left);
+                        t = (this._cache.start.top - (-((nh - h))));
+                        break;
+                }
+                oh = this._checkHeight(h);
+                ow = this._checkWidth(w);
+                if ((oh != h) || (ow != w)) {
+                    t = 0;
+                    l = 0;
+                    if (oh != h) {
+                        ow = this._cache.width;
+                    }
+                    if (ow != w) {
+                        oh = this._cache.height;
+                    }
+                }
+            }
+            return [oh, ow, t, l];
+        },
+        /** 
+        * @private
+        * @method _updateStatus
+        * @param {Number} h The new height setting.
+        * @param {Number} w The new width setting.
+        * @param {Number} t The new top setting.
+        * @param {Number} l The new left setting.
+        * @description Using the Height, Width, Top & Left, it updates the status element with the elements sizes.
+        */
+        _updateStatus: function(h, w, t, l) {
+            if (this._resizeEvent && (!Lang.isString(this._resizeEvent))) {
+                YAHOO.log('Updating Status Box', 'info', 'Resize');
+                if (this.get('status')) {
+                    YAHOO.log('Showing Status Box', 'info', 'Resize');
+                    D.setStyle(this._status, 'display', 'inline');
+                }
+                h = ((h === 0) ? this._cache.start.height : h);
+                w = ((w === 0) ? this._cache.start.width : w);
+                var h1 = parseInt(this.get('height'), 10),
+                    w1 = parseInt(this.get('width'), 10);
+                
+                if (isNaN(h1)) {
+                    h1 = parseInt(h, 10);
+                }
+                if (isNaN(w1)) {
+                    w1 = parseInt(w, 10);
+                }
+                var diffH = (parseInt(h, 10) - h1);
+                var diffW = (parseInt(w, 10) - w1);
+                this._cache.offsetHeight = diffH;
+                this._cache.offsetWidth = diffW;
+                this._status.innerHTML = '<strong>' + parseInt(h, 10) + ' x ' + parseInt(w, 10) + '</strong><em>' + ((diffH > 0) ? '+' : '') + diffH + ' x ' + ((diffW > 0) ? '+' : '') + diffW + '</em>';
+                D.setXY(this._status, [Event.getPageX(this._resizeEvent) + 12, Event.getPageY(this._resizeEvent) + 12]);
+            }
+        },
+        /** 
+        * @method reset
+        * @description Resets the element to is start state.
+        * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
+        */
+        reset: function() {
+            YAHOO.log('Resetting to cached sizes and position', 'info', 'Resize');
+            this.resize(null, this._cache.start.height, this._cache.start.width, this._cache.start.top, this._cache.start.left, true);
+            return this;
+        },
+        /** 
+        * @method resize
+        * @param {Event} ev The mouse event.
+        * @param {Number} h The new height setting.
+        * @param {Number} w The new width setting.
+        * @param {Number} t The new top setting.
+        * @param {Number} l The new left setting.
+        * @param {Boolean} force Resize the element (used for proxy resize).
+        * @param {Boolean} silent Don't fire the beforeResize Event.
+        * @description Resizes the element, wrapper or proxy based on the data from the handlers.
+        * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
+        */
+        resize: function(ev, h, w, t, l, force, silent) {
+            YAHOO.log('Resize: ' + h + ',' + w + ',' + t + ',' + l, 'info', 'Resize');
+            this._resizeEvent = ev;
+            var el = this._wrap, anim = this.get('animate'), set = true;
+            if (this._proxy && !force) {
+                el = this._proxy;
+                anim = false;
+            }
+            this._setAutoRatio(ev);
+            if (this._positioned) {
+                if (this._proxy) {
+                    t = this._cache.top - t;
+                    l = this._cache.left - l;
+                }
+            }
+
+            var ratio = this._setRatio(h, w, t, l);
+            h = parseInt(ratio[0], 10);
+            w = parseInt(ratio[1], 10);
+            t = parseInt(ratio[2], 10);
+            l = parseInt(ratio[3], 10);
+
+            if (t == 0) {
+                //No Offset, get from cache
+                t = D.getY(el);
+            }
+            if (l == 0) {
+                //No Offset, get from cache
+                l = D.getX(el);
+            }
+
+            
+
+            if (this._positioned) {
+                if (this._proxy && force) {
+                    if (!anim) {
+                        el.style.top = this._proxy.style.top;
+                        el.style.left = this._proxy.style.left;
+                    } else {
+                        t = this._proxy.style.top;
+                        l = this._proxy.style.left;
+                    }
+                } else {
+                    if (!this.get('ratio') && !this._proxy) {
+                        t = this._cache.top + -(t);
+                        l = this._cache.left + -(l);
+                    }
+                    if (t) {
+                        if (this.get('minY')) {
+                            if (t < this.get('minY')) {
+                                t = this.get('minY');
+                            }
+                        }
+                        if (this.get('maxY')) {
+                            if (t > this.get('maxY')) {
+                                t = this.get('maxY');
+                            }
+                        }
+                    }
+                    if (l) {
+                        if (this.get('minX')) {
+                            if (l < this.get('minX')) {
+                                l = this.get('minX');
+                            }
+                        }
+                        if (this.get('maxX')) {
+                            if ((l + w) > this.get('maxX')) {
+                                l = (this.get('maxX') - w);
+                            }
+                        }
+                    }
+                }
+            }
+            if (!silent) {
+                YAHOO.log('beforeResize', 'info', 'Resize');
+                var beforeReturn = this.fireEvent('beforeResize', { ev: 'beforeResize', target: this, height: h, width: w, top: t, left: l });
+                if (beforeReturn === false) {
+                    YAHOO.log('Resized cancelled because befireResize returned false', 'info', 'Resize');
+                    return false;
+                }
+            }
+
+            this._updateStatus(h, w, t, l);
+
+            if (this._positioned) {
+                if (this._proxy && force) {
+                    //Do nothing
+                } else {
+                    if (t) {
+                        D.setY(el, t);
+                        this._cache.top = t;
+                    }
+                    if (l) {
+                        D.setX(el, l);
+                        this._cache.left = l;
+                    }
+                }
+            }
+            if (h) {
+                if (!anim) {
+                    set = true;
+                    if (this._proxy && force) {
+                        if (!this.get('setSize')) {
+                            set = false;
+                        }
+                    }
+                    if (set) {
+                        if (this.browser.ie > 6) {
+                            if (h === this._cache.height) {
+                                h = h + 1;
+                            }
+                        }
+                        el.style.height = h + 'px';
+                    }
+                    if ((this._proxy && force) || !this._proxy) {
+                        if (this._wrap != this.get('element')) {
+                            this.get('element').style.height = h + 'px';
+                        }
+                    }
+                }
+                this._cache.height = h;
+            }
+            if (w) {
+                this._cache.width = w;
+                if (!anim) {
+                    set = true;
+                    if (this._proxy && force) {
+                        if (!this.get('setSize')) {
+                            set = false;
+                        }
+                    }
+                    if (set) {
+                        el.style.width = w + 'px';
+                    }
+                    if ((this._proxy && force) || !this._proxy) {
+                        if (this._wrap != this.get('element')) {
+                            this.get('element').style.width = w + 'px';
+                        }
+                    }
+                }
+            }
+            if (anim) {
+                if (YAHOO.util.Anim) {
+                    var _anim = new YAHOO.util.Anim(el, {
+                        height: {
+                            to: this._cache.height
+                        },
+                        width: {
+                            to: this._cache.width
+                        }
+                    }, this.get('animateDuration'), this.get('animateEasing'));
+                    if (this._positioned) {
+                        if (t) {
+                            _anim.attributes.top = {
+                                to: parseInt(t, 10)
+                            };
+                        }
+                        if (l) {
+                            _anim.attributes.left = {
+                                to: parseInt(l, 10)
+                            };
+                        }
+                    }
+
+                    if (this._wrap != this.get('element')) {
+                        _anim.onTween.subscribe(function() {
+                            this.get('element').style.height = el.style.height;
+                            this.get('element').style.width = el.style.width;
+                        }, this, true);
+                    }
+
+                    _anim.onComplete.subscribe(function() {
+                        YAHOO.log('Animation onComplete fired', 'info', 'Resize');
+                        this.set('height', h);
+                        this.set('width', w);
+                        this.fireEvent('resize', { ev: 'resize', target: this, height: h, width: w, top: t, left: l });
+                    }, this, true);
+                    _anim.animate();
+
+                }
+            } else {
+                if (this._proxy && !force) {
+                    YAHOO.log('proxyResize', 'info', 'Resize');
+                    this.fireEvent('proxyResize', { ev: 'proxyresize', target: this, height: h, width: w, top: t, left: l });
+                } else {
+                    YAHOO.log('resize', 'info', 'Resize');
+                    this.fireEvent('resize', { ev: 'resize', target: this, height: h, width: w, top: t, left: l });
+                }
+            }
+            return this;
+        },
+        /** 
+        * @private
+        * @method _handle_for_br
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Bottom Right handle.
+        */
+        _handle_for_br: function(args) {
+            YAHOO.log('Handle BR', 'info', 'Resize');
+            var newW = this._setWidth(args.e);
+            var newH = this._setHeight(args.e);
+            this.resize(args.e, (newH + 1), newW, 0, 0);
+        },
+        /** 
+        * @private
+        * @method _handle_for_bl
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Bottom Left handle.
+        */
+        _handle_for_bl: function(args) {
+            YAHOO.log('Handle BL', 'info', 'Resize');
+            var newW = this._setWidth(args.e, true);
+            var newH = this._setHeight(args.e);
+            var l = (newW - this._cache.width);
+            this.resize(args.e, newH, newW, 0, l);
+        },
+        /** 
+        * @private
+        * @method _handle_for_tl
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Top Left handle.
+        */
+        _handle_for_tl: function(args) {
+            YAHOO.log('Handle TL', 'info', 'Resize');
+            var newW = this._setWidth(args.e, true);
+            var newH = this._setHeight(args.e, true);
+            var t = (newH - this._cache.height);
+            var l = (newW - this._cache.width);
+            this.resize(args.e, newH, newW, t, l);
+        },
+        /** 
+        * @private
+        * @method _handle_for_tr
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Top Right handle.
+        */
+        _handle_for_tr: function(args) {
+            YAHOO.log('Handle TR', 'info', 'Resize');
+            var newW = this._setWidth(args.e);
+            var newH = this._setHeight(args.e, true);
+            var t = (newH - this._cache.height);
+            this.resize(args.e, newH, newW, t, 0);
+        },
+        /** 
+        * @private
+        * @method _handle_for_r
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Right handle.
+        */
+        _handle_for_r: function(args) {
+            YAHOO.log('Handle R', 'info', 'Resize');
+            this._dds.r.setYConstraint(0,0);
+            var newW = this._setWidth(args.e);
+            this.resize(args.e, 0, newW, 0, 0);
+        },
+        /** 
+        * @private
+        * @method _handle_for_l
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Left handle.
+        */
+        _handle_for_l: function(args) {
+            YAHOO.log('Handle L', 'info', 'Resize');
+            this._dds.l.setYConstraint(0,0);
+            var newW = this._setWidth(args.e, true);
+            var l = (newW - this._cache.width);
+            this.resize(args.e, 0, newW, 0, l);
+        },
+        /** 
+        * @private
+        * @method _handle_for_b
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Bottom handle.
+        */
+        _handle_for_b: function(args) {
+            YAHOO.log('Handle B', 'info', 'Resize');
+            this._dds.b.setXConstraint(0,0);
+            var newH = this._setHeight(args.e);
+            this.resize(args.e, newH, 0, 0, 0);
+        },
+        /** 
+        * @private
+        * @method _handle_for_t
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Top handle.
+        */
+        _handle_for_t: function(args) {
+            YAHOO.log('Handle T', 'info', 'Resize');
+            this._dds.t.setXConstraint(0,0);
+            var newH = this._setHeight(args.e, true);
+            var t = (newH - this._cache.height);
+            this.resize(args.e, newH, 0, t, 0);
+        },
+        /** 
+        * @private
+        * @method _setWidth
+        * @param {Event} ev The mouse event.
+        * @param {Boolean} flip Argument to determine the direction of the movement.
+        * @description Calculates the width based on the mouse event.
+        * @return {Number} The new value
+        */
+        _setWidth: function(ev, flip) {
+            YAHOO.log('Set width based on Event', 'info', 'Resize');
+            var xy = this._cache.xy[0],
+                w = this._cache.width,
+                x = Event.getPageX(ev),
+                nw = (x - xy);
+
+                if (flip) {
+                    nw = (xy - x) + parseInt(this.get('width'), 10);
+                }
+                
+                nw = this._snapTick(nw, this.get('yTicks'));
+                nw = this._checkWidth(nw);
+            return nw;
+        },
+        /** 
+        * @private
+        * @method _checkWidth
+        * @param {Number} w The width to check.
+        * @description Checks the value passed against the maxWidth and minWidth.
+        * @return {Number} the new value
+        */
+        _checkWidth: function(w) {
+            YAHOO.log('Checking the min/max width', 'info', 'Resize');
+            if (this.get('minWidth')) {
+                if (w <= this.get('minWidth')) {
+                    YAHOO.log('Using minWidth', 'info', 'Resize');
+                    w = this.get('minWidth');
+                }
+            }
+            if (this.get('maxWidth')) {
+                if (w >= this.get('maxWidth')) {
+                    YAHOO.log('Using Max Width', 'info', 'Resize');
+                    w = this.get('maxWidth');
+                }
+            }
+            return w;
+        },
+        /** 
+        * @private
+        * @method _checkHeight
+        * @param {Number} h The height to check.
+        * @description Checks the value passed against the maxHeight and minHeight.
+        * @return {Number} The new value
+        */
+        _checkHeight: function(h) {
+            YAHOO.log('Checking the min/max height', 'info', 'Resize');
+            if (this.get('minHeight')) {
+                if (h <= this.get('minHeight')) {
+                    YAHOO.log('Using minHeight', 'info', 'Resize');
+                    h = this.get('minHeight');
+                }
+            }
+            if (this.get('maxHeight')) {
+                if (h >= this.get('maxHeight')) {
+                    YAHOO.log('using maxHeight', 'info', 'Resize');
+                    h = this.get('maxHeight');
+                }
+            }
+            return h;
+        },
+        /** 
+        * @private
+        * @method _setHeight
+        * @param {Event} ev The mouse event.
+        * @param {Boolean} flip Argument to determine the direction of the movement.
+        * @description Calculated the height based on the mouse event.
+        * @return {Number} The new value
+        */
+        _setHeight: function(ev, flip) {
+            YAHOO.log('Setting the height based on the Event', 'info', 'Resize');
+            var xy = this._cache.xy[1],
+                h = this._cache.height,
+                y = Event.getPageY(ev),
+                nh = (y - xy);
+
+                if (flip) {
+                    nh = (xy - y) + parseInt(this.get('height'), 10);
+                }
+                nh = this._snapTick(nh, this.get('xTicks'));
+                nh = this._checkHeight(nh);
+                
+            return nh;
+        },
+        /** 
+        * @private
+        * @method _snapTick
+        * @param {Number} size The size to tick against.
+        * @param {Number} pix The tick pixels.
+        * @description Adjusts the number based on the ticks used.
+        * @return {Number} the new snapped position
+        */
+        _snapTick: function(size, pix) {
+            YAHOO.log('Snapping to ticks', 'info', 'Resize');
+            if (!size || !pix) {
+                return size;
+            }
+            var _s = size;
+            var _x = size % pix;
+            if (_x > 0) {
+                if (_x > (pix / 2)) {
+                    _s = size + (pix - _x);
+                } else {
+                    _s = size - _x;
+                }
+            }
+            return _s;
+        },
+        /** 
+        * @private
+        * @method init
+        * @description The Resize class's initialization method
+        */        
+        init: function(p_oElement, p_oAttributes) {
+            YAHOO.log('init', 'info', 'Resize');
+            this._cache = {
+                xy: [],
+                height: 0,
+                width: 0,
+                top: 0,
+                left: 0,
+                offsetHeight: 0,
+                offsetWidth: 0,
+                start: {
+                    height: 0,
+                    width: 0,
+                    top: 0,
+                    left: 0
+                }
+            };
+
+            Resize.superclass.init.call(this, p_oElement, p_oAttributes);
+
+            this.set('setSize', this.get('setSize'));
+
+            if (p_oAttributes.height) {
+                this.set('height', parseInt(p_oAttributes.height, 10));
+            }
+            if (p_oAttributes.width) {
+                this.set('width', parseInt(p_oAttributes.width, 10));
+            }
+            
+            var id = p_oElement;
+            if (!Lang.isString(id)) {
+                id = D.generateId(id);
+            }
+            Resize._instances[id] = this;
+
+            this._active = false;
+            
+            this._createWrap();
+            this._createProxy();
+            this._createHandles();
+
+        },
+        /**
+        * @method getProxyEl
+        * @description Get the HTML reference for the proxy, returns null if no proxy.
+        * @return {HTMLElement} The proxy element
+        */      
+        getProxyEl: function() {
+            return this._proxy;
+        },
+        /**
+        * @method getWrapEl
+        * @description Get the HTML reference for the wrap element, returns the current element if not wrapped.
+        * @return {HTMLElement} The wrap element
+        */      
+        getWrapEl: function() {
+            return this._wrap;
+        },
+        /**
+        * @method getStatusEl
+        * @description Get the HTML reference for the status element.
+        * @return {HTMLElement} The status element
+        */      
+        getStatusEl: function() {
+            return this._status;
+        },
+        /**
+        * @method getActiveHandleEl
+        * @description Get the HTML reference for the currently active resize handle.
+        * @return {HTMLElement} The handle element that is active
+        */      
+        getActiveHandleEl: function() {
+            return this._handles[this._currentHandle];
+        },
+        /**
+        * @method isActive
+        * @description Returns true or false if a resize operation is currently active on the element.
+        * @return {Boolean}
+        */      
+        isActive: function() {
+            return ((this._active) ? true : false);
+        },
+        /**
+        * @private
+        * @method initAttributes
+        * @description Initializes all of the configuration attributes used to create a resizable element.
+        * @param {Object} attr Object literal specifying a set of 
+        * configuration attributes used to create the utility.
+        */      
+        initAttributes: function(attr) {
+            Resize.superclass.initAttributes.call(this, attr);
+
+            /**
+            * @attribute setSize
+            * @description Set the size of the resized element, if set to false the element will not be auto resized,
+            * the resize event will contain the dimensions so the end user can resize it on their own.
+            * This setting will only work with proxy set to true and animate set to false.
+            * @type Boolean
+            */
+            this.setAttributeConfig('setSize', {
+                value: ((attr.setSize === false) ? false : true),
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute wrap
+            * @description Should we wrap the element
+            * @type Boolean
+            */
+            this.setAttributeConfig('wrap', {
+                writeOnce: true,
+                validator: YAHOO.lang.isBoolean,
+                value: attr.wrap || false
+            });
+
+            /**
+            * @attribute handles
+            * @description The handles to use (any combination of): 't', 'b', 'r', 'l', 'bl', 'br', 'tl', 'tr'. Defaults to: ['r', 'b', 'br'].
+            * Can use a shortcut of All. Note: 8 way resizing should be done on an element that is absolutely positioned.
+            * @type Array
+            */
+            this.setAttributeConfig('handles', {
+                writeOnce: true,
+                value: attr.handles || ['r', 'b', 'br'],
+                validator: function(handles) {
+                    if (Lang.isString(handles) && handles.toLowerCase() == 'all') {
+                        handles = ['t', 'b', 'r', 'l', 'bl', 'br', 'tl', 'tr'];
+                    }
+                    if (!Lang.isArray(handles)) {
+                        handles = handles.replace(/, /g, ',');
+                        handles = handles.split(',');
+                    }
+                    this._configs.handles.value = handles;
+                }
+            });
+
+            /**
+            * @attribute width
+            * @description The width of the element
+            * @type Number
+            */
+            this.setAttributeConfig('width', {
+                value: attr.width || parseInt(this.getStyle('width'), 10),
+                validator: YAHOO.lang.isNumber,
+                method: function(width) {
+                    width = parseInt(width, 10);
+                    if (width > 0) {
+                        if (this.get('setSize')) {
+                            this.setStyle('width', width + 'px');
+                        }
+                        this._cache.width = width;
+                        this._configs.width.value = width;
+                    }
+                }
+            });
+
+            /**
+            * @attribute height
+            * @description The height of the element
+            * @type Number
+            */
+            this.setAttributeConfig('height', {
+                value: attr.height || parseInt(this.getStyle('height'), 10),
+                validator: YAHOO.lang.isNumber,
+                method: function(height) {
+                    height = parseInt(height, 10);
+                    if (height > 0) {
+                        if (this.get('setSize')) {
+                            this.setStyle('height', height + 'px');
+                        }
+                        this._cache.height = height;
+                        this._configs.height.value = height;
+                    }
+                }
+            });
+
+            /**
+            * @attribute minWidth
+            * @description The minimum width of the element
+            * @type Number
+            */
+            this.setAttributeConfig('minWidth', {
+                value: attr.minWidth || 15,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute minHeight
+            * @description The minimum height of the element
+            * @type Number
+            */
+            this.setAttributeConfig('minHeight', {
+                value: attr.minHeight || 15,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute maxWidth
+            * @description The maximum width of the element
+            * @type Number
+            */
+            this.setAttributeConfig('maxWidth', {
+                value: attr.maxWidth || 10000,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute maxHeight
+            * @description The maximum height of the element
+            * @type Number
+            */
+            this.setAttributeConfig('maxHeight', {
+                value: attr.maxHeight || 10000,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute minY
+            * @description The minimum y coord of the element
+            * @type Number
+            */
+            this.setAttributeConfig('minY', {
+                value: attr.minY || false
+            });
+
+            /**
+            * @attribute minX
+            * @description The minimum x coord of the element
+            * @type Number
+            */
+            this.setAttributeConfig('minX', {
+                value: attr.minX || false
+            });
+            /**
+            * @attribute maxY
+            * @description The max y coord of the element
+            * @type Number
+            */
+            this.setAttributeConfig('maxY', {
+                value: attr.maxY || false
+            });
+
+            /**
+            * @attribute maxX
+            * @description The max x coord of the element
+            * @type Number
+            */
+            this.setAttributeConfig('maxX', {
+                value: attr.maxX || false
+            });
+
+            /**
+            * @attribute animate
+            * @description Should be use animation to resize the element (can only be used if we use proxy).
+            * @type Boolean
+            */
+            this.setAttributeConfig('animate', {
+                value: attr.animate || false,
+                validator: function(value) {
+                    var ret = true;
+                    if (!YAHOO.util.Anim) {
+                        ret = false;
+                    }
+                    return ret;
+                }               
+            });
+
+            /**
+            * @attribute animateEasing
+            * @description The Easing to apply to the animation.
+            * @type Object
+            */
+            this.setAttributeConfig('animateEasing', {
+                value: attr.animateEasing || function() {
+                    var easing = false;
+                    try {
+                        easing = YAHOO.util.Easing.easeOut;
+                    } catch (e) {}
+                    return easing;
+                }()
+            });
+
+            /**
+            * @attribute animateDuration
+            * @description The Duration to apply to the animation.
+            * @type Number
+            */
+            this.setAttributeConfig('animateDuration', {
+                value: attr.animateDuration || 0.5
+            });
+
+            /**
+            * @attribute proxy
+            * @description Resize a proxy element instead of the real element.
+            * @type Boolean
+            */
+            this.setAttributeConfig('proxy', {
+                value: attr.proxy || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute ratio
+            * @description Maintain the element's ratio when resizing.
+            * @type Boolean
+            */
+            this.setAttributeConfig('ratio', {
+                value: attr.ratio || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute ghost
+            * @description Apply an opacity filter to the element being resized (only works with proxy).
+            * @type Boolean
+            */
+            this.setAttributeConfig('ghost', {
+                value: attr.ghost || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute draggable
+            * @description A convienence method to make the element draggable
+            * @type Boolean
+            */
+            this.setAttributeConfig('draggable', {
+                value: attr.draggable || false,
+                validator: YAHOO.lang.isBoolean,
+                method: function(dd) {
+                    if (dd && this._wrap) {
+                        this._setupDragDrop();
+                    } else {
+                        if (this.dd) {
+                            D.removeClass(this._wrap, this.CSS_DRAG);
+                            this.dd.unreg();
+                        }
+                    }
+                }
+            });
+
+            /**
+            * @attribute hover
+            * @description Only show the handles when they are being moused over.
+            * @type Boolean
+            */
+            this.setAttributeConfig('hover', {
+                value: attr.hover || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute hiddenHandles
+            * @description Don't show the handles, just use the cursor to the user.
+            * @type Boolean
+            */
+            this.setAttributeConfig('hiddenHandles', {
+                value: attr.hiddenHandles || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute knobHandles
+            * @description Use the smaller handles, instead if the full size handles.
+            * @type Boolean
+            */
+            this.setAttributeConfig('knobHandles', {
+                value: attr.knobHandles || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute xTicks
+            * @description The number of x ticks to span the resize to.
+            * @type Number or False
+            */
+            this.setAttributeConfig('xTicks', {
+                value: attr.xTicks || false
+            });
+
+            /**
+            * @attribute yTicks
+            * @description The number of y ticks to span the resize to.
+            * @type Number or False
+            */
+            this.setAttributeConfig('yTicks', {
+                value: attr.yTicks || false
+            });
+
+            /**
+            * @attribute status
+            * @description Show the status (new size) of the resize.
+            * @type Boolean
+            */
+            this.setAttributeConfig('status', {
+                value: attr.status || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute autoRatio
+            * @description Using the shift key during a resize will toggle the ratio config.
+            * @type Boolean
+            */
+            this.setAttributeConfig('autoRatio', {
+                value: attr.autoRatio || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+        },
+        /**
+        * @method destroy
+        * @description Destroys the resize object and all of it's elements & listeners.
+        */        
+        destroy: function() {
+            YAHOO.log('Destroying Resize', 'info', 'Resize');
+            for (var h in this._handles) {
+                if (Lang.hasOwnProperty(this._handles, h)) {
+                    Event.purgeElement(this._handles[h]);
+                    this._handles[h].parentNode.removeChild(this._handles[h]);
+                }
+            }
+            if (this._proxy) {
+                this._proxy.parentNode.removeChild(this._proxy);
+            }
+            if (this._status) {
+                this._status.parentNode.removeChild(this._status);
+            }
+            if (this.dd) {
+                this.dd.unreg();
+                D.removeClass(this._wrap, this.CSS_DRAG);
+            }
+            if (this._wrap != this.get('element')) {
+                this.setStyle('position', '');
+                this.setStyle('top', '');
+                this.setStyle('left', '');
+                this._wrap.parentNode.replaceChild(this.get('element'), this._wrap);
+            }
+            this.removeClass(this.CSS_RESIZE);
+
+            delete YAHOO.util.Resize._instances[this.get('id')];
+            //Brutal Object Destroy
+            for (var i in this) {
+                if (Lang.hasOwnProperty(this, i)) {
+                    this[i] = null;
+                    delete this[i];
+                }
+            }
+        },
+        /**
+        * @method toString
+        * @description Returns a string representing the Resize Object.
+        * @return {String}
+        */        
+        toString: function() {
+            if (this.get) {
+                return 'Resize (#' + this.get('id') + ')';
+            }
+            return 'Resize Utility';
+        }
+    });
+
+    YAHOO.util.Resize = Resize;
+ 
+/**
+* @event dragEvent
+* @description Fires when the <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> dragEvent is fired for the config option draggable.
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event startResize
+* @description Fires when when a resize action is started.
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event resize
+* @description Fires on every element resize (only fires once when used with proxy config setting).
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event beforeResize
+* @description Fires before every element resize after the size calculations, returning false will stop the resize.
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event proxyResize
+* @description Fires on every proxy resize (only fires when used with proxy config setting).
+* @type YAHOO.util.CustomEvent
+*/
+
+})();
+
+YAHOO.register("resize", YAHOO.util.Resize, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/resize/resize-beta-min.js
===================================================================
--- trunk/root/static/yui/resize/resize-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/resize/resize-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,10 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+(function(){var E=YAHOO.util.Dom,A=YAHOO.util.Event,C=YAHOO.lang;var B=function(F,D){var G={element:F,attributes:D||{}};B.superclass.constructor.call(this,G.element,G.attributes);};B._instances={};B.getResizeById=function(D){if(B._instances[D]){return B._instances[D];}return false;};YAHOO.extend(B,YAHOO.util.Element,{CSS_RESIZE:"yui-resize",CSS_DRAG:"yui-draggable",CSS_HOVER:"yui-resize-hover",CSS_PROXY:"yui-resize-proxy",CSS_WRAP:"yui-resize-wrap",CSS_KNOB:"yui-resize-knob",CSS_HIDDEN:"yui-resize-hidden",CSS_HANDLE:"yui-resize-handle",CSS_STATUS:"yui-resize-status",CSS_GHOST:"yui-resize-ghost",CSS_RESIZING:"yui-resize-resizing",_resizeEvent:null,dd:null,browser:YAHOO.env.ua,_positioned:null,_dds:null,_wrap:null,_proxy:null,_handles:null,_currentHandle:null,_currentDD:null,_cache:null,_active:null,_createProxy:function(){if(this.get("proxy")){this._proxy=document.createElement("div");this._proxy.className=this.CSS_PROXY;this._proxy.style.height=this.get("element").clientHei!
 ght+"px";this._proxy.style.width=this.get("element").clientWidth+"px";this._wrap.parentNode.appendChild(this._proxy);}else{this.set("animate",false);}},_createWrap:function(){this._positioned=false;switch(this.get("element").tagName.toLowerCase()){case"img":case"textarea":case"input":case"iframe":case"select":this.set("wrap",true);break;}if(this.get("wrap")){this._wrap=document.createElement("div");this._wrap.id=this.get("element").id+"_wrap";this._wrap.className=this.CSS_WRAP;E.setStyle(this._wrap,"width",this.get("width"));E.setStyle(this._wrap,"height",this.get("height"));E.setStyle(this._wrap,"z-index",this.getStyle("z-index"));this.setStyle("z-index",0);var F=E.getStyle(this.get("element"),"position");E.setStyle(this._wrap,"position",((F=="static")?"relative":F));E.setStyle(this._wrap,"top",E.getStyle(this.get("element"),"top"));E.setStyle(this._wrap,"left",E.getStyle(this.get("element"),"left"));if(E.getStyle(this.get("element"),"position")=="absolute"){this._position!
 ed=true;E.setStyle(this.get("element"),"position","relative");!
 E.setSty
le(this.get("element"),"top","0");E.setStyle(this.get("element"),"left","0");}var D=this.get("element").parentNode;D.replaceChild(this._wrap,this.get("element"));this._wrap.appendChild(this.get("element"));}else{this._wrap=this.get("element");if(E.getStyle(this._wrap,"position")=="absolute"){this._positioned=true;}}if(this.get("draggable")){this._setupDragDrop();}if(this.get("hover")){E.addClass(this._wrap,this.CSS_HOVER);}if(this.get("knobHandles")){E.addClass(this._wrap,this.CSS_KNOB);}if(this.get("hiddenHandles")){E.addClass(this._wrap,this.CSS_HIDDEN);}E.addClass(this._wrap,this.CSS_RESIZE);},_setupDragDrop:function(){E.addClass(this._wrap,this.CSS_DRAG);this.dd=new YAHOO.util.DD(this._wrap,this.get("id")+"-resize",{dragOnly:true});this.dd.on("dragEvent",function(){this.fireEvent("dragEvent",arguments);},this,true);},_createHandles:function(){this._handles={};this._dds={};var G=this.get("handles");for(var F=0;F<G.length;F++){this._handles[G[F]]=document.createElement("di!
 v");this._handles[G[F]].id=E.generateId(this._handles[G[F]]);this._handles[G[F]].className=this.CSS_HANDLE+" "+this.CSS_HANDLE+"-"+G[F];var D=document.createElement("div");D.className=this.CSS_HANDLE+"-inner-"+G[F];this._handles[G[F]].appendChild(D);this._wrap.appendChild(this._handles[G[F]]);A.on(this._handles[G[F]],"mouseover",this._handleMouseOver,this,true);A.on(this._handles[G[F]],"mouseout",this._handleMouseOut,this,true);this._dds[G[F]]=new YAHOO.util.DragDrop(this._handles[G[F]],this.get("id")+"-handle-"+G);this._dds[G[F]].setPadding(15,15,15,15);this._dds[G[F]].on("startDragEvent",this._handleStartDrag,this._dds[G[F]],this);this._dds[G[F]].on("mouseDownEvent",this._handleMouseDown,this._dds[G[F]],this);}this._status=document.createElement("span");this._status.className=this.CSS_STATUS;document.body.insertBefore(this._status,document.body.firstChild);},_ieSelectFix:function(){return false;},_ieSelectBack:null,_setAutoRatio:function(D){if(this.get("autoRatio")){if(D&!
 &D.shiftKey){this.set("ratio",true);}else{this.set("ratio",thi!
 s._confi
gs.ratio._initialConfig.value);}}},_handleMouseDown:function(D){if(E.getStyle(this._wrap,"position")=="absolute"){this._positioned=true;}if(D){this._setAutoRatio(D);}if(this.browser.ie){this._ieSelectBack=document.body.onselectstart;document.body.onselectstart=this._ieSelectFix;}},_handleMouseOver:function(G){E.removeClass(this._wrap,this.CSS_RESIZE);if(this.get("hover")){E.removeClass(this._wrap,this.CSS_HOVER);}var D=A.getTarget(G);if(!E.hasClass(D,this.CSS_HANDLE)){D=D.parentNode;}if(E.hasClass(D,this.CSS_HANDLE)&&!this._active){E.addClass(D,this.CSS_HANDLE+"-active");for(var F in this._handles){if(C.hasOwnProperty(this._handles,F)){if(this._handles[F]==D){E.addClass(D,this.CSS_HANDLE+"-"+F+"-active");break;}}}}E.addClass(this._wrap,this.CSS_RESIZE);},_handleMouseOut:function(G){E.removeClass(this._wrap,this.CSS_RESIZE);if(this.get("hover")&&!this._active){E.addClass(this._wrap,this.CSS_HOVER);}var D=A.getTarget(G);if(!E.hasClass(D,this.CSS_HANDLE)){D=D.parentNode;}if(E.h!
 asClass(D,this.CSS_HANDLE)&&!this._active){E.removeClass(D,this.CSS_HANDLE+"-active");for(var F in this._handles){if(C.hasOwnProperty(this._handles,F)){if(this._handles[F]==D){E.removeClass(D,this.CSS_HANDLE+"-"+F+"-active");break;}}}}E.addClass(this._wrap,this.CSS_RESIZE);},_handleStartDrag:function(G,F){var D=F.getDragEl();if(E.hasClass(D,this.CSS_HANDLE)){if(E.getStyle(this._wrap,"position")=="absolute"){this._positioned=true;}this._active=true;this._currentDD=F;if(this._proxy){this._proxy.style.visibility="visible";this._proxy.style.zIndex="1000";this._proxy.style.height=this.get("element").clientHeight+"px";this._proxy.style.width=this.get("element").clientWidth+"px";}for(var H in this._handles){if(C.hasOwnProperty(this._handles,H)){if(this._handles[H]==D){this._currentHandle=H;var I="_handle_for_"+H;E.addClass(D,this.CSS_HANDLE+"-"+H+"-active");F.on("dragEvent",this[I],this,true);F.on("mouseUpEvent",this._handleMouseUp,this,true);
+break;}}}E.addClass(D,this.CSS_HANDLE+"-active");if(this.get("proxy")){var J=E.getXY(this.get("element"));E.setXY(this._proxy,J);if(this.get("ghost")){this.addClass(this.CSS_GHOST);}}E.addClass(this._wrap,this.CSS_RESIZING);this._setCache();this._updateStatus(this._cache.height,this._cache.width,this._cache.top,this._cache.left);this.fireEvent("startResize",{type:"startresize",target:this});}},_setCache:function(){this._cache.xy=E.getXY(this._wrap);E.setXY(this._wrap,this._cache.xy);this._cache.height=this.get("clientHeight");this._cache.width=this.get("clientWidth");this._cache.start.height=this._cache.height;this._cache.start.width=this._cache.width;this._cache.start.top=this._cache.xy[1];this._cache.start.left=this._cache.xy[0];this._cache.top=this._cache.xy[1];this._cache.left=this._cache.xy[0];this.set("height",this._cache.height,true);this.set("width",this._cache.width,true);},_handleMouseUp:function(F){this._active=false;var G="_handle_for_"+this._currentHandle;this.!
 _currentDD.unsubscribe("dragEvent",this[G],this,true);this._currentDD.unsubscribe("mouseUpEvent",this._handleMouseUp,this,true);if(this._proxy){this._proxy.style.visibility="hidden";this._proxy.style.zIndex="-1";if(this.get("setSize")){this.resize(F,this._cache.height,this._cache.width,this._cache.top,this._cache.left,true);}else{this.fireEvent("resize",{ev:"resize",target:this,height:this._cache.height,width:this._cache.width,top:this._cache.top,left:this._cache.left});}if(this.get("ghost")){this.removeClass(this.CSS_GHOST);}}if(this.get("hover")){E.addClass(this._wrap,this.CSS_HOVER);}if(this._status){E.setStyle(this._status,"display","none");}if(this.browser.ie){document.body.onselectstart=this._ieSelectBack;}if(this.browser.ie){E.removeClass(this._wrap,this.CSS_RESIZE);}for(var D in this._handles){if(C.hasOwnProperty(this._handles,D)){E.removeClass(this._handles[D],this.CSS_HANDLE+"-active");}}if(this.get("hover")&&!this._active){E.addClass(this._wrap,this.CSS_HOVER);}E!
 .removeClass(this._wrap,this.CSS_RESIZING);E.removeClass(this.!
 _handles
[this._currentHandle],this.CSS_HANDLE+"-"+this._currentHandle+"-active");E.removeClass(this._handles[this._currentHandle],this.CSS_HANDLE+"-active");if(this.browser.ie){E.addClass(this._wrap,this.CSS_RESIZE);}this._resizeEvent=null;this._currentHandle=null;},_setRatio:function(K,N,Q,I){var O=K,G=N;if(this.get("ratio")){var P=this._cache.height,H=this._cache.width,F=parseInt(this.get("height"),10),L=parseInt(this.get("width"),10),M=this.get("maxHeight"),R=this.get("minHeight"),D=this.get("maxWidth"),J=this.get("minWidth");switch(this._currentHandle){case"l":K=F*(N/L);K=Math.min(Math.max(R,K),M);N=L*(K/F);Q=(this._cache.start.top-(-((F-K)/2)));I=(this._cache.start.left-(-((L-N))));break;case"r":K=F*(N/L);K=Math.min(Math.max(R,K),M);N=L*(K/F);Q=(this._cache.start.top-(-((F-K)/2)));break;case"t":N=L*(K/F);K=F*(N/L);I=(this._cache.start.left-(-((L-N)/2)));Q=(this._cache.start.top-(-((F-K))));break;case"b":N=L*(K/F);K=F*(N/L);I=(this._cache.start.left-(-((L-N)/2)));break;case"bl":!
 K=F*(N/L);N=L*(K/F);I=(this._cache.start.left-(-((L-N))));break;case"br":K=F*(N/L);N=L*(K/F);break;case"tl":K=F*(N/L);N=L*(K/F);I=(this._cache.start.left-(-((L-N))));Q=(this._cache.start.top-(-((F-K))));break;case"tr":K=F*(N/L);N=L*(K/F);I=(this._cache.start.left);Q=(this._cache.start.top-(-((F-K))));break;}O=this._checkHeight(K);G=this._checkWidth(N);if((O!=K)||(G!=N)){Q=0;I=0;if(O!=K){G=this._cache.width;}if(G!=N){O=this._cache.height;}}}return[O,G,Q,I];},_updateStatus:function(K,G,J,F){if(this._resizeEvent&&(!C.isString(this._resizeEvent))){if(this.get("status")){E.setStyle(this._status,"display","inline");}K=((K===0)?this._cache.start.height:K);G=((G===0)?this._cache.start.width:G);var I=parseInt(this.get("height"),10),D=parseInt(this.get("width"),10);if(isNaN(I)){I=parseInt(K,10);}if(isNaN(D)){D=parseInt(G,10);}var L=(parseInt(K,10)-I);var H=(parseInt(G,10)-D);this._cache.offsetHeight=L;this._cache.offsetWidth=H;this._status.innerHTML="<strong>"+parseInt(K,10)+" x "+pa!
 rseInt(G,10)+"</strong><em>"+((L>0)?"+":"")+L+" x "+((H>0)?"+"!
 :"")+H+"
</em>";E.setXY(this._status,[A.getPageX(this._resizeEvent)+12,A.getPageY(this._resizeEvent)+12]);}},reset:function(){this.resize(null,this._cache.start.height,this._cache.start.width,this._cache.start.top,this._cache.start.left,true);return this;},resize:function(M,J,P,Q,H,F,K){this._resizeEvent=M;var G=this._wrap,I=this.get("animate"),O=true;if(this._proxy&&!F){G=this._proxy;I=false;}this._setAutoRatio(M);if(this._positioned){if(this._proxy){Q=this._cache.top-Q;H=this._cache.left-H;}}var L=this._setRatio(J,P,Q,H);J=parseInt(L[0],10);P=parseInt(L[1],10);Q=parseInt(L[2],10);H=parseInt(L[3],10);if(Q==0){Q=E.getY(G);}if(H==0){H=E.getX(G);}if(this._positioned){if(this._proxy&&F){if(!I){G.style.top=this._proxy.style.top;G.style.left=this._proxy.style.left;}else{Q=this._proxy.style.top;H=this._proxy.style.left;}}else{if(!this.get("ratio")&&!this._proxy){Q=this._cache.top+-(Q);H=this._cache.left+-(H);}if(Q){if(this.get("minY")){if(Q<this.get("minY")){Q=this.get("minY");}}if(this.ge!
 t("maxY")){if(Q>this.get("maxY")){Q=this.get("maxY");}}}if(H){if(this.get("minX")){if(H<this.get("minX")){H=this.get("minX");}}if(this.get("maxX")){if((H+P)>this.get("maxX")){H=(this.get("maxX")-P);}}}}}if(!K){var N=this.fireEvent("beforeResize",{ev:"beforeResize",target:this,height:J,width:P,top:Q,left:H});if(N===false){return false;}}this._updateStatus(J,P,Q,H);if(this._positioned){if(this._proxy&&F){}else{if(Q){E.setY(G,Q);this._cache.top=Q;}if(H){E.setX(G,H);this._cache.left=H;}}}if(J){if(!I){O=true;if(this._proxy&&F){if(!this.get("setSize")){O=false;}}if(O){if(this.browser.ie>6){if(J===this._cache.height){J=J+1;}}G.style.height=J+"px";}if((this._proxy&&F)||!this._proxy){if(this._wrap!=this.get("element")){this.get("element").style.height=J+"px";}}}this._cache.height=J;}if(P){this._cache.width=P;if(!I){O=true;if(this._proxy&&F){if(!this.get("setSize")){O=false;}}if(O){G.style.width=P+"px";}if((this._proxy&&F)||!this._proxy){if(this._wrap!=this.get("element")){this.get("!
 element").style.width=P+"px";
+}}}}if(I){if(YAHOO.util.Anim){var D=new YAHOO.util.Anim(G,{height:{to:this._cache.height},width:{to:this._cache.width}},this.get("animateDuration"),this.get("animateEasing"));if(this._positioned){if(Q){D.attributes.top={to:parseInt(Q,10)};}if(H){D.attributes.left={to:parseInt(H,10)};}}if(this._wrap!=this.get("element")){D.onTween.subscribe(function(){this.get("element").style.height=G.style.height;this.get("element").style.width=G.style.width;},this,true);}D.onComplete.subscribe(function(){this.set("height",J);this.set("width",P);this.fireEvent("resize",{ev:"resize",target:this,height:J,width:P,top:Q,left:H});},this,true);D.animate();}}else{if(this._proxy&&!F){this.fireEvent("proxyResize",{ev:"proxyresize",target:this,height:J,width:P,top:Q,left:H});}else{this.fireEvent("resize",{ev:"resize",target:this,height:J,width:P,top:Q,left:H});}}return this;},_handle_for_br:function(F){var G=this._setWidth(F.e);var D=this._setHeight(F.e);this.resize(F.e,(D+1),G,0,0);},_handle_for_bl!
 :function(G){var H=this._setWidth(G.e,true);var F=this._setHeight(G.e);var D=(H-this._cache.width);this.resize(G.e,F,H,0,D);},_handle_for_tl:function(G){var I=this._setWidth(G.e,true);var F=this._setHeight(G.e,true);var H=(F-this._cache.height);var D=(I-this._cache.width);this.resize(G.e,F,I,H,D);},_handle_for_tr:function(F){var H=this._setWidth(F.e);var D=this._setHeight(F.e,true);var G=(D-this._cache.height);this.resize(F.e,D,H,G,0);},_handle_for_r:function(D){this._dds.r.setYConstraint(0,0);var F=this._setWidth(D.e);this.resize(D.e,0,F,0,0);},_handle_for_l:function(F){this._dds.l.setYConstraint(0,0);var G=this._setWidth(F.e,true);var D=(G-this._cache.width);this.resize(F.e,0,G,0,D);},_handle_for_b:function(F){this._dds.b.setXConstraint(0,0);var D=this._setHeight(F.e);this.resize(F.e,D,0,0,0);},_handle_for_t:function(F){this._dds.t.setXConstraint(0,0);var D=this._setHeight(F.e,true);var G=(D-this._cache.height);this.resize(F.e,D,0,G,0);},_setWidth:function(H,J){var I=this!
 ._cache.xy[0],G=this._cache.width,D=A.getPageX(H),F=(D-I);if(J!
 ){F=(I-D
)+parseInt(this.get("width"),10);}F=this._snapTick(F,this.get("yTicks"));F=this._checkWidth(F);return F;},_checkWidth:function(D){if(this.get("minWidth")){if(D<=this.get("minWidth")){D=this.get("minWidth");}}if(this.get("maxWidth")){if(D>=this.get("maxWidth")){D=this.get("maxWidth");}}return D;},_checkHeight:function(D){if(this.get("minHeight")){if(D<=this.get("minHeight")){D=this.get("minHeight");}}if(this.get("maxHeight")){if(D>=this.get("maxHeight")){D=this.get("maxHeight");}}return D;},_setHeight:function(G,I){var H=this._cache.xy[1],F=this._cache.height,J=A.getPageY(G),D=(J-H);if(I){D=(H-J)+parseInt(this.get("height"),10);}D=this._snapTick(D,this.get("xTicks"));D=this._checkHeight(D);return D;},_snapTick:function(G,F){if(!G||!F){return G;}var H=G;var D=G%F;if(D>0){if(D>(F/2)){H=G+(F-D);}else{H=G-D;}}return H;},init:function(F,D){this._cache={xy:[],height:0,width:0,top:0,left:0,offsetHeight:0,offsetWidth:0,start:{height:0,width:0,top:0,left:0}};B.superclass.init.call(thi!
 s,F,D);this.set("setSize",this.get("setSize"));if(D.height){this.set("height",parseInt(D.height,10));}if(D.width){this.set("width",parseInt(D.width,10));}var G=F;if(!C.isString(G)){G=E.generateId(G);}B._instances[G]=this;this._active=false;this._createWrap();this._createProxy();this._createHandles();},getProxyEl:function(){return this._proxy;},getWrapEl:function(){return this._wrap;},getStatusEl:function(){return this._status;},getActiveHandleEl:function(){return this._handles[this._currentHandle];},isActive:function(){return((this._active)?true:false);},initAttributes:function(D){B.superclass.initAttributes.call(this,D);this.setAttributeConfig("setSize",{value:((D.setSize===false)?false:true),validator:YAHOO.lang.isBoolean});this.setAttributeConfig("wrap",{writeOnce:true,validator:YAHOO.lang.isBoolean,value:D.wrap||false});this.setAttributeConfig("handles",{writeOnce:true,value:D.handles||["r","b","br"],validator:function(F){if(C.isString(F)&&F.toLowerCase()=="all"){F=["t"!
 ,"b","r","l","bl","br","tl","tr"];}if(!C.isArray(F)){F=F.repla!
 ce(/, /g
,",");F=F.split(",");}this._configs.handles.value=F;}});this.setAttributeConfig("width",{value:D.width||parseInt(this.getStyle("width"),10),validator:YAHOO.lang.isNumber,method:function(F){F=parseInt(F,10);if(F>0){if(this.get("setSize")){this.setStyle("width",F+"px");}this._cache.width=F;this._configs.width.value=F;}}});this.setAttributeConfig("height",{value:D.height||parseInt(this.getStyle("height"),10),validator:YAHOO.lang.isNumber,method:function(F){F=parseInt(F,10);if(F>0){if(this.get("setSize")){this.setStyle("height",F+"px");}this._cache.height=F;this._configs.height.value=F;}}});this.setAttributeConfig("minWidth",{value:D.minWidth||15,validator:YAHOO.lang.isNumber});this.setAttributeConfig("minHeight",{value:D.minHeight||15,validator:YAHOO.lang.isNumber});this.setAttributeConfig("maxWidth",{value:D.maxWidth||10000,validator:YAHOO.lang.isNumber});this.setAttributeConfig("maxHeight",{value:D.maxHeight||10000,validator:YAHOO.lang.isNumber});this.setAttributeConfig("minY!
 ",{value:D.minY||false});this.setAttributeConfig("minX",{value:D.minX||false});this.setAttributeConfig("maxY",{value:D.maxY||false});this.setAttributeConfig("maxX",{value:D.maxX||false});this.setAttributeConfig("animate",{value:D.animate||false,validator:function(G){var F=true;if(!YAHOO.util.Anim){F=false;}return F;}});this.setAttributeConfig("animateEasing",{value:D.animateEasing||function(){var G=false;try{G=YAHOO.util.Easing.easeOut;}catch(F){}return G;}()});this.setAttributeConfig("animateDuration",{value:D.animateDuration||0.5});this.setAttributeConfig("proxy",{value:D.proxy||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("ratio",{value:D.ratio||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("ghost",{value:D.ghost||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("draggable",{value:D.draggable||false,validator:YAHOO.lang.isBoolean,method:function(F){if(F&&this._wrap){this._setupDragDrop();
+}else{if(this.dd){E.removeClass(this._wrap,this.CSS_DRAG);this.dd.unreg();}}}});this.setAttributeConfig("hover",{value:D.hover||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("hiddenHandles",{value:D.hiddenHandles||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("knobHandles",{value:D.knobHandles||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("xTicks",{value:D.xTicks||false});this.setAttributeConfig("yTicks",{value:D.yTicks||false});this.setAttributeConfig("status",{value:D.status||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("autoRatio",{value:D.autoRatio||false,validator:YAHOO.lang.isBoolean});},destroy:function(){for(var F in this._handles){if(C.hasOwnProperty(this._handles,F)){A.purgeElement(this._handles[F]);this._handles[F].parentNode.removeChild(this._handles[F]);}}if(this._proxy){this._proxy.parentNode.removeChild(this._proxy);}if(this._status){this._status.parentNode.removeChild(this._status);}if(thi!
 s.dd){this.dd.unreg();E.removeClass(this._wrap,this.CSS_DRAG);}if(this._wrap!=this.get("element")){this.setStyle("position","");this.setStyle("top","");this.setStyle("left","");this._wrap.parentNode.replaceChild(this.get("element"),this._wrap);}this.removeClass(this.CSS_RESIZE);delete YAHOO.util.Resize._instances[this.get("id")];for(var D in this){if(C.hasOwnProperty(this,D)){this[D]=null;delete this[D];}}},toString:function(){if(this.get){return"Resize (#"+this.get("id")+")";}return"Resize Utility";}});YAHOO.util.Resize=B;})();YAHOO.register("resize",YAHOO.util.Resize,{version:"2.5.1",build:"984"});
\ No newline at end of file

Added: trunk/root/static/yui/resize/resize-beta.js
===================================================================
--- trunk/root/static/yui/resize/resize-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/resize/resize-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,1594 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * @description <p>Makes an element resizable</p>
+ * @namespace YAHOO.util
+ * @requires yahoo, dom, dragdrop, element, event
+ * @optional animation
+ * @module resize
+ * @beta
+ */
+(function() {
+var D = YAHOO.util.Dom,
+    Event = YAHOO.util.Event,
+    Lang = YAHOO.lang;
+
+    /**
+     * @constructor
+     * @class Resize
+     * @extends YAHOO.util.Element
+     * @description <p>Makes an element resizable</p>
+     * @param {String/HTMLElement} el The element to make resizable.
+     * @param {Object} attrs Object liternal containing configuration parameters.
+    */
+
+    var Resize = function(el, config) {
+        var oConfig = {
+            element: el,
+            attributes: config || {}
+        };
+
+        Resize.superclass.constructor.call(this, oConfig.element, oConfig.attributes);    
+    };
+
+    /**
+    * @private
+    * @static
+    * @property _instances
+    * @description Internal hash table for all resize instances
+    * @type Object
+    */ 
+    Resize._instances = {};
+    /**
+    * @static
+    * @method getResizeById 
+    * @description Get's a resize object by the HTML id of the element associated with the Resize object.
+    * @return {Object} The Resize Object
+    */ 
+    Resize.getResizeById = function(id) {
+        if (Resize._instances[id]) {
+            return Resize._instances[id];
+        }
+        return false;
+    };
+
+    YAHOO.extend(Resize, YAHOO.util.Element, {
+        /**
+        * @private
+        * @property CSS_RESIZE
+        * @description Base CSS class name
+        * @type String
+        */ 
+        CSS_RESIZE: 'yui-resize',
+        /**
+        * @private
+        * @property CSS_DRAG
+        * @description Class name added when dragging is enabled
+        * @type String
+        */ 
+        CSS_DRAG: 'yui-draggable',
+        /**
+        * @private
+        * @property CSS_HOVER
+        * @description Class name used for hover only handles
+        * @type String
+        */ 
+        CSS_HOVER: 'yui-resize-hover',
+        /**
+        * @private
+        * @property CSS_PROXY
+        * @description Class name given to the proxy element
+        * @type String
+        */ 
+        CSS_PROXY: 'yui-resize-proxy',
+        /**
+        * @private
+        * @property CSS_WRAP
+        * @description Class name given to the wrap element
+        * @type String
+        */ 
+        CSS_WRAP: 'yui-resize-wrap',
+        /**
+        * @private
+        * @property CSS_KNOB
+        * @description Class name used to make the knob style handles
+        * @type String
+        */ 
+        CSS_KNOB: 'yui-resize-knob',
+        /**
+        * @private
+        * @property CSS_HIDDEN
+        * @description Class name given to the wrap element to make all handles hidden
+        * @type String
+        */ 
+        CSS_HIDDEN: 'yui-resize-hidden',
+        /**
+        * @private
+        * @property CSS_HANDLE
+        * @description Class name given to all handles, used as a base for single handle names as well.. Handle "t" will get this.CSS_HANDLE + '-t' as well as this.CSS_HANDLE
+        * @type String
+        */ 
+        CSS_HANDLE: 'yui-resize-handle',
+        /**
+        * @private
+        * @property CSS_STATUS
+        * @description Class name given to the status element
+        * @type String
+        */ 
+        CSS_STATUS: 'yui-resize-status',
+        /**
+        * @private
+        * @property CSS_GHOST
+        * @description Class name given to the wrap element when the ghost property is active
+        * @type String
+        */ 
+        CSS_GHOST: 'yui-resize-ghost',
+        /**
+        * @private
+        * @property CSS_RESIZING
+        * @description Class name given to the wrap element when a resize action is taking place.
+        * @type String
+        */ 
+        CSS_RESIZING: 'yui-resize-resizing',
+        /**
+        * @private
+        * @property _resizeEvent
+        * @description The mouse event used to resize with
+        * @type Event
+        */ 
+        _resizeEvent: null,
+        /**
+        * @private
+        * @property dd
+        * @description The <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> instance used if draggable is true
+        * @type Object
+        */ 
+        dd: null,
+        /** 
+        * @private
+        * @property browser
+        * @description A copy of the YAHOO.env.ua property
+        * @type Object
+        */
+        browser: YAHOO.env.ua,
+        /** 
+        * @private
+        * @property _positioned
+        * @description A flag to show if the element is absolutely positioned
+        * @type Boolean
+        */
+        _positioned: null,
+        /** 
+        * @private
+        * @property _dds
+        * @description An Object containing references to all of the <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> instances used for the resize handles
+        * @type Object
+        */
+        _dds: null,
+        /** 
+        * @private
+        * @property _wrap
+        * @description The HTML reference of the element wrapper
+        * @type HTMLElement
+        */
+        _wrap: null,
+        /** 
+        * @private
+        * @property _proxy
+        * @description The HTML reference of the element proxy
+        * @type HTMLElement
+        */
+        _proxy: null,
+        /** 
+        * @private
+        * @property _handles
+        * @description An object containing references to all of the resize handles.
+        * @type Object
+        */
+        _handles: null,
+        /** 
+        * @private
+        * @property _currentHandle
+        * @description The string identifier of the currently active handle. e.g. 'r', 'br', 'tl'
+        * @type String
+        */
+        _currentHandle: null,
+        /** 
+        * @private
+        * @property _currentDD
+        * @description A link to the currently active DD object
+        * @type Object
+        */
+        _currentDD: null,
+        /** 
+        * @private
+        * @property _cache
+        * @description An lookup table containing key information for the element being resized. e.g. height, width, x position, y position, etc..
+        * @type Object
+        */
+        _cache: null,
+        /** 
+        * @private
+        * @property _active
+        * @description Flag to show if the resize is active. Used for events.
+        * @type Boolean
+        */
+        _active: null,
+        /** 
+        * @private
+        * @method _createProxy
+        * @description Creates the proxy element if the proxy config is true
+        */
+        _createProxy: function() {
+            if (this.get('proxy')) {
+                this._proxy = document.createElement('div');
+                this._proxy.className = this.CSS_PROXY;
+                this._proxy.style.height = this.get('element').clientHeight + 'px';
+                this._proxy.style.width = this.get('element').clientWidth + 'px';
+                this._wrap.parentNode.appendChild(this._proxy);
+            } else {
+                this.set('animate', false);
+            }
+        },
+        /** 
+        * @private
+        * @method _createWrap
+        * @description Creates the wrap element if the wrap config is true. It will auto wrap the following element types: img, textarea, input, iframe, select
+        */
+        _createWrap: function() {
+            this._positioned = false;
+            //Force wrap for elements that can't have children 
+            switch (this.get('element').tagName.toLowerCase()) {
+                case 'img':
+                case 'textarea':
+                case 'input':
+                case 'iframe':
+                case 'select':
+                    this.set('wrap', true);
+                    break;
+            }
+            if (this.get('wrap')) {
+                this._wrap = document.createElement('div');
+                this._wrap.id = this.get('element').id + '_wrap';
+                this._wrap.className = this.CSS_WRAP;
+                D.setStyle(this._wrap, 'width', this.get('width'));
+                D.setStyle(this._wrap, 'height', this.get('height'));
+                D.setStyle(this._wrap, 'z-index', this.getStyle('z-index'));
+                this.setStyle('z-index', 0);
+                var pos = D.getStyle(this.get('element'), 'position');
+                D.setStyle(this._wrap, 'position', ((pos == 'static') ? 'relative' : pos));
+                D.setStyle(this._wrap, 'top', D.getStyle(this.get('element'), 'top'));
+                D.setStyle(this._wrap, 'left', D.getStyle(this.get('element'), 'left'));
+                if (D.getStyle(this.get('element'), 'position') == 'absolute') {
+                    this._positioned = true;
+                    D.setStyle(this.get('element'), 'position', 'relative');
+                    D.setStyle(this.get('element'), 'top', '0');
+                    D.setStyle(this.get('element'), 'left', '0');
+                }
+                var par = this.get('element').parentNode;
+                par.replaceChild(this._wrap, this.get('element'));
+                this._wrap.appendChild(this.get('element'));
+            } else {
+                this._wrap = this.get('element');
+                if (D.getStyle(this._wrap, 'position') == 'absolute') {
+                    this._positioned = true;
+                }
+            }
+            if (this.get('draggable')) {
+                this._setupDragDrop();
+            }
+            if (this.get('hover')) {
+                D.addClass(this._wrap, this.CSS_HOVER);
+            }
+            if (this.get('knobHandles')) {
+                D.addClass(this._wrap, this.CSS_KNOB);
+            }
+            if (this.get('hiddenHandles')) {
+                D.addClass(this._wrap, this.CSS_HIDDEN);
+            }
+            D.addClass(this._wrap, this.CSS_RESIZE);
+        },
+        /** 
+        * @private
+        * @method _setupDragDrop
+        * @description Setup the <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> instance on the element
+        */
+        _setupDragDrop: function() {
+            D.addClass(this._wrap, this.CSS_DRAG);
+            this.dd = new YAHOO.util.DD(this._wrap, this.get('id') + '-resize', { dragOnly: true });
+            this.dd.on('dragEvent', function() {
+                this.fireEvent('dragEvent', arguments);
+            }, this, true);
+        },
+        /** 
+        * @private
+        * @method _createHandles
+        * @description Creates the handles as specified in the config
+        */
+        _createHandles: function() {
+            this._handles = {};
+            this._dds = {};
+            var h = this.get('handles');
+            for (var i = 0; i < h.length; i++) {
+                this._handles[h[i]] = document.createElement('div');
+                this._handles[h[i]].id = D.generateId(this._handles[h[i]]);
+                this._handles[h[i]].className = this.CSS_HANDLE + ' ' + this.CSS_HANDLE + '-' + h[i];
+                var k = document.createElement('div');
+                k.className = this.CSS_HANDLE + '-inner-' + h[i];
+                this._handles[h[i]].appendChild(k);
+                this._wrap.appendChild(this._handles[h[i]]);
+                Event.on(this._handles[h[i]], 'mouseover', this._handleMouseOver, this, true);
+                Event.on(this._handles[h[i]], 'mouseout', this._handleMouseOut, this, true);
+                this._dds[h[i]] = new YAHOO.util.DragDrop(this._handles[h[i]], this.get('id') + '-handle-' + h);
+                this._dds[h[i]].setPadding(15, 15, 15, 15);
+                this._dds[h[i]].on('startDragEvent', this._handleStartDrag, this._dds[h[i]], this);
+                this._dds[h[i]].on('mouseDownEvent', this._handleMouseDown, this._dds[h[i]], this);
+            }
+            this._status = document.createElement('span');
+            this._status.className = this.CSS_STATUS;
+            document.body.insertBefore(this._status, document.body.firstChild);
+        },
+        /** 
+        * @private
+        * @method _ieSelectFix
+        * @description The function we use as the onselectstart handler when we start a drag in Internet Explorer
+        */
+        _ieSelectFix: function() {
+            return false;
+        },
+        /** 
+        * @private
+        * @property _ieSelectBack
+        * @description We will hold a copy of the current "onselectstart" method on this property, and reset it after we are done using it.
+        */
+        _ieSelectBack: null,
+        /** 
+        * @private
+        * @method _setAutoRatio
+        * @param {Event} ev A mouse event.
+        * @description This method checks to see if the "autoRatio" config is set. If it is, we will check to see if the "Shift Key" is pressed. If so, we will set the config ratio to true.
+        */
+        _setAutoRatio: function(ev) {
+            if (this.get('autoRatio')) {
+                if (ev && ev.shiftKey) {
+                    //Shift Pressed
+                    this.set('ratio', true);
+                } else {
+                    this.set('ratio', this._configs.ratio._initialConfig.value);
+                }
+            }
+        },
+        /** 
+        * @private
+        * @method _handleMouseDown
+        * @param {Event} ev A mouse event.
+        * @description This method preps the autoRatio on MouseDown.
+        */
+        _handleMouseDown: function(ev) {
+            if (D.getStyle(this._wrap, 'position') == 'absolute') {
+                this._positioned = true;
+            }
+            if (ev) {
+                this._setAutoRatio(ev);
+            }
+            if (this.browser.ie) {
+                this._ieSelectBack = document.body.onselectstart;
+                document.body.onselectstart = this._ieSelectFix;
+            }
+        },
+        /** 
+        * @private
+        * @method _handleMouseOver
+        * @param {Event} ev A mouse event.
+        * @description Adds CSS class names to the handles
+        */
+        _handleMouseOver: function(ev) {
+            //Internet Explorer needs this
+            D.removeClass(this._wrap, this.CSS_RESIZE);
+            if (this.get('hover')) {
+                D.removeClass(this._wrap, this.CSS_HOVER);
+            }
+            var tar = Event.getTarget(ev);
+            if (!D.hasClass(tar, this.CSS_HANDLE)) {
+                tar = tar.parentNode;
+            }
+            if (D.hasClass(tar, this.CSS_HANDLE) && !this._active) {
+                D.addClass(tar, this.CSS_HANDLE + '-active');
+                for (var i in this._handles) {
+                    if (Lang.hasOwnProperty(this._handles, i)) {
+                        if (this._handles[i] == tar) {
+                            D.addClass(tar, this.CSS_HANDLE + '-' + i + '-active');
+                            break;
+                        }
+                    }
+                }
+            }
+
+            //Internet Explorer needs this
+            D.addClass(this._wrap, this.CSS_RESIZE);
+        },
+        /** 
+        * @private
+        * @method _handleMouseOut
+        * @param {Event} ev A mouse event.
+        * @description Removes CSS class names to the handles
+        */
+        _handleMouseOut: function(ev) {
+            //Internet Explorer needs this
+            D.removeClass(this._wrap, this.CSS_RESIZE);
+            if (this.get('hover') && !this._active) {
+                D.addClass(this._wrap, this.CSS_HOVER);
+            }
+            var tar = Event.getTarget(ev);
+            if (!D.hasClass(tar, this.CSS_HANDLE)) {
+                tar = tar.parentNode;
+            }
+            if (D.hasClass(tar, this.CSS_HANDLE) && !this._active) {
+                D.removeClass(tar, this.CSS_HANDLE + '-active');
+                for (var i in this._handles) {
+                    if (Lang.hasOwnProperty(this._handles, i)) {
+                        if (this._handles[i] == tar) {
+                            D.removeClass(tar, this.CSS_HANDLE + '-' + i + '-active');
+                            break;
+                        }
+                    }
+                }
+            }
+            //Internet Explorer needs this
+            D.addClass(this._wrap, this.CSS_RESIZE);
+        },
+        /** 
+        * @private
+        * @method _handleStartDrag
+        * @param {Object} args The args passed from the CustomEvent.
+        * @param {Object} dd The <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> object we are working with.
+        * @description Resizes the proxy, sets up the <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> handlers, updates the status div and preps the cache
+        */
+        _handleStartDrag: function(args, dd) {
+            var tar = dd.getDragEl();
+            if (D.hasClass(tar, this.CSS_HANDLE)) {
+                if (D.getStyle(this._wrap, 'position') == 'absolute') {
+                    this._positioned = true;
+                }
+                this._active = true;
+                this._currentDD = dd;
+                if (this._proxy) {
+                    this._proxy.style.visibility = 'visible';
+                    this._proxy.style.zIndex = '1000';
+                    this._proxy.style.height = this.get('element').clientHeight + 'px';
+                    this._proxy.style.width = this.get('element').clientWidth + 'px';
+                }
+
+                for (var i in this._handles) {
+                    if (Lang.hasOwnProperty(this._handles, i)) {
+                        if (this._handles[i] == tar) {
+                            this._currentHandle = i;
+                            var handle = '_handle_for_' + i;
+                            D.addClass(tar, this.CSS_HANDLE + '-' + i + '-active');
+                            dd.on('dragEvent', this[handle], this, true);
+                            dd.on('mouseUpEvent', this._handleMouseUp, this, true);
+                            break;
+                        }
+                    }
+                }
+
+
+                D.addClass(tar, this.CSS_HANDLE + '-active');
+
+                if (this.get('proxy')) {
+                    var xy = D.getXY(this.get('element'));
+                    D.setXY(this._proxy, xy);
+                    if (this.get('ghost')) {
+                        this.addClass(this.CSS_GHOST);
+                    }
+                }
+                D.addClass(this._wrap, this.CSS_RESIZING);
+                this._setCache();
+                this._updateStatus(this._cache.height, this._cache.width, this._cache.top, this._cache.left);
+                this.fireEvent('startResize', { type: 'startresize', target: this});
+            }
+        },
+        /** 
+        * @private
+        * @method _setCache
+        * @description Sets up the this._cache hash table.
+        */
+        _setCache: function() {
+            this._cache.xy = D.getXY(this._wrap);
+            D.setXY(this._wrap, this._cache.xy);
+            this._cache.height = this.get('clientHeight');
+            this._cache.width = this.get('clientWidth');
+            this._cache.start.height = this._cache.height;
+            this._cache.start.width = this._cache.width;
+            this._cache.start.top = this._cache.xy[1];
+            this._cache.start.left = this._cache.xy[0];
+            this._cache.top = this._cache.xy[1];
+            this._cache.left = this._cache.xy[0];
+            this.set('height', this._cache.height, true);
+            this.set('width', this._cache.width, true);
+        },
+        /** 
+        * @private
+        * @method _handleMouseUp
+        * @param {Event} ev A mouse event.
+        * @description Cleans up listeners, hides proxy element and removes class names.
+        */
+        _handleMouseUp: function(ev) {
+            this._active = false;
+
+            var handle = '_handle_for_' + this._currentHandle;
+            this._currentDD.unsubscribe('dragEvent', this[handle], this, true);
+            this._currentDD.unsubscribe('mouseUpEvent', this._handleMouseUp, this, true);
+
+            if (this._proxy) {
+                this._proxy.style.visibility = 'hidden';
+                this._proxy.style.zIndex = '-1';
+                if (this.get('setSize')) {
+                    this.resize(ev, this._cache.height, this._cache.width, this._cache.top, this._cache.left, true);
+                } else {
+                    this.fireEvent('resize', { ev: 'resize', target: this, height: this._cache.height, width: this._cache.width, top: this._cache.top, left: this._cache.left });
+                }
+
+                if (this.get('ghost')) {
+                    this.removeClass(this.CSS_GHOST);
+                }
+            }
+
+            if (this.get('hover')) {
+                D.addClass(this._wrap, this.CSS_HOVER);
+            }
+            if (this._status) {
+                D.setStyle(this._status, 'display', 'none');
+            }
+            if (this.browser.ie) {
+                document.body.onselectstart = this._ieSelectBack;
+            }
+
+            if (this.browser.ie) {
+                D.removeClass(this._wrap, this.CSS_RESIZE);
+            }
+
+            for (var i in this._handles) {
+                if (Lang.hasOwnProperty(this._handles, i)) {
+                    D.removeClass(this._handles[i], this.CSS_HANDLE + '-active');
+                }
+            }
+            if (this.get('hover') && !this._active) {
+                D.addClass(this._wrap, this.CSS_HOVER);
+            }
+            D.removeClass(this._wrap, this.CSS_RESIZING);
+
+            D.removeClass(this._handles[this._currentHandle], this.CSS_HANDLE + '-' + this._currentHandle + '-active');
+            D.removeClass(this._handles[this._currentHandle], this.CSS_HANDLE + '-active');
+
+            if (this.browser.ie) {
+                D.addClass(this._wrap, this.CSS_RESIZE);
+            }
+
+            this._resizeEvent = null;
+            this._currentHandle = null;
+        },
+        /** 
+        * @private
+        * @method _setRatio
+        * @param {Number} h The height offset.
+        * @param {Number} w The with offset.
+        * @param {Number} t The top offset.
+        * @param {Number} l The left offset.
+        * @description Using the Height, Width, Top & Left, it recalcuates them based on the original element size.
+        * @return {Array} The new Height, Width, Top & Left settings
+        */
+        _setRatio: function(h, w, t, l) {
+            var oh = h, ow = w;
+            if (this.get('ratio')) {
+                var orgH = this._cache.height,
+                    orgW = this._cache.width,
+                    nh = parseInt(this.get('height'), 10),
+                    nw = parseInt(this.get('width'), 10),
+                    maxH = this.get('maxHeight'),
+                    minH = this.get('minHeight'),
+                    maxW = this.get('maxWidth'),
+                    minW = this.get('minWidth');
+
+                switch (this._currentHandle) {
+                    case 'l':
+                        h = nh * (w / nw);
+                        h = Math.min(Math.max(minH, h), maxH);                        
+                        w = nw * (h / nh);
+                        t = (this._cache.start.top - (-((nh - h) / 2)));
+                        l = (this._cache.start.left - (-((nw - w))));
+                        break;
+                    case 'r':
+                        h = nh * (w / nw);
+                        h = Math.min(Math.max(minH, h), maxH);                        
+                        w = nw * (h / nh);
+                        t = (this._cache.start.top - (-((nh - h) / 2)));
+                        break;
+                    case 't':
+                        w = nw * (h / nh);
+                        h = nh * (w / nw);
+                        l = (this._cache.start.left - (-((nw - w) / 2)));
+                        t = (this._cache.start.top - (-((nh - h))));
+                        break;
+                    case 'b':
+                        w = nw * (h / nh);
+                        h = nh * (w / nw);
+                        l = (this._cache.start.left - (-((nw - w) / 2)));
+                        break;
+                    case 'bl':
+                        h = nh * (w / nw);
+                        w = nw * (h / nh);
+                        l = (this._cache.start.left - (-((nw - w))));
+                        break;
+                    case 'br':
+                        h = nh * (w / nw);
+                        w = nw * (h / nh);
+                        break;
+                    case 'tl':
+                        h = nh * (w / nw);
+                        w = nw * (h / nh);
+                        l = (this._cache.start.left - (-((nw - w))));
+                        t = (this._cache.start.top - (-((nh - h))));
+                        break;
+                    case 'tr':
+                        h = nh * (w / nw);
+                        w = nw * (h / nh);
+                        l = (this._cache.start.left);
+                        t = (this._cache.start.top - (-((nh - h))));
+                        break;
+                }
+                oh = this._checkHeight(h);
+                ow = this._checkWidth(w);
+                if ((oh != h) || (ow != w)) {
+                    t = 0;
+                    l = 0;
+                    if (oh != h) {
+                        ow = this._cache.width;
+                    }
+                    if (ow != w) {
+                        oh = this._cache.height;
+                    }
+                }
+            }
+            return [oh, ow, t, l];
+        },
+        /** 
+        * @private
+        * @method _updateStatus
+        * @param {Number} h The new height setting.
+        * @param {Number} w The new width setting.
+        * @param {Number} t The new top setting.
+        * @param {Number} l The new left setting.
+        * @description Using the Height, Width, Top & Left, it updates the status element with the elements sizes.
+        */
+        _updateStatus: function(h, w, t, l) {
+            if (this._resizeEvent && (!Lang.isString(this._resizeEvent))) {
+                if (this.get('status')) {
+                    D.setStyle(this._status, 'display', 'inline');
+                }
+                h = ((h === 0) ? this._cache.start.height : h);
+                w = ((w === 0) ? this._cache.start.width : w);
+                var h1 = parseInt(this.get('height'), 10),
+                    w1 = parseInt(this.get('width'), 10);
+                
+                if (isNaN(h1)) {
+                    h1 = parseInt(h, 10);
+                }
+                if (isNaN(w1)) {
+                    w1 = parseInt(w, 10);
+                }
+                var diffH = (parseInt(h, 10) - h1);
+                var diffW = (parseInt(w, 10) - w1);
+                this._cache.offsetHeight = diffH;
+                this._cache.offsetWidth = diffW;
+                this._status.innerHTML = '<strong>' + parseInt(h, 10) + ' x ' + parseInt(w, 10) + '</strong><em>' + ((diffH > 0) ? '+' : '') + diffH + ' x ' + ((diffW > 0) ? '+' : '') + diffW + '</em>';
+                D.setXY(this._status, [Event.getPageX(this._resizeEvent) + 12, Event.getPageY(this._resizeEvent) + 12]);
+            }
+        },
+        /** 
+        * @method reset
+        * @description Resets the element to is start state.
+        * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
+        */
+        reset: function() {
+            this.resize(null, this._cache.start.height, this._cache.start.width, this._cache.start.top, this._cache.start.left, true);
+            return this;
+        },
+        /** 
+        * @method resize
+        * @param {Event} ev The mouse event.
+        * @param {Number} h The new height setting.
+        * @param {Number} w The new width setting.
+        * @param {Number} t The new top setting.
+        * @param {Number} l The new left setting.
+        * @param {Boolean} force Resize the element (used for proxy resize).
+        * @param {Boolean} silent Don't fire the beforeResize Event.
+        * @description Resizes the element, wrapper or proxy based on the data from the handlers.
+        * @return {<a href="YAHOO.util.Resize.html">YAHOO.util.Resize</a>} The Resize instance
+        */
+        resize: function(ev, h, w, t, l, force, silent) {
+            this._resizeEvent = ev;
+            var el = this._wrap, anim = this.get('animate'), set = true;
+            if (this._proxy && !force) {
+                el = this._proxy;
+                anim = false;
+            }
+            this._setAutoRatio(ev);
+            if (this._positioned) {
+                if (this._proxy) {
+                    t = this._cache.top - t;
+                    l = this._cache.left - l;
+                }
+            }
+
+            var ratio = this._setRatio(h, w, t, l);
+            h = parseInt(ratio[0], 10);
+            w = parseInt(ratio[1], 10);
+            t = parseInt(ratio[2], 10);
+            l = parseInt(ratio[3], 10);
+
+            if (t == 0) {
+                //No Offset, get from cache
+                t = D.getY(el);
+            }
+            if (l == 0) {
+                //No Offset, get from cache
+                l = D.getX(el);
+            }
+
+            
+
+            if (this._positioned) {
+                if (this._proxy && force) {
+                    if (!anim) {
+                        el.style.top = this._proxy.style.top;
+                        el.style.left = this._proxy.style.left;
+                    } else {
+                        t = this._proxy.style.top;
+                        l = this._proxy.style.left;
+                    }
+                } else {
+                    if (!this.get('ratio') && !this._proxy) {
+                        t = this._cache.top + -(t);
+                        l = this._cache.left + -(l);
+                    }
+                    if (t) {
+                        if (this.get('minY')) {
+                            if (t < this.get('minY')) {
+                                t = this.get('minY');
+                            }
+                        }
+                        if (this.get('maxY')) {
+                            if (t > this.get('maxY')) {
+                                t = this.get('maxY');
+                            }
+                        }
+                    }
+                    if (l) {
+                        if (this.get('minX')) {
+                            if (l < this.get('minX')) {
+                                l = this.get('minX');
+                            }
+                        }
+                        if (this.get('maxX')) {
+                            if ((l + w) > this.get('maxX')) {
+                                l = (this.get('maxX') - w);
+                            }
+                        }
+                    }
+                }
+            }
+            if (!silent) {
+                var beforeReturn = this.fireEvent('beforeResize', { ev: 'beforeResize', target: this, height: h, width: w, top: t, left: l });
+                if (beforeReturn === false) {
+                    return false;
+                }
+            }
+
+            this._updateStatus(h, w, t, l);
+
+            if (this._positioned) {
+                if (this._proxy && force) {
+                    //Do nothing
+                } else {
+                    if (t) {
+                        D.setY(el, t);
+                        this._cache.top = t;
+                    }
+                    if (l) {
+                        D.setX(el, l);
+                        this._cache.left = l;
+                    }
+                }
+            }
+            if (h) {
+                if (!anim) {
+                    set = true;
+                    if (this._proxy && force) {
+                        if (!this.get('setSize')) {
+                            set = false;
+                        }
+                    }
+                    if (set) {
+                        if (this.browser.ie > 6) {
+                            if (h === this._cache.height) {
+                                h = h + 1;
+                            }
+                        }
+                        el.style.height = h + 'px';
+                    }
+                    if ((this._proxy && force) || !this._proxy) {
+                        if (this._wrap != this.get('element')) {
+                            this.get('element').style.height = h + 'px';
+                        }
+                    }
+                }
+                this._cache.height = h;
+            }
+            if (w) {
+                this._cache.width = w;
+                if (!anim) {
+                    set = true;
+                    if (this._proxy && force) {
+                        if (!this.get('setSize')) {
+                            set = false;
+                        }
+                    }
+                    if (set) {
+                        el.style.width = w + 'px';
+                    }
+                    if ((this._proxy && force) || !this._proxy) {
+                        if (this._wrap != this.get('element')) {
+                            this.get('element').style.width = w + 'px';
+                        }
+                    }
+                }
+            }
+            if (anim) {
+                if (YAHOO.util.Anim) {
+                    var _anim = new YAHOO.util.Anim(el, {
+                        height: {
+                            to: this._cache.height
+                        },
+                        width: {
+                            to: this._cache.width
+                        }
+                    }, this.get('animateDuration'), this.get('animateEasing'));
+                    if (this._positioned) {
+                        if (t) {
+                            _anim.attributes.top = {
+                                to: parseInt(t, 10)
+                            };
+                        }
+                        if (l) {
+                            _anim.attributes.left = {
+                                to: parseInt(l, 10)
+                            };
+                        }
+                    }
+
+                    if (this._wrap != this.get('element')) {
+                        _anim.onTween.subscribe(function() {
+                            this.get('element').style.height = el.style.height;
+                            this.get('element').style.width = el.style.width;
+                        }, this, true);
+                    }
+
+                    _anim.onComplete.subscribe(function() {
+                        this.set('height', h);
+                        this.set('width', w);
+                        this.fireEvent('resize', { ev: 'resize', target: this, height: h, width: w, top: t, left: l });
+                    }, this, true);
+                    _anim.animate();
+
+                }
+            } else {
+                if (this._proxy && !force) {
+                    this.fireEvent('proxyResize', { ev: 'proxyresize', target: this, height: h, width: w, top: t, left: l });
+                } else {
+                    this.fireEvent('resize', { ev: 'resize', target: this, height: h, width: w, top: t, left: l });
+                }
+            }
+            return this;
+        },
+        /** 
+        * @private
+        * @method _handle_for_br
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Bottom Right handle.
+        */
+        _handle_for_br: function(args) {
+            var newW = this._setWidth(args.e);
+            var newH = this._setHeight(args.e);
+            this.resize(args.e, (newH + 1), newW, 0, 0);
+        },
+        /** 
+        * @private
+        * @method _handle_for_bl
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Bottom Left handle.
+        */
+        _handle_for_bl: function(args) {
+            var newW = this._setWidth(args.e, true);
+            var newH = this._setHeight(args.e);
+            var l = (newW - this._cache.width);
+            this.resize(args.e, newH, newW, 0, l);
+        },
+        /** 
+        * @private
+        * @method _handle_for_tl
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Top Left handle.
+        */
+        _handle_for_tl: function(args) {
+            var newW = this._setWidth(args.e, true);
+            var newH = this._setHeight(args.e, true);
+            var t = (newH - this._cache.height);
+            var l = (newW - this._cache.width);
+            this.resize(args.e, newH, newW, t, l);
+        },
+        /** 
+        * @private
+        * @method _handle_for_tr
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Top Right handle.
+        */
+        _handle_for_tr: function(args) {
+            var newW = this._setWidth(args.e);
+            var newH = this._setHeight(args.e, true);
+            var t = (newH - this._cache.height);
+            this.resize(args.e, newH, newW, t, 0);
+        },
+        /** 
+        * @private
+        * @method _handle_for_r
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Right handle.
+        */
+        _handle_for_r: function(args) {
+            this._dds.r.setYConstraint(0,0);
+            var newW = this._setWidth(args.e);
+            this.resize(args.e, 0, newW, 0, 0);
+        },
+        /** 
+        * @private
+        * @method _handle_for_l
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Left handle.
+        */
+        _handle_for_l: function(args) {
+            this._dds.l.setYConstraint(0,0);
+            var newW = this._setWidth(args.e, true);
+            var l = (newW - this._cache.width);
+            this.resize(args.e, 0, newW, 0, l);
+        },
+        /** 
+        * @private
+        * @method _handle_for_b
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Bottom handle.
+        */
+        _handle_for_b: function(args) {
+            this._dds.b.setXConstraint(0,0);
+            var newH = this._setHeight(args.e);
+            this.resize(args.e, newH, 0, 0, 0);
+        },
+        /** 
+        * @private
+        * @method _handle_for_t
+        * @param {Object} args The arguments from the CustomEvent.
+        * @description Handles the sizes for the Top handle.
+        */
+        _handle_for_t: function(args) {
+            this._dds.t.setXConstraint(0,0);
+            var newH = this._setHeight(args.e, true);
+            var t = (newH - this._cache.height);
+            this.resize(args.e, newH, 0, t, 0);
+        },
+        /** 
+        * @private
+        * @method _setWidth
+        * @param {Event} ev The mouse event.
+        * @param {Boolean} flip Argument to determine the direction of the movement.
+        * @description Calculates the width based on the mouse event.
+        * @return {Number} The new value
+        */
+        _setWidth: function(ev, flip) {
+            var xy = this._cache.xy[0],
+                w = this._cache.width,
+                x = Event.getPageX(ev),
+                nw = (x - xy);
+
+                if (flip) {
+                    nw = (xy - x) + parseInt(this.get('width'), 10);
+                }
+                
+                nw = this._snapTick(nw, this.get('yTicks'));
+                nw = this._checkWidth(nw);
+            return nw;
+        },
+        /** 
+        * @private
+        * @method _checkWidth
+        * @param {Number} w The width to check.
+        * @description Checks the value passed against the maxWidth and minWidth.
+        * @return {Number} the new value
+        */
+        _checkWidth: function(w) {
+            if (this.get('minWidth')) {
+                if (w <= this.get('minWidth')) {
+                    w = this.get('minWidth');
+                }
+            }
+            if (this.get('maxWidth')) {
+                if (w >= this.get('maxWidth')) {
+                    w = this.get('maxWidth');
+                }
+            }
+            return w;
+        },
+        /** 
+        * @private
+        * @method _checkHeight
+        * @param {Number} h The height to check.
+        * @description Checks the value passed against the maxHeight and minHeight.
+        * @return {Number} The new value
+        */
+        _checkHeight: function(h) {
+            if (this.get('minHeight')) {
+                if (h <= this.get('minHeight')) {
+                    h = this.get('minHeight');
+                }
+            }
+            if (this.get('maxHeight')) {
+                if (h >= this.get('maxHeight')) {
+                    h = this.get('maxHeight');
+                }
+            }
+            return h;
+        },
+        /** 
+        * @private
+        * @method _setHeight
+        * @param {Event} ev The mouse event.
+        * @param {Boolean} flip Argument to determine the direction of the movement.
+        * @description Calculated the height based on the mouse event.
+        * @return {Number} The new value
+        */
+        _setHeight: function(ev, flip) {
+            var xy = this._cache.xy[1],
+                h = this._cache.height,
+                y = Event.getPageY(ev),
+                nh = (y - xy);
+
+                if (flip) {
+                    nh = (xy - y) + parseInt(this.get('height'), 10);
+                }
+                nh = this._snapTick(nh, this.get('xTicks'));
+                nh = this._checkHeight(nh);
+                
+            return nh;
+        },
+        /** 
+        * @private
+        * @method _snapTick
+        * @param {Number} size The size to tick against.
+        * @param {Number} pix The tick pixels.
+        * @description Adjusts the number based on the ticks used.
+        * @return {Number} the new snapped position
+        */
+        _snapTick: function(size, pix) {
+            if (!size || !pix) {
+                return size;
+            }
+            var _s = size;
+            var _x = size % pix;
+            if (_x > 0) {
+                if (_x > (pix / 2)) {
+                    _s = size + (pix - _x);
+                } else {
+                    _s = size - _x;
+                }
+            }
+            return _s;
+        },
+        /** 
+        * @private
+        * @method init
+        * @description The Resize class's initialization method
+        */        
+        init: function(p_oElement, p_oAttributes) {
+            this._cache = {
+                xy: [],
+                height: 0,
+                width: 0,
+                top: 0,
+                left: 0,
+                offsetHeight: 0,
+                offsetWidth: 0,
+                start: {
+                    height: 0,
+                    width: 0,
+                    top: 0,
+                    left: 0
+                }
+            };
+
+            Resize.superclass.init.call(this, p_oElement, p_oAttributes);
+
+            this.set('setSize', this.get('setSize'));
+
+            if (p_oAttributes.height) {
+                this.set('height', parseInt(p_oAttributes.height, 10));
+            }
+            if (p_oAttributes.width) {
+                this.set('width', parseInt(p_oAttributes.width, 10));
+            }
+            
+            var id = p_oElement;
+            if (!Lang.isString(id)) {
+                id = D.generateId(id);
+            }
+            Resize._instances[id] = this;
+
+            this._active = false;
+            
+            this._createWrap();
+            this._createProxy();
+            this._createHandles();
+
+        },
+        /**
+        * @method getProxyEl
+        * @description Get the HTML reference for the proxy, returns null if no proxy.
+        * @return {HTMLElement} The proxy element
+        */      
+        getProxyEl: function() {
+            return this._proxy;
+        },
+        /**
+        * @method getWrapEl
+        * @description Get the HTML reference for the wrap element, returns the current element if not wrapped.
+        * @return {HTMLElement} The wrap element
+        */      
+        getWrapEl: function() {
+            return this._wrap;
+        },
+        /**
+        * @method getStatusEl
+        * @description Get the HTML reference for the status element.
+        * @return {HTMLElement} The status element
+        */      
+        getStatusEl: function() {
+            return this._status;
+        },
+        /**
+        * @method getActiveHandleEl
+        * @description Get the HTML reference for the currently active resize handle.
+        * @return {HTMLElement} The handle element that is active
+        */      
+        getActiveHandleEl: function() {
+            return this._handles[this._currentHandle];
+        },
+        /**
+        * @method isActive
+        * @description Returns true or false if a resize operation is currently active on the element.
+        * @return {Boolean}
+        */      
+        isActive: function() {
+            return ((this._active) ? true : false);
+        },
+        /**
+        * @private
+        * @method initAttributes
+        * @description Initializes all of the configuration attributes used to create a resizable element.
+        * @param {Object} attr Object literal specifying a set of 
+        * configuration attributes used to create the utility.
+        */      
+        initAttributes: function(attr) {
+            Resize.superclass.initAttributes.call(this, attr);
+
+            /**
+            * @attribute setSize
+            * @description Set the size of the resized element, if set to false the element will not be auto resized,
+            * the resize event will contain the dimensions so the end user can resize it on their own.
+            * This setting will only work with proxy set to true and animate set to false.
+            * @type Boolean
+            */
+            this.setAttributeConfig('setSize', {
+                value: ((attr.setSize === false) ? false : true),
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute wrap
+            * @description Should we wrap the element
+            * @type Boolean
+            */
+            this.setAttributeConfig('wrap', {
+                writeOnce: true,
+                validator: YAHOO.lang.isBoolean,
+                value: attr.wrap || false
+            });
+
+            /**
+            * @attribute handles
+            * @description The handles to use (any combination of): 't', 'b', 'r', 'l', 'bl', 'br', 'tl', 'tr'. Defaults to: ['r', 'b', 'br'].
+            * Can use a shortcut of All. Note: 8 way resizing should be done on an element that is absolutely positioned.
+            * @type Array
+            */
+            this.setAttributeConfig('handles', {
+                writeOnce: true,
+                value: attr.handles || ['r', 'b', 'br'],
+                validator: function(handles) {
+                    if (Lang.isString(handles) && handles.toLowerCase() == 'all') {
+                        handles = ['t', 'b', 'r', 'l', 'bl', 'br', 'tl', 'tr'];
+                    }
+                    if (!Lang.isArray(handles)) {
+                        handles = handles.replace(/, /g, ',');
+                        handles = handles.split(',');
+                    }
+                    this._configs.handles.value = handles;
+                }
+            });
+
+            /**
+            * @attribute width
+            * @description The width of the element
+            * @type Number
+            */
+            this.setAttributeConfig('width', {
+                value: attr.width || parseInt(this.getStyle('width'), 10),
+                validator: YAHOO.lang.isNumber,
+                method: function(width) {
+                    width = parseInt(width, 10);
+                    if (width > 0) {
+                        if (this.get('setSize')) {
+                            this.setStyle('width', width + 'px');
+                        }
+                        this._cache.width = width;
+                        this._configs.width.value = width;
+                    }
+                }
+            });
+
+            /**
+            * @attribute height
+            * @description The height of the element
+            * @type Number
+            */
+            this.setAttributeConfig('height', {
+                value: attr.height || parseInt(this.getStyle('height'), 10),
+                validator: YAHOO.lang.isNumber,
+                method: function(height) {
+                    height = parseInt(height, 10);
+                    if (height > 0) {
+                        if (this.get('setSize')) {
+                            this.setStyle('height', height + 'px');
+                        }
+                        this._cache.height = height;
+                        this._configs.height.value = height;
+                    }
+                }
+            });
+
+            /**
+            * @attribute minWidth
+            * @description The minimum width of the element
+            * @type Number
+            */
+            this.setAttributeConfig('minWidth', {
+                value: attr.minWidth || 15,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute minHeight
+            * @description The minimum height of the element
+            * @type Number
+            */
+            this.setAttributeConfig('minHeight', {
+                value: attr.minHeight || 15,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute maxWidth
+            * @description The maximum width of the element
+            * @type Number
+            */
+            this.setAttributeConfig('maxWidth', {
+                value: attr.maxWidth || 10000,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute maxHeight
+            * @description The maximum height of the element
+            * @type Number
+            */
+            this.setAttributeConfig('maxHeight', {
+                value: attr.maxHeight || 10000,
+                validator: YAHOO.lang.isNumber
+            });
+
+            /**
+            * @attribute minY
+            * @description The minimum y coord of the element
+            * @type Number
+            */
+            this.setAttributeConfig('minY', {
+                value: attr.minY || false
+            });
+
+            /**
+            * @attribute minX
+            * @description The minimum x coord of the element
+            * @type Number
+            */
+            this.setAttributeConfig('minX', {
+                value: attr.minX || false
+            });
+            /**
+            * @attribute maxY
+            * @description The max y coord of the element
+            * @type Number
+            */
+            this.setAttributeConfig('maxY', {
+                value: attr.maxY || false
+            });
+
+            /**
+            * @attribute maxX
+            * @description The max x coord of the element
+            * @type Number
+            */
+            this.setAttributeConfig('maxX', {
+                value: attr.maxX || false
+            });
+
+            /**
+            * @attribute animate
+            * @description Should be use animation to resize the element (can only be used if we use proxy).
+            * @type Boolean
+            */
+            this.setAttributeConfig('animate', {
+                value: attr.animate || false,
+                validator: function(value) {
+                    var ret = true;
+                    if (!YAHOO.util.Anim) {
+                        ret = false;
+                    }
+                    return ret;
+                }               
+            });
+
+            /**
+            * @attribute animateEasing
+            * @description The Easing to apply to the animation.
+            * @type Object
+            */
+            this.setAttributeConfig('animateEasing', {
+                value: attr.animateEasing || function() {
+                    var easing = false;
+                    try {
+                        easing = YAHOO.util.Easing.easeOut;
+                    } catch (e) {}
+                    return easing;
+                }()
+            });
+
+            /**
+            * @attribute animateDuration
+            * @description The Duration to apply to the animation.
+            * @type Number
+            */
+            this.setAttributeConfig('animateDuration', {
+                value: attr.animateDuration || 0.5
+            });
+
+            /**
+            * @attribute proxy
+            * @description Resize a proxy element instead of the real element.
+            * @type Boolean
+            */
+            this.setAttributeConfig('proxy', {
+                value: attr.proxy || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute ratio
+            * @description Maintain the element's ratio when resizing.
+            * @type Boolean
+            */
+            this.setAttributeConfig('ratio', {
+                value: attr.ratio || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute ghost
+            * @description Apply an opacity filter to the element being resized (only works with proxy).
+            * @type Boolean
+            */
+            this.setAttributeConfig('ghost', {
+                value: attr.ghost || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute draggable
+            * @description A convienence method to make the element draggable
+            * @type Boolean
+            */
+            this.setAttributeConfig('draggable', {
+                value: attr.draggable || false,
+                validator: YAHOO.lang.isBoolean,
+                method: function(dd) {
+                    if (dd && this._wrap) {
+                        this._setupDragDrop();
+                    } else {
+                        if (this.dd) {
+                            D.removeClass(this._wrap, this.CSS_DRAG);
+                            this.dd.unreg();
+                        }
+                    }
+                }
+            });
+
+            /**
+            * @attribute hover
+            * @description Only show the handles when they are being moused over.
+            * @type Boolean
+            */
+            this.setAttributeConfig('hover', {
+                value: attr.hover || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute hiddenHandles
+            * @description Don't show the handles, just use the cursor to the user.
+            * @type Boolean
+            */
+            this.setAttributeConfig('hiddenHandles', {
+                value: attr.hiddenHandles || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute knobHandles
+            * @description Use the smaller handles, instead if the full size handles.
+            * @type Boolean
+            */
+            this.setAttributeConfig('knobHandles', {
+                value: attr.knobHandles || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute xTicks
+            * @description The number of x ticks to span the resize to.
+            * @type Number or False
+            */
+            this.setAttributeConfig('xTicks', {
+                value: attr.xTicks || false
+            });
+
+            /**
+            * @attribute yTicks
+            * @description The number of y ticks to span the resize to.
+            * @type Number or False
+            */
+            this.setAttributeConfig('yTicks', {
+                value: attr.yTicks || false
+            });
+
+            /**
+            * @attribute status
+            * @description Show the status (new size) of the resize.
+            * @type Boolean
+            */
+            this.setAttributeConfig('status', {
+                value: attr.status || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+            /**
+            * @attribute autoRatio
+            * @description Using the shift key during a resize will toggle the ratio config.
+            * @type Boolean
+            */
+            this.setAttributeConfig('autoRatio', {
+                value: attr.autoRatio || false,
+                validator: YAHOO.lang.isBoolean
+            });
+
+        },
+        /**
+        * @method destroy
+        * @description Destroys the resize object and all of it's elements & listeners.
+        */        
+        destroy: function() {
+            for (var h in this._handles) {
+                if (Lang.hasOwnProperty(this._handles, h)) {
+                    Event.purgeElement(this._handles[h]);
+                    this._handles[h].parentNode.removeChild(this._handles[h]);
+                }
+            }
+            if (this._proxy) {
+                this._proxy.parentNode.removeChild(this._proxy);
+            }
+            if (this._status) {
+                this._status.parentNode.removeChild(this._status);
+            }
+            if (this.dd) {
+                this.dd.unreg();
+                D.removeClass(this._wrap, this.CSS_DRAG);
+            }
+            if (this._wrap != this.get('element')) {
+                this.setStyle('position', '');
+                this.setStyle('top', '');
+                this.setStyle('left', '');
+                this._wrap.parentNode.replaceChild(this.get('element'), this._wrap);
+            }
+            this.removeClass(this.CSS_RESIZE);
+
+            delete YAHOO.util.Resize._instances[this.get('id')];
+            //Brutal Object Destroy
+            for (var i in this) {
+                if (Lang.hasOwnProperty(this, i)) {
+                    this[i] = null;
+                    delete this[i];
+                }
+            }
+        },
+        /**
+        * @method toString
+        * @description Returns a string representing the Resize Object.
+        * @return {String}
+        */        
+        toString: function() {
+            if (this.get) {
+                return 'Resize (#' + this.get('id') + ')';
+            }
+            return 'Resize Utility';
+        }
+    });
+
+    YAHOO.util.Resize = Resize;
+ 
+/**
+* @event dragEvent
+* @description Fires when the <a href="YAHOO.util.DragDrop.html">YAHOO.util.DragDrop</a> dragEvent is fired for the config option draggable.
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event startResize
+* @description Fires when when a resize action is started.
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event resize
+* @description Fires on every element resize (only fires once when used with proxy config setting).
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event beforeResize
+* @description Fires before every element resize after the size calculations, returning false will stop the resize.
+* @type YAHOO.util.CustomEvent
+*/
+/**
+* @event proxyResize
+* @description Fires on every proxy resize (only fires when used with proxy config setting).
+* @type YAHOO.util.CustomEvent
+*/
+
+})();
+
+YAHOO.register("resize", YAHOO.util.Resize, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/selector/README
===================================================================
--- trunk/root/static/yui/selector/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/selector/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,9 +1,16 @@
 YUI Library - Selector - Release Notes
 
-2.4.1
+2.5.1
 
-No change
+  * query() returns null when firstOnly and no result 
+  * correctly handle quoted attributes 
 
+2.5.0
+
+  * query() now returns single node (not array) when firstOnly is true
+  * filter() now works with ID input
+  * pseudos and attributes correctly handle spaces
+
 2.4.0
 
   * Beta release

Modified: trunk/root/static/yui/selector/selector-beta-debug.js
===================================================================
--- trunk/root/static/yui/selector/selector-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/selector/selector-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The selector module provides helper methods allowing CSS3 Selectors to be used with DOM elements.
@@ -23,29 +23,8 @@
 
 var Y = YAHOO.util;
 
-var X = {
-    IDENT: '-?[_a-z]+[-\\w]*',
-    BEGIN: '^',
-    END: '$',
-    OR: '|',
-    SP: '\\s+'
-};
+var reNth = /^(?:([-]?\d*)(n){1}|(odd|even)$)*([-+]?\d*)$/;
 
-var CHARS = {
-    SIMPLE: '-+\\w_\\[\\]\\.\\|\\*\\\'\\(\\)#:^~=$!"',
-    COMBINATORS: ',>+~'
-};
-
-X.CAPTURE_IDENT = '(' + X.IDENT + ')';
-X.BEGIN_SPACE = '(?:' + X.BEGIN + X.OR + X.SP +')';
-X.END_SPACE = '(?:' + X.SP + X.OR + X.END + ')';
-X.SELECTOR = '^(' + X.CAPTURE_IDENT + '?([' + CHARS.SIMPLE + ']*)?\\s*([' + CHARS.COMBINATORS + ']?)?\\s*).*$';
-X.SIMPLE = '(' + X.CAPTURE_IDENT + '?([' + CHARS.SIMPLE + ']*)*)?';
-X.ATTRIBUTES = '\\[([a-z]+\\w*)+([~\\|\\^\\$\\*!=]=?)?"?([^\\]"]*)"?\\]';
-X.CAPTURE_ATTRIBUTES = '(' + X.ATTRIBUTES  + ')';
-X.PSEUDO = ':' + X.CAPTURE_IDENT + '(?:\\({1}' + X.SIMPLE + '\\){1})*';
-X.NTH_CHILD = '^(?:(\\d*)(n){1}|(odd|even)$)*([-+]?\\d*)$';
-X.URL_ATTR = '^href|url$';
 Selector.prototype = {
     /**
      * Default document for use queries 
@@ -61,8 +40,7 @@
      * @type object
      */
     attrAliases: {
-        'for': 'htmlFor',
-        'class': 'className'
+        'for': 'htmlFor'
     },
 
     /**
@@ -73,7 +51,7 @@
     shorthand: {
         //'(?:(?:[^\\)\\]\\s*>+~,]+)(?:-?[_a-z]+[-\\w]))+#(-?[_a-z]+[-\\w]*)': '[id=$1]',
         '\\#(-?[_a-z]+[-\\w]*)': '[id=$1]',
-        '\\.(-?[_a-z]+[-\\w]*)': '[className~=$1]'
+        '\\.(-?[_a-z]+[-\\w]*)': '[class~=$1]'
     },
 
     /**
@@ -86,13 +64,10 @@
         '=': function(attr, val) { return attr === val; }, // Equality
         '!=': function(attr, val) { return attr !== val; }, // Inequality
         '~=': function(attr, val) { // Match one of space seperated words 
-            var str = X.BEGIN_SPACE + val + X.END_SPACE;
-            regexCache[str] = regexCache[str] || new RegExp(str); // skip getRegExp call for perf boost
-
-            //return getRegExp(X.BEGIN_SPACE + val + X.END_SPACE).test(attr);
-            return regexCache[str].test(attr);
+            var s = ' ';
+            return (s + attr + s).indexOf((s + val + s)) > -1;
         },
-        '|=': function(attr, val) { return getRegExp(X.BEGIN + val + '[-]?').test(attr); }, // Match start with value followed by optional hyphen
+        '|=': function(attr, val) { return getRegExp('^' + val + '[-]?').test(attr); }, // Match start with value followed by optional hyphen
         '^=': function(attr, val) { return attr.indexOf(val) === 0; }, // Match starts with value
         '$=': function(attr, val) { return attr.lastIndexOf(val) === attr.length - val.length; }, // Match ends with value
         '*=': function(attr, val) { return attr.indexOf(val) > -1; }, // Match contains value as substring 
@@ -162,7 +137,8 @@
         },
 
         'contains': function(node, str) {
-            return node.innerHTML.indexOf(str) > -1;
+            var text = node.innerText || node.textContent || '';
+            return text.indexOf(str) > -1;
         },
         'checked': function(node) {
             return node.checked === true;
@@ -181,7 +157,12 @@
      */
     test: function(node, selector) {
         node = Selector.document.getElementById(node) || node;
-        var groups = selector.split(',');
+
+        if (!node) {
+            return false;
+        }
+
+        var groups = selector ? selector.split(',') : [];
         if (groups.length) {
             for (var i = 0, len = groups.length; i < len; ++i) {
                 if ( rTestNode(node, groups[i]) ) { // passes if ANY group matches
@@ -197,27 +178,25 @@
      * Filters a set of nodes based on a given CSS selector. 
      * @method filter
      *
-     * @param {array}  A set of nodes/ids to filter. 
+     * @param {array} nodes A set of nodes/ids to filter. 
      * @param {string} selector The selector used to test each node.
      * @return{array} An array of nodes from the supplied array that match the given selector.
      * @static
      */
-    filter: function(arr, selector) {
-        if (!arr || !selector) {
-            YAHOO.log('filter: invalid input, returning array as is', 'warn', 'Selector');
-        }
+    filter: function(nodes, selector) {
+        nodes = nodes || [];
+
         var node,
-            nodes = arr,
             result = [],
             tokens = tokenize(selector);
 
         if (!nodes.item) { // if not HTMLCollection, handle arrays of ids and/or nodes
             YAHOO.log('filter: scanning input for HTMLElements/IDs', 'info', 'Selector');
-            for (var i = 0, len = arr.length; i < len; ++i) {
-                if (!arr[i].tagName) { // tagName limits to HTMLElements 
-                    node = Selector.document.getElementByid(arr[i]);
+            for (var i = 0, len = nodes.length; i < len; ++i) {
+                if (!nodes[i].tagName) { // tagName limits to HTMLElements 
+                    node = Selector.document.getElementById(nodes[i]);
                     if (node) { // skip IDs that return null 
-                        nodes[nodes.length] = node;
+                        nodes[i] = node;
                     } else {
                         YAHOO.log('filter: skipping invalid node', 'warn', 'Selector');
                     }
@@ -242,31 +221,34 @@
      */
     query: function(selector, root, firstOnly) {
         var result = query(selector, root, firstOnly);
-        YAHOO.log('query: returning ' + result.length + ' nodes', 'info', 'Selector');
+        YAHOO.log('query: returning ' + result, 'info', 'Selector');
         return result;
     }
 };
 
 var query = function(selector, root, firstOnly, deDupe) {
+    var result =  (firstOnly) ? null : [];
     if (!selector) {
-        return []; // no nodes for you
+        return result;
     }
-    var result = [];
-    var groups = selector.split(',');
 
+    var groups = selector.split(','); // TODO: handle comma in attribute/pseudo
+
     if (groups.length > 1) {
+        var found;
         for (var i = 0, len = groups.length; i < len; ++i) {
-            result = result.concat( arguments.callee(groups[i], root, firstOnly, true) ); 
+            found = arguments.callee(groups[i], root, firstOnly, true);
+            result = firstOnly ? found : result.concat(found); 
         }
         clearFoundCache();
         return result;
     }
 
-    if (root && !root.tagName) {
+    if (root && !root.nodeName) { // assume ID
         root = Selector.document.getElementById(root);
         if (!root) {
             YAHOO.log('invalid root node provided', 'warn', 'Selector');
-            return [];
+            return result;
         }
     }
 
@@ -276,12 +258,13 @@
         nodes = [],
         node,
         id,
-        token = tokens.pop();
+        token = tokens.pop() || {};
         
     if (idToken) {
         id = getId(idToken.attributes);
     }
-    // if no root alternate root is specified use id shortcut
+
+    // use id shortcut when possible
     if (id) {
         if (id === token.id) { // only one target
             nodes = [Selector.document.getElementById(id)] || root;
@@ -292,7 +275,7 @@
                     root = node; // start from here
                 }
             } else {
-                return [];
+                return result;
             }
         }
     }
@@ -309,7 +292,7 @@
 };
 
 var contains = function() {
-    if (document.documentElement.contains && !YAHOO.env.ua.webkit < 420)  { // IE & Opera, Safari < 3 contains is broken
+    if (document.documentElement.contains && !YAHOO.env.ua.webkit < 422)  { // IE & Opera, Safari < 3 contains is broken
         return function(needle, haystack) {
             return haystack.contains(needle);
         };
@@ -332,67 +315,68 @@
 }();
 
 var rFilter = function(nodes, token, firstOnly, deDupe) {
-    var result = [],
-        node;
+    var result = firstOnly ? null : [];
 
-    for (var i = 0, len = nodes.length; i < len; ++i) {
-        node = nodes[i];
-        if ( !rTestNode(node, null, token) || (deDupe && node._found) ) {
+    for (var i = 0, len = nodes.length; i < len; i++) {
+        if (! rTestNode(nodes[i], '', token, deDupe)) {
             continue;
         }
+
         if (firstOnly) {
-            return [node];
+            return nodes[i];
         }
         if (deDupe) {
-            node._found = true;
-            foundCache[foundCache.length] = node;
+            if (nodes[i]._found) {
+                continue;
+            }
+            nodes[i]._found = true;
+            foundCache[foundCache.length] = nodes[i];
         }
 
-        result[result.length] = node;
+        result[result.length] = nodes[i];
     }
 
     return result;
 };
 
-var rTestNode = function(node, selector, token) {
-    token = token || tokenize(selector).pop();
+var rTestNode = function(node, selector, token, deDupe) {
+    token = token || tokenize(selector).pop() || {};
 
-    if (!node || node._found || (token.tag != '*' && node.tagName.toLowerCase() != token.tag)) {
-        return false; // tag match failed
-    } 
+    if (!node.tagName ||
+        (token.tag !== '*' && node.tagName.toUpperCase() !== token.tag) ||
+        (deDupe && node._found) ) {
+        return false;
+    }
 
-    var ops = Selector.operators,
-        ps = Selector.pseudos,
-        attributes = token.attributes,
-        attr,
-        pseudos = token.pseudos,
-        prev = token.previous;
-
-    for (var i = 0, len = attributes.length; i < len; ++i) {
-        attr = (getRegExp(X.URL_ATTR).test(attributes[i][0])) ?
-                node.getAttribute(attributes[i][0], 2) : // preserve relative urls
-                node[attributes[i][0]];
-
-        if (ops[attributes[i][1]] && !ops[attributes[i][1]](attr, attributes[i][2])) {
-            return false;
+    if (token.attributes.length) {
+        var attribute;
+        for (var i = 0, len = token.attributes.length; i < len; ++i) {
+            attribute = node.getAttribute(token.attributes[i][0], 2);
+            if (attribute === undefined) {
+                return false;
+            }
+            if ( Selector.operators[token.attributes[i][1]] &&
+                    !Selector.operators[token.attributes[i][1]](attribute, token.attributes[i][2])) {
+                return false;
+            }
         }
     }
-    for (var i = 0, len = pseudos.length; i < len; ++i) {
-        if (ps[pseudos[i][0]] &&
-                !ps[pseudos[i][0]](node, pseudos[i][1])) {
-            return false;
-        }
-    }
 
-    if (prev) {
-        if (prev.combinator !== ',') {
-            return combinators[prev.combinator](node, token);
+    if (token.pseudos.length) {
+        for (var i = 0, len = token.pseudos.length; i < len; ++i) {
+            if (Selector.pseudos[token.pseudos[i][0]] &&
+                    !Selector.pseudos[token.pseudos[i][0]](node, token.pseudos[i][1])) {
+                return false;
+            }
         }
     }
-    return true;
 
+    return (token.previous && token.previous.combinator !== ',') ?
+            combinators[token.previous.combinator](node, token) :
+            true;
 };
 
+
 var foundCache = [];
 var parentCache = [];
 var regexCache = {};
@@ -429,18 +413,12 @@
     return regexCache[str + flags];
 };
 
-var trim = function(str) {
-    return str.replace(getRegExp(X.BEGIN + X.SP + X.OR + X.SP + X.END, 'g'), "");
-};
-
 var combinators = {
     ' ': function(node, token) {
-        node = node.parentNode;
-        while (node && node.tagName) {
-            if (rTestNode(node, null, token.previous)) {
+        while (node = node.parentNode) {
+            if (rTestNode(node, '', token.previous)) {
                 return true;
             }
-            node = node.parentNode;
         }  
         return false;
     },
@@ -476,7 +454,7 @@
 var getChildren = function() {
     if (document.documentElement.children) { // document for capability test
         return function(node, tag) {
-            return tag ? node.children.tags(tag) : node.children;
+            return (tag) ? node.children.tags(tag) : node.children || [];
         };
     } else {
         return function(node, tag) {
@@ -508,35 +486,38 @@
 */
 var getNth = function(node, expr, tag, reverse) {
     if (tag) tag = tag.toLowerCase();
-    var re = regexCache[X.NTH_CHILD] = regexCache[X.NTH_CHILD] || new RegExp(X.NTH_CHILD);
-    re.test(expr);
+    reNth.test(expr);
     var a = parseInt(RegExp.$1, 10), // include every _a_ elements (zero means no repeat, just first _a_)
         n = RegExp.$2, // "n"
         oddeven = RegExp.$3, // "odd" or "even"
         b = parseInt(RegExp.$4, 10) || 0, // start scan from element _b_
         result = [];
 
-    if ( isNaN(a) ) {
-        a = (n) ? 1 : 0;
-    }
+    var siblings = getChildren(node.parentNode, tag);
 
     if (oddeven) {
         a = 2; // always every other
         op = '+';
         n = 'n';
         b = (oddeven === 'odd') ? 1 : 0;
+    } else if ( isNaN(a) ) {
+        a = (n) ? 1 : 0; // start from the first or no repeat
     }
 
-    var siblings = getChildren(node.parentNode, tag);
-    if (!siblings) {
-        return false;
-    }
     if (a === 0) { // just the first
+        if (reverse) {
+            b = siblings.length - b + 1; 
+        }
+
         if (siblings[b - 1] === node) {
             return true;
         } else {
             return false;
         }
+
+    } else if (a < 0) {
+        reverse = !!reverse;
+        a = Math.abs(a);
     }
 
     if (!reverse) {
@@ -572,77 +553,116 @@
     return -1;
 };
 
+var patterns = {
+    tag: /^((?:-?[_a-z]+[\w-]*)|\*)/i,
+    attributes: /^\[([a-z]+\w*)+([~\|\^\$\*!=]=?)?['"]?([^'"\]]*)['"]?\]*/i,
+    pseudos: /^:([-\w]+)(?:\(['"]?(.+)['"]?\))*/i,
+    combinator: /^\s*([>+~]|\s)\s*/
+};
+
+/**
+    Break selector into token units per simple selector.
+    Combinator is attached to left-hand selector.
+ */
 var tokenize = function(selector) {
-    if (!selector) return [];
-        var token,
-        tokens = [],
-        m,
-        aliases = Selector.attrAliases,
-        attr,
-        reAttr = getRegExp(X.ATTRIBUTES, 'g'),
-        rePseudo = getRegExp(X.PSEUDO, 'g');
+    var token = {},     // one token per simple selector (left selector holds combinator)
+        tokens = [],    // array of tokens
+        id,             // unique id for the simple selector (if found)
+        found = false,  // whether or not any matches were found this pass
+        match;          // the regex match
 
-    selector = replaceShorthand(selector);
-    // break selector into simple selector units
-    while ( selector.length && getRegExp(X.SELECTOR).test(selector) ) {
-        token = {
-            previous: token,
-            simple: RegExp.$1,
-            tag: RegExp.$2.toLowerCase() || '*',
-            predicate: RegExp.$3,
-            attributes: [],
-            pseudos: [],
-            combinator: RegExp.$4
-        };
+    selector = replaceShorthand(selector); // convert ID and CLASS shortcuts to attributes
 
-        // Parse pseudos first, then strip from predicate to 
-        // avoid false positive from :not.
-        while (m = rePseudo.exec(token.predicate)) {
-            token.predicate = token.predicate.replace(m[0], '');
-            token.pseudos[token.pseudos.length] = m.slice(1);
-        }
-        
-        while (m = reAttr.exec(token.predicate)) { // parse attributes
-            if (aliases[m[1]]) { // convert reserved words, etc
-                m[1] = aliases[m[1]];
+    /*
+        Search for selector patterns, store, and strip them from the selector string
+        until no patterns match (invalid selector) or we run out of chars.
+
+        Multiple attributes and pseudos are allowed, in any order.
+        for example:
+            'form:first-child[type=button]:not(button)[lang|=en]'
+    */
+    do {
+        found = false; // reset after full pass
+        for (var re in patterns) {
+                if (!YAHOO.lang.hasOwnProperty(patterns, re)) {
+                    continue;
+                }
+                if (re != 'tag' && re != 'combinator') { // only one allowed
+                    token[re] = token[re] || [];
+                }
+            if (match = patterns[re].exec(selector)) { // note assignment
+                found = true;
+                if (re != 'tag' && re != 'combinator') { // only one allowed
+                    //token[re] = token[re] || [];
+
+                    // capture ID for fast path to element
+                    if (re === 'attributes' && match[1] === 'id') {
+                        token.id = match[3];
+                    }
+
+                    token[re].push(match.slice(1));
+                } else { // single selector (tag, combinator)
+                    token[re] = match[1];
+                }
+                selector = selector.replace(match[0], ''); // strip current match from selector
+                if (re === 'combinator' || !selector.length) { // next token or done
+                    token.attributes = fixAttributes(token.attributes);
+                    token.pseudos = token.pseudos || [];
+                    token.tag = token.tag ? token.tag.toUpperCase() : '*';
+                    tokens.push(token);
+
+                    token = { // prep next token
+                        previous: token
+                    };
+                }
             }
-            attr = m.slice(1); // capture attribute tokens
-            if (attr[1] === undefined) {
-                attr[1] = ''; // test for existence if no operator
-            }
-            token.attributes[token.attributes.length] = attr;
         }
-        
-        token.id = getId(token.attributes);
-        if (token.previous) {
-            token.previous.combinator = token.previous.combinator || ' ';
-        }
-        tokens[tokens.length] = token;
-        selector = trim(selector.substr(token.simple.length));
-    } 
+    } while (found);
+
     return tokens;
 };
 
+var fixAttributes = function(attr) {
+    var aliases = Selector.attrAliases;
+    attr = attr || [];
+    for (var i = 0, len = attr.length; i < len; ++i) {
+        if (aliases[attr[i][0]]) { // convert reserved words, etc
+            attr[i][0] = aliases[attr[i][0]];
+        }
+        if (!attr[i][1]) { // use exists operator
+            attr[i][1] = '';
+        }
+    }
+    return attr;
+};
+
 var replaceShorthand = function(selector) {
     var shorthand = Selector.shorthand;
-    var attrs = selector.match(getRegExp(X.CAPTURE_ATTRIBUTES, 'g')); // pull attributes to avoid false pos on "." and "#"
+    var attrs = selector.match(patterns.attributes); // pull attributes to avoid false pos on "." and "#"
     if (attrs) {
-        selector = selector.replace(getRegExp(X.CAPTURE_ATTRIBUTES, 'g'), 'REPLACED_ATTRIBUTE');
+        selector = selector.replace(patterns.attributes, 'REPLACED_ATTRIBUTE');
     }
     for (var re in shorthand) {
-        selector = selector.replace(getRegExp(re, 'g'), shorthand[re]);
+        if (!YAHOO.lang.hasOwnProperty(shorthand, re)) {
+            continue;
+        }
+        selector = selector.replace(getRegExp(re, 'gi'), shorthand[re]);
     }
 
-    if (attrs)
+    if (attrs) {
         for (var i = 0, len = attrs.length; i < len; ++i) {
             selector = selector.replace('REPLACED_ATTRIBUTE', attrs[i]);
         }
+    }
     return selector;
 };
 
+if (YAHOO.env.ua.ie) { // rewrite class for IE (others use getAttribute('class')
+    Selector.prototype.attrAliases['class'] = 'className';
+}
+
 Selector = new Selector();
-Selector.CHARS = CHARS;
-Selector.TOKENS = X;
+Selector.patterns = patterns;
 Y.Selector = Selector;
 })();
-YAHOO.register("selector", YAHOO.util.Selector, {version: "2.4.1", build: "742"});
+YAHOO.register("selector", YAHOO.util.Selector, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/selector/selector-beta-min.js
===================================================================
--- trunk/root/static/yui/selector/selector-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/selector/selector-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-(function(){var U=function(){};var D=YAHOO.util;var E={IDENT:"-?[_a-z]+[-\\w]*",BEGIN:"^",END:"$",OR:"|",SP:"\\s+"};var F={SIMPLE:"-+\\w_\\[\\]\\.\\|\\*\\'\\(\\)#:^~=$!\"",COMBINATORS:",>+~"};E.CAPTURE_IDENT="("+E.IDENT+")";E.BEGIN_SPACE="(?:"+E.BEGIN+E.OR+E.SP+")";E.END_SPACE="(?:"+E.SP+E.OR+E.END+")";E.SELECTOR="^("+E.CAPTURE_IDENT+"?(["+F.SIMPLE+"]*)?\\s*(["+F.COMBINATORS+"]?)?\\s*).*$";E.SIMPLE="("+E.CAPTURE_IDENT+"?(["+F.SIMPLE+"]*)*)?";E.ATTRIBUTES="\\[([a-z]+\\w*)+([~\\|\\^\\$\\*!=]=?)?\"?([^\\]\"]*)\"?\\]";E.CAPTURE_ATTRIBUTES="("+E.ATTRIBUTES+")";E.PSEUDO=":"+E.CAPTURE_IDENT+"(?:\\({1}"+E.SIMPLE+"\\){1})*";E.NTH_CHILD="^(?:(\\d*)(n){1}|(odd|even)$)*([-+]?\\d*)$";E.URL_ATTR="^href|url$";U.prototype={document:window.document,attrAliases:{"for":"htmlFor","class":"className"},shorthand:{"\\#(-?[_a-z]+[-\\w]*)":"[id=$1]","\\.(-?[_a-z]+[-\\w]*)":"[className~=$1]"},operators:{"=":function(W,X){return W===X;},"!=":function(W,X){return W!==X;},"~=":function(W,Y){var X=E.BEG!
 IN_SPACE+Y+E.END_SPACE;S[X]=S[X]||new RegExp(X);return S[X].test(W);},"|=":function(W,X){return H(E.BEGIN+X+"[-]?").test(W);},"^=":function(W,X){return W.indexOf(X)===0;},"$=":function(W,X){return W.lastIndexOf(X)===W.length-X.length;},"*=":function(W,X){return W.indexOf(X)>-1;},"":function(W,X){return W;}},pseudos:{"root":function(W){return W===W.ownerDocument.documentElement;},"nth-child":function(W,X){return R(W,X);},"nth-last-child":function(W,X){return R(W,X,null,true);},"nth-of-type":function(W,X){return R(W,X,W.tagName);},"nth-last-of-type":function(W,X){return R(W,X,W.tagName,true);},"first-child":function(W){return G(W.parentNode)[0]===W;},"last-child":function(X){var W=G(X.parentNode);return W[W.length-1]===X;},"first-of-type":function(W,X){return G(W.parentNode,W.tagName.toLowerCase())[0];},"last-of-type":function(X,Y){var W=G(X.parentNode,X.tagName.toLowerCase());return W[W.length-1];},"only-child":function(X){var W=G(X.parentNode);return W.length===1&&W[0]===X;!
 },"only-of-type":function(W){return G(W.parentNode,W.tagName.t!
 oLowerCa
se()).length===1;},"empty":function(W){return W.childNodes.length===0;},"not":function(W,X){return !U.test(W,X);},"contains":function(W,X){return W.innerHTML.indexOf(X)>-1;},"checked":function(W){return W.checked===true;}},test:function(a,Y){a=U.document.getElementById(a)||a;var X=Y.split(",");if(X.length){for(var Z=0,W=X.length;Z<W;++Z){if(V(a,X[Z])){return true;}}return false;}return V(a,Y);},filter:function(Z,Y){if(!Z||!Y){}var c,a=Z,X=[],d=C(Y);if(!a.item){for(var b=0,W=Z.length;b<W;++b){if(!Z[b].tagName){c=U.document.getElementByid(Z[b]);if(c){a[a.length]=c;}else{}}}}X=Q(a,C(Y)[0]);B();return X;},query:function(X,Y,Z){var W=I(X,Y,Z);return W;}};var I=function(c,h,j,a){if(!c){return[];}var k=[];var Y=c.split(",");if(Y.length>1){for(var d=0,e=Y.length;d<e;++d){k=k.concat(arguments.callee(Y[d],h,j,true));}J();return k;}if(h&&!h.tagName){h=U.document.getElementById(h);if(!h){return[];}}h=h||U.document;var g=C(c);var f=g[N(g)],W=[],Z,X,b=g.pop();if(f){X=O(f.attributes);}if(X!
 ){if(X===b.id){W=[U.document.getElementById(X)]||h;}else{Z=U.document.getElementById(X);if(h===U.document||L(Z,h)){if(Z&&V(Z,null,f)){h=Z;}}else{return[];}}}if(h&&!W.length){W=h.getElementsByTagName(b.tag);}if(W.length){k=Q(W,b,j,a);}B();return k;};var L=function(){if(document.documentElement.contains&&!YAHOO.env.ua.webkit<420){return function(X,W){return W.contains(X);};}else{if(document.documentElement.compareDocumentPosition){return function(X,W){return !!(W.compareDocumentPosition(X)&16);};}else{return function(Y,X){var W=Y.parentNode;while(W){if(Y===W){return true;}W=W.parentNode;}return false;};}}}();var Q=function(Z,b,c,Y){var X=[],d;for(var a=0,W=Z.length;a<W;++a){d=Z[a];if(!V(d,null,b)||(Y&&d._found)){continue;}if(c){return[d];}if(Y){d._found=true;M[M.length]=d;}X[X.length]=d;}return X;};var V=function(Y,b,a){a=a||C(b).pop();if(!Y||Y._found||(a.tag!="*"&&Y.tagName.toLowerCase()!=a.tag)){return false;}var X=U.operators,W=U.pseudos,c=a.attributes,f,g=a.pseudos,Z=a.pr!
 evious;for(var d=0,e=c.length;d<e;++d){f=(H(E.URL_ATTR).test(c!
 [d][0]))
?Y.getAttribute(c[d][0],2):Y[c[d][0]];if(X[c[d][1]]&&!X[c[d][1]](f,c[d][2])){return false;}}for(var d=0,e=g.length;d<e;++d){if(W[g[d][0]]&&!W[g[d][0]](Y,g[d][1])){return false;}}if(Z){if(Z.combinator!==","){return P[Z.combinator](Y,a);}}return true;};var M=[];var K=[];var S={};var J=function(){for(var X=0,W=M.length;X<W;++X){try{delete M[X]._found;}catch(Y){M[X].removeAttribute("_found");}}M=[];};var B=function(){if(!document.documentElement.children){return function(){for(var X=0,W=K.length;X<W;++X){delete K[X]._children;}K=[];};}else{return function(){};}}();var H=function(X,W){W=W||"";if(!S[X+W]){S[X+W]=new RegExp(X,W);}return S[X+W];};var T=function(W){return W.replace(H(E.BEGIN+E.SP+E.OR+E.SP+E.END,"g"),"");};var P={" ":function(X,W){X=X.parentNode;while(X&&X.tagName){if(V(X,null,W.previous)){return true;}X=X.parentNode;}return false;},">":function(X,W){return V(X.parentNode,null,W.previous);},"+":function(Y,X){var W=Y.previousSibling;while(W&&W.nodeType!==1){W=W.previo!
 usSibling;}if(W&&V(W,null,X.previous)){return true;}return false;},"~":function(Y,X){var W=Y.previousSibling;while(W){if(W.nodeType===1&&V(W,null,X.previous)){return true;}W=W.previousSibling;}return false;}};var G=function(){if(document.documentElement.children){return function(X,W){return W?X.children.tags(W):X.children;};}else{return function(a,X){if(a._children){return a._children;}var Z=[],b=a.childNodes;for(var Y=0,W=b.length;Y<W;++Y){if(b[Y].tagName){if(!X||b[Y].tagName.toLowerCase()===X){Z[Z.length]=b[Y];}}}a._children=Z;K[K.length]=a;return Z;};}}();var R=function(X,h,l,c){if(l){l=l.toLowerCase();}var j=S[E.NTH_CHILD]=S[E.NTH_CHILD]||new RegExp(E.NTH_CHILD);j.test(h);var g=parseInt(RegExp.$1,10),W=RegExp.$2,d=RegExp.$3,e=parseInt(RegExp.$4,10)||0,k=[];if(isNaN(g)){g=(W)?1:0;}if(d){g=2;op="+";W="n";e=(d==="odd")?1:0;}var f=G(X.parentNode,l);if(!f){return false;}if(g===0){if(f[e-1]===X){return true;
-}else{return false;}}if(!c){for(var Y=e-1,Z=f.length;Y<Z;Y+=g){if(Y>=0&&f[Y]===X){return true;}}}else{for(var Y=f.length-e,Z=f.length;Y>=0;Y-=g){if(Y<Z&&f[Y]===X){return true;}}}return false;};var O=function(X){for(var Y=0,W=X.length;Y<W;++Y){if(X[Y][0]=="id"&&X[Y][1]==="="){return X[Y][2];}}};var N=function(Y){for(var X=0,W=Y.length;X<W;++X){if(O(Y[X].attributes)){return X;}}return -1;};var C=function(Y){if(!Y){return[];}var a,d=[],X,Z=U.attrAliases,W,c=H(E.ATTRIBUTES,"g"),b=H(E.PSEUDO,"g");Y=A(Y);while(Y.length&&H(E.SELECTOR).test(Y)){a={previous:a,simple:RegExp.$1,tag:RegExp.$2.toLowerCase()||"*",predicate:RegExp.$3,attributes:[],pseudos:[],combinator:RegExp.$4};while(X=b.exec(a.predicate)){a.predicate=a.predicate.replace(X[0],"");a.pseudos[a.pseudos.length]=X.slice(1);}while(X=c.exec(a.predicate)){if(Z[X[1]]){X[1]=Z[X[1]];}W=X.slice(1);if(W[1]===undefined){W[1]="";}a.attributes[a.attributes.length]=W;}a.id=O(a.attributes);if(a.previous){a.previous.combinator=a.previous.!
 combinator||" ";}d[d.length]=a;Y=T(Y.substr(a.simple.length));}return d;};var A=function(X){var Y=U.shorthand;var Z=X.match(H(E.CAPTURE_ATTRIBUTES,"g"));if(Z){X=X.replace(H(E.CAPTURE_ATTRIBUTES,"g"),"REPLACED_ATTRIBUTE");}for(var b in Y){X=X.replace(H(b,"g"),Y[b]);}if(Z){for(var a=0,W=Z.length;a<W;++a){X=X.replace("REPLACED_ATTRIBUTE",Z[a]);}}return X;};U=new U();U.CHARS=F;U.TOKENS=E;D.Selector=U;})();YAHOO.register("selector",YAHOO.util.Selector,{version:"2.4.1",build:"742"});
\ No newline at end of file
+(function(){var T=function(){};var E=YAHOO.util;var U=/^(?:([-]?\d*)(n){1}|(odd|even)$)*([-+]?\d*)$/;T.prototype={document:window.document,attrAliases:{"for":"htmlFor"},shorthand:{"\\#(-?[_a-z]+[-\\w]*)":"[id=$1]","\\.(-?[_a-z]+[-\\w]*)":"[class~=$1]"},operators:{"=":function(W,X){return W===X;},"!=":function(W,X){return W!==X;},"~=":function(W,Y){var X=" ";return(X+W+X).indexOf((X+Y+X))>-1;},"|=":function(W,X){return G("^"+X+"[-]?").test(W);},"^=":function(W,X){return W.indexOf(X)===0;},"$=":function(W,X){return W.lastIndexOf(X)===W.length-X.length;},"*=":function(W,X){return W.indexOf(X)>-1;},"":function(W,X){return W;}},pseudos:{"root":function(W){return W===W.ownerDocument.documentElement;},"nth-child":function(W,X){return R(W,X);},"nth-last-child":function(W,X){return R(W,X,null,true);},"nth-of-type":function(W,X){return R(W,X,W.tagName);},"nth-last-of-type":function(W,X){return R(W,X,W.tagName,true);},"first-child":function(W){return F(W.parentNode)[0]===W;},"last-chi!
 ld":function(X){var W=F(X.parentNode);return W[W.length-1]===X;},"first-of-type":function(W,X){return F(W.parentNode,W.tagName.toLowerCase())[0];},"last-of-type":function(X,Y){var W=F(X.parentNode,X.tagName.toLowerCase());return W[W.length-1];},"only-child":function(X){var W=F(X.parentNode);return W.length===1&&W[0]===X;},"only-of-type":function(W){return F(W.parentNode,W.tagName.toLowerCase()).length===1;},"empty":function(W){return W.childNodes.length===0;},"not":function(W,X){return !T.test(W,X);},"contains":function(W,Y){var X=W.innerText||W.textContent||"";return X.indexOf(Y)>-1;},"checked":function(W){return W.checked===true;}},test:function(a,Y){a=T.document.getElementById(a)||a;if(!a){return false;}var X=Y?Y.split(","):[];if(X.length){for(var Z=0,W=X.length;Z<W;++Z){if(V(a,X[Z])){return true;}}return false;}return V(a,Y);},filter:function(Z,Y){Z=Z||[];var b,X=[],c=C(Y);if(!Z.item){for(var a=0,W=Z.length;a<W;++a){if(!Z[a].tagName){b=T.document.getElementById(Z[a]);if!
 (b){Z[a]=b;}else{}}}}X=Q(Z,C(Y)[0]);B();return X;},query:funct!
 ion(X,Y,
Z){var W=H(X,Y,Z);return W;}};var H=function(c,h,j,a){var l=(j)?null:[];if(!c){return l;}var Y=c.split(",");if(Y.length>1){var k;for(var d=0,e=Y.length;d<e;++d){k=arguments.callee(Y[d],h,j,true);l=j?k:l.concat(k);}I();return l;}if(h&&!h.nodeName){h=T.document.getElementById(h);if(!h){return l;}}h=h||T.document;var g=C(c);var f=g[N(g)],W=[],Z,X,b=g.pop()||{};if(f){X=P(f.attributes);}if(X){if(X===b.id){W=[T.document.getElementById(X)]||h;}else{Z=T.document.getElementById(X);if(h===T.document||L(Z,h)){if(Z&&V(Z,null,f)){h=Z;}}else{return l;}}}if(h&&!W.length){W=h.getElementsByTagName(b.tag);}if(W.length){l=Q(W,b,j,a);}B();return l;};var L=function(){if(document.documentElement.contains&&!YAHOO.env.ua.webkit<422){return function(X,W){return W.contains(X);};}else{if(document.documentElement.compareDocumentPosition){return function(X,W){return !!(W.compareDocumentPosition(X)&16);};}else{return function(Y,X){var W=Y.parentNode;while(W){if(Y===W){return true;}W=W.parentNode;}return !
 false;};}}}();var Q=function(Z,b,c,Y){var X=c?null:[];for(var a=0,W=Z.length;a<W;a++){if(!V(Z[a],"",b,Y)){continue;}if(c){return Z[a];}if(Y){if(Z[a]._found){continue;}Z[a]._found=true;M[M.length]=Z[a];}X[X.length]=Z[a];}return X;};var V=function(c,X,a,Y){a=a||C(X).pop()||{};if(!c.tagName||(a.tag!=="*"&&c.tagName.toUpperCase()!==a.tag)||(Y&&c._found)){return false;}if(a.attributes.length){var b;for(var Z=0,W=a.attributes.length;Z<W;++Z){b=c.getAttribute(a.attributes[Z][0],2);if(b===undefined){return false;}if(T.operators[a.attributes[Z][1]]&&!T.operators[a.attributes[Z][1]](b,a.attributes[Z][2])){return false;}}}if(a.pseudos.length){for(var Z=0,W=a.pseudos.length;Z<W;++Z){if(T.pseudos[a.pseudos[Z][0]]&&!T.pseudos[a.pseudos[Z][0]](c,a.pseudos[Z][1])){return false;}}}return(a.previous&&a.previous.combinator!==",")?O[a.previous.combinator](c,a):true;};var M=[];var K=[];var S={};var I=function(){for(var X=0,W=M.length;X<W;++X){try{delete M[X]._found;}catch(Y){M[X].removeAttribut!
 e("_found");}}M=[];};var B=function(){if(!document.documentEle!
 ment.chi
ldren){return function(){for(var X=0,W=K.length;X<W;++X){delete K[X]._children;}K=[];};}else{return function(){};}}();var G=function(X,W){W=W||"";if(!S[X+W]){S[X+W]=new RegExp(X,W);}return S[X+W];};var O={" ":function(X,W){while(X=X.parentNode){if(V(X,"",W.previous)){return true;}}return false;},">":function(X,W){return V(X.parentNode,null,W.previous);},"+":function(Y,X){var W=Y.previousSibling;while(W&&W.nodeType!==1){W=W.previousSibling;}if(W&&V(W,null,X.previous)){return true;}return false;},"~":function(Y,X){var W=Y.previousSibling;while(W){if(W.nodeType===1&&V(W,null,X.previous)){return true;}W=W.previousSibling;}return false;}};var F=function(){if(document.documentElement.children){return function(X,W){return(W)?X.children.tags(W):X.children||[];};}else{return function(a,X){if(a._children){return a._children;}var Z=[],b=a.childNodes;for(var Y=0,W=b.length;Y<W;++Y){if(b[Y].tagName){if(!X||b[Y].tagName.toLowerCase()===X){Z[Z.length]=b[Y];}}}a._children=Z;K[K.length]=a;re!
 turn Z;};}}();var R=function(X,h,k,c){if(k){k=k.toLowerCase();}U.test(h);var g=parseInt(RegExp.$1,10),W=RegExp.$2,d=RegExp.$3,e=parseInt(RegExp.$4,10)||0,j=[];var f=F(X.parentNode,k);if(d){g=2;op="+";W="n";e=(d==="odd")?1:0;}else{if(isNaN(g)){g=(W)?1:0;}}if(g===0){if(c){e=f.length-e+1;}if(f[e-1]===X){return true;}else{return false;}}else{if(g<0){c=!!c;g=Math.abs(g);}}if(!c){for(var Y=e-1,Z=f.length;Y<Z;Y+=g){if(Y>=0&&f[Y]===X){return true;}}}else{for(var Y=f.length-e,Z=f.length;Y>=0;Y-=g){if(Y<Z&&f[Y]===X){return true;}}}return false;};var P=function(X){for(var Y=0,W=X.length;Y<W;++Y){if(X[Y][0]=="id"&&X[Y][1]==="="){return X[Y][2];}}};var N=function(Y){for(var X=0,W=Y.length;X<W;++X){if(P(Y[X].attributes)){return X;}}return -1;};var D={tag:/^((?:-?[_a-z]+[\w-]*)|\*)/i,attributes:/^\[([a-z]+\w*)+([~\|\^\$\*!=]=?)?['"]?([^'"\]]*)['"]?\]*/i,pseudos:/^:([-\w]+)(?:\(['"]?(.+)['"]?\))*/i,combinator:/^\s*([>+~]|\s)\s*/};
+var C=function(W){var Y={},b=[],c,a=false,X;W=A(W);do{a=false;for(var Z in D){if(!YAHOO.lang.hasOwnProperty(D,Z)){continue;}if(Z!="tag"&&Z!="combinator"){Y[Z]=Y[Z]||[];}if(X=D[Z].exec(W)){a=true;if(Z!="tag"&&Z!="combinator"){if(Z==="attributes"&&X[1]==="id"){Y.id=X[3];}Y[Z].push(X.slice(1));}else{Y[Z]=X[1];}W=W.replace(X[0],"");if(Z==="combinator"||!W.length){Y.attributes=J(Y.attributes);Y.pseudos=Y.pseudos||[];Y.tag=Y.tag?Y.tag.toUpperCase():"*";b.push(Y);Y={previous:Y};}}}}while(a);return b;};var J=function(X){var Y=T.attrAliases;X=X||[];for(var Z=0,W=X.length;Z<W;++Z){if(Y[X[Z][0]]){X[Z][0]=Y[X[Z][0]];}if(!X[Z][1]){X[Z][1]="";}}return X;};var A=function(X){var Y=T.shorthand;var Z=X.match(D.attributes);if(Z){X=X.replace(D.attributes,"REPLACED_ATTRIBUTE");}for(var b in Y){if(!YAHOO.lang.hasOwnProperty(Y,b)){continue;}X=X.replace(G(b,"gi"),Y[b]);}if(Z){for(var a=0,W=Z.length;a<W;++a){X=X.replace("REPLACED_ATTRIBUTE",Z[a]);}}return X;};if(YAHOO.env.ua.ie){T.prototype.attrAli!
 ases["class"]="className";}T=new T();T.patterns=D;E.Selector=T;})();YAHOO.register("selector",YAHOO.util.Selector,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/selector/selector-beta.js
===================================================================
--- trunk/root/static/yui/selector/selector-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/selector/selector-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The selector module provides helper methods allowing CSS3 Selectors to be used with DOM elements.
@@ -23,29 +23,8 @@
 
 var Y = YAHOO.util;
 
-var X = {
-    IDENT: '-?[_a-z]+[-\\w]*',
-    BEGIN: '^',
-    END: '$',
-    OR: '|',
-    SP: '\\s+'
-};
+var reNth = /^(?:([-]?\d*)(n){1}|(odd|even)$)*([-+]?\d*)$/;
 
-var CHARS = {
-    SIMPLE: '-+\\w_\\[\\]\\.\\|\\*\\\'\\(\\)#:^~=$!"',
-    COMBINATORS: ',>+~'
-};
-
-X.CAPTURE_IDENT = '(' + X.IDENT + ')';
-X.BEGIN_SPACE = '(?:' + X.BEGIN + X.OR + X.SP +')';
-X.END_SPACE = '(?:' + X.SP + X.OR + X.END + ')';
-X.SELECTOR = '^(' + X.CAPTURE_IDENT + '?([' + CHARS.SIMPLE + ']*)?\\s*([' + CHARS.COMBINATORS + ']?)?\\s*).*$';
-X.SIMPLE = '(' + X.CAPTURE_IDENT + '?([' + CHARS.SIMPLE + ']*)*)?';
-X.ATTRIBUTES = '\\[([a-z]+\\w*)+([~\\|\\^\\$\\*!=]=?)?"?([^\\]"]*)"?\\]';
-X.CAPTURE_ATTRIBUTES = '(' + X.ATTRIBUTES  + ')';
-X.PSEUDO = ':' + X.CAPTURE_IDENT + '(?:\\({1}' + X.SIMPLE + '\\){1})*';
-X.NTH_CHILD = '^(?:(\\d*)(n){1}|(odd|even)$)*([-+]?\\d*)$';
-X.URL_ATTR = '^href|url$';
 Selector.prototype = {
     /**
      * Default document for use queries 
@@ -61,8 +40,7 @@
      * @type object
      */
     attrAliases: {
-        'for': 'htmlFor',
-        'class': 'className'
+        'for': 'htmlFor'
     },
 
     /**
@@ -73,7 +51,7 @@
     shorthand: {
         //'(?:(?:[^\\)\\]\\s*>+~,]+)(?:-?[_a-z]+[-\\w]))+#(-?[_a-z]+[-\\w]*)': '[id=$1]',
         '\\#(-?[_a-z]+[-\\w]*)': '[id=$1]',
-        '\\.(-?[_a-z]+[-\\w]*)': '[className~=$1]'
+        '\\.(-?[_a-z]+[-\\w]*)': '[class~=$1]'
     },
 
     /**
@@ -86,13 +64,10 @@
         '=': function(attr, val) { return attr === val; }, // Equality
         '!=': function(attr, val) { return attr !== val; }, // Inequality
         '~=': function(attr, val) { // Match one of space seperated words 
-            var str = X.BEGIN_SPACE + val + X.END_SPACE;
-            regexCache[str] = regexCache[str] || new RegExp(str); // skip getRegExp call for perf boost
-
-            //return getRegExp(X.BEGIN_SPACE + val + X.END_SPACE).test(attr);
-            return regexCache[str].test(attr);
+            var s = ' ';
+            return (s + attr + s).indexOf((s + val + s)) > -1;
         },
-        '|=': function(attr, val) { return getRegExp(X.BEGIN + val + '[-]?').test(attr); }, // Match start with value followed by optional hyphen
+        '|=': function(attr, val) { return getRegExp('^' + val + '[-]?').test(attr); }, // Match start with value followed by optional hyphen
         '^=': function(attr, val) { return attr.indexOf(val) === 0; }, // Match starts with value
         '$=': function(attr, val) { return attr.lastIndexOf(val) === attr.length - val.length; }, // Match ends with value
         '*=': function(attr, val) { return attr.indexOf(val) > -1; }, // Match contains value as substring 
@@ -162,7 +137,8 @@
         },
 
         'contains': function(node, str) {
-            return node.innerHTML.indexOf(str) > -1;
+            var text = node.innerText || node.textContent || '';
+            return text.indexOf(str) > -1;
         },
         'checked': function(node) {
             return node.checked === true;
@@ -181,7 +157,12 @@
      */
     test: function(node, selector) {
         node = Selector.document.getElementById(node) || node;
-        var groups = selector.split(',');
+
+        if (!node) {
+            return false;
+        }
+
+        var groups = selector ? selector.split(',') : [];
         if (groups.length) {
             for (var i = 0, len = groups.length; i < len; ++i) {
                 if ( rTestNode(node, groups[i]) ) { // passes if ANY group matches
@@ -197,25 +178,24 @@
      * Filters a set of nodes based on a given CSS selector. 
      * @method filter
      *
-     * @param {array}  A set of nodes/ids to filter. 
+     * @param {array} nodes A set of nodes/ids to filter. 
      * @param {string} selector The selector used to test each node.
      * @return{array} An array of nodes from the supplied array that match the given selector.
      * @static
      */
-    filter: function(arr, selector) {
-        if (!arr || !selector) {
-        }
+    filter: function(nodes, selector) {
+        nodes = nodes || [];
+
         var node,
-            nodes = arr,
             result = [],
             tokens = tokenize(selector);
 
         if (!nodes.item) { // if not HTMLCollection, handle arrays of ids and/or nodes
-            for (var i = 0, len = arr.length; i < len; ++i) {
-                if (!arr[i].tagName) { // tagName limits to HTMLElements 
-                    node = Selector.document.getElementByid(arr[i]);
+            for (var i = 0, len = nodes.length; i < len; ++i) {
+                if (!nodes[i].tagName) { // tagName limits to HTMLElements 
+                    node = Selector.document.getElementById(nodes[i]);
                     if (node) { // skip IDs that return null 
-                        nodes[nodes.length] = node;
+                        nodes[i] = node;
                     } else {
                     }
                 }
@@ -243,24 +223,27 @@
 };
 
 var query = function(selector, root, firstOnly, deDupe) {
+    var result =  (firstOnly) ? null : [];
     if (!selector) {
-        return []; // no nodes for you
+        return result;
     }
-    var result = [];
-    var groups = selector.split(',');
 
+    var groups = selector.split(','); // TODO: handle comma in attribute/pseudo
+
     if (groups.length > 1) {
+        var found;
         for (var i = 0, len = groups.length; i < len; ++i) {
-            result = result.concat( arguments.callee(groups[i], root, firstOnly, true) ); 
+            found = arguments.callee(groups[i], root, firstOnly, true);
+            result = firstOnly ? found : result.concat(found); 
         }
         clearFoundCache();
         return result;
     }
 
-    if (root && !root.tagName) {
+    if (root && !root.nodeName) { // assume ID
         root = Selector.document.getElementById(root);
         if (!root) {
-            return [];
+            return result;
         }
     }
 
@@ -270,12 +253,13 @@
         nodes = [],
         node,
         id,
-        token = tokens.pop();
+        token = tokens.pop() || {};
         
     if (idToken) {
         id = getId(idToken.attributes);
     }
-    // if no root alternate root is specified use id shortcut
+
+    // use id shortcut when possible
     if (id) {
         if (id === token.id) { // only one target
             nodes = [Selector.document.getElementById(id)] || root;
@@ -286,7 +270,7 @@
                     root = node; // start from here
                 }
             } else {
-                return [];
+                return result;
             }
         }
     }
@@ -303,7 +287,7 @@
 };
 
 var contains = function() {
-    if (document.documentElement.contains && !YAHOO.env.ua.webkit < 420)  { // IE & Opera, Safari < 3 contains is broken
+    if (document.documentElement.contains && !YAHOO.env.ua.webkit < 422)  { // IE & Opera, Safari < 3 contains is broken
         return function(needle, haystack) {
             return haystack.contains(needle);
         };
@@ -326,67 +310,68 @@
 }();
 
 var rFilter = function(nodes, token, firstOnly, deDupe) {
-    var result = [],
-        node;
+    var result = firstOnly ? null : [];
 
-    for (var i = 0, len = nodes.length; i < len; ++i) {
-        node = nodes[i];
-        if ( !rTestNode(node, null, token) || (deDupe && node._found) ) {
+    for (var i = 0, len = nodes.length; i < len; i++) {
+        if (! rTestNode(nodes[i], '', token, deDupe)) {
             continue;
         }
+
         if (firstOnly) {
-            return [node];
+            return nodes[i];
         }
         if (deDupe) {
-            node._found = true;
-            foundCache[foundCache.length] = node;
+            if (nodes[i]._found) {
+                continue;
+            }
+            nodes[i]._found = true;
+            foundCache[foundCache.length] = nodes[i];
         }
 
-        result[result.length] = node;
+        result[result.length] = nodes[i];
     }
 
     return result;
 };
 
-var rTestNode = function(node, selector, token) {
-    token = token || tokenize(selector).pop();
+var rTestNode = function(node, selector, token, deDupe) {
+    token = token || tokenize(selector).pop() || {};
 
-    if (!node || node._found || (token.tag != '*' && node.tagName.toLowerCase() != token.tag)) {
-        return false; // tag match failed
-    } 
+    if (!node.tagName ||
+        (token.tag !== '*' && node.tagName.toUpperCase() !== token.tag) ||
+        (deDupe && node._found) ) {
+        return false;
+    }
 
-    var ops = Selector.operators,
-        ps = Selector.pseudos,
-        attributes = token.attributes,
-        attr,
-        pseudos = token.pseudos,
-        prev = token.previous;
-
-    for (var i = 0, len = attributes.length; i < len; ++i) {
-        attr = (getRegExp(X.URL_ATTR).test(attributes[i][0])) ?
-                node.getAttribute(attributes[i][0], 2) : // preserve relative urls
-                node[attributes[i][0]];
-
-        if (ops[attributes[i][1]] && !ops[attributes[i][1]](attr, attributes[i][2])) {
-            return false;
+    if (token.attributes.length) {
+        var attribute;
+        for (var i = 0, len = token.attributes.length; i < len; ++i) {
+            attribute = node.getAttribute(token.attributes[i][0], 2);
+            if (attribute === undefined) {
+                return false;
+            }
+            if ( Selector.operators[token.attributes[i][1]] &&
+                    !Selector.operators[token.attributes[i][1]](attribute, token.attributes[i][2])) {
+                return false;
+            }
         }
     }
-    for (var i = 0, len = pseudos.length; i < len; ++i) {
-        if (ps[pseudos[i][0]] &&
-                !ps[pseudos[i][0]](node, pseudos[i][1])) {
-            return false;
-        }
-    }
 
-    if (prev) {
-        if (prev.combinator !== ',') {
-            return combinators[prev.combinator](node, token);
+    if (token.pseudos.length) {
+        for (var i = 0, len = token.pseudos.length; i < len; ++i) {
+            if (Selector.pseudos[token.pseudos[i][0]] &&
+                    !Selector.pseudos[token.pseudos[i][0]](node, token.pseudos[i][1])) {
+                return false;
+            }
         }
     }
-    return true;
 
+    return (token.previous && token.previous.combinator !== ',') ?
+            combinators[token.previous.combinator](node, token) :
+            true;
 };
 
+
 var foundCache = [];
 var parentCache = [];
 var regexCache = {};
@@ -421,18 +406,12 @@
     return regexCache[str + flags];
 };
 
-var trim = function(str) {
-    return str.replace(getRegExp(X.BEGIN + X.SP + X.OR + X.SP + X.END, 'g'), "");
-};
-
 var combinators = {
     ' ': function(node, token) {
-        node = node.parentNode;
-        while (node && node.tagName) {
-            if (rTestNode(node, null, token.previous)) {
+        while (node = node.parentNode) {
+            if (rTestNode(node, '', token.previous)) {
                 return true;
             }
-            node = node.parentNode;
         }  
         return false;
     },
@@ -468,7 +447,7 @@
 var getChildren = function() {
     if (document.documentElement.children) { // document for capability test
         return function(node, tag) {
-            return tag ? node.children.tags(tag) : node.children;
+            return (tag) ? node.children.tags(tag) : node.children || [];
         };
     } else {
         return function(node, tag) {
@@ -500,35 +479,38 @@
 */
 var getNth = function(node, expr, tag, reverse) {
     if (tag) tag = tag.toLowerCase();
-    var re = regexCache[X.NTH_CHILD] = regexCache[X.NTH_CHILD] || new RegExp(X.NTH_CHILD);
-    re.test(expr);
+    reNth.test(expr);
     var a = parseInt(RegExp.$1, 10), // include every _a_ elements (zero means no repeat, just first _a_)
         n = RegExp.$2, // "n"
         oddeven = RegExp.$3, // "odd" or "even"
         b = parseInt(RegExp.$4, 10) || 0, // start scan from element _b_
         result = [];
 
-    if ( isNaN(a) ) {
-        a = (n) ? 1 : 0;
-    }
+    var siblings = getChildren(node.parentNode, tag);
 
     if (oddeven) {
         a = 2; // always every other
         op = '+';
         n = 'n';
         b = (oddeven === 'odd') ? 1 : 0;
+    } else if ( isNaN(a) ) {
+        a = (n) ? 1 : 0; // start from the first or no repeat
     }
 
-    var siblings = getChildren(node.parentNode, tag);
-    if (!siblings) {
-        return false;
-    }
     if (a === 0) { // just the first
+        if (reverse) {
+            b = siblings.length - b + 1; 
+        }
+
         if (siblings[b - 1] === node) {
             return true;
         } else {
             return false;
         }
+
+    } else if (a < 0) {
+        reverse = !!reverse;
+        a = Math.abs(a);
     }
 
     if (!reverse) {
@@ -564,77 +546,116 @@
     return -1;
 };
 
+var patterns = {
+    tag: /^((?:-?[_a-z]+[\w-]*)|\*)/i,
+    attributes: /^\[([a-z]+\w*)+([~\|\^\$\*!=]=?)?['"]?([^'"\]]*)['"]?\]*/i,
+    pseudos: /^:([-\w]+)(?:\(['"]?(.+)['"]?\))*/i,
+    combinator: /^\s*([>+~]|\s)\s*/
+};
+
+/**
+    Break selector into token units per simple selector.
+    Combinator is attached to left-hand selector.
+ */
 var tokenize = function(selector) {
-    if (!selector) return [];
-        var token,
-        tokens = [],
-        m,
-        aliases = Selector.attrAliases,
-        attr,
-        reAttr = getRegExp(X.ATTRIBUTES, 'g'),
-        rePseudo = getRegExp(X.PSEUDO, 'g');
+    var token = {},     // one token per simple selector (left selector holds combinator)
+        tokens = [],    // array of tokens
+        id,             // unique id for the simple selector (if found)
+        found = false,  // whether or not any matches were found this pass
+        match;          // the regex match
 
-    selector = replaceShorthand(selector);
-    // break selector into simple selector units
-    while ( selector.length && getRegExp(X.SELECTOR).test(selector) ) {
-        token = {
-            previous: token,
-            simple: RegExp.$1,
-            tag: RegExp.$2.toLowerCase() || '*',
-            predicate: RegExp.$3,
-            attributes: [],
-            pseudos: [],
-            combinator: RegExp.$4
-        };
+    selector = replaceShorthand(selector); // convert ID and CLASS shortcuts to attributes
 
-        // Parse pseudos first, then strip from predicate to 
-        // avoid false positive from :not.
-        while (m = rePseudo.exec(token.predicate)) {
-            token.predicate = token.predicate.replace(m[0], '');
-            token.pseudos[token.pseudos.length] = m.slice(1);
-        }
-        
-        while (m = reAttr.exec(token.predicate)) { // parse attributes
-            if (aliases[m[1]]) { // convert reserved words, etc
-                m[1] = aliases[m[1]];
+    /*
+        Search for selector patterns, store, and strip them from the selector string
+        until no patterns match (invalid selector) or we run out of chars.
+
+        Multiple attributes and pseudos are allowed, in any order.
+        for example:
+            'form:first-child[type=button]:not(button)[lang|=en]'
+    */
+    do {
+        found = false; // reset after full pass
+        for (var re in patterns) {
+                if (!YAHOO.lang.hasOwnProperty(patterns, re)) {
+                    continue;
+                }
+                if (re != 'tag' && re != 'combinator') { // only one allowed
+                    token[re] = token[re] || [];
+                }
+            if (match = patterns[re].exec(selector)) { // note assignment
+                found = true;
+                if (re != 'tag' && re != 'combinator') { // only one allowed
+                    //token[re] = token[re] || [];
+
+                    // capture ID for fast path to element
+                    if (re === 'attributes' && match[1] === 'id') {
+                        token.id = match[3];
+                    }
+
+                    token[re].push(match.slice(1));
+                } else { // single selector (tag, combinator)
+                    token[re] = match[1];
+                }
+                selector = selector.replace(match[0], ''); // strip current match from selector
+                if (re === 'combinator' || !selector.length) { // next token or done
+                    token.attributes = fixAttributes(token.attributes);
+                    token.pseudos = token.pseudos || [];
+                    token.tag = token.tag ? token.tag.toUpperCase() : '*';
+                    tokens.push(token);
+
+                    token = { // prep next token
+                        previous: token
+                    };
+                }
             }
-            attr = m.slice(1); // capture attribute tokens
-            if (attr[1] === undefined) {
-                attr[1] = ''; // test for existence if no operator
-            }
-            token.attributes[token.attributes.length] = attr;
         }
-        
-        token.id = getId(token.attributes);
-        if (token.previous) {
-            token.previous.combinator = token.previous.combinator || ' ';
-        }
-        tokens[tokens.length] = token;
-        selector = trim(selector.substr(token.simple.length));
-    } 
+    } while (found);
+
     return tokens;
 };
 
+var fixAttributes = function(attr) {
+    var aliases = Selector.attrAliases;
+    attr = attr || [];
+    for (var i = 0, len = attr.length; i < len; ++i) {
+        if (aliases[attr[i][0]]) { // convert reserved words, etc
+            attr[i][0] = aliases[attr[i][0]];
+        }
+        if (!attr[i][1]) { // use exists operator
+            attr[i][1] = '';
+        }
+    }
+    return attr;
+};
+
 var replaceShorthand = function(selector) {
     var shorthand = Selector.shorthand;
-    var attrs = selector.match(getRegExp(X.CAPTURE_ATTRIBUTES, 'g')); // pull attributes to avoid false pos on "." and "#"
+    var attrs = selector.match(patterns.attributes); // pull attributes to avoid false pos on "." and "#"
     if (attrs) {
-        selector = selector.replace(getRegExp(X.CAPTURE_ATTRIBUTES, 'g'), 'REPLACED_ATTRIBUTE');
+        selector = selector.replace(patterns.attributes, 'REPLACED_ATTRIBUTE');
     }
     for (var re in shorthand) {
-        selector = selector.replace(getRegExp(re, 'g'), shorthand[re]);
+        if (!YAHOO.lang.hasOwnProperty(shorthand, re)) {
+            continue;
+        }
+        selector = selector.replace(getRegExp(re, 'gi'), shorthand[re]);
     }
 
-    if (attrs)
+    if (attrs) {
         for (var i = 0, len = attrs.length; i < len; ++i) {
             selector = selector.replace('REPLACED_ATTRIBUTE', attrs[i]);
         }
+    }
     return selector;
 };
 
+if (YAHOO.env.ua.ie) { // rewrite class for IE (others use getAttribute('class')
+    Selector.prototype.attrAliases['class'] = 'className';
+}
+
 Selector = new Selector();
-Selector.CHARS = CHARS;
-Selector.TOKENS = X;
+Selector.patterns = patterns;
 Y.Selector = Selector;
 })();
-YAHOO.register("selector", YAHOO.util.Selector, {version: "2.4.1", build: "742"});
+YAHOO.register("selector", YAHOO.util.Selector, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/slider/README
===================================================================
--- trunk/root/static/yui/slider/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/slider/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,13 @@
 Slider - Release Notes
 
-2.4.1
+2.5.1
     * No change
 
+2.5.0
+    * Slider onDrag now calls fireEvents, so bg mousedown, drag, mouseup fires change events
+    * Slider uses new dragOnly=true property added in dragdrop
+    * Introduced DualSlider
+
 2.4.0
     * No change
 

Modified: trunk/root/static/yui/slider/slider-debug.js
===================================================================
--- trunk/root/static/yui/slider/slider-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/slider/slider-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The Slider component is a UI control that enables the user to adjust 
@@ -118,6 +118,14 @@
 YAHOO.extend(YAHOO.widget.Slider, YAHOO.util.DragDrop, {
 
     /**
+     * Override the default setting of dragOnly to true.
+     * @property dragOnly
+     * @type boolean
+     * @default true
+     */
+    dragOnly : true,
+
+    /**
      * Initializes the slider.  Executed in the constructor
      * @method initSlider
      * @param {string} sType the type of slider (horiz, vert, region)
@@ -197,7 +205,7 @@
 
         /**
          * Specifies the number of pixels the arrow keys will move the slider.
-         * Default is 25.
+         * Default is 20.
          * @property keyIncrement
          * @type int
          */
@@ -1035,6 +1043,7 @@
             var x = YAHOO.util.Event.getPageX(e);
             var y = YAHOO.util.Event.getPageY(e);
             this.moveThumb(x, y, true, true);
+            this.fireEvents();
         }
     },
 
@@ -1199,6 +1208,14 @@
     startOffset: null,
 
     /**
+     * Override the default setting of dragOnly to true.
+     * @property dragOnly
+     * @type boolean
+     * @default true
+     */
+    dragOnly : true,
+
+    /**
      * Flag used to figure out if this is a horizontal or vertical slider
      * @property _isHoriz
      * @type boolean
@@ -1389,4 +1406,535 @@
 
 });
 
-YAHOO.register("slider", YAHOO.widget.Slider, {version: "2.4.1", build: "742"});
+/**
+ * A slider with two thumbs, one that represents the min value and 
+ * the other the max.  Actually a composition of two sliders, both with
+ * the same background.  The constraints for each slider are adjusted
+ * dynamically so that the min value of the max slider is equal or greater
+ * to the current value of the min slider, and the max value of the min
+ * slider is the current value of the max slider.
+ * Constructor assumes both thumbs are positioned absolutely at the 0 mark on
+ * the background.
+ *
+ * @namespace YAHOO.widget
+ * @class DualSlider
+ * @uses YAHOO.util.EventProvider
+ * @constructor
+ * @param {Slider} minSlider The Slider instance used for the min value thumb
+ * @param {Slider} maxSlider The Slider instance used for the max value thumb
+ * @param {int}    range The number of pixels the thumbs may move within
+ * @param {Array}  initVals (optional) [min,max] Initial thumb placement
+ */
+YAHOO.widget.DualSlider = function(minSlider, maxSlider, range, initVals) {
+
+    var self = this,
+        lang = YAHOO.lang;
+
+    /**
+     * A slider instance that keeps track of the lower value of the range.
+     * <strong>read only</strong>
+     * @property minSlider
+     * @type Slider
+     */
+    this.minSlider = minSlider;
+
+    /**
+     * A slider instance that keeps track of the upper value of the range.
+     * <strong>read only</strong>
+     * @property maxSlider
+     * @type Slider
+     */
+    this.maxSlider = maxSlider;
+
+    /**
+     * The currently active slider (min or max). <strong>read only</strong>
+     * @property activeSlider
+     * @type Slider
+     */
+    this.activeSlider = minSlider;
+
+    /**
+     * Is the DualSlider oriented horizontally or vertically?
+     * <strong>read only</strong>
+     * @property isHoriz
+     * @type boolean
+     */
+    this.isHoriz = minSlider.thumb._isHoriz;
+
+    // Validate initial values
+    initVals = YAHOO.lang.isArray(initVals) ? initVals : [0,range];
+    initVals[0] = Math.min(Math.max(parseInt(initVals[0],10)|0,0),range);
+    initVals[1] = Math.max(Math.min(parseInt(initVals[1],10)|0,range),0);
+    // Swap initVals if min > max
+    if (initVals[0] > initVals[1]) {
+        initVals.splice(0,2,initVals[1],initVals[0]);
+    }
+
+    var ready = { min : false, max : false };
+
+    this.minSlider.thumb.onAvailable = function () {
+        minSlider.setStartSliderState();
+        ready.min = true;
+        if (ready.max) {
+            minSlider.setValue(initVals[0],true,true,true);
+            maxSlider.setValue(initVals[1],true,true,true);
+            self.updateValue(true);
+            self.fireEvent('ready',self);
+        }
+    };
+    this.maxSlider.thumb.onAvailable = function () {
+        maxSlider.setStartSliderState();
+        ready.max = true;
+        if (ready.min) {
+            minSlider.setValue(initVals[0],true,true,true);
+            maxSlider.setValue(initVals[1],true,true,true);
+            self.updateValue(true);
+            self.fireEvent('ready',self);
+        }
+    };
+
+    // dispatch mousedowns to the active slider
+    minSlider.onMouseDown = function(e) {
+        self._handleMouseDown(e);
+    };
+
+    // we can safely ignore a mousedown on one of the sliders since
+    // they share a background
+    maxSlider.onMouseDown = function(e) { 
+        YAHOO.util.Event.stopEvent(e); 
+    };
+
+    // Fix the drag behavior so that only the active slider
+    // follows the drag
+    minSlider.onDrag =
+    maxSlider.onDrag = function(e) {
+        self._handleDrag(e);
+    };
+
+    // The core events for each slider are handled so we can expose a single
+    // event for when the event happens on either slider
+    minSlider.subscribe("change", this._handleMinChange, minSlider, this);
+    minSlider.subscribe("slideStart", this._handleSlideStart, minSlider, this);
+    minSlider.subscribe("slideEnd", this._handleSlideEnd, minSlider, this);
+
+    maxSlider.subscribe("change", this._handleMaxChange, maxSlider, this);
+    maxSlider.subscribe("slideStart", this._handleSlideStart, maxSlider, this);
+    maxSlider.subscribe("slideEnd", this._handleSlideEnd, maxSlider, this);
+
+    /**
+     * Event that fires when the slider is finished setting up
+     * @event ready
+     * @param {DualSlider} dualslider the DualSlider instance
+     */
+    this.createEvent("ready", this);
+
+    /**
+     * Event that fires when either the min or max value changes
+     * @event change
+     * @param {DualSlider} dualslider the DualSlider instance
+     */
+    this.createEvent("change", this);
+
+    /**
+     * Event that fires when one of the thumbs begins to move
+     * @event slideStart
+     * @param {Slider} activeSlider the moving slider
+     */
+    this.createEvent("slideStart", this);
+
+    /**
+     * Event that fires when one of the thumbs finishes moving
+     * @event slideEnd
+     * @param {Slider} activeSlider the moving slider
+     */
+    this.createEvent("slideEnd", this);
+};
+
+YAHOO.widget.DualSlider.prototype = {
+
+    /**
+     * The current value of the min thumb. <strong>read only</strong>.
+     * @property minVal
+     * @type int
+     */
+    minVal : -1,
+
+    /**
+     * The current value of the max thumb. <strong>read only</strong>.
+     * @property maxVal
+     * @type int
+     */
+    maxVal : -1,
+
+    /**
+     * Pixel distance to maintain between thumbs.
+     * @property minRange
+     * @type int
+     * @default 0
+     */
+    minRange : 0,
+
+    /**
+     * Executed when one of the sliders fires the slideStart event
+     * @method _handleSlideStart
+     * @private
+     */
+    _handleSlideStart: function(data, slider) {
+        this.fireEvent("slideStart", slider);
+    },
+
+    /**
+     * Executed when one of the sliders fires the slideEnd event
+     * @method _handleSlideEnd
+     * @private
+     */
+    _handleSlideEnd: function(data, slider) {
+        this.fireEvent("slideEnd", slider);
+    },
+
+    /**
+     * Overrides the onDrag method for both sliders
+     * @method _handleDrag
+     * @private
+     */
+    _handleDrag: function(e) {
+        YAHOO.widget.Slider.prototype.onDrag.call(this.activeSlider, e);
+    },
+
+    /**
+     * Executed when the min slider fires the change event
+     * @method _handleMinChange
+     * @private
+     */
+    _handleMinChange: function() {
+        this.activeSlider = this.minSlider;
+        this.updateValue();
+    },
+
+    /**
+     * Executed when the max slider fires the change event
+     * @method _handleMaxChange
+     * @private
+     */
+    _handleMaxChange: function() {
+        this.activeSlider = this.maxSlider;
+        this.updateValue();
+    },
+
+    /**
+     * Sets the min and max thumbs to new values.
+     * @method setValues
+     * @param min {int} Pixel offset to assign to the min thumb
+     * @param max {int} Pixel offset to assign to the max thumb
+     * @param skipAnim {boolean} (optional) Set to true to skip thumb animation.
+     * Default false
+     * @param force {boolean} (optional) ignore the locked setting and set
+     * value anyway. Default false
+     * @param silent {boolean} (optional) Set to true to skip firing change
+     * events.  Default false
+     */
+    setValues : function (min, max, skipAnim, force, silent) {
+        var mins = this.minSlider,
+            maxs = this.maxSlider,
+            mint = mins.thumb,
+            maxt = maxs.thumb,
+            self = this,
+            done = { min : false, max : false };
+
+        // Clear constraints to prevent animated thumbs from prematurely
+        // stopping when hitting a constraint that's moving with the other
+        // thumb.
+        if (mint._isHoriz) {
+            mint.setXConstraint(mint.leftConstraint,maxt.rightConstraint,mint.tickSize);
+            maxt.setXConstraint(mint.leftConstraint,maxt.rightConstraint,maxt.tickSize);
+        } else {
+            mint.setYConstraint(mint.topConstraint,maxt.bottomConstraint,mint.tickSize);
+            maxt.setYConstraint(mint.topConstraint,maxt.bottomConstraint,maxt.tickSize);
+        }
+
+        // Set up one-time slideEnd callbacks to call updateValue when both
+        // thumbs have been set
+        this._oneTimeCallback(mins,'slideEnd',function () {
+            done.min = true;
+            if (done.max) {
+                self.updateValue(silent);
+                // Clean the slider's slideEnd events on a timeout since this
+                // will be executed from inside the event's fire
+                setTimeout(function () {
+                    self._cleanEvent(mins,'slideEnd');
+                    self._cleanEvent(maxs,'slideEnd');
+                },0);
+            }
+        });
+
+        this._oneTimeCallback(maxs,'slideEnd',function () {
+            done.max = true;
+            if (done.min) {
+                self.updateValue(silent);
+                // Clean both sliders' slideEnd events on a timeout since this
+                // will be executed from inside one of the event's fire
+                setTimeout(function () {
+                    self._cleanEvent(mins,'slideEnd');
+                    self._cleanEvent(maxs,'slideEnd');
+                },0);
+            }
+        });
+
+        mins.setValue(min,skipAnim,force,silent);
+        maxs.setValue(max,skipAnim,force,silent);
+    },
+
+    /**
+     * Set the min thumb position to a new value.
+     * @method setMinValue
+     * @param min {int} Pixel offset for min thumb
+     * @param skipAnim {boolean} (optional) Set to true to skip thumb animation.
+     * Default false
+     * @param force {boolean} (optional) ignore the locked setting and set
+     * value anyway. Default false
+     * @param silent {boolean} (optional) Set to true to skip firing change
+     * events.  Default false
+     */
+    setMinValue : function (min, skipAnim, force, silent) {
+        var mins = this.minSlider;
+
+        this.activeSlider = mins;
+
+        // Use a one-time event callback to delay the updateValue call
+        // until after the slide operation is done
+        var self = this;
+        this._oneTimeCallback(mins,'slideEnd',function () {
+            self.updateValue(silent);
+            // Clean the slideEnd event on a timeout since this
+            // will be executed from inside the event's fire
+            setTimeout(function () { self._cleanEvent(mins,'slideEnd'); }, 0);
+        });
+
+        mins.setValue(min, skipAnim, force, silent);
+    },
+
+    /**
+     * Set the max thumb position to a new value.
+     * @method setMaxValue
+     * @param max {int} Pixel offset for max thumb
+     * @param skipAnim {boolean} (optional) Set to true to skip thumb animation.
+     * Default false
+     * @param force {boolean} (optional) ignore the locked setting and set
+     * value anyway. Default false
+     * @param silent {boolean} (optional) Set to true to skip firing change
+     * events.  Default false
+     */
+    setMaxValue : function (max, skipAnim, force, silent) {
+        var maxs = this.maxSlider;
+
+        this.activeSlider = maxs;
+
+        // Use a one-time event callback to delay the updateValue call
+        // until after the slide operation is done
+        var self = this;
+        this._oneTimeCallback(maxs,'slideEnd',function () {
+            self.updateValue(silent);
+            // Clean the slideEnd event on a timeout since this
+            // will be executed from inside the event's fire
+            setTimeout(function () { self._cleanEvent(maxs,'slideEnd'); }, 0);
+        });
+
+        maxs.setValue(max, skipAnim, force, silent);
+    },
+
+    /**
+     * Executed when one of the sliders is moved
+     * @method updateValue
+     * @param silent {boolean} (optional) Set to true to skip firing change
+     * events.  Default false
+     * @private
+     */
+    updateValue: function(silent) {
+        var min     = this.minSlider.getValue(),
+            max     = this.maxSlider.getValue(),
+            changed = false;
+
+        if (min != this.minVal || max != this.maxVal) {
+            changed = true;
+
+            var mint = this.minSlider.thumb;
+            var maxt = this.maxSlider.thumb;
+
+            var thumbInnerWidth = this.minSlider.thumbCenterPoint.x +
+                                  this.maxSlider.thumbCenterPoint.x;
+
+            // Establish barriers within the respective other thumb's edge, less
+            // the minRange.  Limit to the Slider's range in the case of
+            // negative minRanges.
+            var minConstraint = Math.max(max-thumbInnerWidth-this.minRange,0);
+            var maxConstraint = Math.min(-min-thumbInnerWidth-this.minRange,0);
+
+            if (this.isHoriz) {
+                minConstraint = Math.min(minConstraint,maxt.rightConstraint);
+
+                mint.setXConstraint(mint.leftConstraint,minConstraint, mint.tickSize);
+
+                maxt.setXConstraint(maxConstraint,maxt.rightConstraint, maxt.tickSize);
+            } else {
+                minConstraint = Math.min(minConstraint,maxt.bottomConstraint);
+                mint.setYConstraint(mint.leftConstraint,minConstraint, mint.tickSize);
+
+                maxt.setYConstraint(maxConstraint,maxt.bottomConstraint, maxt.tickSize);
+            }
+        }
+
+        this.minVal = min;
+        this.maxVal = max;
+
+        if (changed && !silent) {
+            this.fireEvent("change", this);
+        }
+    },
+
+    /**
+     * A background click will move the slider thumb nearest to the click.
+     * Override if you need different behavior.
+     * @method selectActiveSlider
+     * @param e {Event} the mousedown event
+     * @private
+     */
+    selectActiveSlider: function(e) {
+        var min = this.minSlider.getValue(),
+            max = this.maxSlider.getValue(),
+            d;
+
+        if (this.isHoriz) {
+            d = YAHOO.util.Event.getPageX(e) - this.minSlider.initPageX -
+                this.minSlider.thumbCenterPoint.x;
+        } else {
+            d = YAHOO.util.Event.getPageY(e) - this.minSlider.initPageY -
+                this.minSlider.thumbCenterPoint.y;
+        }
+                
+        // Below the minSlider thumb.  Move the minSlider thumb
+        if (d < min) {
+            this.activeSlider = this.minSlider;
+        // Above the maxSlider thumb.  Move the maxSlider thumb
+        } else if (d > max) {
+            this.activeSlider = this.maxSlider;
+        // Split the difference between thumbs
+        } else {
+            this.activeSlider = d*2 > max+min ? this.maxSlider : this.minSlider;
+        }
+    },
+
+    /**
+     * Overrides the onMouseDown for both slider, only moving the active slider
+     * @method handleMouseDown
+     * @private
+     */
+    _handleMouseDown: function(e) {
+        this.selectActiveSlider(e);
+        YAHOO.widget.Slider.prototype.onMouseDown.call(this.activeSlider, e);
+    },
+
+    /**
+     * Schedule an event callback that will execute once, then unsubscribe
+     * itself.
+     * @method _oneTimeCallback
+     * @param o {EventProvider} Object to attach the event to
+     * @param evt {string} Name of the event
+     * @param fn {Function} function to execute once
+     * @private
+     */
+    _oneTimeCallback : function (o,evt,fn) {
+        o.subscribe(evt,function () {
+            // Unsubscribe myself
+            o.unsubscribe(evt,arguments.callee);
+            // Pass the event handler arguments to the one time callback
+            fn.apply({},[].slice.apply(arguments));
+        });
+    },
+
+    /**
+     * Clean up the slideEnd event subscribers array, since each one-time
+     * callback will be replaced in the event's subscribers property with
+     * null.  This will cause memory bloat and loss of performance.
+     * @method _cleanEvent
+     * @param o {EventProvider} object housing the CustomEvent
+     * @param evt {string} name of the CustomEvent
+     * @private
+     */
+    _cleanEvent : function (o,evt) {
+        if (o.__yui_events && o.events[evt]) {
+            var ce, i, len;
+            for (i = o.__yui_events.length; i >= 0; --i) {
+                if (o.__yui_events[i].type === evt) {
+                    ce = o.__yui_events[i];
+                    break;
+                }
+            }
+            if (ce) {
+                var subs    = ce.subscribers,
+                    newSubs = [],
+                    j = 0;
+                for (i = 0, len = subs.length; i < len; ++i) {
+                    if (subs[i]) {
+                        newSubs[j++] = subs[i];
+                    }
+                }
+                ce.subscribers = newSubs;
+            }
+        }
+    }
+
+};
+
+YAHOO.augment(YAHOO.widget.DualSlider, YAHOO.util.EventProvider);
+
+
+/**
+ * Factory method for creating a horizontal dual-thumb slider
+ * @for YAHOO.widget.Slider
+ * @method YAHOO.widget.Slider.getHorizDualSlider
+ * @static
+ * @param {String} bg the id of the slider's background element
+ * @param {String} minthumb the id of the min thumb
+ * @param {String} maxthumb the id of the thumb thumb
+ * @param {int} range the number of pixels the thumbs can move within
+ * @param {int} iTickSize (optional) the element should move this many pixels
+ * at a time
+ * @param {Array}  initVals (optional) [min,max] Initial thumb placement
+ * @return {DualSlider} a horizontal dual-thumb slider control
+ */
+YAHOO.widget.Slider.getHorizDualSlider = 
+    function (bg, minthumb, maxthumb, range, iTickSize, initVals) {
+        var mint, maxt;
+        var YW = YAHOO.widget, Slider = YW.Slider, Thumb = YW.SliderThumb;
+
+        mint = new Thumb(minthumb, bg, 0, range, 0, 0, iTickSize);
+        maxt = new Thumb(maxthumb, bg, 0, range, 0, 0, iTickSize);
+
+        return new YW.DualSlider(new Slider(bg, bg, mint, "horiz"), new Slider(bg, bg, maxt, "horiz"), range, initVals);
+};
+
+/**
+ * Factory method for creating a vertical dual-thumb slider.
+ * @for YAHOO.widget.Slider
+ * @method YAHOO.widget.Slider.getVertDualSlider
+ * @static
+ * @param {String} bg the id of the slider's background element
+ * @param {String} minthumb the id of the min thumb
+ * @param {String} maxthumb the id of the thumb thumb
+ * @param {int} range the number of pixels the thumbs can move within
+ * @param {int} iTickSize (optional) the element should move this many pixels
+ * at a time
+ * @param {Array}  initVals (optional) [min,max] Initial thumb placement
+ * @return {DualSlider} a vertical dual-thumb slider control
+ */
+YAHOO.widget.Slider.getVertDualSlider = 
+    function (bg, minthumb, maxthumb, range, iTickSize, initVals) {
+        var mint, maxt;
+        var YW = YAHOO.widget, Slider = YW.Slider, Thumb = YW.SliderThumb;
+
+        mint = new Thumb(minthumb, bg, 0, 0, 0, range, iTickSize);
+        maxt = new Thumb(maxthumb, bg, 0, 0, 0, range, iTickSize);
+
+        return new YW.DualSlider(new Slider(bg, bg, mint, "vert"), new Slider(bg, bg, maxt, "vert"), range, initVals);
+};
+YAHOO.register("slider", YAHOO.widget.Slider, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/slider/slider-min.js
===================================================================
--- trunk/root/static/yui/slider/slider-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/slider/slider-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,9 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-YAHOO.widget.Slider=function(B,r,D,I){YAHOO.widget.Slider.ANIM_AVAIL=(!YAHOO.lang.isUndefined(YAHOO.util.Anim));if(B){this.init(B,r,true);this.initSlider(I);this.initThumb(D);}};YAHOO.widget.Slider.getHorizSlider=function(D,B,X,I,r){return new YAHOO.widget.Slider(D,D,new YAHOO.widget.SliderThumb(B,D,X,I,0,0,r),"horiz");};YAHOO.widget.Slider.getVertSlider=function(B,I,r,X,D){return new YAHOO.widget.Slider(B,B,new YAHOO.widget.SliderThumb(I,B,0,0,r,X,D),"vert");};YAHOO.widget.Slider.getSliderRegion=function(B,I,g,X,r,Y,D){return new YAHOO.widget.Slider(B,B,new YAHOO.widget.SliderThumb(I,B,g,X,r,Y,D),"region");};YAHOO.widget.Slider.ANIM_AVAIL=false;YAHOO.extend(YAHOO.widget.Slider,YAHOO.util.DragDrop,{initSlider:function(r){this.type=r;this.createEvent("change",this);this.createEvent("slideStart",this);this.createEvent("slideEnd",this);this.isTarget=false;this.animate=YAHOO.widget.Slider.ANIM_AVAIL;this.backgroundEnabled=true;this.tickPause=40;this.enableKeys=true;this.keyIncr!
 ement=20;this.moveComplete=true;this.animationDuration=0.2;this.SOURCE_UI_EVENT=1;this.SOURCE_SET_VALUE=2;this.valueChangeSource=0;this._silent=false;this.lastOffset=[0,0];},initThumb:function(D){var r=this;this.thumb=D;D.cacheBetweenDrags=true;if(D._isHoriz&&D.xTicks&&D.xTicks.length){this.tickPause=Math.round(360/D.xTicks.length);}else{if(D.yTicks&&D.yTicks.length){this.tickPause=Math.round(360/D.yTicks.length);}}D.onAvailable=function(){return r.setStartSliderState();};D.onMouseDown=function(){return r.focus();};D.startDrag=function(){r._slideStart();};D.onDrag=function(){r.fireEvents(true);};D.onMouseUp=function(){r.thumbMouseUp();};},onAvailable:function(){var r=YAHOO.util.Event;r.on(this.id,"keydown",this.handleKeyDown,this,true);r.on(this.id,"keypress",this.handleKeyPress,this,true);},handleKeyPress:function(B){if(this.enableKeys){var r=YAHOO.util.Event;var D=r.getCharCode(B);switch(D){case 37:case 38:case 39:case 40:case 36:case 35:r.preventDefault(B);break;default:!
 }}},handleKeyDown:function(X){if(this.enableKeys){var Y=YAHOO.!
 util.Eve
nt;var B=Y.getCharCode(X),n=this.thumb;var D=this.getXValue(),g=this.getYValue();var R=false;var I=true;switch(B){case 37:D-=this.keyIncrement;break;case 38:g-=this.keyIncrement;break;case 39:D+=this.keyIncrement;break;case 40:g+=this.keyIncrement;break;case 36:D=n.leftConstraint;g=n.topConstraint;break;case 35:D=n.rightConstraint;g=n.bottomConstraint;break;default:I=false;}if(I){if(n._isRegion){this.setRegionValue(D,g,true);}else{var r=(n._isHoriz)?D:g;this.setValue(r,true);}Y.stopEvent(X);}}},setStartSliderState:function(){this.setThumbCenterPoint();this.baselinePos=YAHOO.util.Dom.getXY(this.getEl());this.thumb.startOffset=this.thumb.getOffsetFromParent(this.baselinePos);if(this.thumb._isRegion){if(this.deferredSetRegionValue){this.setRegionValue.apply(this,this.deferredSetRegionValue,true);this.deferredSetRegionValue=null;}else{this.setRegionValue(0,0,true,true,true);}}else{if(this.deferredSetValue){this.setValue.apply(this,this.deferredSetValue,true);this.deferredSetValu!
 e=null;}else{this.setValue(0,true,true,true);}}},setThumbCenterPoint:function(){var r=this.thumb.getEl();if(r){this.thumbCenterPoint={x:parseInt(r.offsetWidth/2,10),y:parseInt(r.offsetHeight/2,10)};}},lock:function(){this.thumb.lock();this.locked=true;},unlock:function(){this.thumb.unlock();this.locked=false;},thumbMouseUp:function(){if(!this.isLocked()&&!this.moveComplete){this.endMove();}},onMouseUp:function(){if(!this.isLocked()&&!this.moveComplete){this.endMove();}},getThumb:function(){return this.thumb;},focus:function(){this.valueChangeSource=this.SOURCE_UI_EVENT;var r=this.getEl();if(r.focus){try{r.focus();}catch(D){}}this.verifyOffset();if(this.isLocked()){return false;}else{this._slideStart();return true;}},onChange:function(r,D){},onSlideStart:function(){},onSlideEnd:function(){},getValue:function(){return this.thumb.getValue();},getXValue:function(){return this.thumb.getXValue();},getYValue:function(){return this.thumb.getYValue();},handleThumbChange:function(){}!
 ,setValue:function(Y,B,I,r){this._silent=r;this.valueChangeSou!
 rce=this
.SOURCE_SET_VALUE;if(!this.thumb.available){this.deferredSetValue=arguments;return false;}if(this.isLocked()&&!I){return false;}if(isNaN(Y)){return false;}var D=this.thumb;D.lastOffset=[Y,Y];var g,X;this.verifyOffset(true);if(D._isRegion){return false;}else{if(D._isHoriz){this._slideStart();g=D.initPageX+Y+this.thumbCenterPoint.x;this.moveThumb(g,D.initPageY,B);}else{this._slideStart();X=D.initPageY+Y+this.thumbCenterPoint.y;this.moveThumb(D.initPageX,X,B);}}return true;},setRegionValue:function(R,r,I,X,D){this._silent=D;this.valueChangeSource=this.SOURCE_SET_VALUE;if(!this.thumb.available){this.deferredSetRegionValue=arguments;return false;}if(this.isLocked()&&!X){return false;}if(isNaN(R)){return false;}var B=this.thumb;B.lastOffset=[R,r];this.verifyOffset(true);if(B._isRegion){this._slideStart();var Y=B.initPageX+R+this.thumbCenterPoint.x;var g=B.initPageY+r+this.thumbCenterPoint.y;this.moveThumb(Y,g,I);return true;}return false;},verifyOffset:function(D){var r=YAHOO.util!
 .Dom.getXY(this.getEl());if(r){if(r[0]!=this.baselinePos[0]||r[1]!=this.baselinePos[1]){this.thumb.resetConstraints();this.baselinePos=r;return false;}}return true;},moveThumb:function(Y,g,X,I){var R=this.thumb;var n=this;if(!R.available){return ;}R.setDelta(this.thumbCenterPoint.x,this.thumbCenterPoint.y);var D=R.getTargetCoord(Y,g);var B=[D.x,D.y];this._slideStart();if(this.animate&&YAHOO.widget.Slider.ANIM_AVAIL&&R._graduated&&!X){this.lock();this.curCoord=YAHOO.util.Dom.getXY(this.thumb.getEl());setTimeout(function(){n.moveOneTick(B);},this.tickPause);}else{if(this.animate&&YAHOO.widget.Slider.ANIM_AVAIL&&!X){this.lock();var r=new YAHOO.util.Motion(R.id,{points:{to:B}},this.animationDuration,YAHOO.util.Easing.easeOut);r.onComplete.subscribe(function(){n.endMove();});r.animate();}else{R.setDragElPos(Y,g);if(!I){this.endMove();}}}},_slideStart:function(){if(!this._sliding){if(!this._silent){this.onSlideStart();this.fireEvent("slideStart");}this._sliding=true;}},_slideEnd:!
 function(){if(this._sliding&&this.moveComplete){if(!this._sile!
 nt){this
.onSlideEnd();this.fireEvent("slideEnd");}this._sliding=false;this._silent=false;this.moveComplete=false;}},moveOneTick:function(D){var X=this.thumb,I;var g=null;if(X._isRegion){g=this._getNextX(this.curCoord,D);var r=(g)?g[0]:this.curCoord[0];g=this._getNextY([r,this.curCoord[1]],D);}else{if(X._isHoriz){g=this._getNextX(this.curCoord,D);}else{g=this._getNextY(this.curCoord,D);}}if(g){this.curCoord=g;this.thumb.alignElWithMouse(X.getEl(),g[0],g[1]);if(!(g[0]==D[0]&&g[1]==D[1])){var B=this;setTimeout(function(){B.moveOneTick(D);},this.tickPause);}else{this.endMove();}}else{this.endMove();}},_getNextX:function(r,D){var I=this.thumb;var g;var B=[];var X=null;if(r[0]>D[0]){g=I.tickSize-this.thumbCenterPoint.x;B=I.getTargetCoord(r[0]-g,r[1]);X=[B.x,B.y];}else{if(r[0]<D[0]){g=I.tickSize+this.thumbCenterPoint.x;B=I.getTargetCoord(r[0]+g,r[1]);X=[B.x,B.y];}else{}}return X;},_getNextY:function(r,D){var I=this.thumb;var g;var B=[];var X=null;if(r[1]>D[1]){g=I.tickSize-this.thumbCenter!
 Point.y;B=I.getTargetCoord(r[0],r[1]-g);X=[B.x,B.y];}else{if(r[1]<D[1]){g=I.tickSize+this.thumbCenterPoint.y;B=I.getTargetCoord(r[0],r[1]+g);X=[B.x,B.y];}else{}}return X;},b4MouseDown:function(r){this.thumb.autoOffset();this.thumb.resetConstraints();},onMouseDown:function(D){if(!this.isLocked()&&this.backgroundEnabled){var r=YAHOO.util.Event.getPageX(D);var B=YAHOO.util.Event.getPageY(D);this.focus();this.moveThumb(r,B);}},onDrag:function(D){if(!this.isLocked()){var r=YAHOO.util.Event.getPageX(D);var B=YAHOO.util.Event.getPageY(D);this.moveThumb(r,B,true,true);}},endMove:function(){this.unlock();this.moveComplete=true;this.fireEvents();},fireEvents:function(B){var D=this.thumb;if(!B){D.cachePosition();}if(!this.isLocked()){if(D._isRegion){var X=D.getXValue();var I=D.getYValue();if(X!=this.previousX||I!=this.previousY){if(!this._silent){this.onChange(X,I);this.fireEvent("change",{x:X,y:I});}}this.previousX=X;this.previousY=I;}else{var r=D.getValue();if(r!=this.previousVal){i!
 f(!this._silent){this.onChange(r);this.fireEvent("change",r);}!
 }this.pr
eviousVal=r;}this._slideEnd();}},toString:function(){return ("Slider ("+this.type+") "+this.id);}});YAHOO.augment(YAHOO.widget.Slider,YAHOO.util.EventProvider);YAHOO.widget.SliderThumb=function(Y,D,X,I,r,g,B){if(Y){YAHOO.widget.SliderThumb.superclass.constructor.call(this,Y,D);this.parentElId=D;}this.isTarget=false;this.tickSize=B;this.maintainOffset=true;this.initSlider(X,I,r,g,B);this.scroll=false;};YAHOO.extend(YAHOO.widget.SliderThumb,YAHOO.util.DD,{startOffset:null,_isHoriz:false,_prevVal:0,_graduated:false,getOffsetFromParent0:function(B){var r=YAHOO.util.Dom.getXY(this.getEl());var D=B||YAHOO.util.Dom.getXY(this.parentElId);return [(r[0]-D[0]),(r[1]-D[1])];},getOffsetFromParent:function(R){var r=this.getEl(),X;if(!this.deltaOffset){var n=YAHOO.util.Dom.getXY(r);var g=R||YAHOO.util.Dom.getXY(this.parentElId);X=[(n[0]-g[0]),(n[1]-g[1])];var D=parseInt(YAHOO.util.Dom.getStyle(r,"left"),10);var e=parseInt(YAHOO.util.Dom.getStyle(r,"top"),10);var I=D-X[0];var B=e-X[1];if(i!
 sNaN(I)||isNaN(B)){}else{this.deltaOffset=[I,B];}}else{var s=parseInt(YAHOO.util.Dom.getStyle(r,"left"),10);var Y=parseInt(YAHOO.util.Dom.getStyle(r,"top"),10);X=[s+this.deltaOffset[0],Y+this.deltaOffset[1]];}return X;},initSlider:function(I,B,r,X,D){this.initLeft=I;this.initRight=B;this.initUp=r;this.initDown=X;this.setXConstraint(I,B,D);this.setYConstraint(r,X,D);if(D&&D>1){this._graduated=true;}this._isHoriz=(I||B);this._isVert=(r||X);this._isRegion=(this._isHoriz&&this._isVert);},clearTicks:function(){YAHOO.widget.SliderThumb.superclass.clearTicks.call(this);this.tickSize=0;this._graduated=false;},getValue:function(){return (this._isHoriz)?this.getXValue():this.getYValue();},getXValue:function(){if(!this.available){return 0;}var r=this.getOffsetFromParent();if(YAHOO.lang.isNumber(r[0])){this.lastOffset=r;return (r[0]-this.startOffset[0]);}else{return (this.lastOffset[0]-this.startOffset[0]);}},getYValue:function(){if(!this.available){return 0;}var r=this.getOffsetFromPa!
 rent();if(YAHOO.lang.isNumber(r[1])){this.lastOffset=r;return !
 (r[1]-th
is.startOffset[1]);}else{return (this.lastOffset[1]-this.startOffset[1]);}},toString:function(){return "SliderThumb "+this.id;},onChange:function(r,D){}});YAHOO.register("slider",YAHOO.widget.Slider,{version:"2.4.1",build:"742"});
\ No newline at end of file
+YAHOO.widget.Slider=function(C,A,B,D){YAHOO.widget.Slider.ANIM_AVAIL=(!YAHOO.lang.isUndefined(YAHOO.util.Anim));if(C){this.init(C,A,true);this.initSlider(D);this.initThumb(B);}};YAHOO.widget.Slider.getHorizSlider=function(B,C,E,D,A){return new YAHOO.widget.Slider(B,B,new YAHOO.widget.SliderThumb(C,B,E,D,0,0,A),"horiz");};YAHOO.widget.Slider.getVertSlider=function(C,D,A,E,B){return new YAHOO.widget.Slider(C,C,new YAHOO.widget.SliderThumb(D,C,0,0,A,E,B),"vert");};YAHOO.widget.Slider.getSliderRegion=function(C,D,F,E,A,G,B){return new YAHOO.widget.Slider(C,C,new YAHOO.widget.SliderThumb(D,C,F,E,A,G,B),"region");};YAHOO.widget.Slider.ANIM_AVAIL=false;YAHOO.extend(YAHOO.widget.Slider,YAHOO.util.DragDrop,{dragOnly:true,initSlider:function(A){this.type=A;this.createEvent("change",this);this.createEvent("slideStart",this);this.createEvent("slideEnd",this);this.isTarget=false;this.animate=YAHOO.widget.Slider.ANIM_AVAIL;this.backgroundEnabled=true;this.tickPause=40;this.enableKeys=tru!
 e;this.keyIncrement=20;this.moveComplete=true;this.animationDuration=0.2;this.SOURCE_UI_EVENT=1;this.SOURCE_SET_VALUE=2;this.valueChangeSource=0;this._silent=false;this.lastOffset=[0,0];},initThumb:function(B){var A=this;this.thumb=B;B.cacheBetweenDrags=true;if(B._isHoriz&&B.xTicks&&B.xTicks.length){this.tickPause=Math.round(360/B.xTicks.length);}else{if(B.yTicks&&B.yTicks.length){this.tickPause=Math.round(360/B.yTicks.length);}}B.onAvailable=function(){return A.setStartSliderState();};B.onMouseDown=function(){return A.focus();};B.startDrag=function(){A._slideStart();};B.onDrag=function(){A.fireEvents(true);};B.onMouseUp=function(){A.thumbMouseUp();};},onAvailable:function(){var A=YAHOO.util.Event;A.on(this.id,"keydown",this.handleKeyDown,this,true);A.on(this.id,"keypress",this.handleKeyPress,this,true);},handleKeyPress:function(C){if(this.enableKeys){var A=YAHOO.util.Event;var B=A.getCharCode(C);switch(B){case 37:case 38:case 39:case 40:case 36:case 35:A.preventDefault(C);!
 break;default:}}},handleKeyDown:function(E){if(this.enableKeys!
 ){var G=
YAHOO.util.Event;var C=G.getCharCode(E),I=this.thumb;var B=this.getXValue(),F=this.getYValue();var H=false;var D=true;switch(C){case 37:B-=this.keyIncrement;break;case 38:F-=this.keyIncrement;break;case 39:B+=this.keyIncrement;break;case 40:F+=this.keyIncrement;break;case 36:B=I.leftConstraint;F=I.topConstraint;break;case 35:B=I.rightConstraint;F=I.bottomConstraint;break;default:D=false;}if(D){if(I._isRegion){this.setRegionValue(B,F,true);}else{var A=(I._isHoriz)?B:F;this.setValue(A,true);}G.stopEvent(E);}}},setStartSliderState:function(){this.setThumbCenterPoint();this.baselinePos=YAHOO.util.Dom.getXY(this.getEl());this.thumb.startOffset=this.thumb.getOffsetFromParent(this.baselinePos);if(this.thumb._isRegion){if(this.deferredSetRegionValue){this.setRegionValue.apply(this,this.deferredSetRegionValue,true);this.deferredSetRegionValue=null;}else{this.setRegionValue(0,0,true,true,true);}}else{if(this.deferredSetValue){this.setValue.apply(this,this.deferredSetValue,true);this.d!
 eferredSetValue=null;}else{this.setValue(0,true,true,true);}}},setThumbCenterPoint:function(){var A=this.thumb.getEl();if(A){this.thumbCenterPoint={x:parseInt(A.offsetWidth/2,10),y:parseInt(A.offsetHeight/2,10)};}},lock:function(){this.thumb.lock();this.locked=true;},unlock:function(){this.thumb.unlock();this.locked=false;},thumbMouseUp:function(){if(!this.isLocked()&&!this.moveComplete){this.endMove();}},onMouseUp:function(){if(!this.isLocked()&&!this.moveComplete){this.endMove();}},getThumb:function(){return this.thumb;},focus:function(){this.valueChangeSource=this.SOURCE_UI_EVENT;var A=this.getEl();if(A.focus){try{A.focus();}catch(B){}}this.verifyOffset();if(this.isLocked()){return false;}else{this._slideStart();return true;}},onChange:function(A,B){},onSlideStart:function(){},onSlideEnd:function(){},getValue:function(){return this.thumb.getValue();},getXValue:function(){return this.thumb.getXValue();},getYValue:function(){return this.thumb.getYValue();},handleThumbChang!
 e:function(){},setValue:function(G,C,D,A){this._silent=A;this.!
 valueCha
ngeSource=this.SOURCE_SET_VALUE;if(!this.thumb.available){this.deferredSetValue=arguments;return false;}if(this.isLocked()&&!D){return false;}if(isNaN(G)){return false;}var B=this.thumb;B.lastOffset=[G,G];var F,E;this.verifyOffset(true);if(B._isRegion){return false;}else{if(B._isHoriz){this._slideStart();F=B.initPageX+G+this.thumbCenterPoint.x;this.moveThumb(F,B.initPageY,C);}else{this._slideStart();E=B.initPageY+G+this.thumbCenterPoint.y;this.moveThumb(B.initPageX,E,C);}}return true;},setRegionValue:function(H,A,D,E,B){this._silent=B;this.valueChangeSource=this.SOURCE_SET_VALUE;if(!this.thumb.available){this.deferredSetRegionValue=arguments;return false;}if(this.isLocked()&&!E){return false;}if(isNaN(H)){return false;}var C=this.thumb;C.lastOffset=[H,A];this.verifyOffset(true);if(C._isRegion){this._slideStart();var G=C.initPageX+H+this.thumbCenterPoint.x;var F=C.initPageY+A+this.thumbCenterPoint.y;this.moveThumb(G,F,D);return true;}return false;},verifyOffset:function(B){va!
 r A=YAHOO.util.Dom.getXY(this.getEl());if(A){if(A[0]!=this.baselinePos[0]||A[1]!=this.baselinePos[1]){this.thumb.resetConstraints();this.baselinePos=A;return false;}}return true;},moveThumb:function(G,F,E,D){var H=this.thumb;var I=this;if(!H.available){return ;}H.setDelta(this.thumbCenterPoint.x,this.thumbCenterPoint.y);var B=H.getTargetCoord(G,F);var C=[B.x,B.y];this._slideStart();if(this.animate&&YAHOO.widget.Slider.ANIM_AVAIL&&H._graduated&&!E){this.lock();this.curCoord=YAHOO.util.Dom.getXY(this.thumb.getEl());setTimeout(function(){I.moveOneTick(C);},this.tickPause);}else{if(this.animate&&YAHOO.widget.Slider.ANIM_AVAIL&&!E){this.lock();var A=new YAHOO.util.Motion(H.id,{points:{to:C}},this.animationDuration,YAHOO.util.Easing.easeOut);A.onComplete.subscribe(function(){I.endMove();});A.animate();}else{H.setDragElPos(G,F);if(!D){this.endMove();}}}},_slideStart:function(){if(!this._sliding){if(!this._silent){this.onSlideStart();
+this.fireEvent("slideStart");}this._sliding=true;}},_slideEnd:function(){if(this._sliding&&this.moveComplete){if(!this._silent){this.onSlideEnd();this.fireEvent("slideEnd");}this._sliding=false;this._silent=false;this.moveComplete=false;}},moveOneTick:function(B){var E=this.thumb,D;var F=null;if(E._isRegion){F=this._getNextX(this.curCoord,B);var A=(F)?F[0]:this.curCoord[0];F=this._getNextY([A,this.curCoord[1]],B);}else{if(E._isHoriz){F=this._getNextX(this.curCoord,B);}else{F=this._getNextY(this.curCoord,B);}}if(F){this.curCoord=F;this.thumb.alignElWithMouse(E.getEl(),F[0],F[1]);if(!(F[0]==B[0]&&F[1]==B[1])){var C=this;setTimeout(function(){C.moveOneTick(B);},this.tickPause);}else{this.endMove();}}else{this.endMove();}},_getNextX:function(A,B){var D=this.thumb;var F;var C=[];var E=null;if(A[0]>B[0]){F=D.tickSize-this.thumbCenterPoint.x;C=D.getTargetCoord(A[0]-F,A[1]);E=[C.x,C.y];}else{if(A[0]<B[0]){F=D.tickSize+this.thumbCenterPoint.x;C=D.getTargetCoord(A[0]+F,A[1]);E=[C.x,C!
 .y];}else{}}return E;},_getNextY:function(A,B){var D=this.thumb;var F;var C=[];var E=null;if(A[1]>B[1]){F=D.tickSize-this.thumbCenterPoint.y;C=D.getTargetCoord(A[0],A[1]-F);E=[C.x,C.y];}else{if(A[1]<B[1]){F=D.tickSize+this.thumbCenterPoint.y;C=D.getTargetCoord(A[0],A[1]+F);E=[C.x,C.y];}else{}}return E;},b4MouseDown:function(A){this.thumb.autoOffset();this.thumb.resetConstraints();},onMouseDown:function(B){if(!this.isLocked()&&this.backgroundEnabled){var A=YAHOO.util.Event.getPageX(B);var C=YAHOO.util.Event.getPageY(B);this.focus();this.moveThumb(A,C);}},onDrag:function(B){if(!this.isLocked()){var A=YAHOO.util.Event.getPageX(B);var C=YAHOO.util.Event.getPageY(B);this.moveThumb(A,C,true,true);this.fireEvents();}},endMove:function(){this.unlock();this.moveComplete=true;this.fireEvents();},fireEvents:function(C){var B=this.thumb;if(!C){B.cachePosition();}if(!this.isLocked()){if(B._isRegion){var E=B.getXValue();var D=B.getYValue();if(E!=this.previousX||D!=this.previousY){if(!thi!
 s._silent){this.onChange(E,D);this.fireEvent("change",{x:E,y:D!
 });}}thi
s.previousX=E;this.previousY=D;}else{var A=B.getValue();if(A!=this.previousVal){if(!this._silent){this.onChange(A);this.fireEvent("change",A);}}this.previousVal=A;}this._slideEnd();}},toString:function(){return("Slider ("+this.type+") "+this.id);}});YAHOO.augment(YAHOO.widget.Slider,YAHOO.util.EventProvider);YAHOO.widget.SliderThumb=function(G,B,E,D,A,F,C){if(G){YAHOO.widget.SliderThumb.superclass.constructor.call(this,G,B);this.parentElId=B;}this.isTarget=false;this.tickSize=C;this.maintainOffset=true;this.initSlider(E,D,A,F,C);this.scroll=false;};YAHOO.extend(YAHOO.widget.SliderThumb,YAHOO.util.DD,{startOffset:null,dragOnly:true,_isHoriz:false,_prevVal:0,_graduated:false,getOffsetFromParent0:function(C){var A=YAHOO.util.Dom.getXY(this.getEl());var B=C||YAHOO.util.Dom.getXY(this.parentElId);return[(A[0]-B[0]),(A[1]-B[1])];},getOffsetFromParent:function(H){var A=this.getEl(),E;if(!this.deltaOffset){var I=YAHOO.util.Dom.getXY(A);var F=H||YAHOO.util.Dom.getXY(this.parentElId);!
 E=[(I[0]-F[0]),(I[1]-F[1])];var B=parseInt(YAHOO.util.Dom.getStyle(A,"left"),10);var K=parseInt(YAHOO.util.Dom.getStyle(A,"top"),10);var D=B-E[0];var C=K-E[1];if(isNaN(D)||isNaN(C)){}else{this.deltaOffset=[D,C];}}else{var J=parseInt(YAHOO.util.Dom.getStyle(A,"left"),10);var G=parseInt(YAHOO.util.Dom.getStyle(A,"top"),10);E=[J+this.deltaOffset[0],G+this.deltaOffset[1]];}return E;},initSlider:function(D,C,A,E,B){this.initLeft=D;this.initRight=C;this.initUp=A;this.initDown=E;this.setXConstraint(D,C,B);this.setYConstraint(A,E,B);if(B&&B>1){this._graduated=true;}this._isHoriz=(D||C);this._isVert=(A||E);this._isRegion=(this._isHoriz&&this._isVert);},clearTicks:function(){YAHOO.widget.SliderThumb.superclass.clearTicks.call(this);this.tickSize=0;this._graduated=false;},getValue:function(){return(this._isHoriz)?this.getXValue():this.getYValue();},getXValue:function(){if(!this.available){return 0;}var A=this.getOffsetFromParent();if(YAHOO.lang.isNumber(A[0])){this.lastOffset=A;return!
 (A[0]-this.startOffset[0]);}else{return(this.lastOffset[0]-thi!
 s.startO
ffset[0]);}},getYValue:function(){if(!this.available){return 0;}var A=this.getOffsetFromParent();if(YAHOO.lang.isNumber(A[1])){this.lastOffset=A;return(A[1]-this.startOffset[1]);}else{return(this.lastOffset[1]-this.startOffset[1]);}},toString:function(){return"SliderThumb "+this.id;},onChange:function(A,B){}});YAHOO.widget.DualSlider=function(E,B,D,A){var C=this,G=YAHOO.lang;this.minSlider=E;this.maxSlider=B;this.activeSlider=E;this.isHoriz=E.thumb._isHoriz;A=YAHOO.lang.isArray(A)?A:[0,D];A[0]=Math.min(Math.max(parseInt(A[0],10)|0,0),D);A[1]=Math.max(Math.min(parseInt(A[1],10)|0,D),0);if(A[0]>A[1]){A.splice(0,2,A[1],A[0]);}var F={min:false,max:false};this.minSlider.thumb.onAvailable=function(){E.setStartSliderState();F.min=true;if(F.max){E.setValue(A[0],true,true,true);B.setValue(A[1],true,true,true);C.updateValue(true);C.fireEvent("ready",C);}};this.maxSlider.thumb.onAvailable=function(){B.setStartSliderState();F.max=true;if(F.min){E.setValue(A[0],true,true,true);B.setValue!
 (A[1],true,true,true);C.updateValue(true);C.fireEvent("ready",C);}};E.onMouseDown=function(H){C._handleMouseDown(H);};B.onMouseDown=function(H){YAHOO.util.Event.stopEvent(H);};E.onDrag=B.onDrag=function(H){C._handleDrag(H);};E.subscribe("change",this._handleMinChange,E,this);E.subscribe("slideStart",this._handleSlideStart,E,this);E.subscribe("slideEnd",this._handleSlideEnd,E,this);B.subscribe("change",this._handleMaxChange,B,this);B.subscribe("slideStart",this._handleSlideStart,B,this);B.subscribe("slideEnd",this._handleSlideEnd,B,this);this.createEvent("ready",this);this.createEvent("change",this);this.createEvent("slideStart",this);this.createEvent("slideEnd",this);};YAHOO.widget.DualSlider.prototype={minVal:-1,maxVal:-1,minRange:0,_handleSlideStart:function(B,A){this.fireEvent("slideStart",A);},_handleSlideEnd:function(B,A){this.fireEvent("slideEnd",A);},_handleDrag:function(A){YAHOO.widget.Slider.prototype.onDrag.call(this.activeSlider,A);
+},_handleMinChange:function(){this.activeSlider=this.minSlider;this.updateValue();},_handleMaxChange:function(){this.activeSlider=this.maxSlider;this.updateValue();},setValues:function(E,H,F,B,G){var C=this.minSlider,J=this.maxSlider,A=C.thumb,I=J.thumb,K=this,D={min:false,max:false};if(A._isHoriz){A.setXConstraint(A.leftConstraint,I.rightConstraint,A.tickSize);I.setXConstraint(A.leftConstraint,I.rightConstraint,I.tickSize);}else{A.setYConstraint(A.topConstraint,I.bottomConstraint,A.tickSize);I.setYConstraint(A.topConstraint,I.bottomConstraint,I.tickSize);}this._oneTimeCallback(C,"slideEnd",function(){D.min=true;if(D.max){K.updateValue(G);setTimeout(function(){K._cleanEvent(C,"slideEnd");K._cleanEvent(J,"slideEnd");},0);}});this._oneTimeCallback(J,"slideEnd",function(){D.max=true;if(D.min){K.updateValue(G);setTimeout(function(){K._cleanEvent(C,"slideEnd");K._cleanEvent(J,"slideEnd");},0);}});C.setValue(E,F,B,G);J.setValue(H,F,B,G);},setMinValue:function(C,E,F,B){var D=this.!
 minSlider;this.activeSlider=D;var A=this;this._oneTimeCallback(D,"slideEnd",function(){A.updateValue(B);setTimeout(function(){A._cleanEvent(D,"slideEnd");},0);});D.setValue(C,E,F,B);},setMaxValue:function(A,E,F,C){var D=this.maxSlider;this.activeSlider=D;var B=this;this._oneTimeCallback(D,"slideEnd",function(){B.updateValue(C);setTimeout(function(){B._cleanEvent(D,"slideEnd");},0);});D.setValue(A,E,F,C);},updateValue:function(F){var B=this.minSlider.getValue(),G=this.maxSlider.getValue(),C=false;if(B!=this.minVal||G!=this.maxVal){C=true;var A=this.minSlider.thumb;var I=this.maxSlider.thumb;var D=this.minSlider.thumbCenterPoint.x+this.maxSlider.thumbCenterPoint.x;var E=Math.max(G-D-this.minRange,0);var H=Math.min(-B-D-this.minRange,0);if(this.isHoriz){E=Math.min(E,I.rightConstraint);A.setXConstraint(A.leftConstraint,E,A.tickSize);I.setXConstraint(H,I.rightConstraint,I.tickSize);}else{E=Math.min(E,I.bottomConstraint);A.setYConstraint(A.leftConstraint,E,A.tickSize);I.setYConst!
 raint(H,I.bottomConstraint,I.tickSize);}}this.minVal=B;this.ma!
 xVal=G;i
f(C&&!F){this.fireEvent("change",this);}},selectActiveSlider:function(C){var B=this.minSlider.getValue(),A=this.maxSlider.getValue(),D;if(this.isHoriz){D=YAHOO.util.Event.getPageX(C)-this.minSlider.initPageX-this.minSlider.thumbCenterPoint.x;}else{D=YAHOO.util.Event.getPageY(C)-this.minSlider.initPageY-this.minSlider.thumbCenterPoint.y;}if(D<B){this.activeSlider=this.minSlider;}else{if(D>A){this.activeSlider=this.maxSlider;}else{this.activeSlider=D*2>A+B?this.maxSlider:this.minSlider;}}},_handleMouseDown:function(A){this.selectActiveSlider(A);YAHOO.widget.Slider.prototype.onMouseDown.call(this.activeSlider,A);},_oneTimeCallback:function(C,A,B){C.subscribe(A,function(){C.unsubscribe(A,arguments.callee);B.apply({},[].slice.apply(arguments));});},_cleanEvent:function(H,B){if(H.__yui_events&&H.events[B]){var G,F,A;for(F=H.__yui_events.length;F>=0;--F){if(H.__yui_events[F].type===B){G=H.__yui_events[F];break;}}if(G){var E=G.subscribers,C=[],D=0;for(F=0,A=E.length;F<A;++F){if(E[F]!
 ){C[D++]=E[F];}}G.subscribers=C;}}}};YAHOO.augment(YAHOO.widget.DualSlider,YAHOO.util.EventProvider);YAHOO.widget.Slider.getHorizDualSlider=function(F,C,K,G,H,B){var A,J;var D=YAHOO.widget,E=D.Slider,I=D.SliderThumb;A=new I(C,F,0,G,0,0,H);J=new I(K,F,0,G,0,0,H);return new D.DualSlider(new E(F,F,A,"horiz"),new E(F,F,J,"horiz"),G,B);};YAHOO.widget.Slider.getVertDualSlider=function(F,C,K,G,H,B){var A,J;var D=YAHOO.widget,E=D.Slider,I=D.SliderThumb;A=new I(C,F,0,0,0,G,H);J=new I(K,F,0,0,0,G,H);return new D.DualSlider(new E(F,F,A,"vert"),new E(F,F,J,"vert"),G,B);};YAHOO.register("slider",YAHOO.widget.Slider,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/slider/slider.js
===================================================================
--- trunk/root/static/yui/slider/slider.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/slider/slider.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The Slider component is a UI control that enables the user to adjust 
@@ -118,6 +118,14 @@
 YAHOO.extend(YAHOO.widget.Slider, YAHOO.util.DragDrop, {
 
     /**
+     * Override the default setting of dragOnly to true.
+     * @property dragOnly
+     * @type boolean
+     * @default true
+     */
+    dragOnly : true,
+
+    /**
      * Initializes the slider.  Executed in the constructor
      * @method initSlider
      * @param {string} sType the type of slider (horiz, vert, region)
@@ -196,7 +204,7 @@
 
         /**
          * Specifies the number of pixels the arrow keys will move the slider.
-         * Default is 25.
+         * Default is 20.
          * @property keyIncrement
          * @type int
          */
@@ -1004,6 +1012,7 @@
             var x = YAHOO.util.Event.getPageX(e);
             var y = YAHOO.util.Event.getPageY(e);
             this.moveThumb(x, y, true, true);
+            this.fireEvents();
         }
     },
 
@@ -1163,6 +1172,14 @@
     startOffset: null,
 
     /**
+     * Override the default setting of dragOnly to true.
+     * @property dragOnly
+     * @type boolean
+     * @default true
+     */
+    dragOnly : true,
+
+    /**
      * Flag used to figure out if this is a horizontal or vertical slider
      * @property _isHoriz
      * @type boolean
@@ -1347,4 +1364,535 @@
 
 });
 
-YAHOO.register("slider", YAHOO.widget.Slider, {version: "2.4.1", build: "742"});
+/**
+ * A slider with two thumbs, one that represents the min value and 
+ * the other the max.  Actually a composition of two sliders, both with
+ * the same background.  The constraints for each slider are adjusted
+ * dynamically so that the min value of the max slider is equal or greater
+ * to the current value of the min slider, and the max value of the min
+ * slider is the current value of the max slider.
+ * Constructor assumes both thumbs are positioned absolutely at the 0 mark on
+ * the background.
+ *
+ * @namespace YAHOO.widget
+ * @class DualSlider
+ * @uses YAHOO.util.EventProvider
+ * @constructor
+ * @param {Slider} minSlider The Slider instance used for the min value thumb
+ * @param {Slider} maxSlider The Slider instance used for the max value thumb
+ * @param {int}    range The number of pixels the thumbs may move within
+ * @param {Array}  initVals (optional) [min,max] Initial thumb placement
+ */
+YAHOO.widget.DualSlider = function(minSlider, maxSlider, range, initVals) {
+
+    var self = this,
+        lang = YAHOO.lang;
+
+    /**
+     * A slider instance that keeps track of the lower value of the range.
+     * <strong>read only</strong>
+     * @property minSlider
+     * @type Slider
+     */
+    this.minSlider = minSlider;
+
+    /**
+     * A slider instance that keeps track of the upper value of the range.
+     * <strong>read only</strong>
+     * @property maxSlider
+     * @type Slider
+     */
+    this.maxSlider = maxSlider;
+
+    /**
+     * The currently active slider (min or max). <strong>read only</strong>
+     * @property activeSlider
+     * @type Slider
+     */
+    this.activeSlider = minSlider;
+
+    /**
+     * Is the DualSlider oriented horizontally or vertically?
+     * <strong>read only</strong>
+     * @property isHoriz
+     * @type boolean
+     */
+    this.isHoriz = minSlider.thumb._isHoriz;
+
+    // Validate initial values
+    initVals = YAHOO.lang.isArray(initVals) ? initVals : [0,range];
+    initVals[0] = Math.min(Math.max(parseInt(initVals[0],10)|0,0),range);
+    initVals[1] = Math.max(Math.min(parseInt(initVals[1],10)|0,range),0);
+    // Swap initVals if min > max
+    if (initVals[0] > initVals[1]) {
+        initVals.splice(0,2,initVals[1],initVals[0]);
+    }
+
+    var ready = { min : false, max : false };
+
+    this.minSlider.thumb.onAvailable = function () {
+        minSlider.setStartSliderState();
+        ready.min = true;
+        if (ready.max) {
+            minSlider.setValue(initVals[0],true,true,true);
+            maxSlider.setValue(initVals[1],true,true,true);
+            self.updateValue(true);
+            self.fireEvent('ready',self);
+        }
+    };
+    this.maxSlider.thumb.onAvailable = function () {
+        maxSlider.setStartSliderState();
+        ready.max = true;
+        if (ready.min) {
+            minSlider.setValue(initVals[0],true,true,true);
+            maxSlider.setValue(initVals[1],true,true,true);
+            self.updateValue(true);
+            self.fireEvent('ready',self);
+        }
+    };
+
+    // dispatch mousedowns to the active slider
+    minSlider.onMouseDown = function(e) {
+        self._handleMouseDown(e);
+    };
+
+    // we can safely ignore a mousedown on one of the sliders since
+    // they share a background
+    maxSlider.onMouseDown = function(e) { 
+        YAHOO.util.Event.stopEvent(e); 
+    };
+
+    // Fix the drag behavior so that only the active slider
+    // follows the drag
+    minSlider.onDrag =
+    maxSlider.onDrag = function(e) {
+        self._handleDrag(e);
+    };
+
+    // The core events for each slider are handled so we can expose a single
+    // event for when the event happens on either slider
+    minSlider.subscribe("change", this._handleMinChange, minSlider, this);
+    minSlider.subscribe("slideStart", this._handleSlideStart, minSlider, this);
+    minSlider.subscribe("slideEnd", this._handleSlideEnd, minSlider, this);
+
+    maxSlider.subscribe("change", this._handleMaxChange, maxSlider, this);
+    maxSlider.subscribe("slideStart", this._handleSlideStart, maxSlider, this);
+    maxSlider.subscribe("slideEnd", this._handleSlideEnd, maxSlider, this);
+
+    /**
+     * Event that fires when the slider is finished setting up
+     * @event ready
+     * @param {DualSlider} dualslider the DualSlider instance
+     */
+    this.createEvent("ready", this);
+
+    /**
+     * Event that fires when either the min or max value changes
+     * @event change
+     * @param {DualSlider} dualslider the DualSlider instance
+     */
+    this.createEvent("change", this);
+
+    /**
+     * Event that fires when one of the thumbs begins to move
+     * @event slideStart
+     * @param {Slider} activeSlider the moving slider
+     */
+    this.createEvent("slideStart", this);
+
+    /**
+     * Event that fires when one of the thumbs finishes moving
+     * @event slideEnd
+     * @param {Slider} activeSlider the moving slider
+     */
+    this.createEvent("slideEnd", this);
+};
+
+YAHOO.widget.DualSlider.prototype = {
+
+    /**
+     * The current value of the min thumb. <strong>read only</strong>.
+     * @property minVal
+     * @type int
+     */
+    minVal : -1,
+
+    /**
+     * The current value of the max thumb. <strong>read only</strong>.
+     * @property maxVal
+     * @type int
+     */
+    maxVal : -1,
+
+    /**
+     * Pixel distance to maintain between thumbs.
+     * @property minRange
+     * @type int
+     * @default 0
+     */
+    minRange : 0,
+
+    /**
+     * Executed when one of the sliders fires the slideStart event
+     * @method _handleSlideStart
+     * @private
+     */
+    _handleSlideStart: function(data, slider) {
+        this.fireEvent("slideStart", slider);
+    },
+
+    /**
+     * Executed when one of the sliders fires the slideEnd event
+     * @method _handleSlideEnd
+     * @private
+     */
+    _handleSlideEnd: function(data, slider) {
+        this.fireEvent("slideEnd", slider);
+    },
+
+    /**
+     * Overrides the onDrag method for both sliders
+     * @method _handleDrag
+     * @private
+     */
+    _handleDrag: function(e) {
+        YAHOO.widget.Slider.prototype.onDrag.call(this.activeSlider, e);
+    },
+
+    /**
+     * Executed when the min slider fires the change event
+     * @method _handleMinChange
+     * @private
+     */
+    _handleMinChange: function() {
+        this.activeSlider = this.minSlider;
+        this.updateValue();
+    },
+
+    /**
+     * Executed when the max slider fires the change event
+     * @method _handleMaxChange
+     * @private
+     */
+    _handleMaxChange: function() {
+        this.activeSlider = this.maxSlider;
+        this.updateValue();
+    },
+
+    /**
+     * Sets the min and max thumbs to new values.
+     * @method setValues
+     * @param min {int} Pixel offset to assign to the min thumb
+     * @param max {int} Pixel offset to assign to the max thumb
+     * @param skipAnim {boolean} (optional) Set to true to skip thumb animation.
+     * Default false
+     * @param force {boolean} (optional) ignore the locked setting and set
+     * value anyway. Default false
+     * @param silent {boolean} (optional) Set to true to skip firing change
+     * events.  Default false
+     */
+    setValues : function (min, max, skipAnim, force, silent) {
+        var mins = this.minSlider,
+            maxs = this.maxSlider,
+            mint = mins.thumb,
+            maxt = maxs.thumb,
+            self = this,
+            done = { min : false, max : false };
+
+        // Clear constraints to prevent animated thumbs from prematurely
+        // stopping when hitting a constraint that's moving with the other
+        // thumb.
+        if (mint._isHoriz) {
+            mint.setXConstraint(mint.leftConstraint,maxt.rightConstraint,mint.tickSize);
+            maxt.setXConstraint(mint.leftConstraint,maxt.rightConstraint,maxt.tickSize);
+        } else {
+            mint.setYConstraint(mint.topConstraint,maxt.bottomConstraint,mint.tickSize);
+            maxt.setYConstraint(mint.topConstraint,maxt.bottomConstraint,maxt.tickSize);
+        }
+
+        // Set up one-time slideEnd callbacks to call updateValue when both
+        // thumbs have been set
+        this._oneTimeCallback(mins,'slideEnd',function () {
+            done.min = true;
+            if (done.max) {
+                self.updateValue(silent);
+                // Clean the slider's slideEnd events on a timeout since this
+                // will be executed from inside the event's fire
+                setTimeout(function () {
+                    self._cleanEvent(mins,'slideEnd');
+                    self._cleanEvent(maxs,'slideEnd');
+                },0);
+            }
+        });
+
+        this._oneTimeCallback(maxs,'slideEnd',function () {
+            done.max = true;
+            if (done.min) {
+                self.updateValue(silent);
+                // Clean both sliders' slideEnd events on a timeout since this
+                // will be executed from inside one of the event's fire
+                setTimeout(function () {
+                    self._cleanEvent(mins,'slideEnd');
+                    self._cleanEvent(maxs,'slideEnd');
+                },0);
+            }
+        });
+
+        mins.setValue(min,skipAnim,force,silent);
+        maxs.setValue(max,skipAnim,force,silent);
+    },
+
+    /**
+     * Set the min thumb position to a new value.
+     * @method setMinValue
+     * @param min {int} Pixel offset for min thumb
+     * @param skipAnim {boolean} (optional) Set to true to skip thumb animation.
+     * Default false
+     * @param force {boolean} (optional) ignore the locked setting and set
+     * value anyway. Default false
+     * @param silent {boolean} (optional) Set to true to skip firing change
+     * events.  Default false
+     */
+    setMinValue : function (min, skipAnim, force, silent) {
+        var mins = this.minSlider;
+
+        this.activeSlider = mins;
+
+        // Use a one-time event callback to delay the updateValue call
+        // until after the slide operation is done
+        var self = this;
+        this._oneTimeCallback(mins,'slideEnd',function () {
+            self.updateValue(silent);
+            // Clean the slideEnd event on a timeout since this
+            // will be executed from inside the event's fire
+            setTimeout(function () { self._cleanEvent(mins,'slideEnd'); }, 0);
+        });
+
+        mins.setValue(min, skipAnim, force, silent);
+    },
+
+    /**
+     * Set the max thumb position to a new value.
+     * @method setMaxValue
+     * @param max {int} Pixel offset for max thumb
+     * @param skipAnim {boolean} (optional) Set to true to skip thumb animation.
+     * Default false
+     * @param force {boolean} (optional) ignore the locked setting and set
+     * value anyway. Default false
+     * @param silent {boolean} (optional) Set to true to skip firing change
+     * events.  Default false
+     */
+    setMaxValue : function (max, skipAnim, force, silent) {
+        var maxs = this.maxSlider;
+
+        this.activeSlider = maxs;
+
+        // Use a one-time event callback to delay the updateValue call
+        // until after the slide operation is done
+        var self = this;
+        this._oneTimeCallback(maxs,'slideEnd',function () {
+            self.updateValue(silent);
+            // Clean the slideEnd event on a timeout since this
+            // will be executed from inside the event's fire
+            setTimeout(function () { self._cleanEvent(maxs,'slideEnd'); }, 0);
+        });
+
+        maxs.setValue(max, skipAnim, force, silent);
+    },
+
+    /**
+     * Executed when one of the sliders is moved
+     * @method updateValue
+     * @param silent {boolean} (optional) Set to true to skip firing change
+     * events.  Default false
+     * @private
+     */
+    updateValue: function(silent) {
+        var min     = this.minSlider.getValue(),
+            max     = this.maxSlider.getValue(),
+            changed = false;
+
+        if (min != this.minVal || max != this.maxVal) {
+            changed = true;
+
+            var mint = this.minSlider.thumb;
+            var maxt = this.maxSlider.thumb;
+
+            var thumbInnerWidth = this.minSlider.thumbCenterPoint.x +
+                                  this.maxSlider.thumbCenterPoint.x;
+
+            // Establish barriers within the respective other thumb's edge, less
+            // the minRange.  Limit to the Slider's range in the case of
+            // negative minRanges.
+            var minConstraint = Math.max(max-thumbInnerWidth-this.minRange,0);
+            var maxConstraint = Math.min(-min-thumbInnerWidth-this.minRange,0);
+
+            if (this.isHoriz) {
+                minConstraint = Math.min(minConstraint,maxt.rightConstraint);
+
+                mint.setXConstraint(mint.leftConstraint,minConstraint, mint.tickSize);
+
+                maxt.setXConstraint(maxConstraint,maxt.rightConstraint, maxt.tickSize);
+            } else {
+                minConstraint = Math.min(minConstraint,maxt.bottomConstraint);
+                mint.setYConstraint(mint.leftConstraint,minConstraint, mint.tickSize);
+
+                maxt.setYConstraint(maxConstraint,maxt.bottomConstraint, maxt.tickSize);
+            }
+        }
+
+        this.minVal = min;
+        this.maxVal = max;
+
+        if (changed && !silent) {
+            this.fireEvent("change", this);
+        }
+    },
+
+    /**
+     * A background click will move the slider thumb nearest to the click.
+     * Override if you need different behavior.
+     * @method selectActiveSlider
+     * @param e {Event} the mousedown event
+     * @private
+     */
+    selectActiveSlider: function(e) {
+        var min = this.minSlider.getValue(),
+            max = this.maxSlider.getValue(),
+            d;
+
+        if (this.isHoriz) {
+            d = YAHOO.util.Event.getPageX(e) - this.minSlider.initPageX -
+                this.minSlider.thumbCenterPoint.x;
+        } else {
+            d = YAHOO.util.Event.getPageY(e) - this.minSlider.initPageY -
+                this.minSlider.thumbCenterPoint.y;
+        }
+                
+        // Below the minSlider thumb.  Move the minSlider thumb
+        if (d < min) {
+            this.activeSlider = this.minSlider;
+        // Above the maxSlider thumb.  Move the maxSlider thumb
+        } else if (d > max) {
+            this.activeSlider = this.maxSlider;
+        // Split the difference between thumbs
+        } else {
+            this.activeSlider = d*2 > max+min ? this.maxSlider : this.minSlider;
+        }
+    },
+
+    /**
+     * Overrides the onMouseDown for both slider, only moving the active slider
+     * @method handleMouseDown
+     * @private
+     */
+    _handleMouseDown: function(e) {
+        this.selectActiveSlider(e);
+        YAHOO.widget.Slider.prototype.onMouseDown.call(this.activeSlider, e);
+    },
+
+    /**
+     * Schedule an event callback that will execute once, then unsubscribe
+     * itself.
+     * @method _oneTimeCallback
+     * @param o {EventProvider} Object to attach the event to
+     * @param evt {string} Name of the event
+     * @param fn {Function} function to execute once
+     * @private
+     */
+    _oneTimeCallback : function (o,evt,fn) {
+        o.subscribe(evt,function () {
+            // Unsubscribe myself
+            o.unsubscribe(evt,arguments.callee);
+            // Pass the event handler arguments to the one time callback
+            fn.apply({},[].slice.apply(arguments));
+        });
+    },
+
+    /**
+     * Clean up the slideEnd event subscribers array, since each one-time
+     * callback will be replaced in the event's subscribers property with
+     * null.  This will cause memory bloat and loss of performance.
+     * @method _cleanEvent
+     * @param o {EventProvider} object housing the CustomEvent
+     * @param evt {string} name of the CustomEvent
+     * @private
+     */
+    _cleanEvent : function (o,evt) {
+        if (o.__yui_events && o.events[evt]) {
+            var ce, i, len;
+            for (i = o.__yui_events.length; i >= 0; --i) {
+                if (o.__yui_events[i].type === evt) {
+                    ce = o.__yui_events[i];
+                    break;
+                }
+            }
+            if (ce) {
+                var subs    = ce.subscribers,
+                    newSubs = [],
+                    j = 0;
+                for (i = 0, len = subs.length; i < len; ++i) {
+                    if (subs[i]) {
+                        newSubs[j++] = subs[i];
+                    }
+                }
+                ce.subscribers = newSubs;
+            }
+        }
+    }
+
+};
+
+YAHOO.augment(YAHOO.widget.DualSlider, YAHOO.util.EventProvider);
+
+
+/**
+ * Factory method for creating a horizontal dual-thumb slider
+ * @for YAHOO.widget.Slider
+ * @method YAHOO.widget.Slider.getHorizDualSlider
+ * @static
+ * @param {String} bg the id of the slider's background element
+ * @param {String} minthumb the id of the min thumb
+ * @param {String} maxthumb the id of the thumb thumb
+ * @param {int} range the number of pixels the thumbs can move within
+ * @param {int} iTickSize (optional) the element should move this many pixels
+ * at a time
+ * @param {Array}  initVals (optional) [min,max] Initial thumb placement
+ * @return {DualSlider} a horizontal dual-thumb slider control
+ */
+YAHOO.widget.Slider.getHorizDualSlider = 
+    function (bg, minthumb, maxthumb, range, iTickSize, initVals) {
+        var mint, maxt;
+        var YW = YAHOO.widget, Slider = YW.Slider, Thumb = YW.SliderThumb;
+
+        mint = new Thumb(minthumb, bg, 0, range, 0, 0, iTickSize);
+        maxt = new Thumb(maxthumb, bg, 0, range, 0, 0, iTickSize);
+
+        return new YW.DualSlider(new Slider(bg, bg, mint, "horiz"), new Slider(bg, bg, maxt, "horiz"), range, initVals);
+};
+
+/**
+ * Factory method for creating a vertical dual-thumb slider.
+ * @for YAHOO.widget.Slider
+ * @method YAHOO.widget.Slider.getVertDualSlider
+ * @static
+ * @param {String} bg the id of the slider's background element
+ * @param {String} minthumb the id of the min thumb
+ * @param {String} maxthumb the id of the thumb thumb
+ * @param {int} range the number of pixels the thumbs can move within
+ * @param {int} iTickSize (optional) the element should move this many pixels
+ * at a time
+ * @param {Array}  initVals (optional) [min,max] Initial thumb placement
+ * @return {DualSlider} a vertical dual-thumb slider control
+ */
+YAHOO.widget.Slider.getVertDualSlider = 
+    function (bg, minthumb, maxthumb, range, iTickSize, initVals) {
+        var mint, maxt;
+        var YW = YAHOO.widget, Slider = YW.Slider, Thumb = YW.SliderThumb;
+
+        mint = new Thumb(minthumb, bg, 0, 0, 0, range, iTickSize);
+        maxt = new Thumb(maxthumb, bg, 0, 0, 0, range, iTickSize);
+
+        return new YW.DualSlider(new Slider(bg, bg, mint, "vert"), new Slider(bg, bg, maxt, "vert"), range, initVals);
+};
+YAHOO.register("slider", YAHOO.widget.Slider, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/tabview/README
===================================================================
--- trunk/root/static/yui/tabview/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/tabview/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,11 @@
 TabView Release Notes
 
-*** version 2.4.1 ***
+*** version 2.5.1 ***
 * no change
 
+*** version 2.5.0 ***
+* moved Tab default "title" attribute to static Tab.TITLE 
+
 *** version 2.4.0 ***
 * no change
 

Modified: trunk/root/static/yui/tabview/assets/border_tabs.css
===================================================================
--- trunk/root/static/yui/tabview/assets/border_tabs.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/tabview/assets/border_tabs.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-navset .yui-nav li a, .yui-navset .yui-content {
     border:1px solid #000;  /* label and content borders */

Modified: trunk/root/static/yui/tabview/assets/skin-sam.css
===================================================================
--- trunk/root/static/yui/tabview/assets/skin-sam.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/tabview/assets/skin-sam.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-navset .yui-nav li {
     margin-right:0.16em; /* space between tabs */

Modified: trunk/root/static/yui/tabview/assets/skins/sam/tabview-skin.css
===================================================================
--- trunk/root/static/yui/tabview/assets/skins/sam/tabview-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/tabview/assets/skins/sam/tabview-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* .yui-navset defaults to .yui-navset-top */
 .yui-skin-sam .yui-navset .yui-nav,

Modified: trunk/root/static/yui/tabview/assets/skins/sam/tabview.css
===================================================================
--- trunk/root/static/yui/tabview/assets/skins/sam/tabview.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/tabview/assets/skins/sam/tabview.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-navset .yui-nav li,.yui-navset .yui-navset-top .yui-nav li,.yui-navset .yui-navset-bottom .yui-nav li{margin:0 0.5em 0 0;}.yui-navset-left .yui-nav li,.yui-navset-right .yui-nav li{margin:0 0 0.5em;}.yui-navset .yui-navset-left .yui-nav,.yui-navset .yui-navset-right .yui-nav,.yui-navset-left .yui-nav,.yui-navset-right .yui-nav{width:6em;}.yui-navset-top .yui-nav,.yui-navset-bottom .yui-nav{width:auto;}.yui-navset .yui-navset-left,.yui-navset-left{padding:0 0 0 6em;}.yui-navset-right{padding:0 6em 0 0;}.yui-navset-top,.yui-navset-bottom{padding:auto;}.yui-nav,.yui-nav li{margin:0;padding:0;list-style:none;}.yui-navset li em{font-style:normal;}.yui-navset{position:relative;zoom:1;}.yui-navset .yui-content{zoom:1;}.yui-navset .yui-nav li,.yui-navset .yui-navset-top .yui-nav li,.yui-navset .yui-navset-bottom .yui-nav li{display:inline-block;display:-moz-inline-stack;*display:inline;vertical-align:bottom;cursor:pointer;zoom:1;}.yui-navset-left .yui-nav li,.yui-navset-right !
 .yui-nav li{display:block;}.yui-navset .yui-nav a{position:relative;}.yui-navset .yui-nav li a,.yui-navset-top .yui-nav li a,.yui-navset-bottom .yui-nav li a{display:block;display:inline-block;vertical-align:bottom;zoom:1;}.yui-navset-left .yui-nav li a,.yui-navset-right .yui-nav li a{display:block;}.yui-navset-bottom .yui-nav li a{vertical-align:text-top;}.yui-navset .yui-nav li a em,.yui-navset-top .yui-nav li a em,.yui-navset-bottom .yui-nav li a em{display:block;}.yui-navset .yui-navset-left .yui-nav,.yui-navset .yui-navset-right .yui-nav,.yui-navset-left .yui-nav,.yui-navset-right .yui-nav{position:absolute;z-index:1;}.yui-navset-top .yui-nav,.yui-navset-bottom .yui-nav{position:static;}.yui-navset .yui-navset-left .yui-nav,.yui-navset-left .yui-nav{left:0;right:auto;}.yui-navset .yui-navset-right .yui-nav,.yui-navset-right .yui-nav{right:0;left:auto;}.yui-skin-sam .yui-navset .yui-nav,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav{border:solid #2647a0;border-width!
 :0 0 5px;Xposition:relative;zoom:1;}.yui-skin-sam .yui-navset !
 .yui-nav
 li,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav li{margin:0 0.16em 0 0;padding:1px 0 0;zoom:1;}.yui-skin-sam .yui-navset .yui-nav .selected,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav .selected{margin:0 0.16em -1px 0;}.yui-skin-sam .yui-navset .yui-nav a,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav a{background:#d8d8d8 url(../../../../assets/skins/sam/sprite.png) repeat-x;border:solid #a3a3a3;border-width:0 1px;color:#000;position:relative;text-decoration:none;}.yui-skin-sam .yui-navset .yui-nav a em,.yui-skin-sam .yui-navset .yui-navset-top .yui-nav a em{border:solid #a3a3a3;border-width:1px 0 0;cursor:hand;padding:0.25em .75em;left:0;right:0;bottom:0;top:-1px;position:relative;}.yui-skin-sam .yui-navset .yui-nav .selected a,.yui-skin-sam .yui-navset .yui-nav .selected a:focus,.yui-skin-sam .yui-navset .yui-nav .selected a:hover{background:#2647a0 url(../../../../assets/skins/sam/sprite.png) repeat-x left -1400px;color:#fff;}.yui-skin-sam .yui-navset .yu!
 i-nav a:hover,.yui-skin-sam .yui-navset .yui-nav a:focus{background:#bfdaff url(../../../../assets/skins/sam/sprite.png) repeat-x left -1300px;outline:0;}.yui-skin-sam .yui-navset .yui-nav .selected a em{padding:0.35em 0.75em;}.yui-skin-sam .yui-navset .yui-nav .selected a,.yui-skin-sam .yui-navset .yui-nav .selected a em{border-color:#243356;}.yui-skin-sam .yui-navset .yui-content{background:#edf5ff;}.yui-skin-sam .yui-navset .yui-content,.yui-skin-sam .yui-navset .yui-navset-top .yui-content{border:1px solid #808080;border-top-color:#243356;padding:0.25em 0.5em;}.yui-skin-sam .yui-navset-left .yui-nav,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav,.yui-skin-sam .yui-navset .yui-navset-right .yui-nav,.yui-skin-sam .yui-navset-right .yui-nav{border-width:0 5px 0 0;Xposition:absolute;top:0;bottom:0;}.yui-skin-sam .yui-navset .yui-navset-right .yui-nav,.yui-skin-sam .yui-navset-right .yui-nav{border-width:0 0 0 5px;}.yui-skin-sam .yui-navset-left .yui-nav li,.yui-skin-sa!
 m .yui-navset .yui-navset-left .yui-nav li,.yui-skin-sam .yui-!
 navset-r
ight .yui-nav li{margin:0 0 0.16em;padding:0 0 0 1px;}.yui-skin-sam .yui-navset-right .yui-nav li{padding:0 1px 0 0;}.yui-skin-sam .yui-navset-left .yui-nav .selected,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav .selected{margin:0 -1px 0.16em 0;}.yui-skin-sam .yui-navset-right .yui-nav .selected{margin:0 0 0.16em -1px;}.yui-skin-sam .yui-navset-left .yui-nav a,.yui-skin-sam .yui-navset-right .yui-nav a{border-width:1px 0;}.yui-skin-sam .yui-navset-left .yui-nav a em,.yui-skin-sam .yui-navset .yui-navset-left .yui-nav a em,.yui-skin-sam .yui-navset-right .yui-nav a em{border-width:0 0 0 1px;padding:0.2em .75em;top:auto;left:-1px;}.yui-skin-sam .yui-navset-right .yui-nav a em{border-width:0 1px 0 0;left:auto;right:-1px;}.yui-skin-sam .yui-navset-left .yui-nav a,.yui-skin-sam .yui-navset-left .yui-nav .selected a,.yui-skin-sam .yui-navset-left .yui-nav a:hover,.yui-skin-sam .yui-navset-right .yui-nav a,.yui-skin-sam .yui-navset-right .yui-nav .selected a,.yui-skin-sam .y!
 ui-navset-right .yui-nav a:hover,.yui-skin-sam .yui-navset-bottom .yui-nav a,.yui-skin-sam .yui-navset-bottom .yui-nav .selected a,.yui-skin-sam .yui-navset-bottom .yui-nav a:hover{background-image:none;}.yui-skin-sam .yui-navset-left .yui-content{border:1px solid #808080;border-left-color:#243356;}.yui-skin-sam .yui-navset-bottom .yui-nav,.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav{border-width:5px 0 0;}.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav .selected,.yui-skin-sam .yui-navset-bottom .yui-nav .selected{margin:-1px 0.16em 0 0;}.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav li,.yui-skin-sam .yui-navset-bottom .yui-nav li{padding:0 0 1px 0;vertical-align:top;}.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav li a,.yui-skin-sam .yui-navset-bottom .yui-nav li a{}.yui-skin-sam .yui-navset .yui-navset-bottom .yui-nav a em,.yui-skin-sam .yui-navset-bottom .yui-nav a em{border-width:0 0 1px;top:auto;bottom:-1px;}.yui-skin-sam .yui-navset-bottom .!
 yui-content,.yui-skin-sam .yui-navset .yui-navset-bottom .yui-!
 content{
border:1px solid #808080;border-bottom-color:#243356;}

Modified: trunk/root/static/yui/tabview/assets/tabview-core.css
===================================================================
--- trunk/root/static/yui/tabview/assets/tabview-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/tabview/assets/tabview-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* default space between tabs */
 .yui-navset .yui-nav li,

Modified: trunk/root/static/yui/tabview/assets/tabview.css
===================================================================
--- trunk/root/static/yui/tabview/assets/tabview.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/tabview/assets/tabview.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* default space between tabs */
 .yui-navset .yui-nav li {

Modified: trunk/root/static/yui/tabview/tabview-debug.js
===================================================================
--- trunk/root/static/yui/tabview/tabview-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/tabview/tabview-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 (function() {
 
@@ -525,6 +525,14 @@
     proto.ACTIVE_CLASSNAME = 'selected';
     
     /**
+     * The title applied to active tabs.
+     * @property ACTIVE_TITLE
+     * @type String
+     * @default "active"
+     */
+    proto.ACTIVE_TITLE = 'active';
+
+    /**
      * The class name applied to disabled tabs.
      * @property DISABLED_CLASSNAME
      * @type String
@@ -727,7 +735,7 @@
             method: function(value) {
                 if (value === true) {
                     this.addClass(this.ACTIVE_CLASSNAME);
-                    this.set('title', 'active');
+                    this.set('title', this.ACTIVE_TITLE);
                 } else {
                     this.removeClass(this.ACTIVE_CLASSNAME);
                     this.set('title', '');
@@ -886,4 +894,4 @@
     YAHOO.widget.Tab = Tab;
 })();
 
-YAHOO.register("tabview", YAHOO.widget.TabView, {version: "2.4.1", build: "742"});
+YAHOO.register("tabview", YAHOO.widget.TabView, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/tabview/tabview-min.js
===================================================================
--- trunk/root/static/yui/tabview/tabview-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/tabview/tabview-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-(function(){YAHOO.widget.TabView=function(K,J){J=J||{};if(arguments.length==1&&!YAHOO.lang.isString(K)&&!K.nodeName){J=K;K=J.element||null;}if(!K&&!J.element){K=I.call(this,J);}YAHOO.widget.TabView.superclass.constructor.call(this,K,J);};YAHOO.extend(YAHOO.widget.TabView,YAHOO.util.Element);var F=YAHOO.widget.TabView.prototype;var E=YAHOO.util.Dom;var H=YAHOO.util.Event;var D=YAHOO.widget.Tab;F.CLASSNAME="yui-navset";F.TAB_PARENT_CLASSNAME="yui-nav";F.CONTENT_PARENT_CLASSNAME="yui-content";F._tabParent=null;F._contentParent=null;F.addTab=function(M,O){var P=this.get("tabs");if(!P){this._queue[this._queue.length]=["addTab",arguments];return false;}O=(O===undefined)?P.length:O;var R=this.getTab(O);var T=this;var L=this.get("element");var S=this._tabParent;var Q=this._contentParent;var J=M.get("element");var K=M.get("contentEl");if(R){S.insertBefore(J,R.get("element"));}else{S.appendChild(J);}if(K&&!E.isAncestor(Q,K)){Q.appendChild(K);}if(!M.get("active")){M.set("contentVisibl!
 e",false,true);}else{this.set("activeTab",M,true);}var N=function(V){YAHOO.util.Event.preventDefault(V);var U=false;if(this==T.get("activeTab")){U=true;}T.set("activeTab",this,U);};M.addListener(M.get("activationEvent"),N);M.addListener("activationEventChange",function(U){if(U.prevValue!=U.newValue){M.removeListener(U.prevValue,N);M.addListener(U.newValue,N);}});P.splice(O,0,M);};F.DOMEventHandler=function(P){var K=this.get("element");var Q=YAHOO.util.Event.getTarget(P);var S=this._tabParent;if(E.isAncestor(S,Q)){var L;var M=null;var J;var R=this.get("tabs");for(var N=0,O=R.length;N<O;N++){L=R[N].get("element");J=R[N].get("contentEl");if(Q==L||E.isAncestor(L,Q)){M=R[N];break;}}if(M){M.fireEvent(P.type,P);}}};F.getTab=function(J){return this.get("tabs")[J];};F.getTabIndex=function(N){var K=null;var M=this.get("tabs");for(var L=0,J=M.length;L<J;++L){if(N==M[L]){K=L;break;}}return K;};F.removeTab=function(M){var L=this.get("tabs").length;var K=this.getTabIndex(M);var J=K+1;if(!
 M==this.get("activeTab")){if(L>1){if(K+1==L){this.set("activeI!
 ndex",K-
1);}else{this.set("activeIndex",K+1);}}}this._tabParent.removeChild(M.get("element"));this._contentParent.removeChild(M.get("contentEl"));this._configs.tabs.value.splice(K,1);};F.toString=function(){var J=this.get("id")||this.get("tagName");return"TabView "+J;};F.contentTransition=function(K,J){K.set("contentVisible",true);J.set("contentVisible",false);};F.initAttributes=function(J){YAHOO.widget.TabView.superclass.initAttributes.call(this,J);if(!J.orientation){J.orientation="top";}var L=this.get("element");if(!YAHOO.util.Dom.hasClass(L,this.CLASSNAME)){YAHOO.util.Dom.addClass(L,this.CLASSNAME);}this.setAttributeConfig("tabs",{value:[],readOnly:true});this._tabParent=this.getElementsByClassName(this.TAB_PARENT_CLASSNAME,"ul")[0]||G.call(this);this._contentParent=this.getElementsByClassName(this.CONTENT_PARENT_CLASSNAME,"div")[0]||C.call(this);this.setAttributeConfig("orientation",{value:J.orientation,method:function(M){var N=this.get("orientation");this.addClass("yui-navset-"!
 +M);if(N!=M){this.removeClass("yui-navset-"+N);}switch(M){case"bottom":this.appendChild(this._tabParent);break;}}});this.setAttributeConfig("activeIndex",{value:J.activeIndex,method:function(M){this.set("activeTab",this.getTab(M));},validator:function(M){return !this.getTab(M).get("disabled");}});this.setAttributeConfig("activeTab",{value:J.activeTab,method:function(N){var M=this.get("activeTab");if(N){N.set("active",true);this._configs["activeIndex"].value=this.getTabIndex(N);}if(M&&M!=N){M.set("active",false);}if(M&&N!=M){this.contentTransition(N,M);}else{if(N){N.set("contentVisible",true);}}},validator:function(M){return !M.get("disabled");}});if(this._tabParent){B.call(this);}this.DOM_EVENTS.submit=false;this.DOM_EVENTS.focus=false;this.DOM_EVENTS.blur=false;for(var K in this.DOM_EVENTS){if(YAHOO.lang.hasOwnProperty(this.DOM_EVENTS,K)){this.addListener.call(this,K,this.DOMEventHandler);}}};var B=function(){var Q,L,P;var O=this.get("element");var N=A(this._tabParent);var!
  K=A(this._contentParent);for(var M=0,J=N.length;M<J;++M){L={}!
 ;if(K[M]
){L.contentEl=K[M];}Q=new YAHOO.widget.Tab(N[M],L);this.addTab(Q);if(Q.hasClass(Q.ACTIVE_CLASSNAME)){this._configs.activeTab.value=Q;this._configs.activeIndex.value=this.getTabIndex(Q);}}};var I=function(J){var K=document.createElement("div");if(this.CLASSNAME){K.className=this.CLASSNAME;}return K;};var G=function(J){var K=document.createElement("ul");if(this.TAB_PARENT_CLASSNAME){K.className=this.TAB_PARENT_CLASSNAME;}this.get("element").appendChild(K);return K;};var C=function(J){var K=document.createElement("div");if(this.CONTENT_PARENT_CLASSNAME){K.className=this.CONTENT_PARENT_CLASSNAME;}this.get("element").appendChild(K);return K;};var A=function(M){var K=[];var N=M.childNodes;for(var L=0,J=N.length;L<J;++L){if(N[L].nodeType==1){K[K.length]=N[L];}}return K;};})();(function(){var E=YAHOO.util.Dom,J=YAHOO.util.Event;var B=function(L,K){K=K||{};if(arguments.length==1&&!YAHOO.lang.isString(L)&&!L.nodeName){K=L;L=K.element;}if(!L&&!K.element){L=H.call(this,K);}this.loadHand!
 ler={success:function(M){this.set("content",M.responseText);},failure:function(M){}};B.superclass.constructor.call(this,L,K);this.DOM_EVENTS={};};YAHOO.extend(B,YAHOO.util.Element);var F=B.prototype;F.LABEL_TAGNAME="em";F.ACTIVE_CLASSNAME="selected";F.DISABLED_CLASSNAME="disabled";F.LOADING_CLASSNAME="loading";F.dataConnection=null;F.loadHandler=null;F._loading=false;F.toString=function(){var K=this.get("element");var L=K.id||K.tagName;return"Tab "+L;};F.initAttributes=function(K){K=K||{};B.superclass.initAttributes.call(this,K);var M=this.get("element");this.setAttributeConfig("activationEvent",{value:K.activationEvent||"click"});this.setAttributeConfig("labelEl",{value:K.labelEl||G.call(this),method:function(N){var O=this.get("labelEl");if(O){if(O==N){return false;}this.replaceChild(N,O);}else{if(M.firstChild){this.insertBefore(N,M.firstChild);}else{this.appendChild(N);}}}});this.setAttributeConfig("label",{value:K.label||D.call(this),method:function(O){var N=this.get("la!
 belEl");
-if(!N){this.set("labelEl",I.call(this));}C.call(this,O);}});this.setAttributeConfig("contentEl",{value:K.contentEl||document.createElement("div"),method:function(N){var O=this.get("contentEl");if(O){if(O==N){return false;}this.replaceChild(N,O);}}});this.setAttributeConfig("content",{value:K.content,method:function(N){this.get("contentEl").innerHTML=N;}});var L=false;this.setAttributeConfig("dataSrc",{value:K.dataSrc});this.setAttributeConfig("cacheData",{value:K.cacheData||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("loadMethod",{value:K.loadMethod||"GET",validator:YAHOO.lang.isString});this.setAttributeConfig("dataLoaded",{value:false,validator:YAHOO.lang.isBoolean,writeOnce:true});this.setAttributeConfig("dataTimeout",{value:K.dataTimeout||null,validator:YAHOO.lang.isNumber});this.setAttributeConfig("active",{value:K.active||this.hasClass(this.ACTIVE_CLASSNAME),method:function(N){if(N===true){this.addClass(this.ACTIVE_CLASSNAME);this.set("title","activ!
 e");}else{this.removeClass(this.ACTIVE_CLASSNAME);this.set("title","");}},validator:function(N){return YAHOO.lang.isBoolean(N)&&!this.get("disabled");}});this.setAttributeConfig("disabled",{value:K.disabled||this.hasClass(this.DISABLED_CLASSNAME),method:function(N){if(N===true){E.addClass(this.get("element"),this.DISABLED_CLASSNAME);}else{E.removeClass(this.get("element"),this.DISABLED_CLASSNAME);}},validator:YAHOO.lang.isBoolean});this.setAttributeConfig("href",{value:K.href||this.getElementsByTagName("a")[0].getAttribute("href",2)||"#",method:function(N){this.getElementsByTagName("a")[0].href=N;},validator:YAHOO.lang.isString});this.setAttributeConfig("contentVisible",{value:K.contentVisible,method:function(N){if(N){this.get("contentEl").style.display="block";if(this.get("dataSrc")){if(!this._loading&&!(this.get("dataLoaded")&&this.get("cacheData"))){A.call(this);}}}else{this.get("contentEl").style.display="none";}},validator:YAHOO.lang.isBoolean});};var H=function(K){var!
  O=document.createElement("li");var L=document.createElement("!
 a");L.hr
ef=K.href||"#";O.appendChild(L);var N=K.label||null;var M=K.labelEl||null;if(M){if(!N){N=D.call(this,M);}}else{M=I.call(this);}L.appendChild(M);return O;};var G=function(){return this.getElementsByTagName(this.LABEL_TAGNAME)[0];};var I=function(){var K=document.createElement(this.LABEL_TAGNAME);return K;};var C=function(K){var L=this.get("labelEl");L.innerHTML=K;};var D=function(){var K,L=this.get("labelEl");if(!L){return undefined;}return L.innerHTML;};var A=function(){if(!YAHOO.util.Connect){return false;}E.addClass(this.get("contentEl").parentNode,this.LOADING_CLASSNAME);this._loading=true;this.dataConnection=YAHOO.util.Connect.asyncRequest(this.get("loadMethod"),this.get("dataSrc"),{success:function(K){this.loadHandler.success.call(this,K);this.set("dataLoaded",true);this.dataConnection=null;E.removeClass(this.get("contentEl").parentNode,this.LOADING_CLASSNAME);this._loading=false;},failure:function(K){this.loadHandler.failure.call(this,K);this.dataConnection=null;E.remo!
 veClass(this.get("contentEl").parentNode,this.LOADING_CLASSNAME);this._loading=false;},scope:this,timeout:this.get("dataTimeout")});};YAHOO.widget.Tab=B;})();YAHOO.register("tabview",YAHOO.widget.TabView,{version:"2.4.1",build:"742"});
\ No newline at end of file
+(function(){YAHOO.widget.TabView=function(K,J){J=J||{};if(arguments.length==1&&!YAHOO.lang.isString(K)&&!K.nodeName){J=K;K=J.element||null;}if(!K&&!J.element){K=I.call(this,J);}YAHOO.widget.TabView.superclass.constructor.call(this,K,J);};YAHOO.extend(YAHOO.widget.TabView,YAHOO.util.Element);var F=YAHOO.widget.TabView.prototype;var E=YAHOO.util.Dom;var H=YAHOO.util.Event;var D=YAHOO.widget.Tab;F.CLASSNAME="yui-navset";F.TAB_PARENT_CLASSNAME="yui-nav";F.CONTENT_PARENT_CLASSNAME="yui-content";F._tabParent=null;F._contentParent=null;F.addTab=function(M,O){var P=this.get("tabs");if(!P){this._queue[this._queue.length]=["addTab",arguments];return false;}O=(O===undefined)?P.length:O;var R=this.getTab(O);var T=this;var L=this.get("element");var S=this._tabParent;var Q=this._contentParent;var J=M.get("element");var K=M.get("contentEl");if(R){S.insertBefore(J,R.get("element"));}else{S.appendChild(J);}if(K&&!E.isAncestor(Q,K)){Q.appendChild(K);}if(!M.get("active")){M.set("contentVisibl!
 e",false,true);}else{this.set("activeTab",M,true);}var N=function(V){YAHOO.util.Event.preventDefault(V);var U=false;if(this==T.get("activeTab")){U=true;}T.set("activeTab",this,U);};M.addListener(M.get("activationEvent"),N);M.addListener("activationEventChange",function(U){if(U.prevValue!=U.newValue){M.removeListener(U.prevValue,N);M.addListener(U.newValue,N);}});P.splice(O,0,M);};F.DOMEventHandler=function(P){var K=this.get("element");var Q=YAHOO.util.Event.getTarget(P);var S=this._tabParent;if(E.isAncestor(S,Q)){var L;var M=null;var J;var R=this.get("tabs");for(var N=0,O=R.length;N<O;N++){L=R[N].get("element");J=R[N].get("contentEl");if(Q==L||E.isAncestor(L,Q)){M=R[N];break;}}if(M){M.fireEvent(P.type,P);}}};F.getTab=function(J){return this.get("tabs")[J];};F.getTabIndex=function(N){var K=null;var M=this.get("tabs");for(var L=0,J=M.length;L<J;++L){if(N==M[L]){K=L;break;}}return K;};F.removeTab=function(M){var L=this.get("tabs").length;var K=this.getTabIndex(M);var J=K+1;if(!
 M==this.get("activeTab")){if(L>1){if(K+1==L){this.set("activeI!
 ndex",K-
1);}else{this.set("activeIndex",K+1);}}}this._tabParent.removeChild(M.get("element"));this._contentParent.removeChild(M.get("contentEl"));this._configs.tabs.value.splice(K,1);};F.toString=function(){var J=this.get("id")||this.get("tagName");return"TabView "+J;};F.contentTransition=function(K,J){K.set("contentVisible",true);J.set("contentVisible",false);};F.initAttributes=function(J){YAHOO.widget.TabView.superclass.initAttributes.call(this,J);if(!J.orientation){J.orientation="top";}var L=this.get("element");if(!YAHOO.util.Dom.hasClass(L,this.CLASSNAME)){YAHOO.util.Dom.addClass(L,this.CLASSNAME);}this.setAttributeConfig("tabs",{value:[],readOnly:true});this._tabParent=this.getElementsByClassName(this.TAB_PARENT_CLASSNAME,"ul")[0]||G.call(this);this._contentParent=this.getElementsByClassName(this.CONTENT_PARENT_CLASSNAME,"div")[0]||C.call(this);this.setAttributeConfig("orientation",{value:J.orientation,method:function(M){var N=this.get("orientation");this.addClass("yui-navset-"!
 +M);if(N!=M){this.removeClass("yui-navset-"+N);}switch(M){case"bottom":this.appendChild(this._tabParent);break;}}});this.setAttributeConfig("activeIndex",{value:J.activeIndex,method:function(M){this.set("activeTab",this.getTab(M));},validator:function(M){return !this.getTab(M).get("disabled");}});this.setAttributeConfig("activeTab",{value:J.activeTab,method:function(N){var M=this.get("activeTab");if(N){N.set("active",true);this._configs["activeIndex"].value=this.getTabIndex(N);}if(M&&M!=N){M.set("active",false);}if(M&&N!=M){this.contentTransition(N,M);}else{if(N){N.set("contentVisible",true);}}},validator:function(M){return !M.get("disabled");}});if(this._tabParent){B.call(this);}this.DOM_EVENTS.submit=false;this.DOM_EVENTS.focus=false;this.DOM_EVENTS.blur=false;for(var K in this.DOM_EVENTS){if(YAHOO.lang.hasOwnProperty(this.DOM_EVENTS,K)){this.addListener.call(this,K,this.DOMEventHandler);}}};var B=function(){var Q,L,P;var O=this.get("element");var N=A(this._tabParent);var!
  K=A(this._contentParent);for(var M=0,J=N.length;M<J;++M){L={}!
 ;if(K[M]
){L.contentEl=K[M];}Q=new YAHOO.widget.Tab(N[M],L);this.addTab(Q);if(Q.hasClass(Q.ACTIVE_CLASSNAME)){this._configs.activeTab.value=Q;this._configs.activeIndex.value=this.getTabIndex(Q);}}};var I=function(J){var K=document.createElement("div");if(this.CLASSNAME){K.className=this.CLASSNAME;}return K;};var G=function(J){var K=document.createElement("ul");if(this.TAB_PARENT_CLASSNAME){K.className=this.TAB_PARENT_CLASSNAME;}this.get("element").appendChild(K);return K;};var C=function(J){var K=document.createElement("div");if(this.CONTENT_PARENT_CLASSNAME){K.className=this.CONTENT_PARENT_CLASSNAME;}this.get("element").appendChild(K);return K;};var A=function(M){var K=[];var N=M.childNodes;for(var L=0,J=N.length;L<J;++L){if(N[L].nodeType==1){K[K.length]=N[L];}}return K;};})();(function(){var E=YAHOO.util.Dom,J=YAHOO.util.Event;var B=function(L,K){K=K||{};if(arguments.length==1&&!YAHOO.lang.isString(L)&&!L.nodeName){K=L;L=K.element;}if(!L&&!K.element){L=H.call(this,K);}this.loadHand!
 ler={success:function(M){this.set("content",M.responseText);},failure:function(M){}};B.superclass.constructor.call(this,L,K);this.DOM_EVENTS={};};YAHOO.extend(B,YAHOO.util.Element);var F=B.prototype;F.LABEL_TAGNAME="em";F.ACTIVE_CLASSNAME="selected";F.ACTIVE_TITLE="active";F.DISABLED_CLASSNAME="disabled";F.LOADING_CLASSNAME="loading";F.dataConnection=null;F.loadHandler=null;F._loading=false;F.toString=function(){var K=this.get("element");var L=K.id||K.tagName;return"Tab "+L;};F.initAttributes=function(K){K=K||{};B.superclass.initAttributes.call(this,K);var M=this.get("element");this.setAttributeConfig("activationEvent",{value:K.activationEvent||"click"});this.setAttributeConfig("labelEl",{value:K.labelEl||G.call(this),method:function(N){var O=this.get("labelEl");if(O){if(O==N){return false;}this.replaceChild(N,O);}else{if(M.firstChild){this.insertBefore(N,M.firstChild);}else{this.appendChild(N);}}}});this.setAttributeConfig("label",{value:K.label||D.call(this),method:functi!
 on(O){var N=this.get("labelEl");
+if(!N){this.set("labelEl",I.call(this));}C.call(this,O);}});this.setAttributeConfig("contentEl",{value:K.contentEl||document.createElement("div"),method:function(N){var O=this.get("contentEl");if(O){if(O==N){return false;}this.replaceChild(N,O);}}});this.setAttributeConfig("content",{value:K.content,method:function(N){this.get("contentEl").innerHTML=N;}});var L=false;this.setAttributeConfig("dataSrc",{value:K.dataSrc});this.setAttributeConfig("cacheData",{value:K.cacheData||false,validator:YAHOO.lang.isBoolean});this.setAttributeConfig("loadMethod",{value:K.loadMethod||"GET",validator:YAHOO.lang.isString});this.setAttributeConfig("dataLoaded",{value:false,validator:YAHOO.lang.isBoolean,writeOnce:true});this.setAttributeConfig("dataTimeout",{value:K.dataTimeout||null,validator:YAHOO.lang.isNumber});this.setAttributeConfig("active",{value:K.active||this.hasClass(this.ACTIVE_CLASSNAME),method:function(N){if(N===true){this.addClass(this.ACTIVE_CLASSNAME);this.set("title",this.A!
 CTIVE_TITLE);}else{this.removeClass(this.ACTIVE_CLASSNAME);this.set("title","");}},validator:function(N){return YAHOO.lang.isBoolean(N)&&!this.get("disabled");}});this.setAttributeConfig("disabled",{value:K.disabled||this.hasClass(this.DISABLED_CLASSNAME),method:function(N){if(N===true){E.addClass(this.get("element"),this.DISABLED_CLASSNAME);}else{E.removeClass(this.get("element"),this.DISABLED_CLASSNAME);}},validator:YAHOO.lang.isBoolean});this.setAttributeConfig("href",{value:K.href||this.getElementsByTagName("a")[0].getAttribute("href",2)||"#",method:function(N){this.getElementsByTagName("a")[0].href=N;},validator:YAHOO.lang.isString});this.setAttributeConfig("contentVisible",{value:K.contentVisible,method:function(N){if(N){this.get("contentEl").style.display="block";if(this.get("dataSrc")){if(!this._loading&&!(this.get("dataLoaded")&&this.get("cacheData"))){A.call(this);}}}else{this.get("contentEl").style.display="none";}},validator:YAHOO.lang.isBoolean});};var H=functi!
 on(K){var O=document.createElement("li");var L=document.create!
 Element(
"a");L.href=K.href||"#";O.appendChild(L);var N=K.label||null;var M=K.labelEl||null;if(M){if(!N){N=D.call(this,M);}}else{M=I.call(this);}L.appendChild(M);return O;};var G=function(){return this.getElementsByTagName(this.LABEL_TAGNAME)[0];};var I=function(){var K=document.createElement(this.LABEL_TAGNAME);return K;};var C=function(K){var L=this.get("labelEl");L.innerHTML=K;};var D=function(){var K,L=this.get("labelEl");if(!L){return undefined;}return L.innerHTML;};var A=function(){if(!YAHOO.util.Connect){return false;}E.addClass(this.get("contentEl").parentNode,this.LOADING_CLASSNAME);this._loading=true;this.dataConnection=YAHOO.util.Connect.asyncRequest(this.get("loadMethod"),this.get("dataSrc"),{success:function(K){this.loadHandler.success.call(this,K);this.set("dataLoaded",true);this.dataConnection=null;E.removeClass(this.get("contentEl").parentNode,this.LOADING_CLASSNAME);this._loading=false;},failure:function(K){this.loadHandler.failure.call(this,K);this.dataConnection=nu!
 ll;E.removeClass(this.get("contentEl").parentNode,this.LOADING_CLASSNAME);this._loading=false;},scope:this,timeout:this.get("dataTimeout")});};YAHOO.widget.Tab=B;})();YAHOO.register("tabview",YAHOO.widget.TabView,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/tabview/tabview.js
===================================================================
--- trunk/root/static/yui/tabview/tabview.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/tabview/tabview.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 (function() {
 
@@ -523,6 +523,14 @@
     proto.ACTIVE_CLASSNAME = 'selected';
     
     /**
+     * The title applied to active tabs.
+     * @property ACTIVE_TITLE
+     * @type String
+     * @default "active"
+     */
+    proto.ACTIVE_TITLE = 'active';
+
+    /**
      * The class name applied to disabled tabs.
      * @property DISABLED_CLASSNAME
      * @type String
@@ -725,7 +733,7 @@
             method: function(value) {
                 if (value === true) {
                     this.addClass(this.ACTIVE_CLASSNAME);
-                    this.set('title', 'active');
+                    this.set('title', this.ACTIVE_TITLE);
                 } else {
                     this.removeClass(this.ACTIVE_CLASSNAME);
                     this.set('title', '');
@@ -878,4 +886,4 @@
     YAHOO.widget.Tab = Tab;
 })();
 
-YAHOO.register("tabview", YAHOO.widget.TabView, {version: "2.4.1", build: "742"});
+YAHOO.register("tabview", YAHOO.widget.TabView, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/treeview/README
===================================================================
--- trunk/root/static/yui/treeview/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/treeview/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,17 @@
 TreeView - Release Notes
 
-2.4.1
+2.5.1
+  * No change
 
-No change
+2.5.0
+  * Added isLeaf property to Node that allows dynamically loaded trees to
+    have nodes that are not dynamically loaded (without configuring dynamic
+    load for each individual dynamic node, which was the requirement previously).  
+    If set to true, dynamic loading will be disabled for the node and it 
+    will always have the leaf node presentation (rather than the expand icon).
+  * Made CSS adjustments to work with base.css
+  * HTMLNode: removed unused property 'content', and documented the correct
+    property 'html'.
 
 2.4.0
   * added TreeView getNodeByElement, which will return a YAHOO.widget.Node 

Modified: trunk/root/static/yui/treeview/assets/skins/sam/treeview-skin.css
===================================================================
--- trunk/root/static/yui/treeview/assets/skins/sam/treeview-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/treeview/assets/skins/sam/treeview-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* first or middle sibling, no children */
 .ygtvtn {

Modified: trunk/root/static/yui/treeview/assets/skins/sam/treeview.css
===================================================================
--- trunk/root/static/yui/treeview/assets/skins/sam/treeview.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/treeview/assets/skins/sam/treeview.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .ygtvtn{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -5600px no-repeat;}.ygtvtm{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -4000px no-repeat;}.ygtvtmh{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -4800px no-repeat;}.ygtvtp{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -6400px no-repeat;}.ygtvtph{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -7200px no-repeat;}.ygtvln{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -1600px no-repeat;}.ygtvlm{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 0px no-repeat;}.ygtvlmh{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -800px no-repeat;}.ygtvlp{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -2400px no-repeat;}.ygtvlph{width:18px;height:22px;cursor:pointer;background:url(treeview-sprite.gif) 0 -3200px !
 no-repeat;}.ygtvloading{width:18px;height:22px;background:url(treeview-loading.gif) 0 0 no-repeat;}.ygtvdepthcell{width:18px;height:22px;background:url(treeview-sprite.gif) 0 -8000px no-repeat;}.ygtvblankdepthcell{width:18px;height:22px;}.ygtvitem{}.ygtvchildren{*zoom:1;}.ygtvlabel,.ygtvlabel:link,.ygtvlabel:visited,.ygtvlabel:hover{margin-left:2px;text-decoration:none;background-color:white;}.ygtvspacer{height:22px;width:12px;}

Modified: trunk/root/static/yui/treeview/assets/treeview-core.css
===================================================================
--- trunk/root/static/yui/treeview/assets/treeview-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/treeview/assets/treeview-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,6 +1,6 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */

Modified: trunk/root/static/yui/treeview/assets/treeview-menu.css
===================================================================
--- trunk/root/static/yui/treeview/assets/treeview-menu.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/treeview/assets/treeview-menu.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* first or middle sibling, no children */
 .ygtvtn {
@@ -88,6 +88,13 @@
 .ygtvchildren {  }  
 * html .ygtvchildren { height:2%; }  
 
+.ygtvitem  table{
+    margin-bottom:0;
+}
+.ygtvitem  td {
+    border:none;padding:0;
+} 
+
 /* the style of the text label in ygTextNode */
 .ygtvlabel, .ygtvlabel:link, .ygtvlabel:visited, .ygtvlabel:hover { 
 	margin-left:2px;

Modified: trunk/root/static/yui/treeview/assets/treeview.css
===================================================================
--- trunk/root/static/yui/treeview/assets/treeview.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/treeview/assets/treeview.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,10 +1,11 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /* first or middle sibling, no children */
+
 .ygtvtn {
 	width:18px; height:22px; 
 	background: url(sprite-orig.gif) 0 -5600px no-repeat; 
@@ -89,6 +90,14 @@
 /* the style of the div around each node */
 .ygtvitem { }  
 
+
+.ygtvitem  table{
+    margin-bottom:0;
+}
+.ygtvitem  td {
+    border:none;padding:0;
+} 
+
 /* the style of the div around each node's collection of children */
 .ygtvchildren {  }  
 * html .ygtvchildren { height:2%; }  

Modified: trunk/root/static/yui/treeview/treeview-debug.js
===================================================================
--- trunk/root/static/yui/treeview/treeview-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/treeview/treeview-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The treeview widget is a generic tree building tool.
@@ -777,7 +777,8 @@
  * @class Node
  * @uses YAHOO.util.EventProvider
  * @param oData {object} a string or object containing the data that will
- * be used to render this node
+ * be used to render this node, and any custom attributes that should be
+ * stored with the node (which is available in noderef.data).
  * @param oParent {Node} this node's parent node
  * @param expanded {boolean} the initial expanded/collapsed state
  * @constructor
@@ -952,6 +953,17 @@
     nowrap: false,
 
     /**
+     * If true, the node will alway be rendered as a leaf node.  This can be
+     * used to override the presentation when dynamically loading the entire
+     * tree.  Setting this to true also disables the dynamic load call for the
+     * node.
+     * @property isLeaf
+     * @type boolean
+     * @default false
+     */
+    isLeaf: false,
+
+    /**
      * The node type
      * @property _type
      * @private
@@ -1538,14 +1550,19 @@
      * @return {boolean} true if this node's children are to be loaded dynamically
      */
     isDynamic: function() { 
-        var lazy = (!this.isRoot() && (this._dynLoad || this.tree.root._dynLoad));
-        // this.logger.log("isDynamic: " + lazy);
-        return lazy;
+        if (this.isLeaf) {
+            return false;
+        } else {
+            return (!this.isRoot() && (this._dynLoad || this.tree.root._dynLoad));
+            // this.logger.log("isDynamic: " + lazy);
+            // return lazy;
+        }
     },
 
     /**
      * Returns the current icon mode.  This refers to the way childless dynamic
-     * load nodes appear.
+     * load nodes appear (this comes into play only after the initial dynamic
+     * load request produced no children).
      * @method getIconMode
      * @return {int} 0 for collapse style, 1 for leaf node style
      */
@@ -1566,8 +1583,12 @@
      * checking for this condition.
      */
     hasChildren: function(checkForLazyLoad) { 
-        return ( this.children.length > 0 || 
-                (checkForLazyLoad && this.isDynamic() && !this.dynamicLoadComplete) );
+        if (this.isLeaf) {
+            return false;
+        } else {
+            return ( this.children.length > 0 || 
+(checkForLazyLoad && this.isDynamic() && !this.dynamicLoadComplete) );
+        }
     },
 
     /**
@@ -1809,7 +1830,26 @@
  * @extends YAHOO.widget.Node
  * @constructor
  * @param oData {object} a string or object containing the data that will
- * be used to render this node
+ * be used to render this node.
+ * Valid properties: 
+ * <dl>
+ *   <dt>label</dt>
+ *   <dd>The text for the node's label</dd>
+ *   <dt>title</dt>
+ *   <dd>The title attribute for the label anchor</dd>
+ *   <dt>title</dt>
+ *   <dd>The title attribute for the label anchor</dd>
+ *   <dt>href</dt>
+ *   <dd>The href for the node's label.  By default it is set to
+ *   expand/collapse the node.</dd>
+ *   <dt>target</dt>
+ *   <dd>The target attribute for the label anchor</dd>
+ *   <dt>style</dt>
+ *   <dd>A CSS class to apply to the label anchor</dd>
+ * </dl>
+ * All other attributes are made available in noderef.data, which
+ * can be used to store custom attributes.  TreeView.getNode(s)ByProperty
+ * can be used to retreive a node by one of the attributes.
  * @param oParent {YAHOO.widget.Node} this node's parent node
  * @param expanded {boolean} the initial expanded/collapsed state
  */
@@ -2062,11 +2102,22 @@
  * @extends YAHOO.widget.Node
  * @constructor
  * @param oData {object} a string or object containing the data that will
- * be used to render this node
+ * be used to render this node.  
+ * Valid configuration properties: 
+ * <dl>
+ *   <dt>html</dt>
+ *   <dd>The html content for the node</dd>
+ * </dl>
+ * All other attributes are made available in noderef.data, which
+ * can be used to store custom attributes.  TreeView.getNode(s)ByProperty
+ * can be used to retreive a node by one of the attributes.
  * @param oParent {YAHOO.widget.Node} this node's parent node
  * @param expanded {boolean} the initial expanded/collapsed state
  * @param hasIcon {boolean} specifies whether or not leaf nodes should
- * have an icon
+ * be rendered with or without a horizontal line line icon. If the icon
+ * is not displayed, the content fills the space it would have occupied.
+ * This option operates independently of the leaf node presentation logic
+ * for dynamic nodes.
  */
 YAHOO.widget.HTMLNode = function(oData, oParent, expanded, hasIcon) {
     if (oData) { 
@@ -2094,10 +2145,10 @@
 
     /**
      * The HTML content to use for this node's display
-     * @property content
+     * @property html
      * @type string
      */
-    content: null,
+    html: null,
 
     /**
      * Sets up the node label
@@ -2195,7 +2246,26 @@
  * @class MenuNode
  * @extends YAHOO.widget.TextNode
  * @param oData {object} a string or object containing the data that will
- * be used to render this node
+ * be used to render this node.
+ * Valid properties: 
+ * <dl>
+ *   <dt>label</dt>
+ *   <dd>The text for the node's label</dd>
+ *   <dt>title</dt>
+ *   <dd>The title attribute for the label anchor</dd>
+ *   <dt>title</dt>
+ *   <dd>The title attribute for the label anchor</dd>
+ *   <dt>href</dt>
+ *   <dd>The href for the node's label.  By default it is set to
+ *   expand/collapse the node.</dd>
+ *   <dt>target</dt>
+ *   <dd>The target attribute for the label anchor</dd>
+ *   <dt>style</dt>
+ *   <dd>A CSS class to apply to the label anchor</dd>
+ * </dl>
+ * All other attributes are made available in noderef.data, which
+ * can be used to store custom attributes.  TreeView.getNode(s)ByProperty
+ * can be used to retreive a node by one of the attributes.
  * @param oParent {YAHOO.widget.Node} this node's parent node
  * @param expanded {boolean} the initial expanded/collapsed state
  * @constructor
@@ -2397,4 +2467,4 @@
     }
 };
 
-YAHOO.register("treeview", YAHOO.widget.TreeView, {version: "2.4.1", build: "742"});
+YAHOO.register("treeview", YAHOO.widget.TreeView, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/treeview/treeview-min.js
===================================================================
--- trunk/root/static/yui/treeview/treeview-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/treeview/treeview-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,10 +1,10 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-YAHOO.widget.TreeView=function(A){if(A){this.init(A);}};YAHOO.widget.TreeView.prototype={id:null,_el:null,_nodes:null,locked:false,_expandAnim:null,_collapseAnim:null,_animCount:0,maxAnim:2,setExpandAnim:function(A){this._expandAnim=(YAHOO.widget.TVAnim.isValid(A))?A:null;},setCollapseAnim:function(A){this._collapseAnim=(YAHOO.widget.TVAnim.isValid(A))?A:null;},animateExpand:function(C,D){if(this._expandAnim&&this._animCount<this.maxAnim){var A=this;var B=YAHOO.widget.TVAnim.getAnim(this._expandAnim,C,function(){A.expandComplete(D);});if(B){++this._animCount;this.fireEvent("animStart",{"node":D,"type":"expand"});B.animate();}return true;}return false;},animateCollapse:function(C,D){if(this._collapseAnim&&this._animCount<this.maxAnim){var A=this;var B=YAHOO.widget.TVAnim.getAnim(this._collapseAnim,C,function(){A.collapseComplete(D);});if(B){++this._animCount;this.fireEvent("animStart",{"node":D,"type":"collapse"});B.animate();}return true;}return false;},expandComplete:funct!
 ion(A){--this._animCount;this.fireEvent("animComplete",{"node":A,"type":"expand"});},collapseComplete:function(A){--this._animCount;this.fireEvent("animComplete",{"node":A,"type":"collapse"});},init:function(B){this.id=B;if("string"!==typeof B){this._el=B;this.id=this.generateId(B);}this.createEvent("animStart",this);this.createEvent("animComplete",this);this.createEvent("collapse",this);this.createEvent("collapseComplete",this);this.createEvent("expand",this);this.createEvent("expandComplete",this);this._nodes=[];YAHOO.widget.TreeView.trees[this.id]=this;this.root=new YAHOO.widget.RootNode(this);var A=YAHOO.widget.LogWriter;},draw:function(){var A=this.root.getHtml();this.getEl().innerHTML=A;this.firstDraw=false;},getEl:function(){if(!this._el){this._el=document.getElementById(this.id);}return this._el;},regNode:function(A){this._nodes[A.index]=A;},getRoot:function(){return this.root;},setDynamicLoad:function(A,B){this.root.setDynamicLoad(A,B);},expandAll:function(){if(!th!
 is.locked){this.root.expandAll();}},collapseAll:function(){if(!
 !this.lo
cked){this.root.collapseAll();}},getNodeByIndex:function(B){var A=this._nodes[B];return(A)?A:null;},getNodeByProperty:function(C,B){for(var A in this._nodes){var D=this._nodes[A];if(D.data&&B==D.data[C]){return D;}}return null;},getNodesByProperty:function(D,C){var A=[];for(var B in this._nodes){var E=this._nodes[B];if(E.data&&C==E.data[D]){A.push(E);}}return(A.length)?A:null;},getNodeByElement:function(C){var D=C,A,B=/ygtv([^\d]*)(.*)/;do{if(D&&D.id){A=D.id.match(B);if(A&&A[2]){return this.getNodeByIndex(A[2]);}}D=D.parentNode;if(!D||!D.tagName){break;}}while(D.id!==this.id&&D.tagName.toLowerCase()!=="body");return null;},removeNode:function(B,A){if(B.isRoot()){return false;}var C=B.parent;if(C.parent){C=C.parent;}this._deleteNode(B);if(A&&C&&C.childrenRendered){C.refresh();}return true;},_removeChildren_animComplete:function(A){this.unsubscribe(this._removeChildren_animComplete);this.removeChildren(A.node);},removeChildren:function(A){if(A.expanded){if(this._collapseAnim){!
 this.subscribe("animComplete",this._removeChildren_animComplete,this,true);YAHOO.widget.Node.prototype.collapse.call(A);return ;}A.collapse();}while(A.children.length){this._deleteNode(A.children[0]);}if(A.isRoot()){YAHOO.widget.Node.prototype.expand.call(A);}A.childrenRendered=false;A.dynamicLoadComplete=false;A.updateIcon();},_deleteNode:function(A){this.removeChildren(A);this.popNode(A);},popNode:function(D){var E=D.parent;var B=[];for(var C=0,A=E.children.length;C<A;++C){if(E.children[C]!=D){B[B.length]=E.children[C];}}E.children=B;E.childrenRendered=false;if(D.previousSibling){D.previousSibling.nextSibling=D.nextSibling;}if(D.nextSibling){D.nextSibling.previousSibling=D.previousSibling;}D.parent=null;D.previousSibling=null;D.nextSibling=null;D.tree=null;delete this._nodes[D.index];},toString:function(){return"TreeView "+this.id;},generateId:function(A){var B=A.id;if(!B){B="yui-tv-auto-id-"+YAHOO.widget.TreeView.counter;++YAHOO.widget.TreeView.counter;}return B;},onExpa!
 nd:function(A){},onCollapse:function(A){}};YAHOO.augment(YAHOO!
 .widget.
TreeView,YAHOO.util.EventProvider);YAHOO.widget.TreeView.nodeCount=0;YAHOO.widget.TreeView.trees=[];YAHOO.widget.TreeView.counter=0;YAHOO.widget.TreeView.getTree=function(B){var A=YAHOO.widget.TreeView.trees[B];return(A)?A:null;};YAHOO.widget.TreeView.getNode=function(B,C){var A=YAHOO.widget.TreeView.getTree(B);return(A)?A.getNodeByIndex(C):null;};YAHOO.widget.TreeView.addHandler=function(B,C,A){if(B.addEventListener){B.addEventListener(C,A,false);}else{if(B.attachEvent){B.attachEvent("on"+C,A);}}};YAHOO.widget.TreeView.removeHandler=function(B,C,A){if(B.removeEventListener){B.removeEventListener(C,A,false);}else{if(B.detachEvent){B.detachEvent("on"+C,A);}}};YAHOO.widget.TreeView.preload=function(F,E){E=E||"ygtv";var C=["tn","tm","tmh","tp","tph","ln","lm","lmh","lp","lph","loading"];var G=[];for(var A=1;A<C.length;A=A+1){G[G.length]="<span class=\""+E+C[A]+"\"> </span>";}var D=document.createElement("div");var B=D.style;B.className=E+C[0];B.position="absolute";B.height!
 ="1px";B.width="1px";B.top="-1000px";B.left="-1000px";D.innerHTML=G.join("");document.body.appendChild(D);YAHOO.widget.TreeView.removeHandler(window,"load",YAHOO.widget.TreeView.preload);};YAHOO.widget.TreeView.addHandler(window,"load",YAHOO.widget.TreeView.preload);YAHOO.widget.Node=function(C,B,A){if(C){this.init(C,B,A);}};YAHOO.widget.Node.prototype={index:0,children:null,tree:null,data:null,parent:null,depth:-1,href:null,target:"_self",expanded:false,multiExpand:true,renderHidden:false,childrenRendered:false,dynamicLoadComplete:false,previousSibling:null,nextSibling:null,_dynLoad:false,dataLoader:null,isLoading:false,hasIcon:true,iconMode:0,nowrap:false,_type:"Node",init:function(C,B,A){this.data=C;this.children=[];this.index=YAHOO.widget.TreeView.nodeCount;++YAHOO.widget.TreeView.nodeCount;this.expanded=A;this.createEvent("parentChange",this);if(B){B.appendChild(this);}},applyParent:function(B){if(!B){return false;
-}this.tree=B.tree;this.parent=B;this.depth=B.depth+1;if(!this.href){this.href="javascript:"+this.getToggleLink();}this.tree.regNode(this);B.childrenRendered=false;for(var C=0,A=this.children.length;C<A;++C){this.children[C].applyParent(this);}this.fireEvent("parentChange");return true;},appendChild:function(B){if(this.hasChildren()){var A=this.children[this.children.length-1];A.nextSibling=B;B.previousSibling=A;}this.children[this.children.length]=B;B.applyParent(this);if(this.childrenRendered&&this.expanded){this.getChildrenEl().style.display="";}return B;},appendTo:function(A){return A.appendChild(this);},insertBefore:function(A){var C=A.parent;if(C){if(this.tree){this.tree.popNode(this);}var B=A.isChildOf(C);C.children.splice(B,0,this);if(A.previousSibling){A.previousSibling.nextSibling=this;}this.previousSibling=A.previousSibling;this.nextSibling=A;A.previousSibling=this;this.applyParent(C);}return this;},insertAfter:function(A){var C=A.parent;if(C){if(this.tree){this.t!
 ree.popNode(this);}var B=A.isChildOf(C);if(!A.nextSibling){this.nextSibling=null;return this.appendTo(C);}C.children.splice(B+1,0,this);A.nextSibling.previousSibling=this;this.previousSibling=A;this.nextSibling=A.nextSibling;A.nextSibling=this;this.applyParent(C);}return this;},isChildOf:function(B){if(B&&B.children){for(var C=0,A=B.children.length;C<A;++C){if(B.children[C]===this){return C;}}}return -1;},getSiblings:function(){return this.parent.children;},showChildren:function(){if(!this.tree.animateExpand(this.getChildrenEl(),this)){if(this.hasChildren()){this.getChildrenEl().style.display="";}}},hideChildren:function(){if(!this.tree.animateCollapse(this.getChildrenEl(),this)){this.getChildrenEl().style.display="none";}},getElId:function(){return"ygtv"+this.index;},getChildrenElId:function(){return"ygtvc"+this.index;},getToggleElId:function(){return"ygtvt"+this.index;},getEl:function(){return document.getElementById(this.getElId());},getChildrenEl:function(){return docum!
 ent.getElementById(this.getChildrenElId());},getToggleEl:funct!
 ion(){re
turn document.getElementById(this.getToggleElId());},getToggleLink:function(){return"YAHOO.widget.TreeView.getNode('"+this.tree.id+"',"+this.index+").toggle()";},collapse:function(){if(!this.expanded){return ;}var A=this.tree.onCollapse(this);if(false===A){return ;}A=this.tree.fireEvent("collapse",this);if(false===A){return ;}if(!this.getEl()){this.expanded=false;}else{this.hideChildren();this.expanded=false;this.updateIcon();}A=this.tree.fireEvent("collapseComplete",this);},expand:function(C){if(this.expanded&&!C){return ;}var A=true;if(!C){A=this.tree.onExpand(this);if(false===A){return ;}A=this.tree.fireEvent("expand",this);}if(false===A){return ;}if(!this.getEl()){this.expanded=true;return ;}if(!this.childrenRendered){this.getChildrenEl().innerHTML=this.renderChildren();}else{}this.expanded=true;this.updateIcon();if(this.isLoading){this.expanded=false;return ;}if(!this.multiExpand){var D=this.getSiblings();for(var B=0;B<D.length;++B){if(D[B]!=this&&D[B].expanded){D[B].co!
 llapse();}}}this.showChildren();A=this.tree.fireEvent("expandComplete",this);},updateIcon:function(){if(this.hasIcon){var A=this.getToggleEl();if(A){A.className=this.getStyle();}}},getStyle:function(){if(this.isLoading){return"ygtvloading";}else{var B=(this.nextSibling)?"t":"l";var A="n";if(this.hasChildren(true)||(this.isDynamic()&&!this.getIconMode())){A=(this.expanded)?"m":"p";}return"ygtv"+B+A;}},getHoverStyle:function(){var A=this.getStyle();if(this.hasChildren(true)&&!this.isLoading){A+="h";}return A;},expandAll:function(){for(var A=0;A<this.children.length;++A){var B=this.children[A];if(B.isDynamic()){alert("Not supported (lazy load + expand all)");break;}else{if(!B.multiExpand){alert("Not supported (no multi-expand + expand all)");break;}else{B.expand();B.expandAll();}}}},collapseAll:function(){for(var A=0;A<this.children.length;++A){this.children[A].collapse();this.children[A].collapseAll();}},setDynamicLoad:function(A,B){if(A){this.dataLoader=A;this._dynLoad=true;!
 }else{this.dataLoader=null;this._dynLoad=false;}if(B){this.ico!
 nMode=B;
}},isRoot:function(){return(this==this.tree.root);},isDynamic:function(){var A=(!this.isRoot()&&(this._dynLoad||this.tree.root._dynLoad));return A;},getIconMode:function(){return(this.iconMode||this.tree.root.iconMode);},hasChildren:function(A){return(this.children.length>0||(A&&this.isDynamic()&&!this.dynamicLoadComplete));},toggle:function(){if(!this.tree.locked&&(this.hasChildren(true)||this.isDynamic())){if(this.expanded){this.collapse();}else{this.expand();}}},getHtml:function(){this.childrenRendered=false;var A=[];A[A.length]="<div class=\"ygtvitem\" id=\""+this.getElId()+"\">";A[A.length]=this.getNodeHtml();A[A.length]=this.getChildrenHtml();A[A.length]="</div>";return A.join("");},getChildrenHtml:function(){var A=[];A[A.length]="<div class=\"ygtvchildren\"";A[A.length]=" id=\""+this.getChildrenElId()+"\"";if(!this.expanded||!this.hasChildren()){A[A.length]=" style=\"display:none;\"";}A[A.length]=">";if((this.hasChildren(true)&&this.expanded)||(this.renderHidden&&!thi!
 s.isDynamic())){A[A.length]=this.renderChildren();}A[A.length]="</div>";return A.join("");},renderChildren:function(){var A=this;if(this.isDynamic()&&!this.dynamicLoadComplete){this.isLoading=true;this.tree.locked=true;if(this.dataLoader){setTimeout(function(){A.dataLoader(A,function(){A.loadComplete();});},10);}else{if(this.tree.root.dataLoader){setTimeout(function(){A.tree.root.dataLoader(A,function(){A.loadComplete();});},10);}else{return"Error: data loader not found or not specified.";}}return"";}else{return this.completeRender();}},completeRender:function(){var B=[];for(var A=0;A<this.children.length;++A){B[B.length]=this.children[A].getHtml();}this.childrenRendered=true;return B.join("");},loadComplete:function(){this.getChildrenEl().innerHTML=this.completeRender();this.dynamicLoadComplete=true;this.isLoading=false;this.expand(true);this.tree.locked=false;},getAncestor:function(B){if(B>=this.depth||B<0){return null;
-}var A=this.parent;while(A.depth>B){A=A.parent;}return A;},getDepthStyle:function(A){return(this.getAncestor(A).nextSibling)?"ygtvdepthcell":"ygtvblankdepthcell";},getNodeHtml:function(){return"";},refresh:function(){this.getChildrenEl().innerHTML=this.completeRender();if(this.hasIcon){var A=this.getToggleEl();if(A){A.className=this.getStyle();}}},toString:function(){return"Node ("+this.index+")";}};YAHOO.augment(YAHOO.widget.Node,YAHOO.util.EventProvider);YAHOO.widget.TextNode=function(C,B,A){if(C){this.init(C,B,A);this.setUpLabel(C);}};YAHOO.extend(YAHOO.widget.TextNode,YAHOO.widget.Node,{labelStyle:"ygtvlabel",labelElId:null,label:null,textNodeParentChange:function(){if(this.tree&&!this.tree.hasEvent("labelClick")){this.tree.createEvent("labelClick",this.tree);}},setUpLabel:function(A){this.textNodeParentChange();this.subscribe("parentChange",this.textNodeParentChange);if(typeof A=="string"){A={label:A};}this.label=A.label;this.data.label=A.label;if(A.href){this.href=enc!
 odeURI(A.href);}if(A.target){this.target=A.target;}if(A.style){this.labelStyle=A.style;}if(A.title){this.title=A.title;}this.labelElId="ygtvlabelel"+this.index;},getLabelEl:function(){return document.getElementById(this.labelElId);},getNodeHtml:function(){var C=[];C[C.length]="<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">";C[C.length]="<tr>";for(var A=0;A<this.depth;++A){C[C.length]="<td class=\""+this.getDepthStyle(A)+"\"><div class=\"ygtvspacer\"></div></td>";}var B="YAHOO.widget.TreeView.getNode('"+this.tree.id+"',"+this.index+")";C[C.length]="<td";C[C.length]=" id=\""+this.getToggleElId()+"\"";C[C.length]=" class=\""+this.getStyle()+"\"";if(this.hasChildren(true)){C[C.length]=" onmouseover=\"this.className=";C[C.length]=B+".getHoverStyle()\"";C[C.length]=" onmouseout=\"this.className=";C[C.length]=B+".getStyle()\"";}C[C.length]=" onclick=\"javascript:"+this.getToggleLink()+"\">";C[C.length]="<div class=\"ygtvspacer\">";C[C.length]="</div>";C[C.length]="</td>"!
 ;C[C.length]="<td ";C[C.length]=(this.nowrap)?" nowrap=\"nowra!
 p\" ":""
;C[C.length]=" >";C[C.length]="<a";C[C.length]=" id=\""+this.labelElId+"\"";if(this.title){C[C.length]=" title=\""+this.title+"\"";}C[C.length]=" class=\""+this.labelStyle+"\"";C[C.length]=" href=\""+this.href+"\"";C[C.length]=" target=\""+this.target+"\"";C[C.length]=" onclick=\"return "+B+".onLabelClick("+B+")\"";if(this.hasChildren(true)){C[C.length]=" onmouseover=\"document.getElementById('";C[C.length]=this.getToggleElId()+"').className=";C[C.length]=B+".getHoverStyle()\"";C[C.length]=" onmouseout=\"document.getElementById('";C[C.length]=this.getToggleElId()+"').className=";C[C.length]=B+".getStyle()\"";}C[C.length]=" >";C[C.length]=this.label;C[C.length]="</a>";C[C.length]="</td>";C[C.length]="</tr>";C[C.length]="</table>";return C.join("");},onLabelClick:function(A){return A.tree.fireEvent("labelClick",A);},toString:function(){return"TextNode ("+this.index+") "+this.label;}});YAHOO.widget.RootNode=function(A){this.init(null,null,true);this.tree=A;};YAHOO.extend(YAHOO.!
 widget.RootNode,YAHOO.widget.Node,{getNodeHtml:function(){return"";},toString:function(){return"RootNode";},loadComplete:function(){this.tree.draw();},collapse:function(){},expand:function(){}});YAHOO.widget.HTMLNode=function(D,C,B,A){if(D){this.init(D,C,B);this.initContent(D,A);}};YAHOO.extend(YAHOO.widget.HTMLNode,YAHOO.widget.Node,{contentStyle:"ygtvhtml",contentElId:null,content:null,initContent:function(B,A){this.setHtml(B);this.contentElId="ygtvcontentel"+this.index;this.hasIcon=A;},setHtml:function(B){this.data=B;this.html=(typeof B==="string")?B:B.html;var A=this.getContentEl();if(A){A.innerHTML=this.html;}},getContentEl:function(){return document.getElementById(this.contentElId);},getNodeHtml:function(){var B=[];B[B.length]="<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">";B[B.length]="<tr>";for(var A=0;A<this.depth;++A){B[B.length]="<td class=\""+this.getDepthStyle(A)+"\"><div class=\"ygtvspacer\"></div></td>";}if(this.hasIcon){B[B.length]="<td";B[B.lengt!
 h]=" id=\""+this.getToggleElId()+"\"";B[B.length]=" class=\""+!
 this.get
Style()+"\"";B[B.length]=" onclick=\"javascript:"+this.getToggleLink()+"\"";if(this.hasChildren(true)){B[B.length]=" onmouseover=\"this.className=";B[B.length]="YAHOO.widget.TreeView.getNode('";B[B.length]=this.tree.id+"',"+this.index+").getHoverStyle()\"";B[B.length]=" onmouseout=\"this.className=";B[B.length]="YAHOO.widget.TreeView.getNode('";B[B.length]=this.tree.id+"',"+this.index+").getStyle()\"";}B[B.length]="><div class=\"ygtvspacer\"></div></td>";}B[B.length]="<td";B[B.length]=" id=\""+this.contentElId+"\"";B[B.length]=" class=\""+this.contentStyle+"\"";B[B.length]=(this.nowrap)?" nowrap=\"nowrap\" ":"";B[B.length]=" >";B[B.length]=this.html;B[B.length]="</td>";B[B.length]="</tr>";B[B.length]="</table>";return B.join("");},toString:function(){return"HTMLNode ("+this.index+")";}});YAHOO.widget.MenuNode=function(C,B,A){if(C){this.init(C,B,A);this.setUpLabel(C);}this.multiExpand=false;};YAHOO.extend(YAHOO.widget.MenuNode,YAHOO.widget.TextNode,{toString:function(){return!
 "MenuNode ("+this.index+") "+this.label;}});YAHOO.widget.TVAnim=function(){return{FADE_IN:"TVFadeIn",FADE_OUT:"TVFadeOut",getAnim:function(B,A,C){if(YAHOO.widget[B]){return new YAHOO.widget[B](A,C);}else{return null;}},isValid:function(A){return(YAHOO.widget[A]);}};}();YAHOO.widget.TVFadeIn=function(A,B){this.el=A;this.callback=B;};YAHOO.widget.TVFadeIn.prototype={animate:function(){var D=this;var C=this.el.style;C.opacity=0.1;C.filter="alpha(opacity=10)";C.display="";var B=0.4;var A=new YAHOO.util.Anim(this.el,{opacity:{from:0.1,to:1,unit:""}},B);A.onComplete.subscribe(function(){D.onComplete();});A.animate();},onComplete:function(){this.callback();},toString:function(){return"TVFadeIn";}};YAHOO.widget.TVFadeOut=function(A,B){this.el=A;this.callback=B;};YAHOO.widget.TVFadeOut.prototype={animate:function(){var C=this;var B=0.4;var A=new YAHOO.util.Anim(this.el,{opacity:{from:1,to:0.1,unit:""}},B);A.onComplete.subscribe(function(){C.onComplete();
-});A.animate();},onComplete:function(){var A=this.el.style;A.display="none";A.filter="alpha(opacity=100)";this.callback();},toString:function(){return"TVFadeOut";}};YAHOO.register("treeview",YAHOO.widget.TreeView,{version:"2.4.1",build:"742"});
\ No newline at end of file
+YAHOO.widget.TreeView=function(A){if(A){this.init(A);}};YAHOO.widget.TreeView.prototype={id:null,_el:null,_nodes:null,locked:false,_expandAnim:null,_collapseAnim:null,_animCount:0,maxAnim:2,setExpandAnim:function(A){this._expandAnim=(YAHOO.widget.TVAnim.isValid(A))?A:null;},setCollapseAnim:function(A){this._collapseAnim=(YAHOO.widget.TVAnim.isValid(A))?A:null;},animateExpand:function(C,D){if(this._expandAnim&&this._animCount<this.maxAnim){var A=this;var B=YAHOO.widget.TVAnim.getAnim(this._expandAnim,C,function(){A.expandComplete(D);});if(B){++this._animCount;this.fireEvent("animStart",{"node":D,"type":"expand"});B.animate();}return true;}return false;},animateCollapse:function(C,D){if(this._collapseAnim&&this._animCount<this.maxAnim){var A=this;var B=YAHOO.widget.TVAnim.getAnim(this._collapseAnim,C,function(){A.collapseComplete(D);});if(B){++this._animCount;this.fireEvent("animStart",{"node":D,"type":"collapse"});B.animate();}return true;}return false;},expandComplete:funct!
 ion(A){--this._animCount;this.fireEvent("animComplete",{"node":A,"type":"expand"});},collapseComplete:function(A){--this._animCount;this.fireEvent("animComplete",{"node":A,"type":"collapse"});},init:function(B){this.id=B;if("string"!==typeof B){this._el=B;this.id=this.generateId(B);}this.createEvent("animStart",this);this.createEvent("animComplete",this);this.createEvent("collapse",this);this.createEvent("collapseComplete",this);this.createEvent("expand",this);this.createEvent("expandComplete",this);this._nodes=[];YAHOO.widget.TreeView.trees[this.id]=this;this.root=new YAHOO.widget.RootNode(this);var A=YAHOO.widget.LogWriter;},draw:function(){var A=this.root.getHtml();this.getEl().innerHTML=A;this.firstDraw=false;},getEl:function(){if(!this._el){this._el=document.getElementById(this.id);}return this._el;},regNode:function(A){this._nodes[A.index]=A;},getRoot:function(){return this.root;},setDynamicLoad:function(A,B){this.root.setDynamicLoad(A,B);},expandAll:function(){if(!th!
 is.locked){this.root.expandAll();}},collapseAll:function(){if(!
 !this.lo
cked){this.root.collapseAll();}},getNodeByIndex:function(B){var A=this._nodes[B];return(A)?A:null;},getNodeByProperty:function(C,B){for(var A in this._nodes){var D=this._nodes[A];if(D.data&&B==D.data[C]){return D;}}return null;},getNodesByProperty:function(D,C){var A=[];for(var B in this._nodes){var E=this._nodes[B];if(E.data&&C==E.data[D]){A.push(E);}}return(A.length)?A:null;},getNodeByElement:function(C){var D=C,A,B=/ygtv([^\d]*)(.*)/;do{if(D&&D.id){A=D.id.match(B);if(A&&A[2]){return this.getNodeByIndex(A[2]);}}D=D.parentNode;if(!D||!D.tagName){break;}}while(D.id!==this.id&&D.tagName.toLowerCase()!=="body");return null;},removeNode:function(B,A){if(B.isRoot()){return false;}var C=B.parent;if(C.parent){C=C.parent;}this._deleteNode(B);if(A&&C&&C.childrenRendered){C.refresh();}return true;},_removeChildren_animComplete:function(A){this.unsubscribe(this._removeChildren_animComplete);this.removeChildren(A.node);},removeChildren:function(A){if(A.expanded){if(this._collapseAnim){!
 this.subscribe("animComplete",this._removeChildren_animComplete,this,true);YAHOO.widget.Node.prototype.collapse.call(A);return ;}A.collapse();}while(A.children.length){this._deleteNode(A.children[0]);}if(A.isRoot()){YAHOO.widget.Node.prototype.expand.call(A);}A.childrenRendered=false;A.dynamicLoadComplete=false;A.updateIcon();},_deleteNode:function(A){this.removeChildren(A);this.popNode(A);},popNode:function(D){var E=D.parent;var B=[];for(var C=0,A=E.children.length;C<A;++C){if(E.children[C]!=D){B[B.length]=E.children[C];}}E.children=B;E.childrenRendered=false;if(D.previousSibling){D.previousSibling.nextSibling=D.nextSibling;}if(D.nextSibling){D.nextSibling.previousSibling=D.previousSibling;}D.parent=null;D.previousSibling=null;D.nextSibling=null;D.tree=null;delete this._nodes[D.index];},toString:function(){return"TreeView "+this.id;},generateId:function(A){var B=A.id;if(!B){B="yui-tv-auto-id-"+YAHOO.widget.TreeView.counter;++YAHOO.widget.TreeView.counter;}return B;},onExpa!
 nd:function(A){},onCollapse:function(A){}};YAHOO.augment(YAHOO!
 .widget.
TreeView,YAHOO.util.EventProvider);YAHOO.widget.TreeView.nodeCount=0;YAHOO.widget.TreeView.trees=[];YAHOO.widget.TreeView.counter=0;YAHOO.widget.TreeView.getTree=function(B){var A=YAHOO.widget.TreeView.trees[B];return(A)?A:null;};YAHOO.widget.TreeView.getNode=function(B,C){var A=YAHOO.widget.TreeView.getTree(B);return(A)?A.getNodeByIndex(C):null;};YAHOO.widget.TreeView.addHandler=function(B,C,A){if(B.addEventListener){B.addEventListener(C,A,false);}else{if(B.attachEvent){B.attachEvent("on"+C,A);}}};YAHOO.widget.TreeView.removeHandler=function(B,C,A){if(B.removeEventListener){B.removeEventListener(C,A,false);}else{if(B.detachEvent){B.detachEvent("on"+C,A);}}};YAHOO.widget.TreeView.preload=function(F,E){E=E||"ygtv";var C=["tn","tm","tmh","tp","tph","ln","lm","lmh","lp","lph","loading"];var G=[];for(var A=1;A<C.length;A=A+1){G[G.length]='<span class="'+E+C[A]+'"> </span>';}var D=document.createElement("div");var B=D.style;B.className=E+C[0];B.position="absolute";B.height="!
 1px";B.width="1px";B.top="-1000px";B.left="-1000px";D.innerHTML=G.join("");document.body.appendChild(D);YAHOO.widget.TreeView.removeHandler(window,"load",YAHOO.widget.TreeView.preload);};YAHOO.widget.TreeView.addHandler(window,"load",YAHOO.widget.TreeView.preload);YAHOO.widget.Node=function(C,B,A){if(C){this.init(C,B,A);}};YAHOO.widget.Node.prototype={index:0,children:null,tree:null,data:null,parent:null,depth:-1,href:null,target:"_self",expanded:false,multiExpand:true,renderHidden:false,childrenRendered:false,dynamicLoadComplete:false,previousSibling:null,nextSibling:null,_dynLoad:false,dataLoader:null,isLoading:false,hasIcon:true,iconMode:0,nowrap:false,isLeaf:false,_type:"Node",init:function(C,B,A){this.data=C;this.children=[];this.index=YAHOO.widget.TreeView.nodeCount;++YAHOO.widget.TreeView.nodeCount;this.expanded=A;this.createEvent("parentChange",this);if(B){B.appendChild(this);}},applyParent:function(B){if(!B){return false;
+}this.tree=B.tree;this.parent=B;this.depth=B.depth+1;if(!this.href){this.href="javascript:"+this.getToggleLink();}this.tree.regNode(this);B.childrenRendered=false;for(var C=0,A=this.children.length;C<A;++C){this.children[C].applyParent(this);}this.fireEvent("parentChange");return true;},appendChild:function(B){if(this.hasChildren()){var A=this.children[this.children.length-1];A.nextSibling=B;B.previousSibling=A;}this.children[this.children.length]=B;B.applyParent(this);if(this.childrenRendered&&this.expanded){this.getChildrenEl().style.display="";}return B;},appendTo:function(A){return A.appendChild(this);},insertBefore:function(A){var C=A.parent;if(C){if(this.tree){this.tree.popNode(this);}var B=A.isChildOf(C);C.children.splice(B,0,this);if(A.previousSibling){A.previousSibling.nextSibling=this;}this.previousSibling=A.previousSibling;this.nextSibling=A;A.previousSibling=this;this.applyParent(C);}return this;},insertAfter:function(A){var C=A.parent;if(C){if(this.tree){this.t!
 ree.popNode(this);}var B=A.isChildOf(C);if(!A.nextSibling){this.nextSibling=null;return this.appendTo(C);}C.children.splice(B+1,0,this);A.nextSibling.previousSibling=this;this.previousSibling=A;this.nextSibling=A.nextSibling;A.nextSibling=this;this.applyParent(C);}return this;},isChildOf:function(B){if(B&&B.children){for(var C=0,A=B.children.length;C<A;++C){if(B.children[C]===this){return C;}}}return -1;},getSiblings:function(){return this.parent.children;},showChildren:function(){if(!this.tree.animateExpand(this.getChildrenEl(),this)){if(this.hasChildren()){this.getChildrenEl().style.display="";}}},hideChildren:function(){if(!this.tree.animateCollapse(this.getChildrenEl(),this)){this.getChildrenEl().style.display="none";}},getElId:function(){return"ygtv"+this.index;},getChildrenElId:function(){return"ygtvc"+this.index;},getToggleElId:function(){return"ygtvt"+this.index;},getEl:function(){return document.getElementById(this.getElId());},getChildrenEl:function(){return docum!
 ent.getElementById(this.getChildrenElId());},getToggleEl:funct!
 ion(){re
turn document.getElementById(this.getToggleElId());},getToggleLink:function(){return"YAHOO.widget.TreeView.getNode('"+this.tree.id+"',"+this.index+").toggle()";},collapse:function(){if(!this.expanded){return ;}var A=this.tree.onCollapse(this);if(false===A){return ;}A=this.tree.fireEvent("collapse",this);if(false===A){return ;}if(!this.getEl()){this.expanded=false;}else{this.hideChildren();this.expanded=false;this.updateIcon();}A=this.tree.fireEvent("collapseComplete",this);},expand:function(C){if(this.expanded&&!C){return ;}var A=true;if(!C){A=this.tree.onExpand(this);if(false===A){return ;}A=this.tree.fireEvent("expand",this);}if(false===A){return ;}if(!this.getEl()){this.expanded=true;return ;}if(!this.childrenRendered){this.getChildrenEl().innerHTML=this.renderChildren();}else{}this.expanded=true;this.updateIcon();if(this.isLoading){this.expanded=false;return ;}if(!this.multiExpand){var D=this.getSiblings();for(var B=0;B<D.length;++B){if(D[B]!=this&&D[B].expanded){D[B].co!
 llapse();}}}this.showChildren();A=this.tree.fireEvent("expandComplete",this);},updateIcon:function(){if(this.hasIcon){var A=this.getToggleEl();if(A){A.className=this.getStyle();}}},getStyle:function(){if(this.isLoading){return"ygtvloading";}else{var B=(this.nextSibling)?"t":"l";var A="n";if(this.hasChildren(true)||(this.isDynamic()&&!this.getIconMode())){A=(this.expanded)?"m":"p";}return"ygtv"+B+A;}},getHoverStyle:function(){var A=this.getStyle();if(this.hasChildren(true)&&!this.isLoading){A+="h";}return A;},expandAll:function(){for(var A=0;A<this.children.length;++A){var B=this.children[A];if(B.isDynamic()){alert("Not supported (lazy load + expand all)");break;}else{if(!B.multiExpand){alert("Not supported (no multi-expand + expand all)");break;}else{B.expand();B.expandAll();}}}},collapseAll:function(){for(var A=0;A<this.children.length;++A){this.children[A].collapse();this.children[A].collapseAll();}},setDynamicLoad:function(A,B){if(A){this.dataLoader=A;this._dynLoad=true;!
 }else{this.dataLoader=null;this._dynLoad=false;}if(B){this.ico!
 nMode=B;
}},isRoot:function(){return(this==this.tree.root);},isDynamic:function(){if(this.isLeaf){return false;}else{return(!this.isRoot()&&(this._dynLoad||this.tree.root._dynLoad));}},getIconMode:function(){return(this.iconMode||this.tree.root.iconMode);},hasChildren:function(A){if(this.isLeaf){return false;}else{return(this.children.length>0||(A&&this.isDynamic()&&!this.dynamicLoadComplete));}},toggle:function(){if(!this.tree.locked&&(this.hasChildren(true)||this.isDynamic())){if(this.expanded){this.collapse();}else{this.expand();}}},getHtml:function(){this.childrenRendered=false;var A=[];A[A.length]='<div class="ygtvitem" id="'+this.getElId()+'">';A[A.length]=this.getNodeHtml();A[A.length]=this.getChildrenHtml();A[A.length]="</div>";return A.join("");},getChildrenHtml:function(){var A=[];A[A.length]='<div class="ygtvchildren"';A[A.length]=' id="'+this.getChildrenElId()+'"';if(!this.expanded||!this.hasChildren()){A[A.length]=' style="display:none;"';}A[A.length]=">";if((this.hasChi!
 ldren(true)&&this.expanded)||(this.renderHidden&&!this.isDynamic())){A[A.length]=this.renderChildren();}A[A.length]="</div>";return A.join("");},renderChildren:function(){var A=this;if(this.isDynamic()&&!this.dynamicLoadComplete){this.isLoading=true;this.tree.locked=true;if(this.dataLoader){setTimeout(function(){A.dataLoader(A,function(){A.loadComplete();});},10);}else{if(this.tree.root.dataLoader){setTimeout(function(){A.tree.root.dataLoader(A,function(){A.loadComplete();});},10);}else{return"Error: data loader not found or not specified.";}}return"";}else{return this.completeRender();}},completeRender:function(){var B=[];for(var A=0;A<this.children.length;++A){B[B.length]=this.children[A].getHtml();}this.childrenRendered=true;return B.join("");},loadComplete:function(){this.getChildrenEl().innerHTML=this.completeRender();this.dynamicLoadComplete=true;this.isLoading=false;this.expand(true);this.tree.locked=false;
+},getAncestor:function(B){if(B>=this.depth||B<0){return null;}var A=this.parent;while(A.depth>B){A=A.parent;}return A;},getDepthStyle:function(A){return(this.getAncestor(A).nextSibling)?"ygtvdepthcell":"ygtvblankdepthcell";},getNodeHtml:function(){return"";},refresh:function(){this.getChildrenEl().innerHTML=this.completeRender();if(this.hasIcon){var A=this.getToggleEl();if(A){A.className=this.getStyle();}}},toString:function(){return"Node ("+this.index+")";}};YAHOO.augment(YAHOO.widget.Node,YAHOO.util.EventProvider);YAHOO.widget.TextNode=function(C,B,A){if(C){this.init(C,B,A);this.setUpLabel(C);}};YAHOO.extend(YAHOO.widget.TextNode,YAHOO.widget.Node,{labelStyle:"ygtvlabel",labelElId:null,label:null,textNodeParentChange:function(){if(this.tree&&!this.tree.hasEvent("labelClick")){this.tree.createEvent("labelClick",this.tree);}},setUpLabel:function(A){this.textNodeParentChange();this.subscribe("parentChange",this.textNodeParentChange);if(typeof A=="string"){A={label:A};}this.l!
 abel=A.label;this.data.label=A.label;if(A.href){this.href=encodeURI(A.href);}if(A.target){this.target=A.target;}if(A.style){this.labelStyle=A.style;}if(A.title){this.title=A.title;}this.labelElId="ygtvlabelel"+this.index;},getLabelEl:function(){return document.getElementById(this.labelElId);},getNodeHtml:function(){var C=[];C[C.length]='<table border="0" cellpadding="0" cellspacing="0">';C[C.length]="<tr>";for(var A=0;A<this.depth;++A){C[C.length]='<td class="'+this.getDepthStyle(A)+'"><div class="ygtvspacer"></div></td>';}var B="YAHOO.widget.TreeView.getNode('"+this.tree.id+"',"+this.index+")";C[C.length]="<td";C[C.length]=' id="'+this.getToggleElId()+'"';C[C.length]=' class="'+this.getStyle()+'"';if(this.hasChildren(true)){C[C.length]=' onmouseover="this.className=';C[C.length]=B+'.getHoverStyle()"';C[C.length]=' onmouseout="this.className=';C[C.length]=B+'.getStyle()"';}C[C.length]=' onclick="javascript:'+this.getToggleLink()+'">';C[C.length]='<div class="ygtvspacer">';C!
 [C.length]="</div>";C[C.length]="</td>";C[C.length]="<td ";C[C!
 .length]
=(this.nowrap)?' nowrap="nowrap" ':"";C[C.length]=" >";C[C.length]="<a";C[C.length]=' id="'+this.labelElId+'"';if(this.title){C[C.length]=' title="'+this.title+'"';}C[C.length]=' class="'+this.labelStyle+'"';C[C.length]=' href="'+this.href+'"';C[C.length]=' target="'+this.target+'"';C[C.length]=' onclick="return '+B+".onLabelClick("+B+')"';if(this.hasChildren(true)){C[C.length]=" onmouseover=\"document.getElementById('";C[C.length]=this.getToggleElId()+"').className=";C[C.length]=B+'.getHoverStyle()"';C[C.length]=" onmouseout=\"document.getElementById('";C[C.length]=this.getToggleElId()+"').className=";C[C.length]=B+'.getStyle()"';}C[C.length]=" >";C[C.length]=this.label;C[C.length]="</a>";C[C.length]="</td>";C[C.length]="</tr>";C[C.length]="</table>";return C.join("");},onLabelClick:function(A){return A.tree.fireEvent("labelClick",A);},toString:function(){return"TextNode ("+this.index+") "+this.label;}});YAHOO.widget.RootNode=function(A){this.init(null,null,true);this.tree=!
 A;};YAHOO.extend(YAHOO.widget.RootNode,YAHOO.widget.Node,{getNodeHtml:function(){return"";},toString:function(){return"RootNode";},loadComplete:function(){this.tree.draw();},collapse:function(){},expand:function(){}});YAHOO.widget.HTMLNode=function(D,C,B,A){if(D){this.init(D,C,B);this.initContent(D,A);}};YAHOO.extend(YAHOO.widget.HTMLNode,YAHOO.widget.Node,{contentStyle:"ygtvhtml",contentElId:null,html:null,initContent:function(B,A){this.setHtml(B);this.contentElId="ygtvcontentel"+this.index;this.hasIcon=A;},setHtml:function(B){this.data=B;this.html=(typeof B==="string")?B:B.html;var A=this.getContentEl();if(A){A.innerHTML=this.html;}},getContentEl:function(){return document.getElementById(this.contentElId);},getNodeHtml:function(){var B=[];B[B.length]='<table border="0" cellpadding="0" cellspacing="0">';B[B.length]="<tr>";for(var A=0;A<this.depth;++A){B[B.length]='<td class="'+this.getDepthStyle(A)+'"><div class="ygtvspacer"></div></td>';}if(this.hasIcon){B[B.length]="<td"!
 ;B[B.length]=' id="'+this.getToggleElId()+'"';B[B.length]=' cl!
 ass="'+t
his.getStyle()+'"';B[B.length]=' onclick="javascript:'+this.getToggleLink()+'"';if(this.hasChildren(true)){B[B.length]=' onmouseover="this.className=';B[B.length]="YAHOO.widget.TreeView.getNode('";B[B.length]=this.tree.id+"',"+this.index+').getHoverStyle()"';B[B.length]=' onmouseout="this.className=';B[B.length]="YAHOO.widget.TreeView.getNode('";B[B.length]=this.tree.id+"',"+this.index+').getStyle()"';}B[B.length]='><div class="ygtvspacer"></div></td>';}B[B.length]="<td";B[B.length]=' id="'+this.contentElId+'"';B[B.length]=' class="'+this.contentStyle+'"';B[B.length]=(this.nowrap)?' nowrap="nowrap" ':"";B[B.length]=" >";B[B.length]=this.html;B[B.length]="</td>";B[B.length]="</tr>";B[B.length]="</table>";return B.join("");},toString:function(){return"HTMLNode ("+this.index+")";}});YAHOO.widget.MenuNode=function(C,B,A){if(C){this.init(C,B,A);this.setUpLabel(C);}this.multiExpand=false;};YAHOO.extend(YAHOO.widget.MenuNode,YAHOO.widget.TextNode,{toString:function(){return"MenuNod!
 e ("+this.index+") "+this.label;}});YAHOO.widget.TVAnim=function(){return{FADE_IN:"TVFadeIn",FADE_OUT:"TVFadeOut",getAnim:function(B,A,C){if(YAHOO.widget[B]){return new YAHOO.widget[B](A,C);}else{return null;}},isValid:function(A){return(YAHOO.widget[A]);}};}();YAHOO.widget.TVFadeIn=function(A,B){this.el=A;this.callback=B;};YAHOO.widget.TVFadeIn.prototype={animate:function(){var D=this;var C=this.el.style;C.opacity=0.1;C.filter="alpha(opacity=10)";C.display="";var B=0.4;var A=new YAHOO.util.Anim(this.el,{opacity:{from:0.1,to:1,unit:""}},B);A.onComplete.subscribe(function(){D.onComplete();});A.animate();},onComplete:function(){this.callback();},toString:function(){return"TVFadeIn";}};YAHOO.widget.TVFadeOut=function(A,B){this.el=A;this.callback=B;};YAHOO.widget.TVFadeOut.prototype={animate:function(){var C=this;var B=0.4;var A=new YAHOO.util.Anim(this.el,{opacity:{from:1,to:0.1,unit:""}},B);A.onComplete.subscribe(function(){C.onComplete();
+});A.animate();},onComplete:function(){var A=this.el.style;A.display="none";A.filter="alpha(opacity=100)";this.callback();},toString:function(){return"TVFadeOut";}};YAHOO.register("treeview",YAHOO.widget.TreeView,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/treeview/treeview.js
===================================================================
--- trunk/root/static/yui/treeview/treeview.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/treeview/treeview.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The treeview widget is a generic tree building tool.
@@ -769,7 +769,8 @@
  * @class Node
  * @uses YAHOO.util.EventProvider
  * @param oData {object} a string or object containing the data that will
- * be used to render this node
+ * be used to render this node, and any custom attributes that should be
+ * stored with the node (which is available in noderef.data).
  * @param oParent {Node} this node's parent node
  * @param expanded {boolean} the initial expanded/collapsed state
  * @constructor
@@ -944,6 +945,17 @@
     nowrap: false,
 
     /**
+     * If true, the node will alway be rendered as a leaf node.  This can be
+     * used to override the presentation when dynamically loading the entire
+     * tree.  Setting this to true also disables the dynamic load call for the
+     * node.
+     * @property isLeaf
+     * @type boolean
+     * @default false
+     */
+    isLeaf: false,
+
+    /**
      * The node type
      * @property _type
      * @private
@@ -1515,13 +1527,18 @@
      * @return {boolean} true if this node's children are to be loaded dynamically
      */
     isDynamic: function() { 
-        var lazy = (!this.isRoot() && (this._dynLoad || this.tree.root._dynLoad));
-        return lazy;
+        if (this.isLeaf) {
+            return false;
+        } else {
+            return (!this.isRoot() && (this._dynLoad || this.tree.root._dynLoad));
+            // return lazy;
+        }
     },
 
     /**
      * Returns the current icon mode.  This refers to the way childless dynamic
-     * load nodes appear.
+     * load nodes appear (this comes into play only after the initial dynamic
+     * load request produced no children).
      * @method getIconMode
      * @return {int} 0 for collapse style, 1 for leaf node style
      */
@@ -1542,8 +1559,12 @@
      * checking for this condition.
      */
     hasChildren: function(checkForLazyLoad) { 
-        return ( this.children.length > 0 || 
-                (checkForLazyLoad && this.isDynamic() && !this.dynamicLoadComplete) );
+        if (this.isLeaf) {
+            return false;
+        } else {
+            return ( this.children.length > 0 || 
+(checkForLazyLoad && this.isDynamic() && !this.dynamicLoadComplete) );
+        }
     },
 
     /**
@@ -1772,7 +1793,26 @@
  * @extends YAHOO.widget.Node
  * @constructor
  * @param oData {object} a string or object containing the data that will
- * be used to render this node
+ * be used to render this node.
+ * Valid properties: 
+ * <dl>
+ *   <dt>label</dt>
+ *   <dd>The text for the node's label</dd>
+ *   <dt>title</dt>
+ *   <dd>The title attribute for the label anchor</dd>
+ *   <dt>title</dt>
+ *   <dd>The title attribute for the label anchor</dd>
+ *   <dt>href</dt>
+ *   <dd>The href for the node's label.  By default it is set to
+ *   expand/collapse the node.</dd>
+ *   <dt>target</dt>
+ *   <dd>The target attribute for the label anchor</dd>
+ *   <dt>style</dt>
+ *   <dd>A CSS class to apply to the label anchor</dd>
+ * </dl>
+ * All other attributes are made available in noderef.data, which
+ * can be used to store custom attributes.  TreeView.getNode(s)ByProperty
+ * can be used to retreive a node by one of the attributes.
  * @param oParent {YAHOO.widget.Node} this node's parent node
  * @param expanded {boolean} the initial expanded/collapsed state
  */
@@ -2022,11 +2062,22 @@
  * @extends YAHOO.widget.Node
  * @constructor
  * @param oData {object} a string or object containing the data that will
- * be used to render this node
+ * be used to render this node.  
+ * Valid configuration properties: 
+ * <dl>
+ *   <dt>html</dt>
+ *   <dd>The html content for the node</dd>
+ * </dl>
+ * All other attributes are made available in noderef.data, which
+ * can be used to store custom attributes.  TreeView.getNode(s)ByProperty
+ * can be used to retreive a node by one of the attributes.
  * @param oParent {YAHOO.widget.Node} this node's parent node
  * @param expanded {boolean} the initial expanded/collapsed state
  * @param hasIcon {boolean} specifies whether or not leaf nodes should
- * have an icon
+ * be rendered with or without a horizontal line line icon. If the icon
+ * is not displayed, the content fills the space it would have occupied.
+ * This option operates independently of the leaf node presentation logic
+ * for dynamic nodes.
  */
 YAHOO.widget.HTMLNode = function(oData, oParent, expanded, hasIcon) {
     if (oData) { 
@@ -2054,10 +2105,10 @@
 
     /**
      * The HTML content to use for this node's display
-     * @property content
+     * @property html
      * @type string
      */
-    content: null,
+    html: null,
 
     /**
      * Sets up the node label
@@ -2153,7 +2204,26 @@
  * @class MenuNode
  * @extends YAHOO.widget.TextNode
  * @param oData {object} a string or object containing the data that will
- * be used to render this node
+ * be used to render this node.
+ * Valid properties: 
+ * <dl>
+ *   <dt>label</dt>
+ *   <dd>The text for the node's label</dd>
+ *   <dt>title</dt>
+ *   <dd>The title attribute for the label anchor</dd>
+ *   <dt>title</dt>
+ *   <dd>The title attribute for the label anchor</dd>
+ *   <dt>href</dt>
+ *   <dd>The href for the node's label.  By default it is set to
+ *   expand/collapse the node.</dd>
+ *   <dt>target</dt>
+ *   <dd>The target attribute for the label anchor</dd>
+ *   <dt>style</dt>
+ *   <dd>A CSS class to apply to the label anchor</dd>
+ * </dl>
+ * All other attributes are made available in noderef.data, which
+ * can be used to store custom attributes.  TreeView.getNode(s)ByProperty
+ * can be used to retreive a node by one of the attributes.
  * @param oParent {YAHOO.widget.Node} this node's parent node
  * @param expanded {boolean} the initial expanded/collapsed state
  * @constructor
@@ -2352,4 +2422,4 @@
     }
 };
 
-YAHOO.register("treeview", YAHOO.widget.TreeView, {version: "2.4.1", build: "742"});
+YAHOO.register("treeview", YAHOO.widget.TreeView, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/uploader/README
===================================================================
--- trunk/root/static/yui/uploader/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/uploader/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,7 @@
+YUI Library - Uploader - Release Notes
+
+2.5.1
+  * Fix to ensure UploadCancel fires when expected.
+  
+2.5.0
+  * Experimental release
\ No newline at end of file

Added: trunk/root/static/yui/uploader/assets/uploader.swf
===================================================================
(Binary files differ)


Property changes on: trunk/root/static/yui/uploader/assets/uploader.swf
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/root/static/yui/uploader/uploader-experimental-debug.js
===================================================================
--- trunk/root/static/yui/uploader/uploader-experimental-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/uploader/uploader-experimental-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,636 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * The YUI Uploader Control
+ * @module uploader
+ * @description <p>YUI Uploader provides file upload functionality that goes beyond the basic browser-based methods. 
+ * Specifically, the YUI Uploader allows for:
+ * <ol>
+ * <li> Multiple file selection in a single "Open File" dialog.</li>
+ * <li> File extension filters to facilitate the user's selection.</li>
+ * <li> Progress tracking for file uploads.</li>
+ * <li> A range of file metadata: filename, size, date created, date modified, and author.</li>
+ * <li> A set of events dispatched on various aspects of the file upload process: file selection, upload progress, upload completion, etc.</li>
+ * <li> Inclusion of additional data in the file upload POST request.</li>
+ * <li> Faster file upload on broadband connections due to the modified SEND buffer size.</li>
+ * <li> Same-page server response upon completion of the file upload.</li>
+ * </ol>
+ * </p>
+ * @title Uploader
+ * @namespace YAHOO.widget
+ * @requires yahoo, dom, element, event
+ */
+/*!
+ * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
+ *
+ * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ */
+if(typeof deconcept == "undefined") var deconcept = new Object();
+if(typeof deconcept.util == "undefined") deconcept.util = new Object();
+if(typeof deconcept.SWFObjectUtil == "undefined") deconcept.SWFObjectUtil = new Object();
+deconcept.SWFObject = function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey) {
+	if (!document.getElementById) { return; }
+	this.DETECT_KEY = detectKey ? detectKey : 'detectflash';
+	this.skipDetect = deconcept.util.getRequestParameter(this.DETECT_KEY);
+	this.params = new Object();
+	this.variables = new Object();
+	this.attributes = new Array();
+	if(swf) { this.setAttribute('swf', swf); }
+	if(id) { this.setAttribute('id', id); }
+	if(w) { this.setAttribute('width', w); }
+	if(h) { this.setAttribute('height', h); }
+	if(ver) { this.setAttribute('version', new deconcept.PlayerVersion(ver.toString().split("."))); }
+	this.installedVer = deconcept.SWFObjectUtil.getPlayerVersion();
+	if (!window.opera && document.all && this.installedVer.major > 7) {
+		// only add the onunload cleanup if the Flash Player version supports External Interface and we are in IE
+		deconcept.SWFObject.doPrepUnload = true;
+	}
+	if(c) { this.addParam('bgcolor', c); }
+	var q = quality ? quality : 'high';
+	this.addParam('quality', q);
+	this.setAttribute('useExpressInstall', false);
+	this.setAttribute('doExpressInstall', false);
+	var xir = (xiRedirectUrl) ? xiRedirectUrl : window.location;
+	this.setAttribute('xiRedirectUrl', xir);
+	this.setAttribute('redirectUrl', '');
+	if(redirectUrl) { this.setAttribute('redirectUrl', redirectUrl); }
+}
+deconcept.SWFObject.prototype = {
+	useExpressInstall: function(path) {
+		this.xiSWFPath = !path ? "expressinstall.swf" : path;
+		this.setAttribute('useExpressInstall', true);
+	},
+	setAttribute: function(name, value){
+		this.attributes[name] = value;
+	},
+	getAttribute: function(name){
+		return this.attributes[name];
+	},
+	addParam: function(name, value){
+		this.params[name] = value;
+	},
+	getParams: function(){
+		return this.params;
+	},
+	addVariable: function(name, value){
+		this.variables[name] = value;
+	},
+	getVariable: function(name){
+		return this.variables[name];
+	},
+	getVariables: function(){
+		return this.variables;
+	},
+	getVariablePairs: function(){
+		var variablePairs = new Array();
+		var key;
+		var variables = this.getVariables();
+		for(key in variables){
+			variablePairs[variablePairs.length] = key +"="+ variables[key];
+		}
+		return variablePairs;
+	},
+	getSWFHTML: function() {
+		var swfNode = "";
+		if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { // netscape plugin architecture
+			if (this.getAttribute("doExpressInstall")) {
+				this.addVariable("MMplayerType", "PlugIn");
+				this.setAttribute('swf', this.xiSWFPath);
+			}
+			swfNode = '<embed type="application/x-shockwave-flash" src="'+ this.getAttribute('swf') +'" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'"';
+			swfNode += ' id="'+ this.getAttribute('id') +'" name="'+ this.getAttribute('id') +'" ';
+			var params = this.getParams();
+			 for(var key in params){ swfNode += [key] +'="'+ params[key] +'" '; }
+			var pairs = this.getVariablePairs().join("&");
+			 if (pairs.length > 0){ swfNode += 'flashvars="'+ pairs +'"'; }
+			swfNode += '/>';
+		} else { // PC IE
+			if (this.getAttribute("doExpressInstall")) {
+				this.addVariable("MMplayerType", "ActiveX");
+				this.setAttribute('swf', this.xiSWFPath);
+			}
+			swfNode = '<object id="'+ this.getAttribute('id') +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'">';
+			swfNode += '<param name="movie" value="'+ this.getAttribute('swf') +'" />';
+			var params = this.getParams();
+			for(var key in params) {
+			 swfNode += '<param name="'+ key +'" value="'+ params[key] +'" />';
+			}
+			var pairs = this.getVariablePairs().join("&");
+			if(pairs.length > 0) {swfNode += '<param name="flashvars" value="'+ pairs +'" />';}
+			swfNode += "</object>";
+		}
+		return swfNode;
+	},
+	write: function(elementId){
+		if(this.getAttribute('useExpressInstall')) {
+			// check to see if we need to do an express install
+			var expressInstallReqVer = new deconcept.PlayerVersion([6,0,65]);
+			if (this.installedVer.versionIsValid(expressInstallReqVer) && !this.installedVer.versionIsValid(this.getAttribute('version'))) {
+				this.setAttribute('doExpressInstall', true);
+				this.addVariable("MMredirectURL", escape(this.getAttribute('xiRedirectUrl')));
+				document.title = document.title.slice(0, 47) + " - Flash Player Installation";
+				this.addVariable("MMdoctitle", document.title);
+			}
+		}
+		if(this.skipDetect || this.getAttribute('doExpressInstall') || this.installedVer.versionIsValid(this.getAttribute('version'))){
+			var n = (typeof elementId == 'string') ? document.getElementById(elementId) : elementId;
+			n.innerHTML = this.getSWFHTML();
+			return true;
+		}else{
+			if(this.getAttribute('redirectUrl') != "") {
+				document.location.replace(this.getAttribute('redirectUrl'));
+			}
+		}
+		return false;
+	}
+}
+
+/* ---- detection functions ---- */
+deconcept.SWFObjectUtil.getPlayerVersion = function(){
+	var PlayerVersion = new deconcept.PlayerVersion([0,0,0]);
+	if(navigator.plugins && navigator.mimeTypes.length){
+		var x = navigator.plugins["Shockwave Flash"];
+		if(x && x.description) {
+			PlayerVersion = new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split("."));
+		}
+	}else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ // if Windows CE
+		var axo = 1;
+		var counter = 3;
+		while(axo) {
+			try {
+				counter++;
+				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ counter);
+//				document.write("player v: "+ counter);
+				PlayerVersion = new deconcept.PlayerVersion([counter,0,0]);
+			} catch (e) {
+				axo = null;
+			}
+		}
+	} else { // Win IE (non mobile)
+		// do minor version lookup in IE, but avoid fp6 crashing issues
+		// see http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/
+		try{
+			var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
+		}catch(e){
+			try {
+				var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
+				PlayerVersion = new deconcept.PlayerVersion([6,0,21]);
+				axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code)
+			} catch(e) {
+				if (PlayerVersion.major == 6) {
+					return PlayerVersion;
+				}
+			}
+			try {
+				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+			} catch(e) {}
+		}
+		if (axo != null) {
+			PlayerVersion = new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));
+		}
+	}
+	return PlayerVersion;
+}
+deconcept.PlayerVersion = function(arrVersion){
+	this.major = arrVersion[0] != null ? parseInt(arrVersion[0]) : 0;
+	this.minor = arrVersion[1] != null ? parseInt(arrVersion[1]) : 0;
+	this.rev = arrVersion[2] != null ? parseInt(arrVersion[2]) : 0;
+}
+deconcept.PlayerVersion.prototype.versionIsValid = function(fv){
+	if(this.major < fv.major) return false;
+	if(this.major > fv.major) return true;
+	if(this.minor < fv.minor) return false;
+	if(this.minor > fv.minor) return true;
+	if(this.rev < fv.rev) return false;
+	return true;
+}
+/* ---- get value of query string param ---- */
+deconcept.util = {
+	getRequestParameter: function(param) {
+		var q = document.location.search || document.location.hash;
+		if (param == null) { return q; }
+		if(q) {
+			var pairs = q.substring(1).split("&");
+			for (var i=0; i < pairs.length; i++) {
+				if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
+					return pairs[i].substring((pairs[i].indexOf("=")+1));
+				}
+			}
+		}
+		return "";
+	}
+}
+/* fix for video streaming bug */
+deconcept.SWFObjectUtil.cleanupSWFs = function() {
+	var objects = document.getElementsByTagName("OBJECT");
+	for (var i = objects.length - 1; i >= 0; i--) {
+		objects[i].style.display = 'none';
+		for (var x in objects[i]) {
+			if (typeof objects[i][x] == 'function') {
+				objects[i][x] = function(){};
+			}
+		}
+	}
+}
+// fixes bug in some fp9 versions see http://blog.deconcept.com/2006/07/28/swfobject-143-released/
+if (deconcept.SWFObject.doPrepUnload) {
+	if (!deconcept.unloadSet) {
+		deconcept.SWFObjectUtil.prepUnload = function() {
+			__flash_unloadHandler = function(){};
+			__flash_savedUnloadHandler = function(){};
+			window.attachEvent("onunload", deconcept.SWFObjectUtil.cleanupSWFs);
+		}
+		window.attachEvent("onbeforeunload", deconcept.SWFObjectUtil.prepUnload);
+		deconcept.unloadSet = true;
+	}
+}
+/* add document.getElementById if needed (mobile IE < 5) */
+if (!document.getElementById && document.all) { document.getElementById = function(id) { return document.all[id]; }}
+
+/* add some aliases for ease of use/backwards compatibility */
+var getQueryParamValue = deconcept.util.getRequestParameter;
+var FlashObject = deconcept.SWFObject; // for legacy support
+var SWFObject = deconcept.SWFObject;
+
+/**
+ * Wraps Flash embedding functionality and allows communication with SWF through
+ * attributes.
+ *
+ * @namespace YAHOO.widget
+ * @class FlashAdapter
+ * @uses YAHOO.util.AttributeProvider
+ */
+YAHOO.widget.FlashAdapter = function(swfURL, containerID, attributes)
+{
+	// set up the initial events and attributes stuff
+	this._queue = this._queue || [];
+	this._events = this._events || {};
+	this._configs = this._configs || {};
+	attributes = attributes || {};
+	
+	//the Flash Player external interface code from Adobe doesn't play nicely
+	//with the default value, yui-gen, in IE
+	this._id = attributes.id = attributes.id || YAHOO.util.Dom.generateId(null, "yuigen");
+	attributes.version = attributes.version || "9.0.45";
+	attributes.backgroundColor = attributes.backgroundColor || "#ffffff";
+	
+	//we can't use the initial attributes right away
+	//so save them for once the SWF finishes loading
+	this._attributes = attributes;
+	
+	this._swfURL = swfURL;
+	
+	//embed the SWF file in the page
+	this._embedSWF(this._swfURL, containerID, attributes.id, attributes.version, attributes.backgroundColor, attributes.expressInstall);
+	
+	/**
+	 * Fires when the SWF is initialized and communication is possible.
+	 * @event contentReady
+	 */
+	this.createEvent("contentReady");
+};
+
+YAHOO.extend(YAHOO.widget.FlashAdapter, YAHOO.util.AttributeProvider,
+{
+	/**
+	 * The URL of the SWF file.
+	 * @property _swfURL
+	 * @type String
+	 * @private
+	 */
+	_swfURL: null,
+
+	/**
+	 * A reference to the embedded SWF file.
+	 * @property _swf
+	 * @private
+	 */
+	_swf: null,
+
+	/**
+	 * The id of this instance.
+	 * @property _id
+	 * @type String
+	 * @private
+	 */
+	_id: null,
+	
+	/**
+	 * The initializing attributes are stored here until the SWF is ready.
+	 * @property _attributes
+	 * @type Object
+	 * @private
+	 */
+	_attributes: null, //the intializing attributes
+
+	/**
+	 * Public accessor to the unique name of the FlashAdapter instance.
+	 *
+	 * @method toString
+	 * @return {String} Unique name of the FlashAdapter instance.
+	 */
+	toString: function()
+	{
+		return "FlashAdapter " + this._id;
+	},
+
+	/**
+	 * Embeds the SWF in the page and associates it with this instance.
+	 *
+	 * @method _embedSWF
+	 * @private
+	 */
+	_embedSWF: function(swfURL, containerID, swfID, version, backgroundColor, expressInstall)
+	{
+		//standard SWFObject embed
+		var swfObj = new deconcept.SWFObject(swfURL, swfID, "100%", "100%", version, backgroundColor, expressInstall);
+
+		//make sure we can communicate with ExternalInterface
+		swfObj.addParam("allowScriptAccess", "always");
+		
+		//again, a useful ExternalInterface trick
+		swfObj.addVariable("allowedDomain", document.location.hostname);
+
+		//tell the SWF which HTML element it is in
+		swfObj.addVariable("elementID", swfID);
+
+		// set the name of the function to call when the swf has an event
+		swfObj.addVariable("eventHandler", "YAHOO.widget.FlashAdapter.eventHandler");
+
+		var container = YAHOO.util.Dom.get(containerID);
+		var result = swfObj.write(container);
+		if(result)
+		{
+			this._swf = YAHOO.util.Dom.get(swfID);
+			//if successful, let's add an owner property to the SWF reference
+			//this will allow the event handler to communicate with a YAHOO.widget.FlashAdapter
+			this._swf.owner = this;
+		}
+	},
+
+	/**
+	 * Handles or re-dispatches events received from the SWF.
+	 *
+	 * @method _eventHandler
+	 * @private
+	 */
+	_eventHandler: function(event)
+	{
+		var type = event.type;
+		switch(type)
+		{
+			case "swfReady":
+			{
+   				this._loadHandler();
+				return;
+			}
+			case "log":
+			{
+				return;
+			}
+		}
+		
+		//be sure to return after your case or the event will automatically fire!
+		this.fireEvent(type, event);
+	},
+
+	/**
+	 * Called when the SWF has been initialized.
+	 *
+	 * @method _loadHandler
+	 * @private
+	 */
+	_loadHandler: function()
+	{
+		this._initAttributes(this._attributes);
+		this.setAttributes(this._attributes, true);
+		this._attributes = null;
+		
+		this.fireEvent("contentReady");
+	},
+	
+	/**
+	 * Initializes the attributes.
+	 *
+	 * @method _initAttributes
+	 * @private
+	 */
+	_initAttributes: function(attributes)
+	{
+		//should be overridden if other attributes need to be set up
+		
+		/**
+		 * @attribute swfURL
+		 * @description Absolute or relative URL to the SWF displayed by the FlashAdapter.
+		 * @type String
+		 */
+		this.getAttributeConfig("swfURL",
+		{
+			method: this._getSWFURL
+		});
+	},
+	
+	/**
+	 * Getter for swfURL attribute.
+	 *
+	 * @method _getSWFURL
+	 * @private
+	 */
+	_getSWFURL: function()
+	{
+		return this._swfURL;
+	}
+});
+
+/**
+ * Receives event messages from SWF and passes them to the correct instance
+ * of FlashAdapter.
+ *
+ * @method YAHOO.widget.FlashAdapter.eventHandler
+ * @static
+ * @private
+ */
+YAHOO.widget.FlashAdapter.eventHandler = function(elementID, event)
+{
+	var loadedSWF = YAHOO.util.Dom.get(elementID);
+	if(!loadedSWF.owner)
+	{
+		//fix for ie: if owner doesn't exist yet, try again in a moment
+		setTimeout(function() { YAHOO.widget.FlashAdapter.eventHandler( elementID, event ); }, 0);
+	}
+	else loadedSWF.owner._eventHandler(event);
+};
+/**
+ * Uploader class for the YUI Uploader component.
+ *
+ * @namespace YAHOO.widget
+ * @class Uploader
+ * @uses YAHOO.widget.FlashAdapter
+ * @constructor
+ * @param containerId {HTMLElement} Container element for the Flash Player instance.
+ */
+YAHOO.widget.Uploader = function(containerId)
+{
+	YAHOO.widget.Uploader.superclass.constructor.call(this, YAHOO.widget.Uploader.SWFURL, containerId, null);
+	
+	/**
+	 * Fires when the user has finished selecting files in the "Open File" dialog.
+	 *
+	 * @event fileSelect
+	 * @param event.type {String} The event type
+	 * @param event.fileList {Array} An array of objects with file information
+	 * @param event.fileList[].size {Number} File size in bytes for a specific file in fileList
+	 * @param event.fileList[].cDate {Date} Creation date for a specific file in fileList
+	 * @param event.fileList[].mDate {Date} Modification date for a specific file in fileList
+	 * @param event.fileList[].name {String} File name for a specific file in fileList
+	 * @param event.fileList[].id {String} Unique file id of a specific file in fileList
+	 */
+	this.createEvent("fileSelect");
+
+	/**
+	 * Fires when an upload of a specific file has started.
+	 *
+	 * @event uploadStart
+	 * @param event.type {String} The event type
+	 * @param event.id {String} The id of the file that's started to upload
+	 */
+	this.createEvent("uploadStart");
+
+	/**
+	 * Fires when new information about the upload progress for a specific file is available.
+	 *
+	 * @event uploadProgress
+	 * @param event.type {String} The event type
+	 * @param event.id {String} The id of the file with which the upload progress data is associated
+	 * @param bytesLoaded {Number} The number of bytes of the file uploaded so far
+	 * @param bytesTotal {Number} The total size of the file
+	 */
+	this.createEvent("uploadProgress");
+	
+	/**
+	 * Fires when an upload for a specific file is cancelled.
+	 *
+	 * @event uploadCancel
+	 * @param event.type {String} The event type
+	 * @param event.id {String} The id of the file with which the upload has been cancelled.
+	 */	
+	this.createEvent("uploadCancel");
+
+	/**
+	 * Fires when an upload for a specific file is complete.
+	 *
+	 * @event uploadComplete
+	 * @param event.type {String} The event type
+	 * @param event.id {String} The id of the file for which the upload has been completed.
+	 */	
+	this.createEvent("uploadComplete");
+
+	/**
+	 * Fires when the server sends data in response to a completed upload.
+	 *
+	 * @event uploadCompleteData
+	 * @param event.type {String} The event type
+	 * @param event.id {String} The id of the file for which the upload has been completed.
+	 * @param event.data {String} The raw data returned by the server in response to the upload.
+	 */	
+	this.createEvent("uploadCompleteData");
+	
+	/**
+	 * Fires when an upload error occurs.
+	 *
+	 * @event uploadError
+	 * @param event.type {String} The event type
+	 * @param event.id {String} The id of the file that was being uploaded when the error has occurred.
+	 * @param event.status {String} The status message associated with the error.
+	 */	
+	this.createEvent("uploadError");
+}
+
+/**
+ * Location of the Uploader SWF
+ *
+ * @property Chart.SWFURL
+ * @private
+ * @static
+ * @final
+ * @default "assets/uploader.swf"
+ */
+YAHOO.widget.Uploader.SWFURL = "assets/uploader.swf";
+
+YAHOO.extend(YAHOO.widget.Uploader, YAHOO.widget.FlashAdapter,
+{
+/**
+ * Invokes the "Open File" dialog and allows the user to select the files for upload
+ *
+ * @param allowMultiple {Boolean} If true, allows for multiple file selection; if false, only a single file can be selected. False by default.
+ * @param extensionFilterArray {Array} An array of key-value pairs for permissible file extensions. The array elements should 
+ * be of the form: {description: "Images", extensions: "*.jpg; *.gif; *.png"}.
+ */
+	browse: function(allowMultiple,extensionFilterArray)
+	{
+		this._swf.browse(allowMultiple,extensionFilterArray);
+	},
+	
+/**
+ * Starts the upload of the file specified by fileID to the location specified by uploadScriptPath.
+ *
+ * @param fileID {String} The id of the file to start uploading.
+ * @param uploadScriptPath {String} The URL of the upload location.
+ * @param method {String} Either "GET" or "POST", specifying how the variables accompanying the file upload POST request should be submitted. "GET" by default.
+ * @param vars {Object} The object containing variables to be sent in the same request as the file upload.
+ * @param fieldName {String} The name of the variable in the POST request containing the file data. "Filedata" by default.
+ */
+	upload: function(fileID, uploadScriptPath, method, vars, fieldName)
+	{
+		this._swf.upload(fileID, uploadScriptPath, method, vars, fieldName);
+	},
+	
+/**
+ * Starts uploading all files in the queue. If this function is called, the upload queue is automatically managed.
+ *
+ * @param uploadScriptPath {String} The URL of the upload location.
+ * @param method {String} Either "GET" or "POST", specifying how the variables accompanying the file upload POST request should be submitted. "GET" by default.
+ * @param vars {Object} The object containing variables to be sent in the same request as the file upload.
+ * @param fieldName {String} The name of the variable in the POST request containing the file data. "Filedata" by default.
+ */
+	uploadAll: function(uploadScriptPath, method, vars, fieldName)
+	{
+		this._swf.uploadAll(uploadScriptPath, method, vars, fieldName);
+	},
+
+/**
+ * Cancels the upload of a specified file. If no file id is specified, all ongoing uploads are cancelled.
+ *
+ * @param fileID {String} The ID of the file whose upload should be cancelled.
+ */
+	cancel: function(fileID)
+	{
+		this._swf.cancel(fileID);
+	},
+
+/**
+ * Clears the list of files queued for upload.
+ *
+ */
+	clearFileList: function()
+	{
+		this._swf.clearFileList();
+	},
+	
+/**
+ * Removes the specified file from the upload queue. 
+ *
+ * @param fileID {String} The id of the file to remove from the upload queue. 
+ */
+	removeFile: function (fileID) 
+	{
+		this._swf.removeFile(fileID);
+	}
+});
+YAHOO.register("uploader", YAHOO.widget.Uploader, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/uploader/uploader-experimental-min.js
===================================================================
--- trunk/root/static/yui/uploader/uploader-experimental-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/uploader/uploader-experimental-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/*
+ * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
+ *
+ * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ */
+if(typeof deconcept=="undefined"){var deconcept=new Object();}if(typeof deconcept.util=="undefined"){deconcept.util=new Object();}if(typeof deconcept.SWFObjectUtil=="undefined"){deconcept.SWFObjectUtil=new Object();}deconcept.SWFObject=function(E,C,K,F,H,J,L,G,A,D){if(!document.getElementById){return ;}this.DETECT_KEY=D?D:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params=new Object();this.variables=new Object();this.attributes=new Array();if(E){this.setAttribute("swf",E);}if(C){this.setAttribute("id",C);}if(K){this.setAttribute("width",K);}if(F){this.setAttribute("height",F);}if(H){this.setAttribute("version",new deconcept.PlayerVersion(H.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}if(J){this.addParam("bgcolor",J);}var B=L?L:"high";this.addParam("quality",B);this.setAttribute("useExpressInstal!
 l",false);this.setAttribute("doExpressInstall",false);var I=(G)?G:window.location;this.setAttribute("xiRedirectUrl",I);this.setAttribute("redirectUrl","");if(A){this.setAttribute("redirectUrl",A);}};deconcept.SWFObject.prototype={useExpressInstall:function(A){this.xiSWFPath=!A?"expressinstall.swf":A;this.setAttribute("useExpressInstall",true);},setAttribute:function(A,B){this.attributes[A]=B;},getAttribute:function(A){return this.attributes[A];},addParam:function(A,B){this.params[A]=B;},getParams:function(){return this.params;},addVariable:function(A,B){this.variables[A]=B;},getVariable:function(A){return this.variables[A];},getVariables:function(){return this.variables;},getVariablePairs:function(){var A=new Array();var B;var C=this.getVariables();for(B in C){A[A.length]=B+"="+C[B];}return A;},getSWFHTML:function(){var D="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugI!
 n");this.setAttribute("swf",this.xiSWFPath);}D='<embed type="a!
 pplicati
on/x-shockwave-flash" src="'+this.getAttribute("swf")+'" width="'+this.getAttribute("width")+'" height="'+this.getAttribute("height")+'" style="'+this.getAttribute("style")+'"';D+=' id="'+this.getAttribute("id")+'" name="'+this.getAttribute("id")+'" ';var C=this.getParams();for(var A in C){D+=[A]+'="'+C[A]+'" ';}var B=this.getVariablePairs().join("&");if(B.length>0){D+='flashvars="'+B+'"';}D+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}D='<object id="'+this.getAttribute("id")+'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+this.getAttribute("width")+'" height="'+this.getAttribute("height")+'" style="'+this.getAttribute("style")+'">';D+='<param name="movie" value="'+this.getAttribute("swf")+'" />';var C=this.getParams();for(var A in C){D+='<param name="'+A+'" value="'+C[A]+'" />';}var B=this.getVariablePairs().join("&");if(B.length>0){D+='<param name="flashvars" value!
 ="'+B+'" />';}D+="</object>";}return D;},write:function(A){if(this.getAttribute("useExpressInstall")){var B=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(B)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var C=(typeof A=="string")?document.getElementById(A):A;C.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var C=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var A!
 =navigator.plugins["Shockwave Flash"];if(A&&A.description){C=n!
 ew decon
cept.PlayerVersion(A.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var D=1;var B=3;while(D){try{B++;D=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+B);C=new deconcept.PlayerVersion([B,0,0]);}catch(E){D=null;}}}else{try{var D=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(E){try{var D=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");C=new deconcept.PlayerVersion([6,0,21]);D.AllowScriptAccess="always";}catch(E){if(C.major==6){return C;}}try{D=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(E){}}if(D!=null){C=new deconcept.PlayerVersion(D.GetVariable("$version").split(" ")[1].split(","));}}}return C;};deconcept.PlayerVersion=function(A){this.major=A[0]!=null?parseInt(A[0]):0;this.minor=A[1]!=null?parseInt(A[1]):0;this.rev=A[2]!=null?parseInt(A[2]):0;};deconcept.PlayerVersion.prototype.versionIsValid=function(A){if(this.major<A.majo!
 r){return false;}if(this.major>A.major){return true;}if(this.minor<A.minor){return false;}if(this.minor>A.minor){return true;}if(this.rev<A.rev){return false;}return true;};deconcept.util={getRequestParameter:function(D){var C=document.location.search||document.location.hash;if(D==null){return C;}if(C){var B=C.substring(1).split("&");for(var A=0;A<B.length;A++){if(B[A].substring(0,B[A].indexOf("="))==D){return B[A].substring((B[A].indexOf("=")+1));}}}return"";}};deconcept.SWFObjectUtil.cleanupSWFs=function(){var C=document.getElementsByTagName("OBJECT");for(var B=C.length-1;B>=0;B--){C[B].style.display="none";for(var A in C[B]){if(typeof C[B][A]=="function"){C[B][A]=function(){};
+}}}};if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(!document.getElementById&&document.all){document.getElementById=function(A){return document.all[A];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;YAHOO.widget.FlashAdapter=function(C,A,B){this._queue=this._queue||[];this._events=this._events||{};this._configs=this._configs||{};B=B||{};this._id=B.id=B.id||YAHOO.util.Dom.generateId(null,"yuigen");B.version=B.version||"9.0.45";B.backgroundColor=B.backgroundColor||"#ffffff";this._attributes=B;this._swfURL=C;this._embedSWF(this._swfURL,A,B.id,B.version,B.backgroundColor,B.expressInstall);this.c!
 reateEvent("contentReady");};YAHOO.extend(YAHOO.widget.FlashAdapter,YAHOO.util.AttributeProvider,{_swfURL:null,_swf:null,_id:null,_attributes:null,toString:function(){return"FlashAdapter "+this._id;},_embedSWF:function(H,G,C,B,E,F){var D=new deconcept.SWFObject(H,C,"100%","100%",B,E,F);D.addParam("allowScriptAccess","always");D.addVariable("allowedDomain",document.location.hostname);D.addVariable("elementID",C);D.addVariable("eventHandler","YAHOO.widget.FlashAdapter.eventHandler");var A=YAHOO.util.Dom.get(G);var I=D.write(A);if(I){this._swf=YAHOO.util.Dom.get(C);this._swf.owner=this;}},_eventHandler:function(B){var A=B.type;switch(A){case"swfReady":this._loadHandler();return ;case"log":return ;}this.fireEvent(A,B);},_loadHandler:function(){this._initAttributes(this._attributes);this.setAttributes(this._attributes,true);this._attributes=null;this.fireEvent("contentReady");},_initAttributes:function(A){this.getAttributeConfig("swfURL",{method:this._getSWFURL});},_getSWFURL:fu!
 nction(){return this._swfURL;}});YAHOO.widget.FlashAdapter.eve!
 ntHandle
r=function(A,C){var B=YAHOO.util.Dom.get(A);if(!B.owner){setTimeout(function(){YAHOO.widget.FlashAdapter.eventHandler(A,C);},0);}else{B.owner._eventHandler(C);}};YAHOO.widget.Uploader=function(A){YAHOO.widget.Uploader.superclass.constructor.call(this,YAHOO.widget.Uploader.SWFURL,A,null);this.createEvent("fileSelect");this.createEvent("uploadStart");this.createEvent("uploadProgress");this.createEvent("uploadCancel");this.createEvent("uploadComplete");this.createEvent("uploadCompleteData");this.createEvent("uploadError");};YAHOO.widget.Uploader.SWFURL="assets/uploader.swf";YAHOO.extend(YAHOO.widget.Uploader,YAHOO.widget.FlashAdapter,{browse:function(B,A){this._swf.browse(B,A);},upload:function(A,B,E,C,D){this._swf.upload(A,B,E,C,D);},uploadAll:function(A,D,B,C){this._swf.uploadAll(A,D,B,C);},cancel:function(A){this._swf.cancel(A);},clearFileList:function(){this._swf.clearFileList();},removeFile:function(A){this._swf.removeFile(A);}});YAHOO.register("uploader",YAHOO.widget.Uplo!
 ader,{version:"2.5.1",build:"984"});
\ No newline at end of file

Added: trunk/root/static/yui/uploader/uploader-experimental.js
===================================================================
--- trunk/root/static/yui/uploader/uploader-experimental.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/uploader/uploader-experimental.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,636 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+/**
+ * The YUI Uploader Control
+ * @module uploader
+ * @description <p>YUI Uploader provides file upload functionality that goes beyond the basic browser-based methods. 
+ * Specifically, the YUI Uploader allows for:
+ * <ol>
+ * <li> Multiple file selection in a single "Open File" dialog.</li>
+ * <li> File extension filters to facilitate the user's selection.</li>
+ * <li> Progress tracking for file uploads.</li>
+ * <li> A range of file metadata: filename, size, date created, date modified, and author.</li>
+ * <li> A set of events dispatched on various aspects of the file upload process: file selection, upload progress, upload completion, etc.</li>
+ * <li> Inclusion of additional data in the file upload POST request.</li>
+ * <li> Faster file upload on broadband connections due to the modified SEND buffer size.</li>
+ * <li> Same-page server response upon completion of the file upload.</li>
+ * </ol>
+ * </p>
+ * @title Uploader
+ * @namespace YAHOO.widget
+ * @requires yahoo, dom, element, event
+ */
+/*!
+ * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
+ *
+ * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ */
+if(typeof deconcept == "undefined") var deconcept = new Object();
+if(typeof deconcept.util == "undefined") deconcept.util = new Object();
+if(typeof deconcept.SWFObjectUtil == "undefined") deconcept.SWFObjectUtil = new Object();
+deconcept.SWFObject = function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey) {
+	if (!document.getElementById) { return; }
+	this.DETECT_KEY = detectKey ? detectKey : 'detectflash';
+	this.skipDetect = deconcept.util.getRequestParameter(this.DETECT_KEY);
+	this.params = new Object();
+	this.variables = new Object();
+	this.attributes = new Array();
+	if(swf) { this.setAttribute('swf', swf); }
+	if(id) { this.setAttribute('id', id); }
+	if(w) { this.setAttribute('width', w); }
+	if(h) { this.setAttribute('height', h); }
+	if(ver) { this.setAttribute('version', new deconcept.PlayerVersion(ver.toString().split("."))); }
+	this.installedVer = deconcept.SWFObjectUtil.getPlayerVersion();
+	if (!window.opera && document.all && this.installedVer.major > 7) {
+		// only add the onunload cleanup if the Flash Player version supports External Interface and we are in IE
+		deconcept.SWFObject.doPrepUnload = true;
+	}
+	if(c) { this.addParam('bgcolor', c); }
+	var q = quality ? quality : 'high';
+	this.addParam('quality', q);
+	this.setAttribute('useExpressInstall', false);
+	this.setAttribute('doExpressInstall', false);
+	var xir = (xiRedirectUrl) ? xiRedirectUrl : window.location;
+	this.setAttribute('xiRedirectUrl', xir);
+	this.setAttribute('redirectUrl', '');
+	if(redirectUrl) { this.setAttribute('redirectUrl', redirectUrl); }
+}
+deconcept.SWFObject.prototype = {
+	useExpressInstall: function(path) {
+		this.xiSWFPath = !path ? "expressinstall.swf" : path;
+		this.setAttribute('useExpressInstall', true);
+	},
+	setAttribute: function(name, value){
+		this.attributes[name] = value;
+	},
+	getAttribute: function(name){
+		return this.attributes[name];
+	},
+	addParam: function(name, value){
+		this.params[name] = value;
+	},
+	getParams: function(){
+		return this.params;
+	},
+	addVariable: function(name, value){
+		this.variables[name] = value;
+	},
+	getVariable: function(name){
+		return this.variables[name];
+	},
+	getVariables: function(){
+		return this.variables;
+	},
+	getVariablePairs: function(){
+		var variablePairs = new Array();
+		var key;
+		var variables = this.getVariables();
+		for(key in variables){
+			variablePairs[variablePairs.length] = key +"="+ variables[key];
+		}
+		return variablePairs;
+	},
+	getSWFHTML: function() {
+		var swfNode = "";
+		if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) { // netscape plugin architecture
+			if (this.getAttribute("doExpressInstall")) {
+				this.addVariable("MMplayerType", "PlugIn");
+				this.setAttribute('swf', this.xiSWFPath);
+			}
+			swfNode = '<embed type="application/x-shockwave-flash" src="'+ this.getAttribute('swf') +'" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'"';
+			swfNode += ' id="'+ this.getAttribute('id') +'" name="'+ this.getAttribute('id') +'" ';
+			var params = this.getParams();
+			 for(var key in params){ swfNode += [key] +'="'+ params[key] +'" '; }
+			var pairs = this.getVariablePairs().join("&");
+			 if (pairs.length > 0){ swfNode += 'flashvars="'+ pairs +'"'; }
+			swfNode += '/>';
+		} else { // PC IE
+			if (this.getAttribute("doExpressInstall")) {
+				this.addVariable("MMplayerType", "ActiveX");
+				this.setAttribute('swf', this.xiSWFPath);
+			}
+			swfNode = '<object id="'+ this.getAttribute('id') +'" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+ this.getAttribute('width') +'" height="'+ this.getAttribute('height') +'" style="'+ this.getAttribute('style') +'">';
+			swfNode += '<param name="movie" value="'+ this.getAttribute('swf') +'" />';
+			var params = this.getParams();
+			for(var key in params) {
+			 swfNode += '<param name="'+ key +'" value="'+ params[key] +'" />';
+			}
+			var pairs = this.getVariablePairs().join("&");
+			if(pairs.length > 0) {swfNode += '<param name="flashvars" value="'+ pairs +'" />';}
+			swfNode += "</object>";
+		}
+		return swfNode;
+	},
+	write: function(elementId){
+		if(this.getAttribute('useExpressInstall')) {
+			// check to see if we need to do an express install
+			var expressInstallReqVer = new deconcept.PlayerVersion([6,0,65]);
+			if (this.installedVer.versionIsValid(expressInstallReqVer) && !this.installedVer.versionIsValid(this.getAttribute('version'))) {
+				this.setAttribute('doExpressInstall', true);
+				this.addVariable("MMredirectURL", escape(this.getAttribute('xiRedirectUrl')));
+				document.title = document.title.slice(0, 47) + " - Flash Player Installation";
+				this.addVariable("MMdoctitle", document.title);
+			}
+		}
+		if(this.skipDetect || this.getAttribute('doExpressInstall') || this.installedVer.versionIsValid(this.getAttribute('version'))){
+			var n = (typeof elementId == 'string') ? document.getElementById(elementId) : elementId;
+			n.innerHTML = this.getSWFHTML();
+			return true;
+		}else{
+			if(this.getAttribute('redirectUrl') != "") {
+				document.location.replace(this.getAttribute('redirectUrl'));
+			}
+		}
+		return false;
+	}
+}
+
+/* ---- detection functions ---- */
+deconcept.SWFObjectUtil.getPlayerVersion = function(){
+	var PlayerVersion = new deconcept.PlayerVersion([0,0,0]);
+	if(navigator.plugins && navigator.mimeTypes.length){
+		var x = navigator.plugins["Shockwave Flash"];
+		if(x && x.description) {
+			PlayerVersion = new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split("."));
+		}
+	}else if (navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ // if Windows CE
+		var axo = 1;
+		var counter = 3;
+		while(axo) {
+			try {
+				counter++;
+				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+ counter);
+//				document.write("player v: "+ counter);
+				PlayerVersion = new deconcept.PlayerVersion([counter,0,0]);
+			} catch (e) {
+				axo = null;
+			}
+		}
+	} else { // Win IE (non mobile)
+		// do minor version lookup in IE, but avoid fp6 crashing issues
+		// see http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/
+		try{
+			var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
+		}catch(e){
+			try {
+				var axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
+				PlayerVersion = new deconcept.PlayerVersion([6,0,21]);
+				axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code)
+			} catch(e) {
+				if (PlayerVersion.major == 6) {
+					return PlayerVersion;
+				}
+			}
+			try {
+				axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
+			} catch(e) {}
+		}
+		if (axo != null) {
+			PlayerVersion = new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));
+		}
+	}
+	return PlayerVersion;
+}
+deconcept.PlayerVersion = function(arrVersion){
+	this.major = arrVersion[0] != null ? parseInt(arrVersion[0]) : 0;
+	this.minor = arrVersion[1] != null ? parseInt(arrVersion[1]) : 0;
+	this.rev = arrVersion[2] != null ? parseInt(arrVersion[2]) : 0;
+}
+deconcept.PlayerVersion.prototype.versionIsValid = function(fv){
+	if(this.major < fv.major) return false;
+	if(this.major > fv.major) return true;
+	if(this.minor < fv.minor) return false;
+	if(this.minor > fv.minor) return true;
+	if(this.rev < fv.rev) return false;
+	return true;
+}
+/* ---- get value of query string param ---- */
+deconcept.util = {
+	getRequestParameter: function(param) {
+		var q = document.location.search || document.location.hash;
+		if (param == null) { return q; }
+		if(q) {
+			var pairs = q.substring(1).split("&");
+			for (var i=0; i < pairs.length; i++) {
+				if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
+					return pairs[i].substring((pairs[i].indexOf("=")+1));
+				}
+			}
+		}
+		return "";
+	}
+}
+/* fix for video streaming bug */
+deconcept.SWFObjectUtil.cleanupSWFs = function() {
+	var objects = document.getElementsByTagName("OBJECT");
+	for (var i = objects.length - 1; i >= 0; i--) {
+		objects[i].style.display = 'none';
+		for (var x in objects[i]) {
+			if (typeof objects[i][x] == 'function') {
+				objects[i][x] = function(){};
+			}
+		}
+	}
+}
+// fixes bug in some fp9 versions see http://blog.deconcept.com/2006/07/28/swfobject-143-released/
+if (deconcept.SWFObject.doPrepUnload) {
+	if (!deconcept.unloadSet) {
+		deconcept.SWFObjectUtil.prepUnload = function() {
+			__flash_unloadHandler = function(){};
+			__flash_savedUnloadHandler = function(){};
+			window.attachEvent("onunload", deconcept.SWFObjectUtil.cleanupSWFs);
+		}
+		window.attachEvent("onbeforeunload", deconcept.SWFObjectUtil.prepUnload);
+		deconcept.unloadSet = true;
+	}
+}
+/* add document.getElementById if needed (mobile IE < 5) */
+if (!document.getElementById && document.all) { document.getElementById = function(id) { return document.all[id]; }}
+
+/* add some aliases for ease of use/backwards compatibility */
+var getQueryParamValue = deconcept.util.getRequestParameter;
+var FlashObject = deconcept.SWFObject; // for legacy support
+var SWFObject = deconcept.SWFObject;
+
+/**
+ * Wraps Flash embedding functionality and allows communication with SWF through
+ * attributes.
+ *
+ * @namespace YAHOO.widget
+ * @class FlashAdapter
+ * @uses YAHOO.util.AttributeProvider
+ */
+YAHOO.widget.FlashAdapter = function(swfURL, containerID, attributes)
+{
+	// set up the initial events and attributes stuff
+	this._queue = this._queue || [];
+	this._events = this._events || {};
+	this._configs = this._configs || {};
+	attributes = attributes || {};
+	
+	//the Flash Player external interface code from Adobe doesn't play nicely
+	//with the default value, yui-gen, in IE
+	this._id = attributes.id = attributes.id || YAHOO.util.Dom.generateId(null, "yuigen");
+	attributes.version = attributes.version || "9.0.45";
+	attributes.backgroundColor = attributes.backgroundColor || "#ffffff";
+	
+	//we can't use the initial attributes right away
+	//so save them for once the SWF finishes loading
+	this._attributes = attributes;
+	
+	this._swfURL = swfURL;
+	
+	//embed the SWF file in the page
+	this._embedSWF(this._swfURL, containerID, attributes.id, attributes.version, attributes.backgroundColor, attributes.expressInstall);
+	
+	/**
+	 * Fires when the SWF is initialized and communication is possible.
+	 * @event contentReady
+	 */
+	this.createEvent("contentReady");
+};
+
+YAHOO.extend(YAHOO.widget.FlashAdapter, YAHOO.util.AttributeProvider,
+{
+	/**
+	 * The URL of the SWF file.
+	 * @property _swfURL
+	 * @type String
+	 * @private
+	 */
+	_swfURL: null,
+
+	/**
+	 * A reference to the embedded SWF file.
+	 * @property _swf
+	 * @private
+	 */
+	_swf: null,
+
+	/**
+	 * The id of this instance.
+	 * @property _id
+	 * @type String
+	 * @private
+	 */
+	_id: null,
+	
+	/**
+	 * The initializing attributes are stored here until the SWF is ready.
+	 * @property _attributes
+	 * @type Object
+	 * @private
+	 */
+	_attributes: null, //the intializing attributes
+
+	/**
+	 * Public accessor to the unique name of the FlashAdapter instance.
+	 *
+	 * @method toString
+	 * @return {String} Unique name of the FlashAdapter instance.
+	 */
+	toString: function()
+	{
+		return "FlashAdapter " + this._id;
+	},
+
+	/**
+	 * Embeds the SWF in the page and associates it with this instance.
+	 *
+	 * @method _embedSWF
+	 * @private
+	 */
+	_embedSWF: function(swfURL, containerID, swfID, version, backgroundColor, expressInstall)
+	{
+		//standard SWFObject embed
+		var swfObj = new deconcept.SWFObject(swfURL, swfID, "100%", "100%", version, backgroundColor, expressInstall);
+
+		//make sure we can communicate with ExternalInterface
+		swfObj.addParam("allowScriptAccess", "always");
+		
+		//again, a useful ExternalInterface trick
+		swfObj.addVariable("allowedDomain", document.location.hostname);
+
+		//tell the SWF which HTML element it is in
+		swfObj.addVariable("elementID", swfID);
+
+		// set the name of the function to call when the swf has an event
+		swfObj.addVariable("eventHandler", "YAHOO.widget.FlashAdapter.eventHandler");
+
+		var container = YAHOO.util.Dom.get(containerID);
+		var result = swfObj.write(container);
+		if(result)
+		{
+			this._swf = YAHOO.util.Dom.get(swfID);
+			//if successful, let's add an owner property to the SWF reference
+			//this will allow the event handler to communicate with a YAHOO.widget.FlashAdapter
+			this._swf.owner = this;
+		}
+	},
+
+	/**
+	 * Handles or re-dispatches events received from the SWF.
+	 *
+	 * @method _eventHandler
+	 * @private
+	 */
+	_eventHandler: function(event)
+	{
+		var type = event.type;
+		switch(type)
+		{
+			case "swfReady":
+			{
+   				this._loadHandler();
+				return;
+			}
+			case "log":
+			{
+				return;
+			}
+		}
+		
+		//be sure to return after your case or the event will automatically fire!
+		this.fireEvent(type, event);
+	},
+
+	/**
+	 * Called when the SWF has been initialized.
+	 *
+	 * @method _loadHandler
+	 * @private
+	 */
+	_loadHandler: function()
+	{
+		this._initAttributes(this._attributes);
+		this.setAttributes(this._attributes, true);
+		this._attributes = null;
+		
+		this.fireEvent("contentReady");
+	},
+	
+	/**
+	 * Initializes the attributes.
+	 *
+	 * @method _initAttributes
+	 * @private
+	 */
+	_initAttributes: function(attributes)
+	{
+		//should be overridden if other attributes need to be set up
+		
+		/**
+		 * @attribute swfURL
+		 * @description Absolute or relative URL to the SWF displayed by the FlashAdapter.
+		 * @type String
+		 */
+		this.getAttributeConfig("swfURL",
+		{
+			method: this._getSWFURL
+		});
+	},
+	
+	/**
+	 * Getter for swfURL attribute.
+	 *
+	 * @method _getSWFURL
+	 * @private
+	 */
+	_getSWFURL: function()
+	{
+		return this._swfURL;
+	}
+});
+
+/**
+ * Receives event messages from SWF and passes them to the correct instance
+ * of FlashAdapter.
+ *
+ * @method YAHOO.widget.FlashAdapter.eventHandler
+ * @static
+ * @private
+ */
+YAHOO.widget.FlashAdapter.eventHandler = function(elementID, event)
+{
+	var loadedSWF = YAHOO.util.Dom.get(elementID);
+	if(!loadedSWF.owner)
+	{
+		//fix for ie: if owner doesn't exist yet, try again in a moment
+		setTimeout(function() { YAHOO.widget.FlashAdapter.eventHandler( elementID, event ); }, 0);
+	}
+	else loadedSWF.owner._eventHandler(event);
+};
+/**
+ * Uploader class for the YUI Uploader component.
+ *
+ * @namespace YAHOO.widget
+ * @class Uploader
+ * @uses YAHOO.widget.FlashAdapter
+ * @constructor
+ * @param containerId {HTMLElement} Container element for the Flash Player instance.
+ */
+YAHOO.widget.Uploader = function(containerId)
+{
+	YAHOO.widget.Uploader.superclass.constructor.call(this, YAHOO.widget.Uploader.SWFURL, containerId, null);
+	
+	/**
+	 * Fires when the user has finished selecting files in the "Open File" dialog.
+	 *
+	 * @event fileSelect
+	 * @param event.type {String} The event type
+	 * @param event.fileList {Array} An array of objects with file information
+	 * @param event.fileList[].size {Number} File size in bytes for a specific file in fileList
+	 * @param event.fileList[].cDate {Date} Creation date for a specific file in fileList
+	 * @param event.fileList[].mDate {Date} Modification date for a specific file in fileList
+	 * @param event.fileList[].name {String} File name for a specific file in fileList
+	 * @param event.fileList[].id {String} Unique file id of a specific file in fileList
+	 */
+	this.createEvent("fileSelect");
+
+	/**
+	 * Fires when an upload of a specific file has started.
+	 *
+	 * @event uploadStart
+	 * @param event.type {String} The event type
+	 * @param event.id {String} The id of the file that's started to upload
+	 */
+	this.createEvent("uploadStart");
+
+	/**
+	 * Fires when new information about the upload progress for a specific file is available.
+	 *
+	 * @event uploadProgress
+	 * @param event.type {String} The event type
+	 * @param event.id {String} The id of the file with which the upload progress data is associated
+	 * @param bytesLoaded {Number} The number of bytes of the file uploaded so far
+	 * @param bytesTotal {Number} The total size of the file
+	 */
+	this.createEvent("uploadProgress");
+	
+	/**
+	 * Fires when an upload for a specific file is cancelled.
+	 *
+	 * @event uploadCancel
+	 * @param event.type {String} The event type
+	 * @param event.id {String} The id of the file with which the upload has been cancelled.
+	 */	
+	this.createEvent("uploadCancel");
+
+	/**
+	 * Fires when an upload for a specific file is complete.
+	 *
+	 * @event uploadComplete
+	 * @param event.type {String} The event type
+	 * @param event.id {String} The id of the file for which the upload has been completed.
+	 */	
+	this.createEvent("uploadComplete");
+
+	/**
+	 * Fires when the server sends data in response to a completed upload.
+	 *
+	 * @event uploadCompleteData
+	 * @param event.type {String} The event type
+	 * @param event.id {String} The id of the file for which the upload has been completed.
+	 * @param event.data {String} The raw data returned by the server in response to the upload.
+	 */	
+	this.createEvent("uploadCompleteData");
+	
+	/**
+	 * Fires when an upload error occurs.
+	 *
+	 * @event uploadError
+	 * @param event.type {String} The event type
+	 * @param event.id {String} The id of the file that was being uploaded when the error has occurred.
+	 * @param event.status {String} The status message associated with the error.
+	 */	
+	this.createEvent("uploadError");
+}
+
+/**
+ * Location of the Uploader SWF
+ *
+ * @property Chart.SWFURL
+ * @private
+ * @static
+ * @final
+ * @default "assets/uploader.swf"
+ */
+YAHOO.widget.Uploader.SWFURL = "assets/uploader.swf";
+
+YAHOO.extend(YAHOO.widget.Uploader, YAHOO.widget.FlashAdapter,
+{
+/**
+ * Invokes the "Open File" dialog and allows the user to select the files for upload
+ *
+ * @param allowMultiple {Boolean} If true, allows for multiple file selection; if false, only a single file can be selected. False by default.
+ * @param extensionFilterArray {Array} An array of key-value pairs for permissible file extensions. The array elements should 
+ * be of the form: {description: "Images", extensions: "*.jpg; *.gif; *.png"}.
+ */
+	browse: function(allowMultiple,extensionFilterArray)
+	{
+		this._swf.browse(allowMultiple,extensionFilterArray);
+	},
+	
+/**
+ * Starts the upload of the file specified by fileID to the location specified by uploadScriptPath.
+ *
+ * @param fileID {String} The id of the file to start uploading.
+ * @param uploadScriptPath {String} The URL of the upload location.
+ * @param method {String} Either "GET" or "POST", specifying how the variables accompanying the file upload POST request should be submitted. "GET" by default.
+ * @param vars {Object} The object containing variables to be sent in the same request as the file upload.
+ * @param fieldName {String} The name of the variable in the POST request containing the file data. "Filedata" by default.
+ */
+	upload: function(fileID, uploadScriptPath, method, vars, fieldName)
+	{
+		this._swf.upload(fileID, uploadScriptPath, method, vars, fieldName);
+	},
+	
+/**
+ * Starts uploading all files in the queue. If this function is called, the upload queue is automatically managed.
+ *
+ * @param uploadScriptPath {String} The URL of the upload location.
+ * @param method {String} Either "GET" or "POST", specifying how the variables accompanying the file upload POST request should be submitted. "GET" by default.
+ * @param vars {Object} The object containing variables to be sent in the same request as the file upload.
+ * @param fieldName {String} The name of the variable in the POST request containing the file data. "Filedata" by default.
+ */
+	uploadAll: function(uploadScriptPath, method, vars, fieldName)
+	{
+		this._swf.uploadAll(uploadScriptPath, method, vars, fieldName);
+	},
+
+/**
+ * Cancels the upload of a specified file. If no file id is specified, all ongoing uploads are cancelled.
+ *
+ * @param fileID {String} The ID of the file whose upload should be cancelled.
+ */
+	cancel: function(fileID)
+	{
+		this._swf.cancel(fileID);
+	},
+
+/**
+ * Clears the list of files queued for upload.
+ *
+ */
+	clearFileList: function()
+	{
+		this._swf.clearFileList();
+	},
+	
+/**
+ * Removes the specified file from the upload queue. 
+ *
+ * @param fileID {String} The id of the file to remove from the upload queue. 
+ */
+	removeFile: function (fileID) 
+	{
+		this._swf.removeFile(fileID);
+	}
+});
+YAHOO.register("uploader", YAHOO.widget.Uploader, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/utilities/README
===================================================================
--- trunk/root/static/yui/utilities/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/utilities/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -13,6 +13,8 @@
 animation/README
 dragdrop/README
 element/README
+get/README
+yuiloader/README
 
 *************
 
@@ -26,6 +28,8 @@
 * Animation
 * Drag & Drop
 * Element
+* Get
+* YUI Loader
 
 For implementations that use four or more  of these files, it may prove
 more efficient to include utilities.js as opposed to including separate files

Modified: trunk/root/static/yui/utilities/utilities.js
===================================================================
--- trunk/root/static/yui/utilities/utilities.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/utilities/utilities.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,17 +1,36 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var A=arguments,E=null,C,B,D;for(C=0;C<A.length;C=C+1){D=A[C].split(".");E=YAHOO;for(B=(D[0]=="YAHOO")?1:0;B<D.length;B=B+1){E[D[B]]=E[D[B]]||{};E=E[D[B]];}}return E;};YAHOO.log=function(D,A,C){var B=YAHOO.widget.Logger;if(B&&B.log){return B.log(D,A,C);}else{return false;}};YAHOO.register=function(A,E,D){var I=YAHOO.env.modules;if(!I[A]){I[A]={versions:[],builds:[]};}var B=I[A],H=D.version,G=D.build,F=YAHOO.env.listeners;B.name=A;B.version=H;B.build=G;B.versions.push(H);B.builds.push(G);B.mainClass=E;for(var C=0;C<F.length;C=C+1){F[C](B);}if(E){E.VERSION=H;E.BUILD=G;}else{YAHOO.log("mainClass is undefined for module "+A,"warn");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[]};YAHOO.env.getVersion=function(A){return YAHOO.env.modules[A]||null;};YAHOO.env.ua=function(){var C={ie:0,opera:0,gecko:0,webkit:0,mobile:null};var B=navigator.userAgent,A;if((/KHTML/).test(B)){C.webkit=1;}A=B.match(/AppleWe!
 bKit\/([^\s]*)/);if(A&&A[1]){C.webkit=parseFloat(A[1]);if(/ Mobile\//.test(B)){C.mobile="Apple";}else{A=B.match(/NokiaN[^\/]*/);if(A){C.mobile=A[0];}}}if(!C.webkit){A=B.match(/Opera[\s\/]([^\s]*)/);if(A&&A[1]){C.opera=parseFloat(A[1]);A=B.match(/Opera Mini[^;]*/);if(A){C.mobile=A[0];}}else{A=B.match(/MSIE\s([^;]*)/);if(A&&A[1]){C.ie=parseFloat(A[1]);}else{A=B.match(/Gecko\/([^\s]*)/);if(A){C.gecko=1;A=B.match(/rv:([^\s\)]*)/);if(A&&A[1]){C.gecko=parseFloat(A[1]);}}}}}return C;}();(function(){YAHOO.namespace("util","widget","example");if("undefined"!==typeof YAHOO_config){var B=YAHOO_config.listener,A=YAHOO.env.listeners,D=true,C;if(B){for(C=0;C<A.length;C=C+1){if(A[C]==B){D=false;break;}}if(D){A.push(B);}}}})();YAHOO.lang=YAHOO.lang||{isArray:function(B){if(B){var A=YAHOO.lang;return A.isNumber(B.length)&&A.isFunction(B.splice);}return false;},isBoolean:function(A){return typeof A==="boolean";},isFunction:function(A){return typeof A==="function";},isNull:function(A){return !
 A===null;},isNumber:function(A){return typeof A==="number"&&is!
 Finite(A
);},isObject:function(A){return(A&&(typeof A==="object"||YAHOO.lang.isFunction(A)))||false;},isString:function(A){return typeof A==="string";},isUndefined:function(A){return typeof A==="undefined";},hasOwnProperty:function(A,B){if(Object.prototype.hasOwnProperty){return A.hasOwnProperty(B);}return !YAHOO.lang.isUndefined(A[B])&&A.constructor.prototype[B]!==A[B];},_IEEnumFix:function(C,B){if(YAHOO.env.ua.ie){var E=["toString","valueOf"],A;for(A=0;A<E.length;A=A+1){var F=E[A],D=B[F];if(YAHOO.lang.isFunction(D)&&D!=Object.prototype[F]){C[F]=D;}}}},extend:function(D,E,C){if(!E||!D){throw new Error("YAHOO.lang.extend failed, please check that all dependencies are included.");}var B=function(){};B.prototype=E.prototype;D.prototype=new B();D.prototype.constructor=D;D.superclass=E.prototype;if(E.prototype.constructor==Object.prototype.constructor){E.prototype.constructor=E;}if(C){for(var A in C){D.prototype[A]=C[A];}YAHOO.lang._IEEnumFix(D.prototype,C);}},augmentObject:function(E,D)!
 {if(!D||!E){throw new Error("Absorb failed, verify dependencies.");}var A=arguments,C,F,B=A[2];if(B&&B!==true){for(C=2;C<A.length;C=C+1){E[A[C]]=D[A[C]];}}else{for(F in D){if(B||!E[F]){E[F]=D[F];}}YAHOO.lang._IEEnumFix(E,D);}},augmentProto:function(D,C){if(!C||!D){throw new Error("Augment failed, verify dependencies.");}var A=[D.prototype,C.prototype];for(var B=2;B<arguments.length;B=B+1){A.push(arguments[B]);}YAHOO.lang.augmentObject.apply(this,A);},dump:function(A,G){var C=YAHOO.lang,D,F,I=[],J="{...}",B="f(){...}",H=", ",E=" => ";if(!C.isObject(A)){return A+"";}else{if(A instanceof Date||("nodeType" in A&&"tagName" in A)){return A;}else{if(C.isFunction(A)){return B;}}}G=(C.isNumber(G))?G:3;if(C.isArray(A)){I.push("[");for(D=0,F=A.length;D<F;D=D+1){if(C.isObject(A[D])){I.push((G>0)?C.dump(A[D],G-1):J);}else{I.push(A[D]);}I.push(H);}if(I.length>1){I.pop();}I.push("]");}else{I.push("{");for(D in A){if(C.hasOwnProperty(A,D)){I.push(D+E);if(C.isObject(A[D])){I.push((G>0)?C.du!
 mp(A[D],G-1):J);}else{I.push(A[D]);}I.push(H);}}if(I.length>1)!
 {I.pop()
;}I.push("}");}return I.join("");},substitute:function(Q,B,J){var G,F,E,M,N,P,D=YAHOO.lang,L=[],C,H="dump",K=" ",A="{",O="}";for(;;){G=Q.lastIndexOf(A);if(G<0){break;}F=Q.indexOf(O,G);if(G+1>=F){break;}C=Q.substring(G+1,F);M=C;P=null;E=M.indexOf(K);if(E>-1){P=M.substring(E+1);M=M.substring(0,E);}N=B[M];if(J){N=J(M,N,P);}if(D.isObject(N)){if(D.isArray(N)){N=D.dump(N,parseInt(P,10));}else{P=P||"";var I=P.indexOf(H);if(I>-1){P=P.substring(4);}if(N.toString===Object.prototype.toString||I>-1){N=D.dump(N,parseInt(P,10));}else{N=N.toString();}}}else{if(!D.isString(N)&&!D.isNumber(N)){N="~-"+L.length+"-~";L[L.length]=C;}}Q=Q.substring(0,G)+N+Q.substring(F+1);}for(G=L.length-1;G>=0;G=G-1){Q=Q.replace(new RegExp("~-"+G+"-~"),"{"+L[G]+"}","g");}return Q;},trim:function(A){try{return A.replace(/^\s+|\s+$/g,"");}catch(B){return A;}},merge:function(){var D={},B=arguments;for(var C=0,A=B.length;C<A;C=C+1){YAHOO.lang.augmentObject(D,B[C],true);}return D;},later:function(H,B,I,D,E){H=H||0;B=!
 B||{};var C=I,G=D,F,A;if(YAHOO.lang.isString(I)){C=B[I];}if(!C){throw new TypeError("method undefined");}if(!YAHOO.lang.isArray(G)){G=[D];}F=function(){C.apply(B,G);};A=(E)?setInterval(F,H):setTimeout(F,H);return{interval:E,cancel:function(){if(this.interval){clearInterval(A);}else{clearTimeout(A);}}};},isValue:function(B){var A=YAHOO.lang;return(A.isObject(B)||A.isString(B)||A.isNumber(B)||A.isBoolean(B));}};YAHOO.util.Lang=YAHOO.lang;YAHOO.lang.augment=YAHOO.lang.augmentProto;YAHOO.augment=YAHOO.lang.augmentProto;YAHOO.extend=YAHOO.lang.extend;YAHOO.register("yahoo",YAHOO,{version:"2.4.1",build:"742"});(function(){var B=YAHOO.util,L,J,H=0,K={},F={},N=window.document;var C=YAHOO.env.ua.opera,M=YAHOO.env.ua.webkit,A=YAHOO.env.ua.gecko,G=YAHOO.env.ua.ie;var E={HYPHEN:/(-[a-z])/i,ROOT_TAG:/^body|html$/i};var O=function(Q){if(!E.HYPHEN.test(Q)){return Q;}if(K[Q]){return K[Q];}var R=Q;while(E.HYPHEN.exec(R)){R=R.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());}K[Q]=R;retur!
 n R;};var P=function(R){var Q=F[R];if(!Q){Q=new RegExp("(?:^|\!
 \s+)"+R+
"(?:\\s+|$)");F[R]=Q;}return Q;};if(N.defaultView&&N.defaultView.getComputedStyle){L=function(Q,T){var S=null;if(T=="float"){T="cssFloat";}var R=N.defaultView.getComputedStyle(Q,"");if(R){S=R[O(T)];}return Q.style[T]||S;};}else{if(N.documentElement.currentStyle&&G){L=function(Q,S){switch(O(S)){case"opacity":var U=100;try{U=Q.filters["DXImageTransform.Microsoft.Alpha"].opacity;}catch(T){try{U=Q.filters("alpha").opacity;}catch(T){}}return U/100;case"float":S="styleFloat";default:var R=Q.currentStyle?Q.currentStyle[S]:null;return(Q.style[S]||R);}};}else{L=function(Q,R){return Q.style[R];};}}if(G){J=function(Q,R,S){switch(R){case"opacity":if(YAHOO.lang.isString(Q.style.filter)){Q.style.filter="alpha(opacity="+S*100+")";if(!Q.currentStyle||!Q.currentStyle.hasLayout){Q.style.zoom=1;}}break;case"float":R="styleFloat";default:Q.style[R]=S;}};}else{J=function(Q,R,S){if(R=="float"){R="cssFloat";}Q.style[R]=S;};}var D=function(Q,R){return Q&&Q.nodeType==1&&(!R||R(Q));};YAHOO.util.Dom={!
 get:function(S){if(S&&(S.tagName||S.item)){return S;}if(YAHOO.lang.isString(S)||!S){return N.getElementById(S);}if(S.length!==undefined){var T=[];for(var R=0,Q=S.length;R<Q;++R){T[T.length]=B.Dom.get(S[R]);}return T;}return S;},getStyle:function(Q,S){S=O(S);var R=function(T){return L(T,S);};return B.Dom.batch(Q,R,B.Dom,true);},setStyle:function(Q,S,T){S=O(S);var R=function(U){J(U,S,T);};B.Dom.batch(Q,R,B.Dom,true);},getXY:function(Q){var R=function(S){if((S.parentNode===null||S.offsetParent===null||this.getStyle(S,"display")=="none")&&S!=S.ownerDocument.body){return false;}return I(S);};return B.Dom.batch(Q,R,B.Dom,true);},getX:function(Q){var R=function(S){return B.Dom.getXY(S)[0];};return B.Dom.batch(Q,R,B.Dom,true);},getY:function(Q){var R=function(S){return B.Dom.getXY(S)[1];};return B.Dom.batch(Q,R,B.Dom,true);},setXY:function(Q,T,S){var R=function(W){var V=this.getStyle(W,"position");if(V=="static"){this.setStyle(W,"position","relative");V="relative";}var Y=this.getXY!
 (W);if(Y===false){return false;}var X=[parseInt(this.getStyle(!
 W,"left"
),10),parseInt(this.getStyle(W,"top"),10)];if(isNaN(X[0])){X[0]=(V=="relative")?0:W.offsetLeft;}if(isNaN(X[1])){X[1]=(V=="relative")?0:W.offsetTop;}if(T[0]!==null){W.style.left=T[0]-Y[0]+X[0]+"px";}if(T[1]!==null){W.style.top=T[1]-Y[1]+X[1]+"px";}if(!S){var U=this.getXY(W);if((T[0]!==null&&U[0]!=T[0])||(T[1]!==null&&U[1]!=T[1])){this.setXY(W,T,true);}}};B.Dom.batch(Q,R,B.Dom,true);},setX:function(R,Q){B.Dom.setXY(R,[Q,null]);},setY:function(Q,R){B.Dom.setXY(Q,[null,R]);},getRegion:function(Q){var R=function(S){if((S.parentNode===null||S.offsetParent===null||this.getStyle(S,"display")=="none")&&S!=N.body){return false;}var T=B.Region.getRegion(S);return T;};return B.Dom.batch(Q,R,B.Dom,true);},getClientWidth:function(){return B.Dom.getViewportWidth();},getClientHeight:function(){return B.Dom.getViewportHeight();},getElementsByClassName:function(U,Y,V,W){Y=Y||"*";V=(V)?B.Dom.get(V):null||N;if(!V){return[];}var R=[],Q=V.getElementsByTagName(Y),X=P(U);for(var S=0,T=Q.length;S<T;!
 ++S){if(X.test(Q[S].className)){R[R.length]=Q[S];if(W){W.call(Q[S],Q[S]);}}}return R;},hasClass:function(S,R){var Q=P(R);var T=function(U){return Q.test(U.className);};return B.Dom.batch(S,T,B.Dom,true);},addClass:function(R,Q){var S=function(T){if(this.hasClass(T,Q)){return false;}T.className=YAHOO.lang.trim([T.className,Q].join(" "));return true;};return B.Dom.batch(R,S,B.Dom,true);},removeClass:function(S,R){var Q=P(R);var T=function(U){if(!this.hasClass(U,R)){return false;}var V=U.className;U.className=V.replace(Q," ");if(this.hasClass(U,R)){this.removeClass(U,R);}U.className=YAHOO.lang.trim(U.className);return true;};return B.Dom.batch(S,T,B.Dom,true);},replaceClass:function(T,R,Q){if(!Q||R===Q){return false;}var S=P(R);var U=function(V){if(!this.hasClass(V,R)){this.addClass(V,Q);return true;}V.className=V.className.replace(S," "+Q+" ");if(this.hasClass(V,R)){this.replaceClass(V,R,Q);}V.className=YAHOO.lang.trim(V.className);return true;};return B.Dom.batch(T,U,B.Dom,t!
 rue);},generateId:function(Q,S){S=S||"yui-gen";var R=function(!
 T){if(T&
&T.id){return T.id;}var U=S+H++;if(T){T.id=U;}return U;};return B.Dom.batch(Q,R,B.Dom,true)||R.apply(B.Dom,arguments);},isAncestor:function(Q,R){Q=B.Dom.get(Q);R=B.Dom.get(R);if(!Q||!R){return false;}if(Q.contains&&R.nodeType&&!M){return Q.contains(R);}else{if(Q.compareDocumentPosition&&R.nodeType){return !!(Q.compareDocumentPosition(R)&16);}else{if(R.nodeType){return !!this.getAncestorBy(R,function(S){return S==Q;});}}}return false;},inDocument:function(Q){return this.isAncestor(N.documentElement,Q);},getElementsBy:function(X,R,S,U){R=R||"*";S=(S)?B.Dom.get(S):null||N;if(!S){return[];}var T=[],W=S.getElementsByTagName(R);for(var V=0,Q=W.length;V<Q;++V){if(X(W[V])){T[T.length]=W[V];if(U){U(W[V]);}}}return T;},batch:function(U,X,W,S){U=(U&&(U.tagName||U.item))?U:B.Dom.get(U);if(!U||!X){return false;}var T=(S)?W:window;if(U.tagName||U.length===undefined){return X.call(T,U,W);}var V=[];for(var R=0,Q=U.length;R<Q;++R){V[V.length]=X.call(T,U[R],W);}return V;},getDocumentHeight:fu!
 nction(){var R=(N.compatMode!="CSS1Compat")?N.body.scrollHeight:N.documentElement.scrollHeight;var Q=Math.max(R,B.Dom.getViewportHeight());return Q;},getDocumentWidth:function(){var R=(N.compatMode!="CSS1Compat")?N.body.scrollWidth:N.documentElement.scrollWidth;var Q=Math.max(R,B.Dom.getViewportWidth());return Q;},getViewportHeight:function(){var Q=self.innerHeight;var R=N.compatMode;if((R||G)&&!C){Q=(R=="CSS1Compat")?N.documentElement.clientHeight:N.body.clientHeight;
-}return Q;},getViewportWidth:function(){var Q=self.innerWidth;var R=N.compatMode;if(R||G){Q=(R=="CSS1Compat")?N.documentElement.clientWidth:N.body.clientWidth;}return Q;},getAncestorBy:function(Q,R){while(Q=Q.parentNode){if(D(Q,R)){return Q;}}return null;},getAncestorByClassName:function(R,Q){R=B.Dom.get(R);if(!R){return null;}var S=function(T){return B.Dom.hasClass(T,Q);};return B.Dom.getAncestorBy(R,S);},getAncestorByTagName:function(R,Q){R=B.Dom.get(R);if(!R){return null;}var S=function(T){return T.tagName&&T.tagName.toUpperCase()==Q.toUpperCase();};return B.Dom.getAncestorBy(R,S);},getPreviousSiblingBy:function(Q,R){while(Q){Q=Q.previousSibling;if(D(Q,R)){return Q;}}return null;},getPreviousSibling:function(Q){Q=B.Dom.get(Q);if(!Q){return null;}return B.Dom.getPreviousSiblingBy(Q);},getNextSiblingBy:function(Q,R){while(Q){Q=Q.nextSibling;if(D(Q,R)){return Q;}}return null;},getNextSibling:function(Q){Q=B.Dom.get(Q);if(!Q){return null;}return B.Dom.getNextSiblingBy(Q);},g!
 etFirstChildBy:function(Q,S){var R=(D(Q.firstChild,S))?Q.firstChild:null;return R||B.Dom.getNextSiblingBy(Q.firstChild,S);},getFirstChild:function(Q,R){Q=B.Dom.get(Q);if(!Q){return null;}return B.Dom.getFirstChildBy(Q);},getLastChildBy:function(Q,S){if(!Q){return null;}var R=(D(Q.lastChild,S))?Q.lastChild:null;return R||B.Dom.getPreviousSiblingBy(Q.lastChild,S);},getLastChild:function(Q){Q=B.Dom.get(Q);return B.Dom.getLastChildBy(Q);},getChildrenBy:function(R,T){var S=B.Dom.getFirstChildBy(R,T);var Q=S?[S]:[];B.Dom.getNextSiblingBy(S,function(U){if(!T||T(U)){Q[Q.length]=U;}return false;});return Q;},getChildren:function(Q){Q=B.Dom.get(Q);if(!Q){}return B.Dom.getChildrenBy(Q);},getDocumentScrollLeft:function(Q){Q=Q||N;return Math.max(Q.documentElement.scrollLeft,Q.body.scrollLeft);},getDocumentScrollTop:function(Q){Q=Q||N;return Math.max(Q.documentElement.scrollTop,Q.body.scrollTop);},insertBefore:function(R,Q){R=B.Dom.get(R);Q=B.Dom.get(Q);if(!R||!Q||!Q.parentNode){return n!
 ull;}return Q.parentNode.insertBefore(R,Q);},insertAfter:funct!
 ion(R,Q)
{R=B.Dom.get(R);Q=B.Dom.get(Q);if(!R||!Q||!Q.parentNode){return null;}if(Q.nextSibling){return Q.parentNode.insertBefore(R,Q.nextSibling);}else{return Q.parentNode.appendChild(R);}},getClientRegion:function(){var S=B.Dom.getDocumentScrollTop(),R=B.Dom.getDocumentScrollLeft(),T=B.Dom.getViewportWidth()+R,Q=B.Dom.getViewportHeight()+S;return new B.Region(S,T,Q,R);}};var I=function(){if(N.documentElement.getBoundingClientRect){return function(R){var S=R.getBoundingClientRect();var Q=R.ownerDocument;return[S.left+B.Dom.getDocumentScrollLeft(Q),S.top+B.Dom.getDocumentScrollTop(Q)];};}else{return function(S){var T=[S.offsetLeft,S.offsetTop];var R=S.offsetParent;var Q=(M&&B.Dom.getStyle(S,"position")=="absolute"&&S.offsetParent==S.ownerDocument.body);if(R!=S){while(R){T[0]+=R.offsetLeft;T[1]+=R.offsetTop;if(!Q&&M&&B.Dom.getStyle(R,"position")=="absolute"){Q=true;}R=R.offsetParent;}}if(Q){T[0]-=S.ownerDocument.body.offsetLeft;T[1]-=S.ownerDocument.body.offsetTop;}R=S.parentNode;whil!
 e(R.tagName&&!E.ROOT_TAG.test(R.tagName)){if(B.Dom.getStyle(R,"display").search(/^inline|table-row.*$/i)){T[0]-=R.scrollLeft;T[1]-=R.scrollTop;}R=R.parentNode;}return T;};}}();})();YAHOO.util.Region=function(C,D,A,B){this.top=C;this[1]=C;this.right=D;this.bottom=A;this.left=B;this[0]=B;};YAHOO.util.Region.prototype.contains=function(A){return(A.left>=this.left&&A.right<=this.right&&A.top>=this.top&&A.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(E){var C=Math.max(this.top,E.top);var D=Math.min(this.right,E.right);var A=Math.min(this.bottom,E.bottom);var B=Math.max(this.left,E.left);if(A>=C&&D>=B){return new YAHOO.util.Region(C,D,A,B);}else{return null;}};YAHOO.util.Region.prototype.union=function(E){var C=Math.min(this.top,E.top);var D=Math.max(this.right,E.right);var A=Math.max(this.bottom,E.bottom);var B=Math.min(this.left,E.left);return new YAHOO!
 .util.Region(C,D,A,B);};YAHOO.util.Region.prototype.toString=f!
 unction(
){return("Region {top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+"}");};YAHOO.util.Region.getRegion=function(D){var F=YAHOO.util.Dom.getXY(D);var C=F[1];var E=F[0]+D.offsetWidth;var A=F[1]+D.offsetHeight;var B=F[0];return new YAHOO.util.Region(C,E,A,B);};YAHOO.util.Point=function(A,B){if(YAHOO.lang.isArray(A)){B=A[1];A=A[0];}this.x=this.right=this.left=this[0]=A;this.y=this.top=this.bottom=this[1]=B;};YAHOO.util.Point.prototype=new YAHOO.util.Region();YAHOO.register("dom",YAHOO.util.Dom,{version:"2.4.1",build:"742"});YAHOO.util.CustomEvent=function(D,B,C,A){this.type=D;this.scope=B||window;this.silent=C;this.signature=A||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){}var E="_YUICEOnSubscribe";if(D!==E){this.subscribeEvent=new YAHOO.util.CustomEvent(E,this,true);}this.lastError=null;};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(B,C,A){if(!B){throw new !
 Error("Invalid callback for subscriber to '"+this.type+"'");}if(this.subscribeEvent){this.subscribeEvent.fire(B,C,A);}this.subscribers.push(new YAHOO.util.Subscriber(B,C,A));},unsubscribe:function(D,F){if(!D){return this.unsubscribeAll();}var E=false;for(var B=0,A=this.subscribers.length;B<A;++B){var C=this.subscribers[B];if(C&&C.contains(D,F)){this._delete(B);E=true;}}return E;},fire:function(){var D=this.subscribers.length;if(!D&&this.silent){return true;}var H=[],F=true,C,I=false;for(C=0;C<arguments.length;++C){H.push(arguments[C]);}if(!this.silent){}for(C=0;C<D;++C){var L=this.subscribers[C];if(!L){I=true;}else{if(!this.silent){}var K=L.getScope(this.scope);if(this.signature==YAHOO.util.CustomEvent.FLAT){var A=null;if(H.length>0){A=H[0];}try{F=L.fn.call(K,A,L.obj);}catch(E){this.lastError=E;}}else{try{F=L.fn.call(K,this.type,H,L.obj);}catch(G){this.lastError=G;}}if(false===F){if(!this.silent){}return false;}}}if(I){var J=[],B=this.subscribers;for(C=0,D=B.length;C<D;C=C+!
 1){J.push(B[C]);}this.subscribers=J;}return true;},unsubscribe!
 All:func
tion(){for(var B=0,A=this.subscribers.length;B<A;++B){this._delete(A-1-B);}this.subscribers=[];return B;},_delete:function(A){var B=this.subscribers[A];if(B){delete B.fn;delete B.obj;}this.subscribers[A]=null;},toString:function(){return"CustomEvent: '"+this.type+"', scope: "+this.scope;}};YAHOO.util.Subscriber=function(B,C,A){this.fn=B;this.obj=YAHOO.lang.isUndefined(C)?null:C;this.override=A;};YAHOO.util.Subscriber.prototype.getScope=function(A){if(this.override){if(this.override===true){return this.obj;}else{return this.override;}}return A;};YAHOO.util.Subscriber.prototype.contains=function(A,B){if(B){return(this.fn==A&&this.obj==B);}else{return(this.fn==A);}};YAHOO.util.Subscriber.prototype.toString=function(){return"Subscriber { obj: "+this.obj+", override: "+(this.override||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var H=false;var I=[];var J=[];var G=[];var E=[];var C=0;var F=[];var B=[];var A=0;var D={63232:38,63233:40,63234:37,63235:39,63276:33,6!
 3277:34,25:9};return{POLL_RETRYS:4000,POLL_INTERVAL:10,EL:0,TYPE:1,FN:2,WFN:3,UNLOAD_OBJ:3,ADJ_SCOPE:4,OBJ:5,OVERRIDE:6,lastError:null,isSafari:YAHOO.env.ua.webkit,webkit:YAHOO.env.ua.webkit,isIE:YAHOO.env.ua.ie,_interval:null,_dri:null,DOMReady:false,startInterval:function(){if(!this._interval){var K=this;var L=function(){K._tryPreloadAttach();};this._interval=setInterval(L,this.POLL_INTERVAL);}},onAvailable:function(P,M,Q,O,N){var K=(YAHOO.lang.isString(P))?[P]:P;for(var L=0;L<K.length;L=L+1){F.push({id:K[L],fn:M,obj:Q,override:O,checkReady:N});}C=this.POLL_RETRYS;this.startInterval();},onContentReady:function(M,K,N,L){this.onAvailable(M,K,N,L,true);},onDOMReady:function(K,M,L){if(this.DOMReady){setTimeout(function(){var N=window;if(L){if(L===true){N=M;}else{N=L;}}K.call(N,"DOMReady",[],M);},0);}else{this.DOMReadyEvent.subscribe(K,M,L);}},addListener:function(M,K,V,Q,L){if(!V||!V.call){return false;}if(this._isValidCollection(M)){var W=true;for(var R=0,T=M.length;R<T;++R)!
 {W=this.on(M[R],K,V,Q,L)&&W;}return W;}else{if(YAHOO.lang.isSt!
 ring(M))
{var P=this.getEl(M);if(P){M=P;}else{this.onAvailable(M,function(){YAHOO.util.Event.on(M,K,V,Q,L);});return true;}}}if(!M){return false;}if("unload"==K&&Q!==this){J[J.length]=[M,K,V,Q,L];return true;}var Y=M;if(L){if(L===true){Y=Q;}else{Y=L;}}var N=function(Z){return V.call(Y,YAHOO.util.Event.getEvent(Z,M),Q);};var X=[M,K,V,N,Y,Q,L];var S=I.length;I[S]=X;if(this.useLegacyEvent(M,K)){var O=this.getLegacyIndex(M,K);if(O==-1||M!=G[O][0]){O=G.length;B[M.id+K]=O;G[O]=[M,K,M["on"+K]];E[O]=[];M["on"+K]=function(Z){YAHOO.util.Event.fireLegacyEvent(YAHOO.util.Event.getEvent(Z),O);};}E[O].push(X);}else{try{this._simpleAdd(M,K,N,false);}catch(U){this.lastError=U;this.removeListener(M,K,V);return false;}}return true;},fireLegacyEvent:function(O,M){var Q=true,K,S,R,T,P;S=E[M];for(var L=0,N=S.length;L<N;++L){R=S[L];if(R&&R[this.WFN]){T=R[this.ADJ_SCOPE];P=R[this.WFN].call(T,O);Q=(Q&&P);}}K=G[M];if(K&&K[2]){K[2](O);}return Q;},getLegacyIndex:function(L,M){var K=this.generateId(L)+M;if(type!
 of B[K]=="undefined"){return -1;}else{return B[K];}},useLegacyEvent:function(L,M){if(this.webkit&&("click"==M||"dblclick"==M)){var K=parseInt(this.webkit,10);if(!isNaN(K)&&K<418){return true;}}return false;},removeListener:function(L,K,T){var O,R,V;if(typeof L=="string"){L=this.getEl(L);}else{if(this._isValidCollection(L)){var U=true;for(O=0,R=L.length;O<R;++O){U=(this.removeListener(L[O],K,T)&&U);}return U;}}if(!T||!T.call){return this.purgeElement(L,false,K);}if("unload"==K){for(O=0,R=J.length;O<R;O++){V=J[O];if(V&&V[0]==L&&V[1]==K&&V[2]==T){J[O]=null;return true;}}return false;}var P=null;var Q=arguments[3];if("undefined"===typeof Q){Q=this._getCacheIndex(L,K,T);}if(Q>=0){P=I[Q];}if(!L||!P){return false;}if(this.useLegacyEvent(L,K)){var N=this.getLegacyIndex(L,K);var M=E[N];if(M){for(O=0,R=M.length;O<R;++O){V=M[O];if(V&&V[this.EL]==L&&V[this.TYPE]==K&&V[this.FN]==T){M[O]=null;break;}}}}else{try{this._simpleRemove(L,K,P[this.WFN],false);}catch(S){this.lastError=S;return f!
 alse;}}delete I[Q][this.WFN];delete I[Q][this.FN];I[Q]=null;re!
 turn tru
e;},getTarget:function(M,L){var K=M.target||M.srcElement;return this.resolveTextNode(K);},resolveTextNode:function(K){if(K&&3==K.nodeType){return K.parentNode;}else{return K;}},getPageX:function(L){var K=L.pageX;if(!K&&0!==K){K=L.clientX||0;if(this.isIE){K+=this._getScrollLeft();}}return K;},getPageY:function(K){var L=K.pageY;if(!L&&0!==L){L=K.clientY||0;if(this.isIE){L+=this._getScrollTop();}}return L;},getXY:function(K){return[this.getPageX(K),this.getPageY(K)];
-},getRelatedTarget:function(L){var K=L.relatedTarget;if(!K){if(L.type=="mouseout"){K=L.toElement;}else{if(L.type=="mouseover"){K=L.fromElement;}}}return this.resolveTextNode(K);},getTime:function(M){if(!M.time){var L=new Date().getTime();try{M.time=L;}catch(K){this.lastError=K;return L;}}return M.time;},stopEvent:function(K){this.stopPropagation(K);this.preventDefault(K);},stopPropagation:function(K){if(K.stopPropagation){K.stopPropagation();}else{K.cancelBubble=true;}},preventDefault:function(K){if(K.preventDefault){K.preventDefault();}else{K.returnValue=false;}},getEvent:function(M,K){var L=M||window.event;if(!L){var N=this.getEvent.caller;while(N){L=N.arguments[0];if(L&&Event==L.constructor){break;}N=N.caller;}}return L;},getCharCode:function(L){var K=L.keyCode||L.charCode||0;if(YAHOO.env.ua.webkit&&(K in D)){K=D[K];}return K;},_getCacheIndex:function(O,P,N){for(var M=0,L=I.length;M<L;++M){var K=I[M];if(K&&K[this.FN]==N&&K[this.EL]==O&&K[this.TYPE]==P){return M;}}return !
 -1;},generateId:function(K){var L=K.id;if(!L){L="yuievtautoid-"+A;++A;K.id=L;}return L;},_isValidCollection:function(L){try{return(L&&typeof L!=="string"&&L.length&&!L.tagName&&!L.alert&&typeof L[0]!=="undefined");}catch(K){return false;}},elCache:{},getEl:function(K){return(typeof K==="string")?document.getElementById(K):K;},clearCache:function(){},DOMReadyEvent:new YAHOO.util.CustomEvent("DOMReady",this),_load:function(L){if(!H){H=true;var K=YAHOO.util.Event;K._ready();K._tryPreloadAttach();}},_ready:function(L){var K=YAHOO.util.Event;if(!K.DOMReady){K.DOMReady=true;K.DOMReadyEvent.fire();K._simpleRemove(document,"DOMContentLoaded",K._ready);}},_tryPreloadAttach:function(){if(this.locked){return false;}if(this.isIE){if(!this.DOMReady){this.startInterval();return false;}}this.locked=true;var P=!H;if(!P){P=(C>0);}var O=[];var Q=function(S,T){var R=S;if(T.override){if(T.override===true){R=T.obj;}else{R=T.override;}}T.fn.call(R,T.obj);};var L,K,N,M;for(L=0,K=F.length;L<K;++L)!
 {N=F[L];if(N&&!N.checkReady){M=this.getEl(N.id);if(M){Q(M,N);F!
 [L]=null
;}else{O.push(N);}}}for(L=0,K=F.length;L<K;++L){N=F[L];if(N&&N.checkReady){M=this.getEl(N.id);if(M){if(H||M.nextSibling){Q(M,N);F[L]=null;}}else{O.push(N);}}}C=(O.length===0)?0:C-1;if(P){this.startInterval();}else{clearInterval(this._interval);this._interval=null;}this.locked=false;return true;},purgeElement:function(O,P,R){var M=(YAHOO.lang.isString(O))?this.getEl(O):O;var Q=this.getListeners(M,R),N,K;if(Q){for(N=0,K=Q.length;N<K;++N){var L=Q[N];this.removeListener(M,L.type,L.fn,L.index);}}if(P&&M&&M.childNodes){for(N=0,K=M.childNodes.length;N<K;++N){this.purgeElement(M.childNodes[N],P,R);}}},getListeners:function(M,K){var P=[],L;if(!K){L=[I,J];}else{if(K==="unload"){L=[J];}else{L=[I];}}var R=(YAHOO.lang.isString(M))?this.getEl(M):M;for(var O=0;O<L.length;O=O+1){var T=L[O];if(T&&T.length>0){for(var Q=0,S=T.length;Q<S;++Q){var N=T[Q];if(N&&N[this.EL]===R&&(!K||K===N[this.TYPE])){P.push({type:N[this.TYPE],fn:N[this.FN],obj:N[this.OBJ],adjust:N[this.OVERRIDE],scope:N[this.ADJ_!
 SCOPE],index:Q});}}}}return(P.length)?P:null;},_unload:function(R){var Q=YAHOO.util.Event,O,N,L,K,M;for(O=0,K=J.length;O<K;++O){L=J[O];if(L){var P=window;if(L[Q.ADJ_SCOPE]){if(L[Q.ADJ_SCOPE]===true){P=L[Q.UNLOAD_OBJ];}else{P=L[Q.ADJ_SCOPE];}}L[Q.FN].call(P,Q.getEvent(R,L[Q.EL]),L[Q.UNLOAD_OBJ]);J[O]=null;L=null;P=null;}}J=null;if(YAHOO.env.ua.ie&&I&&I.length>0){N=I.length;while(N){M=N-1;L=I[M];if(L){Q.removeListener(L[Q.EL],L[Q.TYPE],L[Q.FN],M);}N--;}L=null;}G=null;Q._simpleRemove(window,"unload",Q._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var K=document.documentElement,L=document.body;if(K&&(K.scrollTop||K.scrollLeft)){return[K.scrollTop,K.scrollLeft];}else{if(L){return[L.scrollTop,L.scrollLeft];}else{return[0,0];}}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(M,N,L,K){M.addEventListener(N,L,(K));};}else{if(window.attachEvent){retur!
 n function(M,N,L,K){M.attachEvent("on"+N,L);};}else{return fun!
 ction(){
};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(M,N,L,K){M.removeEventListener(N,L,(K));};}else{if(window.detachEvent){return function(L,M,K){L.detachEvent("on"+M,K);};}else{return function(){};}}}()};}();(function(){var A=YAHOO.util.Event;A.on=A.addListener;if(A.isIE){YAHOO.util.Event.onDOMReady(YAHOO.util.Event._tryPreloadAttach,YAHOO.util.Event,true);A._dri=setInterval(function(){var C=document.createElement("p");try{C.doScroll("left");clearInterval(A._dri);A._dri=null;A._ready();C=null;}catch(B){C=null;}},A.POLL_INTERVAL);}else{if(A.webkit){A._dri=setInterval(function(){var B=document.readyState;if("loaded"==B||"complete"==B){clearInterval(A._dri);A._dri=null;A._ready();}},A.POLL_INTERVAL);}else{A._simpleAdd(document,"DOMContentLoaded",A._ready);}}A._simpleAdd(window,"load",A._load);A._simpleAdd(window,"unload",A._unload);A._tryPreloadAttach();})();}YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null!
 ,__yui_subscribers:null,subscribe:function(A,C,F,E){this.__yui_events=this.__yui_events||{};var D=this.__yui_events[A];if(D){D.subscribe(C,F,E);}else{this.__yui_subscribers=this.__yui_subscribers||{};var B=this.__yui_subscribers;if(!B[A]){B[A]=[];}B[A].push({fn:C,obj:F,override:E});}},unsubscribe:function(C,E,G){this.__yui_events=this.__yui_events||{};var A=this.__yui_events;if(C){var F=A[C];if(F){return F.unsubscribe(E,G);}}else{var B=true;for(var D in A){if(YAHOO.lang.hasOwnProperty(A,D)){B=B&&A[D].unsubscribe(E,G);}}return B;}return false;},unsubscribeAll:function(A){return this.unsubscribe(A);},createEvent:function(G,D){this.__yui_events=this.__yui_events||{};var A=D||{};var I=this.__yui_events;if(I[G]){}else{var H=A.scope||this;var E=(A.silent);var B=new YAHOO.util.CustomEvent(G,H,E,YAHOO.util.CustomEvent.FLAT);I[G]=B;if(A.onSubscribeCallback){B.subscribeEvent.subscribe(A.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};
-var F=this.__yui_subscribers[G];if(F){for(var C=0;C<F.length;++C){B.subscribe(F[C].fn,F[C].obj,F[C].override);}}}return I[G];},fireEvent:function(E,D,A,C){this.__yui_events=this.__yui_events||{};var G=this.__yui_events[E];if(!G){return null;}var B=[];for(var F=1;F<arguments.length;++F){B.push(arguments[F]);}return G.fire.apply(G,B);},hasEvent:function(A){if(this.__yui_events){if(this.__yui_events[A]){return true;}}return false;}};YAHOO.util.KeyListener=function(A,F,B,C){if(!A){}else{if(!F){}else{if(!B){}}}if(!C){C=YAHOO.util.KeyListener.KEYDOWN;}var D=new YAHOO.util.CustomEvent("keyPressed");this.enabledEvent=new YAHOO.util.CustomEvent("enabled");this.disabledEvent=new YAHOO.util.CustomEvent("disabled");if(typeof A=="string"){A=document.getElementById(A);}if(typeof B=="function"){D.subscribe(B);}else{D.subscribe(B.fn,B.scope,B.correctScope);}function E(J,I){if(!F.shift){F.shift=false;}if(!F.alt){F.alt=false;}if(!F.ctrl){F.ctrl=false;}if(J.shiftKey==F.shift&&J.altKey==F.alt&!
 &J.ctrlKey==F.ctrl){var G;if(F.keys instanceof Array){for(var H=0;H<F.keys.length;H++){G=F.keys[H];if(G==J.charCode){D.fire(J.charCode,J);break;}else{if(G==J.keyCode){D.fire(J.keyCode,J);break;}}}}else{G=F.keys;if(G==J.charCode){D.fire(J.charCode,J);}else{if(G==J.keyCode){D.fire(J.keyCode,J);}}}}}this.enable=function(){if(!this.enabled){YAHOO.util.Event.addListener(A,C,E);this.enabledEvent.fire(F);}this.enabled=true;};this.disable=function(){if(this.enabled){YAHOO.util.Event.removeListener(A,C,E);this.disabledEvent.fire(F);}this.enabled=false;};this.toString=function(){return"KeyListener ["+F.keys+"] "+A.tagName+(A.id?"["+A.id+"]":"");};};YAHOO.util.KeyListener.KEYDOWN="keydown";YAHOO.util.KeyListener.KEYUP="keyup";YAHOO.util.KeyListener.KEY={ALT:18,BACK_SPACE:8,CAPS_LOCK:20,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,META:224,NUM_LOCK:144,PAGE_DOWN:34,PAGE_UP:33,PAUSE:19,PRINTSCREEN:44,RIGHT:39,SCROLL_LOCK:145,SHIFT:16,SPACE:32,TAB:9,UP:38};YAHOO!
 .register("event",YAHOO.util.Event,{version:"2.4.1",build:"742!
 "});YAHO
O.util.Connect={_msxml_progid:["Microsoft.XMLHTTP","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP"],_http_headers:{},_has_http_headers:false,_use_default_post_header:true,_default_post_header:"application/x-www-form-urlencoded; charset=UTF-8",_default_form_header:"application/x-www-form-urlencoded",_use_default_xhr_header:true,_default_xhr_header:"XMLHttpRequest",_has_default_headers:true,_default_headers:{},_isFormSubmit:false,_isFileUpload:false,_formNode:null,_sFormData:null,_poll:{},_timeOut:{},_polling_interval:50,_transaction_id:0,_submitElementValue:null,_hasSubmitListener:(function(){if(YAHOO.util.Event){YAHOO.util.Event.addListener(document,"click",function(B){var A=YAHOO.util.Event.getTarget(B);if(A.type&&A.type.toLowerCase()=="submit"){YAHOO.util.Connect._submitElementValue=encodeURIComponent(A.name)+"="+encodeURIComponent(A.value);}});return true;}return false;})(),startEvent:new YAHOO.util.CustomEvent("start"),completeEvent:new YAHOO.util.CustomEvent("complete"),successEv!
 ent:new YAHOO.util.CustomEvent("success"),failureEvent:new YAHOO.util.CustomEvent("failure"),uploadEvent:new YAHOO.util.CustomEvent("upload"),abortEvent:new YAHOO.util.CustomEvent("abort"),_customEvents:{onStart:["startEvent","start"],onComplete:["completeEvent","complete"],onSuccess:["successEvent","success"],onFailure:["failureEvent","failure"],onUpload:["uploadEvent","upload"],onAbort:["abortEvent","abort"]},setProgId:function(A){this._msxml_progid.unshift(A);},setDefaultPostHeader:function(A){if(typeof A=="string"){this._default_post_header=A;}else{if(typeof A=="boolean"){this._use_default_post_header=A;}}},setDefaultXhrHeader:function(A){if(typeof A=="string"){this._default_xhr_header=A;}else{this._use_default_xhr_header=A;}},setPollingInterval:function(A){if(typeof A=="number"&&isFinite(A)){this._polling_interval=A;}},createXhrObject:function(E){var D,A;try{A=new XMLHttpRequest();D={conn:A,tId:E};}catch(C){for(var B=0;B<this._msxml_progid.length;++B){try{A=new ActiveX!
 Object(this._msxml_progid[B]);D={conn:A,tId:E};break;}catch(C)!
 {}}}fina
lly{return D;}},getConnectionObject:function(A){var C;var D=this._transaction_id;try{if(!A){C=this.createXhrObject(D);}else{C={};C.tId=D;C.isUpload=true;}if(C){this._transaction_id++;}}catch(B){}finally{return C;}},asyncRequest:function(F,C,E,A){var D=(this._isFileUpload)?this.getConnectionObject(true):this.getConnectionObject();var B=(E&&E.argument)?E.argument:null;if(!D){return null;}else{if(E&&E.customevents){this.initCustomEvents(D,E);}if(this._isFormSubmit){if(this._isFileUpload){this.uploadFile(D,E,C,A);return D;}if(F.toUpperCase()=="GET"){if(this._sFormData.length!==0){C+=((C.indexOf("?")==-1)?"?":"&")+this._sFormData;}}else{if(F.toUpperCase()=="POST"){A=A?this._sFormData+"&"+A:this._sFormData;}}}if(F.toUpperCase()=="GET"&&(E&&E.cache===false)){C+=((C.indexOf("?")==-1)?"?":"&")+"rnd="+new Date().valueOf().toString();}D.conn.open(F,C,true);if(this._use_default_xhr_header){if(!this._default_headers["X-Requested-With"]){this.initHeader("X-Requested-With",this._default_xh!
 r_header,true);}}if((F.toUpperCase()=="POST"&&this._use_default_post_header)&&this._isFormSubmit===false){this.initHeader("Content-Type",this._default_post_header);}if(this._has_default_headers||this._has_http_headers){this.setHeader(D);}this.handleReadyState(D,E);D.conn.send(A||null);if(this._isFormSubmit===true){this.resetFormState();}this.startEvent.fire(D,B);if(D.startEvent){D.startEvent.fire(D,B);}return D;}},initCustomEvents:function(A,C){for(var B in C.customevents){if(this._customEvents[B][0]){A[this._customEvents[B][0]]=new YAHOO.util.CustomEvent(this._customEvents[B][1],(C.scope)?C.scope:null);A[this._customEvents[B][0]].subscribe(C.customevents[B]);}}},handleReadyState:function(C,D){var B=this;var A=(D&&D.argument)?D.argument:null;if(D&&D.timeout){this._timeOut[C.tId]=window.setTimeout(function(){B.abort(C,D,true);},D.timeout);}this._poll[C.tId]=window.setInterval(function(){if(C.conn&&C.conn.readyState===4){window.clearInterval(B._poll[C.tId]);delete B._poll[C.t!
 Id];if(D&&D.timeout){window.clearTimeout(B._timeOut[C.tId]);de!
 lete B._
timeOut[C.tId];}B.completeEvent.fire(C,A);if(C.completeEvent){C.completeEvent.fire(C,A);}B.handleTransactionResponse(C,D);}},this._polling_interval);},handleTransactionResponse:function(F,G,A){var D,C;var B=(G&&G.argument)?G.argument:null;try{if(F.conn.status!==undefined&&F.conn.status!==0){D=F.conn.status;}else{D=13030;}}catch(E){D=13030;}if(D>=200&&D<300||D===1223){C=this.createResponseObject(F,B);if(G&&G.success){if(!G.scope){G.success(C);}else{G.success.apply(G.scope,[C]);}}this.successEvent.fire(C);if(F.successEvent){F.successEvent.fire(C);}}else{switch(D){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:C=this.createExceptionObject(F.tId,B,(A?A:false));if(G&&G.failure){if(!G.scope){G.failure(C);}else{G.failure.apply(G.scope,[C]);}}break;default:C=this.createResponseObject(F,B);if(G&&G.failure){if(!G.scope){G.failure(C);}else{G.failure.apply(G.scope,[C]);}}}this.failureEvent.fire(C);if(F.failureEvent){F.failureEvent.fire(C);}}this.releaseObject(F);C=nul!
 l;},createResponseObject:function(A,G){var D={};var I={};try{var C=A.conn.getAllResponseHeaders();var F=C.split("\n");for(var E=0;E<F.length;E++){var B=F[E].indexOf(":");if(B!=-1){I[F[E].substring(0,B)]=F[E].substring(B+2);}}}catch(H){}D.tId=A.tId;D.status=(A.conn.status==1223)?204:A.conn.status;D.statusText=(A.conn.status==1223)?"No Content":A.conn.statusText;D.getResponseHeader=I;D.getAllResponseHeaders=C;D.responseText=A.conn.responseText;D.responseXML=A.conn.responseXML;if(G){D.argument=G;}return D;},createExceptionObject:function(H,D,A){var F=0;var G="communication failure";var C=-1;var B="transaction aborted";var E={};E.tId=H;if(A){E.status=C;E.statusText=B;}else{E.status=F;E.statusText=G;}if(D){E.argument=D;}return E;},initHeader:function(A,D,C){var B=(C)?this._default_headers:this._http_headers;B[A]=D;if(C){this._has_default_headers=true;}else{this._has_http_headers=true;}},setHeader:function(A){if(this._has_default_headers){for(var B in this._default_headers){if(YA!
 HOO.lang.hasOwnProperty(this._default_headers,B)){A.conn.setRe!
 questHea
der(B,this._default_headers[B]);
-}}}if(this._has_http_headers){for(var B in this._http_headers){if(YAHOO.lang.hasOwnProperty(this._http_headers,B)){A.conn.setRequestHeader(B,this._http_headers[B]);}}delete this._http_headers;this._http_headers={};this._has_http_headers=false;}},resetDefaultHeaders:function(){delete this._default_headers;this._default_headers={};this._has_default_headers=false;},setForm:function(K,E,B){this.resetFormState();var J;if(typeof K=="string"){J=(document.getElementById(K)||document.forms[K]);}else{if(typeof K=="object"){J=K;}else{return ;}}if(E){var F=this.createFrame(B?B:null);this._isFormSubmit=true;this._isFileUpload=true;this._formNode=J;return ;}var A,I,G,L;var H=false;for(var D=0;D<J.elements.length;D++){A=J.elements[D];L=A.disabled;I=A.name;G=A.value;if(!L&&I){switch(A.type){case"select-one":case"select-multiple":for(var C=0;C<A.options.length;C++){if(A.options[C].selected){if(window.ActiveXObject){this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(A.options[C].a!
 ttributes["value"].specified?A.options[C].value:A.options[C].text)+"&";}else{this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(A.options[C].hasAttribute("value")?A.options[C].value:A.options[C].text)+"&";}}}break;case"radio":case"checkbox":if(A.checked){this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(G)+"&";}break;case"file":case undefined:case"reset":case"button":break;case"submit":if(H===false){if(this._hasSubmitListener&&this._submitElementValue){this._sFormData+=this._submitElementValue+"&";}else{this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(G)+"&";}H=true;}break;default:this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(G)+"&";}}}this._isFormSubmit=true;this._sFormData=this._sFormData.substr(0,this._sFormData.length-1);this.initHeader("Content-Type",this._default_form_header);return this._sFormData;},resetFormState:function(){this._isFormSubmit=false;this._isFileUpload=false;this._formNode=null;this._sFormData="";},c!
 reateFrame:function(A){var B="yuiIO"+this._transaction_id;var !
 C;if(win
dow.ActiveXObject){C=document.createElement("<iframe id=\""+B+"\" name=\""+B+"\" />");if(typeof A=="boolean"){C.src="javascript:false";}else{if(typeof secureURI=="string"){C.src=A;}}}else{C=document.createElement("iframe");C.id=B;C.name=B;}C.style.position="absolute";C.style.top="-1000px";C.style.left="-1000px";document.body.appendChild(C);},appendPostData:function(A){var D=[];var B=A.split("&");for(var C=0;C<B.length;C++){var E=B[C].indexOf("=");if(E!=-1){D[C]=document.createElement("input");D[C].type="hidden";D[C].name=B[C].substring(0,E);D[C].value=B[C].substring(E+1);this._formNode.appendChild(D[C]);}}return D;},uploadFile:function(D,M,E,C){var N=this;var H="yuiIO"+D.tId;var I="multipart/form-data";var K=document.getElementById(H);var J=(M&&M.argument)?M.argument:null;var B={action:this._formNode.getAttribute("action"),method:this._formNode.getAttribute("method"),target:this._formNode.getAttribute("target")};this._formNode.setAttribute("action",E);this._formNode.setAttri!
 bute("method","POST");this._formNode.setAttribute("target",H);if(this._formNode.encoding){this._formNode.setAttribute("encoding",I);}else{this._formNode.setAttribute("enctype",I);}if(C){var L=this.appendPostData(C);}this._formNode.submit();this.startEvent.fire(D,J);if(D.startEvent){D.startEvent.fire(D,J);}if(M&&M.timeout){this._timeOut[D.tId]=window.setTimeout(function(){N.abort(D,M,true);},M.timeout);}if(L&&L.length>0){for(var G=0;G<L.length;G++){this._formNode.removeChild(L[G]);}}for(var A in B){if(YAHOO.lang.hasOwnProperty(B,A)){if(B[A]){this._formNode.setAttribute(A,B[A]);}else{this._formNode.removeAttribute(A);}}}this.resetFormState();var F=function(){if(M&&M.timeout){window.clearTimeout(N._timeOut[D.tId]);delete N._timeOut[D.tId];}N.completeEvent.fire(D,J);if(D.completeEvent){D.completeEvent.fire(D,J);}var P={};P.tId=D.tId;P.argument=M.argument;try{P.responseText=K.contentWindow.document.body?K.contentWindow.document.body.innerHTML:K.contentWindow.document.documentEle!
 ment.textContent;P.responseXML=K.contentWindow.document.XMLDoc!
 ument?K.
contentWindow.document.XMLDocument:K.contentWindow.document;}catch(O){}if(M&&M.upload){if(!M.scope){M.upload(P);}else{M.upload.apply(M.scope,[P]);}}N.uploadEvent.fire(P);if(D.uploadEvent){D.uploadEvent.fire(P);}YAHOO.util.Event.removeListener(K,"load",F);setTimeout(function(){document.body.removeChild(K);N.releaseObject(D);},100);};YAHOO.util.Event.addListener(K,"load",F);},abort:function(E,G,A){var D;var B=(G&&G.argument)?G.argument:null;if(E&&E.conn){if(this.isCallInProgress(E)){E.conn.abort();window.clearInterval(this._poll[E.tId]);delete this._poll[E.tId];if(A){window.clearTimeout(this._timeOut[E.tId]);delete this._timeOut[E.tId];}D=true;}}else{if(E&&E.isUpload===true){var C="yuiIO"+E.tId;var F=document.getElementById(C);if(F){YAHOO.util.Event.removeListener(F,"load");document.body.removeChild(F);if(A){window.clearTimeout(this._timeOut[E.tId]);delete this._timeOut[E.tId];}D=true;}}else{D=false;}}if(D===true){this.abortEvent.fire(E,B);if(E.abortEvent){E.abortEvent.fire(E,!
 B);}this.handleTransactionResponse(E,G,true);}return D;},isCallInProgress:function(B){if(B&&B.conn){return B.conn.readyState!==4&&B.conn.readyState!==0;}else{if(B&&B.isUpload===true){var A="yuiIO"+B.tId;return document.getElementById(A)?true:false;}else{return false;}}},releaseObject:function(A){if(A&&A.conn){A.conn=null;A=null;}}};YAHOO.register("connection",YAHOO.util.Connect,{version:"2.4.1",build:"742"});YAHOO.util.Anim=function(B,A,C,D){if(!B){}this.init(B,A,C,D);};YAHOO.util.Anim.prototype={toString:function(){var A=this.getEl();var B=A.id||A.tagName||A;return("Anim "+B);},patterns:{noNegatives:/width|height|opacity|padding/i,offsetAttribute:/^((width|height)|(top|left))$/,defaultUnit:/width|height|top$|bottom$|left$|right$/i,offsetUnit:/\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i},doMethod:function(A,C,B){return this.method(this.currentFrame,C,B-C,this.totalFrames);},setAttribute:function(A,C,B){if(this.patterns.noNegatives.test(A)){C=(C>0)?C:0;}YAHOO.util.Dom.setStyle(this.ge!
 tEl(),A,C+B);},getAttribute:function(A){var C=this.getEl();var!
  E=YAHOO
.util.Dom.getStyle(C,A);if(E!=="auto"&&!this.patterns.offsetUnit.test(E)){return parseFloat(E);}var B=this.patterns.offsetAttribute.exec(A)||[];var F=!!(B[3]);var D=!!(B[2]);if(D||(YAHOO.util.Dom.getStyle(C,"position")=="absolute"&&F)){E=C["offset"+B[0].charAt(0).toUpperCase()+B[0].substr(1)];}else{E=0;}return E;},getDefaultUnit:function(A){if(this.patterns.defaultUnit.test(A)){return"px";}return"";},setRuntimeAttribute:function(B){var G;var C;var D=this.attributes;this.runtimeAttributes[B]={};var F=function(H){return(typeof H!=="undefined");};if(!F(D[B]["to"])&&!F(D[B]["by"])){return false;}G=(F(D[B]["from"]))?D[B]["from"]:this.getAttribute(B);if(F(D[B]["to"])){C=D[B]["to"];}else{if(F(D[B]["by"])){if(G.constructor==Array){C=[];for(var E=0,A=G.length;E<A;++E){C[E]=G[E]+D[B]["by"][E]*1;}}else{C=G+D[B]["by"]*1;}}}this.runtimeAttributes[B].start=G;this.runtimeAttributes[B].end=C;this.runtimeAttributes[B].unit=(F(D[B].unit))?D[B]["unit"]:this.getDefaultUnit(B);return true;},init!
 :function(C,H,G,A){var B=false;var D=null;var F=0;C=YAHOO.util.Dom.get(C);this.attributes=H||{};this.duration=!YAHOO.lang.isUndefined(G)?G:1;this.method=A||YAHOO.util.Easing.easeNone;this.useSeconds=true;this.currentFrame=0;this.totalFrames=YAHOO.util.AnimMgr.fps;this.setEl=function(K){C=YAHOO.util.Dom.get(K);};this.getEl=function(){return C;};this.isAnimated=function(){return B;};this.getStartTime=function(){return D;};this.runtimeAttributes={};this.animate=function(){if(this.isAnimated()){return false;}this.currentFrame=0;this.totalFrames=(this.useSeconds)?Math.ceil(YAHOO.util.AnimMgr.fps*this.duration):this.duration;if(this.duration===0&&this.useSeconds){this.totalFrames=1;}YAHOO.util.AnimMgr.registerElement(this);return true;};this.stop=function(K){if(!this.isAnimated()){return false;}if(K){this.currentFrame=this.totalFrames;this._onTween.fire();}YAHOO.util.AnimMgr.stop(this);};var J=function(){this.onStart.fire();this.runtimeAttributes={};for(var K in this.attributes){!
 this.setRuntimeAttribute(K);}B=true;F=0;D=new Date();};var I=f!
 unction(
){var M={duration:new Date()-this.getStartTime(),currentFrame:this.currentFrame};M.toString=function(){return("duration: "+M.duration+", currentFrame: "+M.currentFrame);};this.onTween.fire(M);var L=this.runtimeAttributes;for(var K in L){this.setAttribute(K,this.doMethod(K,L[K].start,L[K].end),L[K].unit);}F+=1;};var E=function(){var K=(new Date()-D)/1000;var L={duration:K,frames:F,fps:F/K};L.toString=function(){return("duration: "+L.duration+", frames: "+L.frames+", fps: "+L.fps);};B=false;F=0;this.onComplete.fire(L);};this._onStart=new YAHOO.util.CustomEvent("_start",this,true);this.onStart=new YAHOO.util.CustomEvent("start",this);this.onTween=new YAHOO.util.CustomEvent("tween",this);this._onTween=new YAHOO.util.CustomEvent("_tween",this,true);this.onComplete=new YAHOO.util.CustomEvent("complete",this);this._onComplete=new YAHOO.util.CustomEvent("_complete",this,true);this._onStart.subscribe(J);this._onTween.subscribe(I);this._onComplete.subscribe(E);}};YAHOO.util.AnimMgr=ne!
 w function(){var C=null;var B=[];var A=0;this.fps=1000;this.delay=1;this.registerElement=function(F){B[B.length]=F;A+=1;F._onStart.fire();this.start();};this.unRegister=function(G,F){F=F||E(G);if(!G.isAnimated()||F==-1){return false;}G._onComplete.fire();B.splice(F,1);A-=1;if(A<=0){this.stop();}return true;};this.start=function(){if(C===null){C=setInterval(this.run,this.delay);}};this.stop=function(H){if(!H){clearInterval(C);for(var G=0,F=B.length;G<F;++G){this.unRegister(B[0],0);}B=[];C=null;A=0;}else{this.unRegister(H);}};this.run=function(){for(var H=0,F=B.length;H<F;++H){var G=B[H];if(!G||!G.isAnimated()){continue;}if(G.currentFrame<G.totalFrames||G.totalFrames===null){G.currentFrame+=1;if(G.useSeconds){D(G);}G._onTween.fire();}else{YAHOO.util.AnimMgr.stop(G,H);}}};var E=function(H){for(var G=0,F=B.length;G<F;++G){if(B[G]==H){return G;}}return -1;};var D=function(G){var J=G.totalFrames;var I=G.currentFrame;var H=(G.currentFrame*G.duration*1000/G.totalFrames);var F=(new !
 Date()-G.getStartTime());var K=0;if(F<G.duration*1000){K=Math.!
 round((F
/H-1)*G.currentFrame);}else{K=J-(I+1);}if(K>0&&isFinite(K)){if(G.currentFrame+K>=J){K=J-(I+1);}G.currentFrame+=K;}};};YAHOO.util.Bezier=new function(){this.getPosition=function(E,D){var F=E.length;var C=[];for(var B=0;B<F;++B){C[B]=[E[B][0],E[B][1]];}for(var A=1;A<F;++A){for(B=0;B<F-A;++B){C[B][0]=(1-D)*C[B][0]+D*C[parseInt(B+1,10)][0];C[B][1]=(1-D)*C[B][1]+D*C[parseInt(B+1,10)][1];}}return[C[0][0],C[0][1]];};};(function(){YAHOO.util.ColorAnim=function(E,D,F,G){YAHOO.util.ColorAnim.superclass.constructor.call(this,E,D,F,G);};YAHOO.extend(YAHOO.util.ColorAnim,YAHOO.util.Anim);var B=YAHOO.util;var C=B.ColorAnim.superclass;var A=B.ColorAnim.prototype;A.toString=function(){var D=this.getEl();var E=D.id||D.tagName;return("ColorAnim "+E);};A.patterns.color=/color$/i;A.patterns.rgb=/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;A.patterns.hex=/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;A.patterns.hex3=/^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;A.patterns.transparent=/^tr!
 ansparent|rgba\(0, 0, 0, 0\)$/;A.parseColor=function(D){if(D.length==3){return D;}var E=this.patterns.hex.exec(D);if(E&&E.length==4){return[parseInt(E[1],16),parseInt(E[2],16),parseInt(E[3],16)];}E=this.patterns.rgb.exec(D);if(E&&E.length==4){return[parseInt(E[1],10),parseInt(E[2],10),parseInt(E[3],10)];
-}E=this.patterns.hex3.exec(D);if(E&&E.length==4){return[parseInt(E[1]+E[1],16),parseInt(E[2]+E[2],16),parseInt(E[3]+E[3],16)];}return null;};A.getAttribute=function(D){var F=this.getEl();if(this.patterns.color.test(D)){var G=YAHOO.util.Dom.getStyle(F,D);if(this.patterns.transparent.test(G)){var E=F.parentNode;G=B.Dom.getStyle(E,D);while(E&&this.patterns.transparent.test(G)){E=E.parentNode;G=B.Dom.getStyle(E,D);if(E.tagName.toUpperCase()=="HTML"){G="#fff";}}}}else{G=C.getAttribute.call(this,D);}return G;};A.doMethod=function(E,I,F){var H;if(this.patterns.color.test(E)){H=[];for(var G=0,D=I.length;G<D;++G){H[G]=C.doMethod.call(this,E,I[G],F[G]);}H="rgb("+Math.floor(H[0])+","+Math.floor(H[1])+","+Math.floor(H[2])+")";}else{H=C.doMethod.call(this,E,I,F);}return H;};A.setRuntimeAttribute=function(E){C.setRuntimeAttribute.call(this,E);if(this.patterns.color.test(E)){var G=this.attributes;var I=this.parseColor(this.runtimeAttributes[E].start);var F=this.parseColor(this.runtimeAttr!
 ibutes[E].end);if(typeof G[E]["to"]==="undefined"&&typeof G[E]["by"]!=="undefined"){F=this.parseColor(G[E].by);for(var H=0,D=I.length;H<D;++H){F[H]=I[H]+F[H];}}this.runtimeAttributes[E].start=I;this.runtimeAttributes[E].end=F;}};})();YAHOO.util.Easing={easeNone:function(B,A,D,C){return D*B/C+A;},easeIn:function(B,A,D,C){return D*(B/=C)*B+A;},easeOut:function(B,A,D,C){return -D*(B/=C)*(B-2)+A;},easeBoth:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B+A;}return -D/2*((--B)*(B-2)-1)+A;},easeInStrong:function(B,A,D,C){return D*(B/=C)*B*B*B+A;},easeOutStrong:function(B,A,D,C){return -D*((B=B/C-1)*B*B*B-1)+A;},easeBothStrong:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B*B*B+A;}return -D/2*((B-=2)*B*B*B-2)+A;},elasticIn:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return -(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;},elasticOut:function(C,A,G,F,B,E)!
 {if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}!
 if(!B||B
<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return B*Math.pow(2,-10*C)*Math.sin((C*F-D)*(2*Math.PI)/E)+G+A;},elasticBoth:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F/2)==2){return A+G;}if(!E){E=F*(0.3*1.5);}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}if(C<1){return -0.5*(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;}return B*Math.pow(2,-10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E)*0.5+G+A;},backIn:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*(B/=D)*B*((C+1)*B-C)+A;},backOut:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*((B=B/D-1)*B*((C+1)*B+C)+1)+A;},backBoth:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}if((B/=D/2)<1){return E/2*(B*B*(((C*=(1.525))+1)*B-C))+A;}return E/2*((B-=2)*B*(((C*=(1.525))+1)*B+C)+2)+A;},bounceIn:function(B,A,D,C){return D-YAHOO.util.Easing.bounceOut(C-B,0,D,C)+A;},bounceOut:function(B,A,D,C){if((B/=C)<(1/2.75)){return D*(7.!
 5625*B*B)+A;}else{if(B<(2/2.75)){return D*(7.5625*(B-=(1.5/2.75))*B+0.75)+A;}else{if(B<(2.5/2.75)){return D*(7.5625*(B-=(2.25/2.75))*B+0.9375)+A;}}}return D*(7.5625*(B-=(2.625/2.75))*B+0.984375)+A;},bounceBoth:function(B,A,D,C){if(B<C/2){return YAHOO.util.Easing.bounceIn(B*2,0,D,C)*0.5+A;}return YAHOO.util.Easing.bounceOut(B*2-C,0,D,C)*0.5+D*0.5+A;}};(function(){YAHOO.util.Motion=function(G,F,H,I){if(G){YAHOO.util.Motion.superclass.constructor.call(this,G,F,H,I);}};YAHOO.extend(YAHOO.util.Motion,YAHOO.util.ColorAnim);var D=YAHOO.util;var E=D.Motion.superclass;var B=D.Motion.prototype;B.toString=function(){var F=this.getEl();var G=F.id||F.tagName;return("Motion "+G);};B.patterns.points=/^points$/i;B.setAttribute=function(F,H,G){if(this.patterns.points.test(F)){G=G||"px";E.setAttribute.call(this,"left",H[0],G);E.setAttribute.call(this,"top",H[1],G);}else{E.setAttribute.call(this,F,H,G);}};B.getAttribute=function(F){if(this.patterns.points.test(F)){var G=[E.getAttribute.call(t!
 his,"left"),E.getAttribute.call(this,"top")];}else{G=E.getAttr!
 ibute.ca
ll(this,F);}return G;};B.doMethod=function(F,J,G){var I=null;if(this.patterns.points.test(F)){var H=this.method(this.currentFrame,0,100,this.totalFrames)/100;I=D.Bezier.getPosition(this.runtimeAttributes[F],H);}else{I=E.doMethod.call(this,F,J,G);}return I;};B.setRuntimeAttribute=function(O){if(this.patterns.points.test(O)){var G=this.getEl();var I=this.attributes;var F;var K=I["points"]["control"]||[];var H;var L,N;if(K.length>0&&!(K[0] instanceof Array)){K=[K];}else{var J=[];for(L=0,N=K.length;L<N;++L){J[L]=K[L];}K=J;}if(D.Dom.getStyle(G,"position")=="static"){D.Dom.setStyle(G,"position","relative");}if(C(I["points"]["from"])){D.Dom.setXY(G,I["points"]["from"]);}else{D.Dom.setXY(G,D.Dom.getXY(G));}F=this.getAttribute("points");if(C(I["points"]["to"])){H=A.call(this,I["points"]["to"],F);var M=D.Dom.getXY(this.getEl());for(L=0,N=K.length;L<N;++L){K[L]=A.call(this,K[L],F);}}else{if(C(I["points"]["by"])){H=[F[0]+I["points"]["by"][0],F[1]+I["points"]["by"][1]];for(L=0,N=K.length!
 ;L<N;++L){K[L]=[F[0]+K[L][0],F[1]+K[L][1]];}}}this.runtimeAttributes[O]=[F];if(K.length>0){this.runtimeAttributes[O]=this.runtimeAttributes[O].concat(K);}this.runtimeAttributes[O][this.runtimeAttributes[O].length]=H;}else{E.setRuntimeAttribute.call(this,O);}};var A=function(F,H){var G=D.Dom.getXY(this.getEl());F=[F[0]-G[0]+H[0],F[1]-G[1]+H[1]];return F;};var C=function(F){return(typeof F!=="undefined");};})();(function(){YAHOO.util.Scroll=function(E,D,F,G){if(E){YAHOO.util.Scroll.superclass.constructor.call(this,E,D,F,G);}};YAHOO.extend(YAHOO.util.Scroll,YAHOO.util.ColorAnim);var B=YAHOO.util;var C=B.Scroll.superclass;var A=B.Scroll.prototype;A.toString=function(){var D=this.getEl();var E=D.id||D.tagName;return("Scroll "+E);};A.doMethod=function(D,G,E){var F=null;if(D=="scroll"){F=[this.method(this.currentFrame,G[0],E[0]-G[0],this.totalFrames),this.method(this.currentFrame,G[1],E[1]-G[1],this.totalFrames)];
-}else{F=C.doMethod.call(this,D,G,E);}return F;};A.getAttribute=function(D){var F=null;var E=this.getEl();if(D=="scroll"){F=[E.scrollLeft,E.scrollTop];}else{F=C.getAttribute.call(this,D);}return F;};A.setAttribute=function(D,G,F){var E=this.getEl();if(D=="scroll"){E.scrollLeft=G[0];E.scrollTop=G[1];}else{C.setAttribute.call(this,D,G,F);}};})();YAHOO.register("animation",YAHOO.util.Anim,{version:"2.4.1",build:"742"});if(!YAHOO.util.DragDropMgr){YAHOO.util.DragDropMgr=function(){var A=YAHOO.util.Event;return{ids:{},handleIds:{},dragCurrent:null,dragOvers:{},deltaX:0,deltaY:0,preventDefault:true,stopPropagation:true,initialized:false,locked:false,interactionInfo:null,init:function(){this.initialized=true;},POINT:0,INTERSECT:1,STRICT_INTERSECT:2,mode:0,_execOnAll:function(D,C){for(var E in this.ids){for(var B in this.ids[E]){var F=this.ids[E][B];if(!this.isTypeOfDD(F)){continue;}F[D].apply(F,C);}}},_onLoad:function(){this.init();A.on(document,"mouseup",this.handleMouseUp,this,tr!
 ue);A.on(document,"mousemove",this.handleMouseMove,this,true);A.on(window,"unload",this._onUnload,this,true);A.on(window,"resize",this._onResize,this,true);},_onResize:function(B){this._execOnAll("resetConstraints",[]);},lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isLocked:function(){return this.locked;},locationCache:{},useCache:true,clickPixelThresh:3,clickTimeThresh:1000,dragThreshMet:false,clickTimeout:null,startX:0,startY:0,fromTimeout:false,regDragDrop:function(C,B){if(!this.initialized){this.init();}if(!this.ids[B]){this.ids[B]={};}this.ids[B][C.id]=C;},removeDDFromGroup:function(D,B){if(!this.ids[B]){this.ids[B]={};}var C=this.ids[B];if(C&&C[D.id]){delete C[D.id];}},_remove:function(C){for(var B in C.groups){if(B&&this.ids[B][C.id]){delete this.ids[B][C.id];}}delete this.handleIds[C.id];},regHandle:function(C,B){if(!this.handleIds[C]){this.handleIds[C]={};}this.handleIds[C][B]=B;},isDragDrop:function(B){return(this.getDDById(B))?true:fal!
 se;},getRelated:function(G,C){var F=[];for(var E in G.groups){!
 for(var 
D in this.ids[E]){var B=this.ids[E][D];if(!this.isTypeOfDD(B)){continue;}if(!C||B.isTarget){F[F.length]=B;}}}return F;},isLegalTarget:function(F,E){var C=this.getRelated(F,true);for(var D=0,B=C.length;D<B;++D){if(C[D].id==E.id){return true;}}return false;},isTypeOfDD:function(B){return(B&&B.__ygDragDrop);},isHandle:function(C,B){return(this.handleIds[C]&&this.handleIds[C][B]);},getDDById:function(C){for(var B in this.ids){if(this.ids[B][C]){return this.ids[B][C];}}return null;},handleMouseDown:function(D,C){this.currentTarget=YAHOO.util.Event.getTarget(D);this.dragCurrent=C;var B=C.getEl();this.startX=YAHOO.util.Event.getPageX(D);this.startY=YAHOO.util.Event.getPageY(D);this.deltaX=this.startX-B.offsetLeft;this.deltaY=this.startY-B.offsetTop;this.dragThreshMet=false;this.clickTimeout=setTimeout(function(){var E=YAHOO.util.DDM;E.startDrag(E.startX,E.startY);E.fromTimeout=true;},this.clickTimeThresh);},startDrag:function(B,D){clearTimeout(this.clickTimeout);var C=this.dragCurr!
 ent;if(C){C.b4StartDrag(B,D);}if(C){C.startDrag(B,D);}this.dragThreshMet=true;},handleMouseUp:function(B){if(this.dragCurrent){clearTimeout(this.clickTimeout);if(this.dragThreshMet){if(this.fromTimeout){this.handleMouseMove(B);}this.fromTimeout=false;this.fireEvents(B,true);}else{}this.stopDrag(B);this.stopEvent(B);}},stopEvent:function(B){if(this.stopPropagation){YAHOO.util.Event.stopPropagation(B);}if(this.preventDefault){YAHOO.util.Event.preventDefault(B);}},stopDrag:function(C,B){if(this.dragCurrent&&!B){if(this.dragThreshMet){this.dragCurrent.b4EndDrag(C);this.dragCurrent.endDrag(C);}this.dragCurrent.onMouseUp(C);}this.dragCurrent=null;this.dragOvers={};},handleMouseMove:function(E){var B=this.dragCurrent;if(B){if(YAHOO.util.Event.isIE&&!E.button){this.stopEvent(E);return this.handleMouseUp(E);}if(!this.dragThreshMet){var D=Math.abs(this.startX-YAHOO.util.Event.getPageX(E));var C=Math.abs(this.startY-YAHOO.util.Event.getPageY(E));if(D>this.clickPixelThresh||C>this.clic!
 kPixelThresh){this.startDrag(this.startX,this.startY);}}if(thi!
 s.dragTh
reshMet){B.b4Drag(E);if(B){B.onDrag(E);}if(B){this.fireEvents(E,false);}}this.stopEvent(E);}},fireEvents:function(T,J){var V=this.dragCurrent;if(!V||V.isLocked()||V.dragOnly){return ;}var L=YAHOO.util.Event.getPageX(T),K=YAHOO.util.Event.getPageY(T),M=new YAHOO.util.Point(L,K),H=V.getTargetCoord(M.x,M.y),E=V.getDragEl(),S=new YAHOO.util.Region(H.y,H.x+E.offsetWidth,H.y+E.offsetHeight,H.x),G=[],I=[],D=[],U=[],R=[],C={},N=[];for(var P in this.dragOvers){var W=this.dragOvers[P];if(!this.isTypeOfDD(W)){continue;}if(!this.isOverTarget(M,W,this.mode,S)){I.push(W);}G[P]=true;delete this.dragOvers[P];}for(var O in V.groups){if("string"!=typeof O){continue;}for(P in this.ids[O]){var F=this.ids[O][P];if(!this.isTypeOfDD(F)){continue;}if(F.isTarget&&!F.isLocked()&&F!=V){if(this.isOverTarget(M,F,this.mode,S)){C[O]=true;if(J){U.push(F);}else{if(!G[F.id]){R.push(F);}else{D.push(F);}this.dragOvers[F.id]=F;}}}}}this.interactionInfo={out:I,enter:R,over:D,drop:U,point:M,draggedRegion:S,source!
 Region:this.locationCache[V.id],validDrop:J};for(var B in C){N.push(B);}if(J&&!U.length){this.interactionInfo.validDrop=false;V.onInvalidDrop(T);}if(this.mode){if(I.length){V.b4DragOut(T,I);if(V){V.onDragOut(T,I);}}if(R.length){if(V){V.onDragEnter(T,R,N);}}if(D.length){if(V){V.b4DragOver(T,D,N);}if(V){V.onDragOver(T,D,N);}}if(U.length){if(V){V.b4DragDrop(T,U,N);}if(V){V.onDragDrop(T,U,N);}}}else{var Q=0;for(P=0,Q=I.length;P<Q;++P){if(V){V.b4DragOut(T,I[P].id,N[0]);}if(V){V.onDragOut(T,I[P].id,N[0]);}}for(P=0,Q=R.length;P<Q;++P){if(V){V.onDragEnter(T,R[P].id,N[0]);}}for(P=0,Q=D.length;P<Q;++P){if(V){V.b4DragOver(T,D[P].id,N[0]);}if(V){V.onDragOver(T,D[P].id,N[0]);}}for(P=0,Q=U.length;P<Q;++P){if(V){V.b4DragDrop(T,U[P].id,N[0]);}if(V){V.onDragDrop(T,U[P].id,N[0]);}}}},getBestMatch:function(D){var F=null;var C=D.length;if(C==1){F=D[0];}else{for(var E=0;E<C;++E){var B=D[E];if(this.mode==this.INTERSECT&&B.cursorIsOver){F=B;break;}else{if(!F||!F.overlap||(B.overlap&&F.overlap.get!
 Area()<B.overlap.getArea())){F=B;}}}}return F;},refreshCache:f!
 unction(
C){var E=C||this.ids;for(var B in E){if("string"!=typeof B){continue;}for(var D in this.ids[B]){var F=this.ids[B][D];if(this.isTypeOfDD(F)){var G=this.getLocation(F);if(G){this.locationCache[F.id]=G;}else{delete this.locationCache[F.id];}}}}},verifyEl:function(C){try{if(C){var B=C.offsetParent;
-if(B){return true;}}}catch(D){}return false;},getLocation:function(G){if(!this.isTypeOfDD(G)){return null;}var E=G.getEl(),J,D,C,L,K,M,B,I,F;try{J=YAHOO.util.Dom.getXY(E);}catch(H){}if(!J){return null;}D=J[0];C=D+E.offsetWidth;L=J[1];K=L+E.offsetHeight;M=L-G.padding[0];B=C+G.padding[1];I=K+G.padding[2];F=D-G.padding[3];return new YAHOO.util.Region(M,B,I,F);},isOverTarget:function(J,B,D,E){var F=this.locationCache[B.id];if(!F||!this.useCache){F=this.getLocation(B);this.locationCache[B.id]=F;}if(!F){return false;}B.cursorIsOver=F.contains(J);var I=this.dragCurrent;if(!I||(!D&&!I.constrainX&&!I.constrainY)){return B.cursorIsOver;}B.overlap=null;if(!E){var G=I.getTargetCoord(J.x,J.y);var C=I.getDragEl();E=new YAHOO.util.Region(G.y,G.x+C.offsetWidth,G.y+C.offsetHeight,G.x);}var H=E.intersect(F);if(H){B.overlap=H;return(D)?true:B.cursorIsOver;}else{return false;}},_onUnload:function(C,B){this.unregAll();},unregAll:function(){if(this.dragCurrent){this.stopDrag();this.dragCurrent=n!
 ull;}this._execOnAll("unreg",[]);this.ids={};},elementCache:{},getElWrapper:function(C){var B=this.elementCache[C];if(!B||!B.el){B=this.elementCache[C]=new this.ElementWrapper(YAHOO.util.Dom.get(C));}return B;},getElement:function(B){return YAHOO.util.Dom.get(B);},getCss:function(C){var B=YAHOO.util.Dom.get(C);return(B)?B.style:null;},ElementWrapper:function(B){this.el=B||null;this.id=this.el&&B.id;this.css=this.el&&B.style;},getPosX:function(B){return YAHOO.util.Dom.getX(B);},getPosY:function(B){return YAHOO.util.Dom.getY(B);},swapNode:function(D,B){if(D.swapNode){D.swapNode(B);}else{var E=B.parentNode;var C=B.nextSibling;if(C==D){E.insertBefore(D,B);}else{if(B==D.nextSibling){E.insertBefore(B,D);}else{D.parentNode.replaceChild(B,D);E.insertBefore(D,C);}}}},getScroll:function(){var D,B,E=document.documentElement,C=document.body;if(E&&(E.scrollTop||E.scrollLeft)){D=E.scrollTop;B=E.scrollLeft;}else{if(C){D=C.scrollTop;B=C.scrollLeft;}else{}}return{top:D,left:B};},getStyle:fu!
 nction(C,B){return YAHOO.util.Dom.getStyle(C,B);},getScrollTop!
 :functio
n(){return this.getScroll().top;},getScrollLeft:function(){return this.getScroll().left;},moveToEl:function(B,D){var C=YAHOO.util.Dom.getXY(D);YAHOO.util.Dom.setXY(B,C);},getClientHeight:function(){return YAHOO.util.Dom.getViewportHeight();},getClientWidth:function(){return YAHOO.util.Dom.getViewportWidth();},numericSort:function(C,B){return(C-B);},_timeoutCount:0,_addListeners:function(){var B=YAHOO.util.DDM;if(YAHOO.util.Event&&document){B._onLoad();}else{if(B._timeoutCount>2000){}else{setTimeout(B._addListeners,10);if(document&&document.body){B._timeoutCount+=1;}}}},handleWasClicked:function(B,D){if(this.isHandle(D,B.id)){return true;}else{var C=B.parentNode;while(C){if(this.isHandle(D,C.id)){return true;}else{C=C.parentNode;}}}return false;}};}();YAHOO.util.DDM=YAHOO.util.DragDropMgr;YAHOO.util.DDM._addListeners();}(function(){var A=YAHOO.util.Event;var B=YAHOO.util.Dom;YAHOO.util.DragDrop=function(E,C,D){if(E){this.init(E,C,D);}};YAHOO.util.DragDrop.prototype={id:null,c!
 onfig:null,dragElId:null,handleElId:null,invalidHandleTypes:null,invalidHandleIds:null,invalidHandleClasses:null,startPageX:0,startPageY:0,groups:null,locked:false,lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isTarget:true,padding:null,dragOnly:false,_domRef:null,__ygDragDrop:true,constrainX:false,constrainY:false,minX:0,maxX:0,minY:0,maxY:0,deltaX:0,deltaY:0,maintainOffset:false,xTicks:null,yTicks:null,primaryButtonOnly:true,available:false,hasOuterHandles:false,cursorIsOver:false,overlap:null,b4StartDrag:function(C,D){},startDrag:function(C,D){},b4Drag:function(C){},onDrag:function(C){},onDragEnter:function(C,D){},b4DragOver:function(C){},onDragOver:function(C,D){},b4DragOut:function(C){},onDragOut:function(C,D){},b4DragDrop:function(C){},onDragDrop:function(C,D){},onInvalidDrop:function(C){},b4EndDrag:function(C){},endDrag:function(C){},b4MouseDown:function(C){},onMouseDown:function(C){},onMouseUp:function(C){},onAvailable:function(){},getEl:f!
 unction(){if(!this._domRef){this._domRef=B.get(this.id);}retur!
 n this._
domRef;},getDragEl:function(){return B.get(this.dragElId);},init:function(E,C,D){this.initTarget(E,C,D);A.on(this._domRef||this.id,"mousedown",this.handleMouseDown,this,true);},initTarget:function(E,C,D){this.config=D||{};this.DDM=YAHOO.util.DDM;this.groups={};if(typeof E!=="string"){this._domRef=E;E=B.generateId(E);}this.id=E;this.addToGroup((C)?C:"default");this.handleElId=E;A.onAvailable(E,this.handleOnAvailable,this,true);this.setDragElId(E);this.invalidHandleTypes={A:"A"};this.invalidHandleIds={};this.invalidHandleClasses=[];this.applyConfig();},applyConfig:function(){this.padding=this.config.padding||[0,0,0,0];this.isTarget=(this.config.isTarget!==false);this.maintainOffset=(this.config.maintainOffset);this.primaryButtonOnly=(this.config.primaryButtonOnly!==false);this.dragOnly=((this.config.dragOnly===true)?true:false);},handleOnAvailable:function(){this.available=true;this.resetConstraints();this.onAvailable();},setPadding:function(E,C,F,D){if(!C&&0!==C){this.padding!
 =[E,E,E,E];}else{if(!F&&0!==F){this.padding=[E,C,E,C];}else{this.padding=[E,C,F,D];}}},setInitPosition:function(F,E){var G=this.getEl();if(!this.DDM.verifyEl(G)){return ;}var D=F||0;var C=E||0;var H=B.getXY(G);this.initPageX=H[0]-D;this.initPageY=H[1]-C;this.lastPageX=H[0];this.lastPageY=H[1];this.setStartPosition(H);},setStartPosition:function(D){var C=D||B.getXY(this.getEl());this.deltaSetXY=null;this.startPageX=C[0];this.startPageY=C[1];},addToGroup:function(C){this.groups[C]=true;this.DDM.regDragDrop(this,C);},removeFromGroup:function(C){if(this.groups[C]){delete this.groups[C];}this.DDM.removeDDFromGroup(this,C);},setDragElId:function(C){this.dragElId=C;},setHandleElId:function(C){if(typeof C!=="string"){C=B.generateId(C);}this.handleElId=C;this.DDM.regHandle(this.id,C);},setOuterHandleElId:function(C){if(typeof C!=="string"){C=B.generateId(C);}A.on(C,"mousedown",this.handleMouseDown,this,true);this.setHandleElId(C);
-this.hasOuterHandles=true;},unreg:function(){A.removeListener(this.id,"mousedown",this.handleMouseDown);this._domRef=null;this.DDM._remove(this);},isLocked:function(){return(this.DDM.isLocked()||this.locked);},handleMouseDown:function(H,G){var D=H.which||H.button;if(this.primaryButtonOnly&&D>1){return ;}if(this.isLocked()){return ;}var C=this.b4MouseDown(H);var E=this.onMouseDown(H);if((C===false)||(E===false)){return ;}this.DDM.refreshCache(this.groups);var F=new YAHOO.util.Point(A.getPageX(H),A.getPageY(H));if(!this.hasOuterHandles&&!this.DDM.isOverTarget(F,this)){}else{if(this.clickValidator(H)){this.setStartPosition();this.DDM.handleMouseDown(H,this);this.DDM.stopEvent(H);}else{}}},clickValidator:function(D){var C=A.getTarget(D);return(this.isValidHandleChild(C)&&(this.id==this.handleElId||this.DDM.handleWasClicked(C,this.id)));},getTargetCoord:function(E,D){var C=E-this.deltaX;var F=D-this.deltaY;if(this.constrainX){if(C<this.minX){C=this.minX;}if(C>this.maxX){C=this.m!
 axX;}}if(this.constrainY){if(F<this.minY){F=this.minY;}if(F>this.maxY){F=this.maxY;}}C=this.getTick(C,this.xTicks);F=this.getTick(F,this.yTicks);return{x:C,y:F};},addInvalidHandleType:function(C){var D=C.toUpperCase();this.invalidHandleTypes[D]=D;},addInvalidHandleId:function(C){if(typeof C!=="string"){C=B.generateId(C);}this.invalidHandleIds[C]=C;},addInvalidHandleClass:function(C){this.invalidHandleClasses.push(C);},removeInvalidHandleType:function(C){var D=C.toUpperCase();delete this.invalidHandleTypes[D];},removeInvalidHandleId:function(C){if(typeof C!=="string"){C=B.generateId(C);}delete this.invalidHandleIds[C];},removeInvalidHandleClass:function(D){for(var E=0,C=this.invalidHandleClasses.length;E<C;++E){if(this.invalidHandleClasses[E]==D){delete this.invalidHandleClasses[E];}}},isValidHandleChild:function(F){var E=true;var H;try{H=F.nodeName.toUpperCase();}catch(G){H=F.nodeName;}E=E&&!this.invalidHandleTypes[H];E=E&&!this.invalidHandleIds[F.id];for(var D=0,C=this.inv!
 alidHandleClasses.length;E&&D<C;++D){E=!B.hasClass(F,this.inva!
 lidHandl
eClasses[D]);}return E;},setXTicks:function(F,C){this.xTicks=[];this.xTickSize=C;var E={};for(var D=this.initPageX;D>=this.minX;D=D-C){if(!E[D]){this.xTicks[this.xTicks.length]=D;E[D]=true;}}for(D=this.initPageX;D<=this.maxX;D=D+C){if(!E[D]){this.xTicks[this.xTicks.length]=D;E[D]=true;}}this.xTicks.sort(this.DDM.numericSort);},setYTicks:function(F,C){this.yTicks=[];this.yTickSize=C;var E={};for(var D=this.initPageY;D>=this.minY;D=D-C){if(!E[D]){this.yTicks[this.yTicks.length]=D;E[D]=true;}}for(D=this.initPageY;D<=this.maxY;D=D+C){if(!E[D]){this.yTicks[this.yTicks.length]=D;E[D]=true;}}this.yTicks.sort(this.DDM.numericSort);},setXConstraint:function(E,D,C){this.leftConstraint=parseInt(E,10);this.rightConstraint=parseInt(D,10);this.minX=this.initPageX-this.leftConstraint;this.maxX=this.initPageX+this.rightConstraint;if(C){this.setXTicks(this.initPageX,C);}this.constrainX=true;},clearConstraints:function(){this.constrainX=false;this.constrainY=false;this.clearTicks();},clearTic!
 ks:function(){this.xTicks=null;this.yTicks=null;this.xTickSize=0;this.yTickSize=0;},setYConstraint:function(C,E,D){this.topConstraint=parseInt(C,10);this.bottomConstraint=parseInt(E,10);this.minY=this.initPageY-this.topConstraint;this.maxY=this.initPageY+this.bottomConstraint;if(D){this.setYTicks(this.initPageY,D);}this.constrainY=true;},resetConstraints:function(){if(this.initPageX||this.initPageX===0){var D=(this.maintainOffset)?this.lastPageX-this.initPageX:0;var C=(this.maintainOffset)?this.lastPageY-this.initPageY:0;this.setInitPosition(D,C);}else{this.setInitPosition();}if(this.constrainX){this.setXConstraint(this.leftConstraint,this.rightConstraint,this.xTickSize);}if(this.constrainY){this.setYConstraint(this.topConstraint,this.bottomConstraint,this.yTickSize);}},getTick:function(I,F){if(!F){return I;}else{if(F[0]>=I){return F[0];}else{for(var D=0,C=F.length;D<C;++D){var E=D+1;if(F[E]&&F[E]>=I){var H=I-F[D];var G=F[E]-I;return(G>H)?F[D]:F[E];}}return F[F.length-1];}}!
 },toString:function(){return("DragDrop "+this.id);}};})();YAHO!
 O.util.D
D=function(C,A,B){if(C){this.init(C,A,B);}};YAHOO.extend(YAHOO.util.DD,YAHOO.util.DragDrop,{scroll:true,autoOffset:function(C,B){var A=C-this.startPageX;var D=B-this.startPageY;this.setDelta(A,D);},setDelta:function(B,A){this.deltaX=B;this.deltaY=A;},setDragElPos:function(C,B){var A=this.getDragEl();this.alignElWithMouse(A,C,B);},alignElWithMouse:function(C,G,F){var E=this.getTargetCoord(G,F);if(!this.deltaSetXY){var H=[E.x,E.y];YAHOO.util.Dom.setXY(C,H);var D=parseInt(YAHOO.util.Dom.getStyle(C,"left"),10);var B=parseInt(YAHOO.util.Dom.getStyle(C,"top"),10);this.deltaSetXY=[D-E.x,B-E.y];}else{YAHOO.util.Dom.setStyle(C,"left",(E.x+this.deltaSetXY[0])+"px");YAHOO.util.Dom.setStyle(C,"top",(E.y+this.deltaSetXY[1])+"px");}this.cachePosition(E.x,E.y);var A=this;setTimeout(function(){A.autoScroll.call(A,E.x,E.y,C.offsetHeight,C.offsetWidth);},0);},cachePosition:function(B,A){if(B){this.lastPageX=B;this.lastPageY=A;}else{var C=YAHOO.util.Dom.getXY(this.getEl());this.lastPageX=C[0];!
 this.lastPageY=C[1];}},autoScroll:function(J,I,E,K){if(this.scroll){var L=this.DDM.getClientHeight();var B=this.DDM.getClientWidth();var N=this.DDM.getScrollTop();var D=this.DDM.getScrollLeft();var H=E+I;var M=K+J;var G=(L+N-I-this.deltaY);var F=(B+D-J-this.deltaX);var C=40;var A=(document.all)?80:30;if(H>L&&G<C){window.scrollTo(D,N+A);}if(I<N&&N>0&&I-N<C){window.scrollTo(D,N-A);}if(M>B&&F<C){window.scrollTo(D+A,N);}if(J<D&&D>0&&J-D<C){window.scrollTo(D-A,N);}}},applyConfig:function(){YAHOO.util.DD.superclass.applyConfig.call(this);this.scroll=(this.config.scroll!==false);},b4MouseDown:function(A){this.setStartPosition();this.autoOffset(YAHOO.util.Event.getPageX(A),YAHOO.util.Event.getPageY(A));},b4Drag:function(A){this.setDragElPos(YAHOO.util.Event.getPageX(A),YAHOO.util.Event.getPageY(A));},toString:function(){return("DD "+this.id);}});YAHOO.util.DDProxy=function(C,A,B){if(C){this.init(C,A,B);this.initFrame();
-}};YAHOO.util.DDProxy.dragElId="ygddfdiv";YAHOO.extend(YAHOO.util.DDProxy,YAHOO.util.DD,{resizeFrame:true,centerFrame:false,createFrame:function(){var B=this,A=document.body;if(!A||!A.firstChild){setTimeout(function(){B.createFrame();},50);return ;}var F=this.getDragEl(),E=YAHOO.util.Dom;if(!F){F=document.createElement("div");F.id=this.dragElId;var D=F.style;D.position="absolute";D.visibility="hidden";D.cursor="move";D.border="2px solid #aaa";D.zIndex=999;D.height="25px";D.width="25px";var C=document.createElement("div");E.setStyle(C,"height","100%");E.setStyle(C,"width","100%");E.setStyle(C,"background-color","#ccc");E.setStyle(C,"opacity","0");F.appendChild(C);A.insertBefore(F,A.firstChild);}},initFrame:function(){this.createFrame();},applyConfig:function(){YAHOO.util.DDProxy.superclass.applyConfig.call(this);this.resizeFrame=(this.config.resizeFrame!==false);this.centerFrame=(this.config.centerFrame);this.setDragElId(this.config.dragElId||YAHOO.util.DDProxy.dragElId);},s!
 howFrame:function(E,D){var C=this.getEl();var A=this.getDragEl();var B=A.style;this._resizeProxy();if(this.centerFrame){this.setDelta(Math.round(parseInt(B.width,10)/2),Math.round(parseInt(B.height,10)/2));}this.setDragElPos(E,D);YAHOO.util.Dom.setStyle(A,"visibility","visible");},_resizeProxy:function(){if(this.resizeFrame){var H=YAHOO.util.Dom;var B=this.getEl();var C=this.getDragEl();var G=parseInt(H.getStyle(C,"borderTopWidth"),10);var I=parseInt(H.getStyle(C,"borderRightWidth"),10);var F=parseInt(H.getStyle(C,"borderBottomWidth"),10);var D=parseInt(H.getStyle(C,"borderLeftWidth"),10);if(isNaN(G)){G=0;}if(isNaN(I)){I=0;}if(isNaN(F)){F=0;}if(isNaN(D)){D=0;}var E=Math.max(0,B.offsetWidth-I-D);var A=Math.max(0,B.offsetHeight-G-F);H.setStyle(C,"width",E+"px");H.setStyle(C,"height",A+"px");}},b4MouseDown:function(B){this.setStartPosition();var A=YAHOO.util.Event.getPageX(B);var C=YAHOO.util.Event.getPageY(B);this.autoOffset(A,C);},b4StartDrag:function(A,B){this.showFrame(A,B!
 );},b4EndDrag:function(A){YAHOO.util.Dom.setStyle(this.getDrag!
 El(),"vi
sibility","hidden");},endDrag:function(D){var C=YAHOO.util.Dom;var B=this.getEl();var A=this.getDragEl();C.setStyle(A,"visibility","");C.setStyle(B,"visibility","hidden");YAHOO.util.DDM.moveToEl(B,A);C.setStyle(A,"visibility","hidden");C.setStyle(B,"visibility","");},toString:function(){return("DDProxy "+this.id);}});YAHOO.util.DDTarget=function(C,A,B){if(C){this.initTarget(C,A,B);}};YAHOO.extend(YAHOO.util.DDTarget,YAHOO.util.DragDrop,{toString:function(){return("DDTarget "+this.id);}});YAHOO.register("dragdrop",YAHOO.util.DragDropMgr,{version:"2.4.1",build:"742"});YAHOO.util.Attribute=function(B,A){if(A){this.owner=A;this.configure(B,true);}};YAHOO.util.Attribute.prototype={name:undefined,value:null,owner:null,readOnly:false,writeOnce:false,_initialConfig:null,_written:false,method:null,validator:null,getValue:function(){return this.value;},setValue:function(F,B){var E;var A=this.owner;var C=this.name;var D={type:C,prevValue:this.getValue(),newValue:F};if(this.readOnly||(t!
 his.writeOnce&&this._written)){return false;}if(this.validator&&!this.validator.call(A,F)){return false;}if(!B){E=A.fireBeforeChangeEvent(D);if(E===false){return false;}}if(this.method){this.method.call(A,F);}this.value=F;this._written=true;D.type=C;if(!B){this.owner.fireChangeEvent(D);}return true;},configure:function(B,C){B=B||{};this._written=false;this._initialConfig=this._initialConfig||{};for(var A in B){if(A&&YAHOO.lang.hasOwnProperty(B,A)){this[A]=B[A];if(C){this._initialConfig[A]=B[A];}}}},resetValue:function(){return this.setValue(this._initialConfig.value);},resetConfig:function(){this.configure(this._initialConfig);},refresh:function(A){this.setValue(this.value,A);}};(function(){var A=YAHOO.util.Lang;YAHOO.util.AttributeProvider=function(){};YAHOO.util.AttributeProvider.prototype={_configs:null,get:function(C){this._configs=this._configs||{};var B=this._configs[C];if(!B){return undefined;}return B.value;},set:function(D,E,B){this._configs=this._configs||{};var C!
 =this._configs[D];if(!C){return false;}return C.setValue(E,B);!
 },getAtt
ributeKeys:function(){this._configs=this._configs;var D=[];var B;for(var C in this._configs){B=this._configs[C];if(A.hasOwnProperty(this._configs,C)&&!A.isUndefined(B)){D[D.length]=C;}}return D;},setAttributes:function(D,B){for(var C in D){if(A.hasOwnProperty(D,C)){this.set(C,D[C],B);}}},resetValue:function(C,B){this._configs=this._configs||{};if(this._configs[C]){this.set(C,this._configs[C]._initialConfig.value,B);return true;}return false;},refresh:function(E,C){this._configs=this._configs;E=((A.isString(E))?[E]:E)||this.getAttributeKeys();for(var D=0,B=E.length;D<B;++D){if(this._configs[E[D]]&&!A.isUndefined(this._configs[E[D]].value)&&!A.isNull(this._configs[E[D]].value)){this._configs[E[D]].refresh(C);}}},register:function(B,C){this.setAttributeConfig(B,C);},getAttributeConfig:function(C){this._configs=this._configs||{};var B=this._configs[C]||{};var D={};for(C in B){if(A.hasOwnProperty(B,C)){D[C]=B[C];}}return D;},setAttributeConfig:function(B,C,D){this._configs=this._!
 configs||{};C=C||{};if(!this._configs[B]){C.name=B;this._configs[B]=this.createAttribute(C);}else{this._configs[B].configure(C,D);}},configureAttribute:function(B,C,D){this.setAttributeConfig(B,C,D);},resetAttributeConfig:function(B){this._configs=this._configs||{};this._configs[B].resetConfig();},subscribe:function(B,C){this._events=this._events||{};if(!(B in this._events)){this._events[B]=this.createEvent(B);}YAHOO.util.EventProvider.prototype.subscribe.apply(this,arguments);},on:function(){this.subscribe.apply(this,arguments);},addListener:function(){this.subscribe.apply(this,arguments);},fireBeforeChangeEvent:function(C){var B="before";B+=C.type.charAt(0).toUpperCase()+C.type.substr(1)+"Change";C.type=B;return this.fireEvent(C.type,C);},fireChangeEvent:function(B){B.type+="Change";return this.fireEvent(B.type,B);},createAttribute:function(B){return new YAHOO.util.Attribute(B,this);}};YAHOO.augment(YAHOO.util.AttributeProvider,YAHOO.util.EventProvider);})();(function(){v!
 ar D=YAHOO.util.Dom,F=YAHOO.util.AttributeProvider;YAHOO.util.!
 Element=
function(G,H){if(arguments.length){this.init(G,H);}};YAHOO.util.Element.prototype={DOM_EVENTS:null,appendChild:function(G){G=G.get?G.get("element"):G;this.get("element").appendChild(G);},getElementsByTagName:function(G){return this.get("element").getElementsByTagName(G);},hasChildNodes:function(){return this.get("element").hasChildNodes();},insertBefore:function(G,H){G=G.get?G.get("element"):G;H=(H&&H.get)?H.get("element"):H;this.get("element").insertBefore(G,H);},removeChild:function(G){G=G.get?G.get("element"):G;this.get("element").removeChild(G);return true;},replaceChild:function(G,H){G=G.get?G.get("element"):G;H=H.get?H.get("element"):H;return this.get("element").replaceChild(G,H);},initAttributes:function(G){},addListener:function(K,J,L,I){var H=this.get("element");I=I||this;H=this.get("id")||H;var G=this;if(!this._events[K]){if(this.DOM_EVENTS[K]){YAHOO.util.Event.addListener(H,K,function(M){if(M.srcElement&&!M.target){M.target=M.srcElement;}G.fireEvent(K,M);},L,I);}t!
 his.createEvent(K,this);}YAHOO.util.EventProvider.prototype.subscribe.apply(this,arguments);},on:function(){this.addListener.apply(this,arguments);},subscribe:function(){this.addListener.apply(this,arguments);},removeListener:function(H,G){this.unsubscribe.apply(this,arguments);},addClass:function(G){D.addClass(this.get("element"),G);},getElementsByClassName:function(H,G){return D.getElementsByClassName(H,G,this.get("element"));},hasClass:function(G){return D.hasClass(this.get("element"),G);},removeClass:function(G){return D.removeClass(this.get("element"),G);},replaceClass:function(H,G){return D.replaceClass(this.get("element"),H,G);},setStyle:function(I,H){var G=this.get("element");if(!G){return this._queue[this._queue.length]=["setStyle",arguments];}return D.setStyle(G,I,H);},getStyle:function(G){return D.getStyle(this.get("element"),G);},fireQueue:function(){var H=this._queue;for(var I=0,G=H.length;I<G;++I){this[H[I][0]].apply(this,H[I][1]);}},appendTo:function(H,I){H=(!
 H.get)?H.get("element"):D.get(H);this.fireEvent("beforeAppendT!
 o",{type
:"beforeAppendTo",target:H});I=(I&&I.get)?I.get("element"):D.get(I);var G=this.get("element");if(!G){return false;}if(!H){return false;}if(G.parent!=H){if(I){H.insertBefore(G,I);}else{H.appendChild(G);}}this.fireEvent("appendTo",{type:"appendTo",target:H});},get:function(G){var I=this._configs||{};var H=I.element;if(H&&!I[G]&&!YAHOO.lang.isUndefined(H.value[G])){return H.value[G];}return F.prototype.get.call(this,G);},setAttributes:function(L,H){var K=this.get("element");
-for(var J in L){if(!this._configs[J]&&!YAHOO.lang.isUndefined(K[J])){this.setAttributeConfig(J);}}for(var I=0,G=this._configOrder.length;I<G;++I){if(L[this._configOrder[I]]){this.set(this._configOrder[I],L[this._configOrder[I]],H);}}},set:function(H,J,G){var I=this.get("element");if(!I){this._queue[this._queue.length]=["set",arguments];if(this._configs[H]){this._configs[H].value=J;}return ;}if(!this._configs[H]&&!YAHOO.lang.isUndefined(I[H])){C.call(this,H);}return F.prototype.set.apply(this,arguments);},setAttributeConfig:function(G,I,J){var H=this.get("element");if(H&&!this._configs[G]&&!YAHOO.lang.isUndefined(H[G])){C.call(this,G,I);}else{F.prototype.setAttributeConfig.apply(this,arguments);}this._configOrder.push(G);},getAttributeKeys:function(){var H=this.get("element");var I=F.prototype.getAttributeKeys.call(this);for(var G in H){if(!this._configs[G]){I[G]=I[G]||H[G];}}return I;},createEvent:function(H,G){this._events[H]=true;F.prototype.createEvent.apply(this,argumen!
 ts);},init:function(H,G){A.apply(this,arguments);}};var A=function(H,G){this._queue=this._queue||[];this._events=this._events||{};this._configs=this._configs||{};this._configOrder=[];G=G||{};G.element=G.element||H||null;this.DOM_EVENTS={"click":true,"dblclick":true,"keydown":true,"keypress":true,"keyup":true,"mousedown":true,"mousemove":true,"mouseout":true,"mouseover":true,"mouseup":true,"focus":true,"blur":true,"submit":true};var I=false;if(YAHOO.lang.isString(H)){C.call(this,"id",{value:G.element});}if(D.get(H)){I=true;E.call(this,G);B.call(this,G);}YAHOO.util.Event.onAvailable(G.element,function(){if(!I){E.call(this,G);}this.fireEvent("available",{type:"available",target:G.element});},this,true);YAHOO.util.Event.onContentReady(G.element,function(){if(!I){B.call(this,G);}this.fireEvent("contentReady",{type:"contentReady",target:G.element});},this,true);};var E=function(G){this.setAttributeConfig("element",{value:D.get(G.element),readOnly:true});};var B=function(G){this.i!
 nitAttributes(G);this.setAttributes(G,true);this.fireQueue();}!
 ;var C=f
unction(G,I){var H=this.get("element");I=I||{};I.name=G;I.method=I.method||function(J){H[G]=J;};I.value=I.value||H[G];this._configs[G]=new YAHOO.util.Attribute(I,this);};YAHOO.augment(YAHOO.util.Element,F);})();YAHOO.register("element",YAHOO.util.Element,{version:"2.4.1",build:"742"});YAHOO.register("utilities", YAHOO, {version: "2.4.1", build: "742"});
+if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var A=arguments,E=null,C,B,D;for(C=0;C<A.length;C=C+1){D=A[C].split(".");E=YAHOO;for(B=(D[0]=="YAHOO")?1:0;B<D.length;B=B+1){E[D[B]]=E[D[B]]||{};E=E[D[B]];}}return E;};YAHOO.log=function(D,A,C){var B=YAHOO.widget.Logger;if(B&&B.log){return B.log(D,A,C);}else{return false;}};YAHOO.register=function(A,E,D){var I=YAHOO.env.modules;if(!I[A]){I[A]={versions:[],builds:[]};}var B=I[A],H=D.version,G=D.build,F=YAHOO.env.listeners;B.name=A;B.version=H;B.build=G;B.versions.push(H);B.builds.push(G);B.mainClass=E;for(var C=0;C<F.length;C=C+1){F[C](B);}if(E){E.VERSION=H;E.BUILD=G;}else{YAHOO.log("mainClass is undefined for module "+A,"warn");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[]};YAHOO.env.getVersion=function(A){return YAHOO.env.modules[A]||null;};YAHOO.env.ua=function(){var C={ie:0,opera:0,gecko:0,webkit:0,mobile:null,air:0};var B=navigator.userAgent,A;if((/KHTML/).test(B)){C.webkit=1;}A=B.match(/A!
 ppleWebKit\/([^\s]*)/);if(A&&A[1]){C.webkit=parseFloat(A[1]);if(/ Mobile\//.test(B)){C.mobile="Apple";}else{A=B.match(/NokiaN[^\/]*/);if(A){C.mobile=A[0];}}A=B.match(/AdobeAIR\/([^\s]*)/);if(A){C.air=A[0];}}if(!C.webkit){A=B.match(/Opera[\s\/]([^\s]*)/);if(A&&A[1]){C.opera=parseFloat(A[1]);A=B.match(/Opera Mini[^;]*/);if(A){C.mobile=A[0];}}else{A=B.match(/MSIE\s([^;]*)/);if(A&&A[1]){C.ie=parseFloat(A[1]);}else{A=B.match(/Gecko\/([^\s]*)/);if(A){C.gecko=1;A=B.match(/rv:([^\s\)]*)/);if(A&&A[1]){C.gecko=parseFloat(A[1]);}}}}}return C;}();(function(){YAHOO.namespace("util","widget","example");if("undefined"!==typeof YAHOO_config){var B=YAHOO_config.listener,A=YAHOO.env.listeners,D=true,C;if(B){for(C=0;C<A.length;C=C+1){if(A[C]==B){D=false;break;}}if(D){A.push(B);}}}})();YAHOO.lang=YAHOO.lang||{isArray:function(B){if(B){var A=YAHOO.lang;return A.isNumber(B.length)&&A.isFunction(B.splice);}return false;},isBoolean:function(A){return typeof A==="boolean";},isFunction:function(A){r!
 eturn typeof A==="function";},isNull:function(A){return A===nu!
 ll;},isN
umber:function(A){return typeof A==="number"&&isFinite(A);},isObject:function(A){return(A&&(typeof A==="object"||YAHOO.lang.isFunction(A)))||false;},isString:function(A){return typeof A==="string";},isUndefined:function(A){return typeof A==="undefined";},hasOwnProperty:function(A,B){if(Object.prototype.hasOwnProperty){return A.hasOwnProperty(B);}return !YAHOO.lang.isUndefined(A[B])&&A.constructor.prototype[B]!==A[B];},_IEEnumFix:function(C,B){if(YAHOO.env.ua.ie){var E=["toString","valueOf"],A;for(A=0;A<E.length;A=A+1){var F=E[A],D=B[F];if(YAHOO.lang.isFunction(D)&&D!=Object.prototype[F]){C[F]=D;}}}},extend:function(D,E,C){if(!E||!D){throw new Error("YAHOO.lang.extend failed, please check that "+"all dependencies are included.");}var B=function(){};B.prototype=E.prototype;D.prototype=new B();D.prototype.constructor=D;D.superclass=E.prototype;if(E.prototype.constructor==Object.prototype.constructor){E.prototype.constructor=E;}if(C){for(var A in C){D.prototype[A]=C[A];}YAHOO.la!
 ng._IEEnumFix(D.prototype,C);}},augmentObject:function(E,D){if(!D||!E){throw new Error("Absorb failed, verify dependencies.");}var A=arguments,C,F,B=A[2];if(B&&B!==true){for(C=2;C<A.length;C=C+1){E[A[C]]=D[A[C]];}}else{for(F in D){if(B||!E[F]){E[F]=D[F];}}YAHOO.lang._IEEnumFix(E,D);}},augmentProto:function(D,C){if(!C||!D){throw new Error("Augment failed, verify dependencies.");}var A=[D.prototype,C.prototype];for(var B=2;B<arguments.length;B=B+1){A.push(arguments[B]);}YAHOO.lang.augmentObject.apply(this,A);},dump:function(A,G){var C=YAHOO.lang,D,F,I=[],J="{...}",B="f(){...}",H=", ",E=" => ";if(!C.isObject(A)){return A+"";}else{if(A instanceof Date||("nodeType" in A&&"tagName" in A)){return A;}else{if(C.isFunction(A)){return B;}}}G=(C.isNumber(G))?G:3;if(C.isArray(A)){I.push("[");for(D=0,F=A.length;D<F;D=D+1){if(C.isObject(A[D])){I.push((G>0)?C.dump(A[D],G-1):J);}else{I.push(A[D]);}I.push(H);}if(I.length>1){I.pop();}I.push("]");}else{I.push("{");for(D in A){if(C.hasOwnProper!
 ty(A,D)){I.push(D+E);if(C.isObject(A[D])){I.push((G>0)?C.dump(!
 A[D],G-1
):J);}else{I.push(A[D]);}I.push(H);}}if(I.length>1){I.pop();}I.push("}");}return I.join("");},substitute:function(Q,B,J){var G,F,E,M,N,P,D=YAHOO.lang,L=[],C,H="dump",K=" ",A="{",O="}";for(;;){G=Q.lastIndexOf(A);if(G<0){break;}F=Q.indexOf(O,G);if(G+1>=F){break;}C=Q.substring(G+1,F);M=C;P=null;E=M.indexOf(K);if(E>-1){P=M.substring(E+1);M=M.substring(0,E);}N=B[M];if(J){N=J(M,N,P);}if(D.isObject(N)){if(D.isArray(N)){N=D.dump(N,parseInt(P,10));}else{P=P||"";var I=P.indexOf(H);if(I>-1){P=P.substring(4);}if(N.toString===Object.prototype.toString||I>-1){N=D.dump(N,parseInt(P,10));}else{N=N.toString();}}}else{if(!D.isString(N)&&!D.isNumber(N)){N="~-"+L.length+"-~";L[L.length]=C;}}Q=Q.substring(0,G)+N+Q.substring(F+1);}for(G=L.length-1;G>=0;G=G-1){Q=Q.replace(new RegExp("~-"+G+"-~"),"{"+L[G]+"}","g");}return Q;},trim:function(A){try{return A.replace(/^\s+|\s+$/g,"");}catch(B){return A;}},merge:function(){var D={},B=arguments;for(var C=0,A=B.length;C<A;C=C+1){YAHOO.lang.augmentObject(D!
 ,B[C],true);}return D;},later:function(H,B,I,D,E){H=H||0;B=B||{};var C=I,G=D,F,A;if(YAHOO.lang.isString(I)){C=B[I];}if(!C){throw new TypeError("method undefined");}if(!YAHOO.lang.isArray(G)){G=[D];}F=function(){C.apply(B,G);};A=(E)?setInterval(F,H):setTimeout(F,H);return{interval:E,cancel:function(){if(this.interval){clearInterval(A);}else{clearTimeout(A);}}};},isValue:function(B){var A=YAHOO.lang;return(A.isObject(B)||A.isString(B)||A.isNumber(B)||A.isBoolean(B));}};YAHOO.util.Lang=YAHOO.lang;YAHOO.lang.augment=YAHOO.lang.augmentProto;YAHOO.augment=YAHOO.lang.augmentProto;YAHOO.extend=YAHOO.lang.extend;YAHOO.register("yahoo",YAHOO,{version:"2.5.1",build:"984"});YAHOO.util.Get=function(){var M={},L=0,Q=0,E=false,N=YAHOO.env.ua,R=YAHOO.lang;var J=function(V,S,W){var T=W||window,X=T.document,Y=X.createElement(V);for(var U in S){if(S[U]&&YAHOO.lang.hasOwnProperty(S,U)){Y.setAttribute(U,S[U]);}}return Y;
+};var H=function(S,T,V){var U=V||"utf-8";return J("link",{"id":"yui__dyn_"+(Q++),"type":"text/css","charset":U,"rel":"stylesheet","href":S},T);};var O=function(S,T,V){var U=V||"utf-8";return J("script",{"id":"yui__dyn_"+(Q++),"type":"text/javascript","charset":U,"src":S},T);};var A=function(S,T){return{tId:S.tId,win:S.win,data:S.data,nodes:S.nodes,msg:T,purge:function(){D(this.tId);}};};var B=function(S,V){var T=M[V],U=(R.isString(S))?T.win.document.getElementById(S):S;if(!U){P(V,"target node not found: "+S);}return U;};var P=function(V,U){var S=M[V];if(S.onFailure){var T=S.scope||S.win;S.onFailure.call(T,A(S,U));}};var C=function(V){var S=M[V];S.finished=true;if(S.aborted){var U="transaction "+V+" was aborted";P(V,U);return ;}if(S.onSuccess){var T=S.scope||S.win;S.onSuccess.call(T,A(S));}};var G=function(U,Y){var T=M[U];if(T.aborted){var W="transaction "+U+" was aborted";P(U,W);return ;}if(Y){T.url.shift();if(T.varName){T.varName.shift();}}else{T.url=(R.isString(T.url))?[T!
 .url]:T.url;if(T.varName){T.varName=(R.isString(T.varName))?[T.varName]:T.varName;}}var b=T.win,a=b.document,Z=a.getElementsByTagName("head")[0],V;if(T.url.length===0){if(T.type==="script"&&N.webkit&&N.webkit<420&&!T.finalpass&&!T.varName){var X=O(null,T.win,T.charset);X.innerHTML='YAHOO.util.Get._finalize("'+U+'");';T.nodes.push(X);Z.appendChild(X);}else{C(U);}return ;}var S=T.url[0];if(T.type==="script"){V=O(S,b,T.charset);}else{V=H(S,b,T.charset);}F(T.type,V,U,S,b,T.url.length);T.nodes.push(V);if(T.insertBefore){var c=B(T.insertBefore,U);if(c){c.parentNode.insertBefore(V,c);}}else{Z.appendChild(V);}if((N.webkit||N.gecko)&&T.type==="css"){G(U,S);}};var K=function(){if(E){return ;}E=true;for(var S in M){var T=M[S];if(T.autopurge&&T.finished){D(T.tId);delete M[S];}}E=false;};var D=function(Z){var W=M[Z];if(W){var Y=W.nodes,S=Y.length,X=W.win.document,V=X.getElementsByTagName("head")[0];if(W.insertBefore){var U=B(W.insertBefore,Z);if(U){V=U.parentNode;}}for(var T=0;T<S;T=T+1!
 ){V.removeChild(Y[T]);}}W.nodes=[];};var I=function(T,S,U){var!
  W="q"+(
L++);U=U||{};if(L%YAHOO.util.Get.PURGE_THRESH===0){K();}M[W]=R.merge(U,{tId:W,type:T,url:S,finished:false,nodes:[]});var V=M[W];V.win=V.win||window;V.scope=V.scope||V.win;V.autopurge=("autopurge" in V)?V.autopurge:(T==="script")?true:false;R.later(0,V,G,W);return{tId:W};};var F=function(b,W,V,T,X,Y,a){var Z=a||G;if(N.ie){W.onreadystatechange=function(){var c=this.readyState;if("loaded"===c||"complete"===c){Z(V,T);}};}else{if(N.webkit){if(b==="script"){if(N.webkit>=420){W.addEventListener("load",function(){Z(V,T);});}else{var S=M[V];if(S.varName){var U=YAHOO.util.Get.POLL_FREQ;S.maxattempts=YAHOO.util.Get.TIMEOUT/U;S.attempts=0;S._cache=S.varName[0].split(".");S.timer=R.later(U,S,function(h){var e=this._cache,d=e.length,c=this.win,f;for(f=0;f<d;f=f+1){c=c[e[f]];if(!c){this.attempts++;if(this.attempts++>this.maxattempts){var g="Over retry limit, giving up";S.timer.cancel();P(V,g);}else{}return ;}}S.timer.cancel();Z(V,T);},null,true);}else{R.later(YAHOO.util.Get.POLL_FREQ,null,!
 Z,[V,T]);}}}}else{W.onload=function(){Z(V,T);};}}};return{POLL_FREQ:10,PURGE_THRESH:20,TIMEOUT:2000,_finalize:function(S){R.later(0,null,C,S);},abort:function(T){var U=(R.isString(T))?T:T.tId;var S=M[U];if(S){S.aborted=true;}},script:function(S,T){return I("script",S,T);},css:function(S,T){return I("css",S,T);}};}();YAHOO.register("get",YAHOO.util.Get,{version:"2.5.1",build:"984"});(function(){var Y=YAHOO,util=Y.util,lang=Y.lang,env=Y.env,PROV="_provides",SUPER="_supersedes",REQ="expanded",AFTER="_after";var YUI={dupsAllowed:{"yahoo":true,"get":true},info:{"base":"http://yui.yahooapis.com/2.5.1/build/","skin":{"defaultSkin":"sam","base":"assets/skins/","path":"skin.css","after":["reset","fonts","grids","base"],"rollup":3},dupsAllowed:["yahoo","get"],"moduleInfo":{"animation":{"type":"js","path":"animation/animation-min.js","requires":["dom","event"]},"autocomplete":{"type":"js","path":"autocomplete/autocomplete-min.js","requires":["dom","event"],"optional":["connection","an!
 imation"],"skinnable":true},"base":{"type":"css","path":"base/!
 base-min
.css","after":["reset","fonts","grids"]},"button":{"type":"js","path":"button/button-min.js","requires":["element"],"optional":["menu"],"skinnable":true},"calendar":{"type":"js","path":"calendar/calendar-min.js","requires":["event","dom"],"skinnable":true},"charts":{"type":"js","path":"charts/charts-experimental-min.js","requires":["element","json","datasource"]},"colorpicker":{"type":"js","path":"colorpicker/colorpicker-min.js","requires":["slider","element"],"optional":["animation"],"skinnable":true},"connection":{"type":"js","path":"connection/connection-min.js","requires":["event"]},"container":{"type":"js","path":"container/container-min.js","requires":["dom","event"],"optional":["dragdrop","animation","connection"],"supersedes":["containercore"],"skinnable":true},"containercore":{"type":"js","path":"container/container_core-min.js","requires":["dom","event"],"pkg":"container"},"cookie":{"type":"js","path":"cookie/cookie-beta-min.js","requires":["yahoo"]},"datasource":{!
 "type":"js","path":"datasource/datasource-beta-min.js","requires":["event"],"optional":["connection"]},"datatable":{"type":"js","path":"datatable/datatable-beta-min.js","requires":["element","datasource"],"optional":["calendar","dragdrop"],"skinnable":true},"dom":{"type":"js","path":"dom/dom-min.js","requires":["yahoo"]},"dragdrop":{"type":"js","path":"dragdrop/dragdrop-min.js","requires":["dom","event"]},"editor":{"type":"js","path":"editor/editor-beta-min.js","requires":["menu","element","button"],"optional":["animation","dragdrop"],"skinnable":true},"element":{"type":"js","path":"element/element-beta-min.js","requires":["dom","event"]},"event":{"type":"js","path":"event/event-min.js","requires":["yahoo"]},"fonts":{"type":"css","path":"fonts/fonts-min.css"},"get":{"type":"js","path":"get/get-min.js","requires":["yahoo"]},"grids":{"type":"css","path":"grids/grids-min.css","requires":["fonts"],"optional":["reset"]},"history":{"type":"js","path":"history/history-min.js","req!
 uires":["event"]},"imagecropper":{"type":"js","path":"imagecro!
 pper/ima
gecropper-beta-min.js","requires":["dom","event","dragdrop","element","resize"],"skinnable":true},"imageloader":{"type":"js","path":"imageloader/imageloader-min.js","requires":["event","dom"]},"json":{"type":"js","path":"json/json-min.js","requires":["yahoo"]},"layout":{"type":"js","path":"layout/layout-beta-min.js","requires":["dom","event","element"],"optional":["animation","dragdrop","resize","selector"],"skinnable":true},"logger":{"type":"js","path":"logger/logger-min.js","requires":["event","dom"],"optional":["dragdrop"],"skinnable":true},"menu":{"type":"js","path":"menu/menu-min.js","requires":["containercore"],"skinnable":true},"profiler":{"type":"js","path":"profiler/profiler-beta-min.js","requires":["yahoo"]},"profilerviewer":{"type":"js","path":"profilerviewer/profilerviewer-beta-min.js","requires":["profiler","yuiloader","element"],"skinnable":true},"reset":{"type":"css","path":"reset/reset-min.css"},"reset-fonts-grids":{"type":"css","path":"reset-fonts-grids/rese!
 t-fonts-grids.css","supersedes":["reset","fonts","grids","reset-fonts"],"rollup":4},"reset-fonts":{"type":"css","path":"reset-fonts/reset-fonts.css","supersedes":["reset","fonts"],"rollup":2},"resize":{"type":"js","path":"resize/resize-beta-min.js","requires":["dom","event","dragdrop","element"],"optional":["animation"],"skinnable":true},"selector":{"type":"js","path":"selector/selector-beta-min.js","requires":["yahoo","dom"]},"simpleeditor":{"type":"js","path":"editor/simpleeditor-beta-min.js","requires":["element"],"optional":["containercore","menu","button","animation","dragdrop"],"skinnable":true,"pkg":"editor"},"slider":{"type":"js","path":"slider/slider-min.js","requires":["dragdrop"],"optional":["animation"]},"tabview":{"type":"js","path":"tabview/tabview-min.js","requires":["element"],"optional":["connection"],"skinnable":true},"treeview":{"type":"js","path":"treeview/treeview-min.js","requires":["event"],"skinnable":true},"uploader":{"type":"js","path":"uploader/up!
 loader-experimental.js","requires":["yahoo"]},"utilities":{"ty!
 pe":"js"
,"path":"utilities/utilities.js","supersedes":["yahoo","event","dragdrop","animation","dom","connection","element","yahoo-dom-event","get","yuiloader","yuiloader-dom-event"],"rollup":8},"yahoo":{"type":"js","path":"yahoo/yahoo-min.js"},"yahoo-dom-event":{"type":"js","path":"yahoo-dom-event/yahoo-dom-event.js","supersedes":["yahoo","event","dom"],"rollup":3},"yuiloader":{"type":"js","path":"yuiloader/yuiloader-beta-min.js","supersedes":["yahoo","get"]},"yuiloader-dom-event":{"type":"js","path":"yuiloader-dom-event/yuiloader-dom-event.js","supersedes":["yahoo","dom","event","get","yuiloader","yahoo-dom-event"],"rollup":5},"yuitest":{"type":"js","path":"yuitest/yuitest-min.js","requires":["logger"],"skinnable":true}}},ObjectUtil:{appendArray:function(o,a){if(a){for(var i=0;
+i<a.length;i=i+1){o[a[i]]=true;}}},keys:function(o,ordered){var a=[],i;for(i in o){if(lang.hasOwnProperty(o,i)){a.push(i);}}return a;}},ArrayUtil:{appendArray:function(a1,a2){Array.prototype.push.apply(a1,a2);},indexOf:function(a,val){for(var i=0;i<a.length;i=i+1){if(a[i]===val){return i;}}return -1;},toObject:function(a){var o={};for(var i=0;i<a.length;i=i+1){o[a[i]]=true;}return o;},uniq:function(a){return YUI.ObjectUtil.keys(YUI.ArrayUtil.toObject(a));}}};YAHOO.util.YUILoader=function(o){this._internalCallback=null;this._useYahooListener=false;this.onSuccess=null;this.onFailure=Y.log;this.onProgress=null;this.scope=this;this.data=null;this.insertBefore=null;this.charset=null;this.varName=null;this.base=YUI.info.base;this.ignore=null;this.force=null;this.allowRollup=true;this.filter=null;this.required={};this.moduleInfo=lang.merge(YUI.info.moduleInfo);this.rollups=null;this.loadOptional=false;this.sorted=[];this.loaded={};this.dirty=true;this.inserted={};var self=this;env!
 .listeners.push(function(m){if(self._useYahooListener){self.loadNext(m.name);}});this.skin=lang.merge(YUI.info.skin);this._config(o);};Y.util.YUILoader.prototype={FILTERS:{RAW:{"searchExp":"-min\\.js","replaceStr":".js"},DEBUG:{"searchExp":"-min\\.js","replaceStr":"-debug.js"}},SKIN_PREFIX:"skin-",_config:function(o){if(o){for(var i in o){if(lang.hasOwnProperty(o,i)){if(i=="require"){this.require(o[i]);}else{this[i]=o[i];}}}}var f=this.filter;if(lang.isString(f)){f=f.toUpperCase();if(f==="DEBUG"){this.require("logger");}if(!Y.widget.LogWriter){Y.widget.LogWriter=function(){return Y;};}this.filter=this.FILTERS[f];}},addModule:function(o){if(!o||!o.name||!o.type||(!o.path&&!o.fullpath)){return false;}o.ext=("ext" in o)?o.ext:true;o.requires=o.requires||[];this.moduleInfo[o.name]=o;this.dirty=true;return true;},require:function(what){var a=(typeof what==="string")?arguments:what;this.dirty=true;YUI.ObjectUtil.appendArray(this.required,a);},_addSkin:function(skin,mod){var name=!
 this.formatSkin(skin),info=this.moduleInfo,sinf=this.skin,ext=!
 info[mod
]&&info[mod].ext;if(!info[name]){this.addModule({"name":name,"type":"css","path":sinf.base+skin+"/"+sinf.path,"after":sinf.after,"rollup":sinf.rollup,"ext":ext});}if(mod){name=this.formatSkin(skin,mod);if(!info[name]){var mdef=info[mod],pkg=mdef.pkg||mod;this.addModule({"name":name,"type":"css","after":sinf.after,"path":pkg+"/"+sinf.base+skin+"/"+mod+".css","ext":ext});}}return name;},getRequires:function(mod){if(!mod){return[];}if(!this.dirty&&mod.expanded){return mod.expanded;}mod.requires=mod.requires||[];var i,d=[],r=mod.requires,o=mod.optional,info=this.moduleInfo,m;for(i=0;i<r.length;i=i+1){d.push(r[i]);m=info[r[i]];YUI.ArrayUtil.appendArray(d,this.getRequires(m));}if(o&&this.loadOptional){for(i=0;i<o.length;i=i+1){d.push(o[i]);YUI.ArrayUtil.appendArray(d,this.getRequires(info[o[i]]));}}mod.expanded=YUI.ArrayUtil.uniq(d);return mod.expanded;},getProvides:function(name,notMe){var addMe=!(notMe),ckey=(addMe)?PROV:SUPER,m=this.moduleInfo[name],o={};if(!m){return o;}if(m[c!
 key]){return m[ckey];}var s=m.supersedes,done={},me=this;var add=function(mm){if(!done[mm]){done[mm]=true;lang.augmentObject(o,me.getProvides(mm));}};if(s){for(var i=0;i<s.length;i=i+1){add(s[i]);}}m[SUPER]=o;m[PROV]=lang.merge(o);m[PROV][name]=true;return m[ckey];},calculate:function(o){if(this.dirty){this._config(o);this._setup();this._explode();if(this.allowRollup){this._rollup();}this._reduce();this._sort();this.dirty=false;}},_setup:function(){var info=this.moduleInfo,name,i,j;for(name in info){var m=info[name];if(m&&m.skinnable){var o=this.skin.overrides,smod;if(o&&o[name]){for(i=0;i<o[name].length;i=i+1){smod=this._addSkin(o[name][i],name);}}else{smod=this._addSkin(this.skin.defaultSkin,name);}m.requires.push(smod);}}var l=lang.merge(this.inserted);if(!this._sandbox){l=lang.merge(l,env.modules);}if(this.ignore){YUI.ObjectUtil.appendArray(l,this.ignore);}if(this.force){for(i=0;i<this.force.length;i=i+1){if(this.force[i] in l){delete l[this.force[i]];}}}for(j in l){if(!
 lang.hasOwnProperty(l,j)){lang.augmentObject(l,this.getProvide!
 s(j));}}
this.loaded=l;},_explode:function(){var r=this.required,i,mod;for(i in r){mod=this.moduleInfo[i];if(mod){var req=this.getRequires(mod);if(req){YUI.ObjectUtil.appendArray(r,req);}}}},_skin:function(){},formatSkin:function(skin,mod){var s=this.SKIN_PREFIX+skin;if(mod){s=s+"-"+mod;}return s;},parseSkin:function(mod){if(mod.indexOf(this.SKIN_PREFIX)===0){var a=mod.split("-");return{skin:a[1],module:a[2]};}return null;},_rollup:function(){var i,j,m,s,rollups={},r=this.required,roll;if(this.dirty||!this.rollups){for(i in this.moduleInfo){m=this.moduleInfo[i];if(m&&m.rollup){rollups[i]=m;}}this.rollups=rollups;}for(;;){var rolled=false;for(i in rollups){if(!r[i]&&!this.loaded[i]){m=this.moduleInfo[i];s=m.supersedes;roll=false;if(!m.rollup){continue;}var skin=(m.ext)?false:this.parseSkin(i),c=0;if(skin){for(j in r){if(i!==j&&this.parseSkin(j)){c++;roll=(c>=m.rollup);if(roll){break;}}}}else{for(j=0;j<s.length;j=j+1){if(this.loaded[s[j]]&&(!YUI.dupsAllowed[s[j]])){roll=false;break;}el!
 se{if(r[s[j]]){c++;roll=(c>=m.rollup);if(roll){break;}}}}}if(roll){r[i]=true;rolled=true;this.getRequires(m);}}}if(!rolled){break;}}},_reduce:function(){var i,j,s,m,r=this.required;for(i in r){if(i in this.loaded){delete r[i];}else{var skinDef=this.parseSkin(i);if(skinDef){if(!skinDef.module){var skin_pre=this.SKIN_PREFIX+skinDef.skin;for(j in r){m=this.moduleInfo[j];var ext=m&&m.ext;if(!ext&&j!==i&&j.indexOf(skin_pre)>-1){delete r[j];}}}}else{m=this.moduleInfo[i];s=m&&m.supersedes;if(s){for(j=0;j<s.length;j=j+1){if(s[j] in r){delete r[s[j]];}}}}}}},_sort:function(){var s=[],info=this.moduleInfo,loaded=this.loaded,me=this;var requires=function(aa,bb){if(loaded[bb]){return false;}var ii,mm=info[aa],rr=mm&&mm.expanded,after=mm&&mm.after,other=info[bb];if(rr&&YUI.ArrayUtil.indexOf(rr,bb)>-1){return true;}if(after&&YUI.ArrayUtil.indexOf(after,bb)>-1){return true;}var ss=info[bb]&&info[bb].supersedes;if(ss){for(ii=0;
+ii<ss.length;ii=ii+1){if(requires(aa,ss[ii])){return true;}}}if(mm.ext&&mm.type=="css"&&(!other.ext)){return true;}return false;};for(var i in this.required){s.push(i);}var p=0;for(;;){var l=s.length,a,b,j,k,moved=false;for(j=p;j<l;j=j+1){a=s[j];for(k=j+1;k<l;k=k+1){if(requires(a,s[k])){b=s.splice(k,1);s.splice(j,0,b[0]);moved=true;break;}}if(moved){break;}else{p=p+1;}}if(!moved){break;}}this.sorted=s;},toString:function(){var o={type:"YUILoader",base:this.base,filter:this.filter,required:this.required,loaded:this.loaded,inserted:this.inserted};lang.dump(o,1);},insert:function(o,type){this.calculate(o);if(!type){var self=this;this._internalCallback=function(){self._internalCallback=null;self.insert(null,"js");};this.insert(null,"css");return ;}this._loading=true;this.loadType=type;this.loadNext();},sandbox:function(o,type){if(o){}else{}this._config(o);if(!this.onSuccess){throw new Error("You must supply an onSuccess handler for your sandbox");}this._sandbox=true;var self=th!
 is;if(!type||type!=="js"){this._internalCallback=function(){self._internalCallback=null;self.sandbox(null,"js");};this.insert(null,"css");return ;}if(!util.Connect){var ld=new YAHOO.util.YUILoader();ld.insert({base:this.base,filter:this.filter,require:"connection",insertBefore:this.insertBefore,charset:this.charset,onSuccess:function(){this.sandbox(null,"js");},scope:this},"js");return ;}this._scriptText=[];this._loadCount=0;this._stopCount=this.sorted.length;this._xhr=[];this.calculate();var s=this.sorted,l=s.length,i,m,url;for(i=0;i<l;i=i+1){m=this.moduleInfo[s[i]];if(!m){this.onFailure.call(this.scope,{msg:"undefined module "+m,data:this.data});for(var j=0;j<this._xhr.length;j=j+1){this._xhr[j].abort();}return ;}if(m.type!=="js"){this._loadCount++;continue;}url=m.fullpath||this._url(m.path);var xhrData={success:function(o){var idx=o.argument[0],name=o.argument[2];this._scriptText[idx]=o.responseText;if(this.onProgress){this.onProgress.call(this.scope,{name:name,scriptTex!
 t:o.responseText,xhrResponse:o,data:this.data});}this._loadCou!
 nt++;if(
this._loadCount>=this._stopCount){var v=this.varName||"YAHOO";var t="(function() {\n";var b="\nreturn "+v+";\n})();";var ref=eval(t+this._scriptText.join("\n")+b);this._pushEvents(ref);if(ref){this.onSuccess.call(this.scope,{reference:ref,data:this.data});}else{this.onFailure.call(this.scope,{msg:this.varName+" reference failure",data:this.data});}}},failure:function(o){this.onFailure.call(this.scope,{msg:"XHR failure",xhrResponse:o,data:this.data});},scope:this,argument:[i,url,s[i]]};this._xhr.push(util.Connect.asyncRequest("GET",url,xhrData));}},loadNext:function(mname){if(!this._loading){return ;}if(mname){if(mname!==this._loading){return ;}this.inserted[mname]=true;if(this.onProgress){this.onProgress.call(this.scope,{name:mname,data:this.data});}}var s=this.sorted,len=s.length,i,m;for(i=0;i<len;i=i+1){if(s[i] in this.inserted){continue;}if(s[i]===this._loading){return ;}m=this.moduleInfo[s[i]];if(!m){this.onFailure.call(this.scope,{msg:"undefined module "+m,data:this.dat!
 a});return ;}if(!this.loadType||this.loadType===m.type){this._loading=s[i];var fn=(m.type==="css")?util.Get.css:util.Get.script,url=m.fullpath||this._url(m.path),self=this,c=function(o){self.loadNext(o.data);};if(env.ua.webkit&&env.ua.webkit<420&&m.type==="js"&&!m.varName){c=null;this._useYahooListener=true;}fn(url,{data:s[i],onSuccess:c,insertBefore:this.insertBefore,charset:this.charset,varName:m.varName,scope:self});return ;}}this._loading=null;if(this._internalCallback){var f=this._internalCallback;this._internalCallback=null;f.call(this);}else{if(this.onSuccess){this._pushEvents();this.onSuccess.call(this.scope,{data:this.data});}}},_pushEvents:function(ref){var r=ref||YAHOO;if(r.util&&r.util.Event){r.util.Event._load();}},_url:function(path){var u=this.base||"",f=this.filter;u=u+path;if(f){u=u.replace(new RegExp(f.searchExp),f.replaceStr);}return u;}};})();(function(){var B=YAHOO.util,K,I,J={},F={},M=window.document;YAHOO.env._id_counter=YAHOO.env._id_counter||0;var C!
 =YAHOO.env.ua.opera,L=YAHOO.env.ua.webkit,A=YAHOO.env.ua.gecko!
 ,G=YAHOO
.env.ua.ie;var E={HYPHEN:/(-[a-z])/i,ROOT_TAG:/^body|html$/i,OP_SCROLL:/^(?:inline|table-row)$/i};var N=function(P){if(!E.HYPHEN.test(P)){return P;}if(J[P]){return J[P];}var Q=P;while(E.HYPHEN.exec(Q)){Q=Q.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());}J[P]=Q;return Q;};var O=function(Q){var P=F[Q];if(!P){P=new RegExp("(?:^|\\s+)"+Q+"(?:\\s+|$)");F[Q]=P;}return P;};if(M.defaultView&&M.defaultView.getComputedStyle){K=function(P,S){var R=null;if(S=="float"){S="cssFloat";}var Q=P.ownerDocument.defaultView.getComputedStyle(P,"");if(Q){R=Q[N(S)];}return P.style[S]||R;};}else{if(M.documentElement.currentStyle&&G){K=function(P,R){switch(N(R)){case"opacity":var T=100;try{T=P.filters["DXImageTransform.Microsoft.Alpha"].opacity;}catch(S){try{T=P.filters("alpha").opacity;}catch(S){}}return T/100;case"float":R="styleFloat";default:var Q=P.currentStyle?P.currentStyle[R]:null;return(P.style[R]||Q);}};}else{K=function(P,Q){return P.style[Q];};}}if(G){I=function(P,Q,R){switch(Q){case!
 "opacity":if(YAHOO.lang.isString(P.style.filter)){P.style.filter="alpha(opacity="+R*100+")";if(!P.currentStyle||!P.currentStyle.hasLayout){P.style.zoom=1;}}break;case"float":Q="styleFloat";default:P.style[Q]=R;}};}else{I=function(P,Q,R){if(Q=="float"){Q="cssFloat";}P.style[Q]=R;};}var D=function(P,Q){return P&&P.nodeType==1&&(!Q||Q(P));};YAHOO.util.Dom={get:function(R){if(R&&(R.nodeType||R.item)){return R;}if(YAHOO.lang.isString(R)||!R){return M.getElementById(R);}if(R.length!==undefined){var S=[];for(var Q=0,P=R.length;Q<P;++Q){S[S.length]=B.Dom.get(R[Q]);}return S;}return R;},getStyle:function(P,R){R=N(R);var Q=function(S){return K(S,R);};return B.Dom.batch(P,Q,B.Dom,true);},setStyle:function(P,R,S){R=N(R);var Q=function(T){I(T,R,S);};B.Dom.batch(P,Q,B.Dom,true);},getXY:function(P){var Q=function(R){if((R.parentNode===null||R.offsetParent===null||this.getStyle(R,"display")=="none")&&R!=R.ownerDocument.body){return false;}return H(R);};return B.Dom.batch(P,Q,B.Dom,true);},!
 getX:function(P){var Q=function(R){return B.Dom.getXY(R)[0];};!
 return B
.Dom.batch(P,Q,B.Dom,true);},getY:function(P){var Q=function(R){return B.Dom.getXY(R)[1];};return B.Dom.batch(P,Q,B.Dom,true);},setXY:function(P,S,R){var Q=function(V){var U=this.getStyle(V,"position");if(U=="static"){this.setStyle(V,"position","relative");U="relative";}var X=this.getXY(V);if(X===false){return false;}var W=[parseInt(this.getStyle(V,"left"),10),parseInt(this.getStyle(V,"top"),10)];if(isNaN(W[0])){W[0]=(U=="relative")?0:V.offsetLeft;}if(isNaN(W[1])){W[1]=(U=="relative")?0:V.offsetTop;}if(S[0]!==null){V.style.left=S[0]-X[0]+W[0]+"px";}if(S[1]!==null){V.style.top=S[1]-X[1]+W[1]+"px";}if(!R){var T=this.getXY(V);if((S[0]!==null&&T[0]!=S[0])||(S[1]!==null&&T[1]!=S[1])){this.setXY(V,S,true);}}};B.Dom.batch(P,Q,B.Dom,true);},setX:function(Q,P){B.Dom.setXY(Q,[P,null]);},setY:function(P,Q){B.Dom.setXY(P,[null,Q]);},getRegion:function(P){var Q=function(R){if((R.parentNode===null||R.offsetParent===null||this.getStyle(R,"display")=="none")&&R!=R.ownerDocument.body){return!
  false;}var S=B.Region.getRegion(R);return S;};return B.Dom.batch(P,Q,B.Dom,true);},getClientWidth:function(){return B.Dom.getViewportWidth();},getClientHeight:function(){return B.Dom.getViewportHeight();},getElementsByClassName:function(T,X,U,V){X=X||"*";U=(U)?B.Dom.get(U):null||M;if(!U){return[];}var Q=[],P=U.getElementsByTagName(X),W=O(T);for(var R=0,S=P.length;R<S;++R){if(W.test(P[R].className)){Q[Q.length]=P[R];if(V){V.call(P[R],P[R]);}}}return Q;},hasClass:function(R,Q){var P=O(Q);var S=function(T){return P.test(T.className);};return B.Dom.batch(R,S,B.Dom,true);},addClass:function(Q,P){var R=function(S){if(this.hasClass(S,P)){return false;}S.className=YAHOO.lang.trim([S.className,P].join(" "));return true;};return B.Dom.batch(Q,R,B.Dom,true);},removeClass:function(R,Q){var P=O(Q);var S=function(T){if(!Q||!this.hasClass(T,Q)){return false;}var U=T.className;T.className=U.replace(P," ");if(this.hasClass(T,Q)){this.removeClass(T,Q);}T.className=YAHOO.lang.trim(T.classNam!
 e);return true;};return B.Dom.batch(R,S,B.Dom,true);},replaceC!
 lass:fun
ction(S,Q,P){if(!P||Q===P){return false;}var R=O(Q);var T=function(U){if(!this.hasClass(U,Q)){this.addClass(U,P);return true;}U.className=U.className.replace(R," "+P+" ");if(this.hasClass(U,Q)){this.replaceClass(U,Q,P);}U.className=YAHOO.lang.trim(U.className);return true;};return B.Dom.batch(S,T,B.Dom,true);},generateId:function(P,R){R=R||"yui-gen";var Q=function(S){if(S&&S.id){return S.id;}var T=R+YAHOO.env._id_counter++;if(S){S.id=T;}return T;};return B.Dom.batch(P,Q,B.Dom,true)||Q.apply(B.Dom,arguments);},isAncestor:function(P,Q){P=B.Dom.get(P);Q=B.Dom.get(Q);if(!P||!Q){return false;}if(P.contains&&Q.nodeType&&!L){return P.contains(Q);}else{if(P.compareDocumentPosition&&Q.nodeType){return !!(P.compareDocumentPosition(Q)&16);}else{if(Q.nodeType){return !!this.getAncestorBy(Q,function(R){return R==P;});}}}return false;},inDocument:function(P){return this.isAncestor(M.documentElement,P);},getElementsBy:function(W,Q,R,T){Q=Q||"*";R=(R)?B.Dom.get(R):null||M;if(!R){return[];}v!
 ar S=[],V=R.getElementsByTagName(Q);for(var U=0,P=V.length;U<P;++U){if(W(V[U])){S[S.length]=V[U];if(T){T(V[U]);}}}return S;},batch:function(T,W,V,R){T=(T&&(T.tagName||T.item))?T:B.Dom.get(T);if(!T||!W){return false;}var S=(R)?V:window;if(T.tagName||T.length===undefined){return W.call(S,T,V);}var U=[];for(var Q=0,P=T.length;Q<P;++Q){U[U.length]=W.call(S,T[Q],V);}return U;},getDocumentHeight:function(){var Q=(M.compatMode!="CSS1Compat")?M.body.scrollHeight:M.documentElement.scrollHeight;var P=Math.max(Q,B.Dom.getViewportHeight());return P;},getDocumentWidth:function(){var Q=(M.compatMode!="CSS1Compat")?M.body.scrollWidth:M.documentElement.scrollWidth;var P=Math.max(Q,B.Dom.getViewportWidth());return P;},getViewportHeight:function(){var P=self.innerHeight;
+var Q=M.compatMode;if((Q||G)&&!C){P=(Q=="CSS1Compat")?M.documentElement.clientHeight:M.body.clientHeight;}return P;},getViewportWidth:function(){var P=self.innerWidth;var Q=M.compatMode;if(Q||G){P=(Q=="CSS1Compat")?M.documentElement.clientWidth:M.body.clientWidth;}return P;},getAncestorBy:function(P,Q){while(P=P.parentNode){if(D(P,Q)){return P;}}return null;},getAncestorByClassName:function(Q,P){Q=B.Dom.get(Q);if(!Q){return null;}var R=function(S){return B.Dom.hasClass(S,P);};return B.Dom.getAncestorBy(Q,R);},getAncestorByTagName:function(Q,P){Q=B.Dom.get(Q);if(!Q){return null;}var R=function(S){return S.tagName&&S.tagName.toUpperCase()==P.toUpperCase();};return B.Dom.getAncestorBy(Q,R);},getPreviousSiblingBy:function(P,Q){while(P){P=P.previousSibling;if(D(P,Q)){return P;}}return null;},getPreviousSibling:function(P){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getPreviousSiblingBy(P);},getNextSiblingBy:function(P,Q){while(P){P=P.nextSibling;if(D(P,Q)){return P;}}return !
 null;},getNextSibling:function(P){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getNextSiblingBy(P);},getFirstChildBy:function(P,R){var Q=(D(P.firstChild,R))?P.firstChild:null;return Q||B.Dom.getNextSiblingBy(P.firstChild,R);},getFirstChild:function(P,Q){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getFirstChildBy(P);},getLastChildBy:function(P,R){if(!P){return null;}var Q=(D(P.lastChild,R))?P.lastChild:null;return Q||B.Dom.getPreviousSiblingBy(P.lastChild,R);},getLastChild:function(P){P=B.Dom.get(P);return B.Dom.getLastChildBy(P);},getChildrenBy:function(Q,S){var R=B.Dom.getFirstChildBy(Q,S);var P=R?[R]:[];B.Dom.getNextSiblingBy(R,function(T){if(!S||S(T)){P[P.length]=T;}return false;});return P;},getChildren:function(P){P=B.Dom.get(P);if(!P){}return B.Dom.getChildrenBy(P);},getDocumentScrollLeft:function(P){P=P||M;return Math.max(P.documentElement.scrollLeft,P.body.scrollLeft);},getDocumentScrollTop:function(P){P=P||M;return Math.max(P.documentElement.scrollTop,P.body!
 .scrollTop);},insertBefore:function(Q,P){Q=B.Dom.get(Q);P=B.Do!
 m.get(P)
;if(!Q||!P||!P.parentNode){return null;}return P.parentNode.insertBefore(Q,P);},insertAfter:function(Q,P){Q=B.Dom.get(Q);P=B.Dom.get(P);if(!Q||!P||!P.parentNode){return null;}if(P.nextSibling){return P.parentNode.insertBefore(Q,P.nextSibling);}else{return P.parentNode.appendChild(Q);}},getClientRegion:function(){var R=B.Dom.getDocumentScrollTop(),Q=B.Dom.getDocumentScrollLeft(),S=B.Dom.getViewportWidth()+Q,P=B.Dom.getViewportHeight()+R;return new B.Region(R,S,P,Q);}};var H=function(){if(M.documentElement.getBoundingClientRect){return function(Q){var R=Q.getBoundingClientRect();var P=Q.ownerDocument;return[R.left+B.Dom.getDocumentScrollLeft(P),R.top+B.Dom.getDocumentScrollTop(P)];};}else{return function(R){var S=[R.offsetLeft,R.offsetTop];var Q=R.offsetParent;var P=(L&&B.Dom.getStyle(R,"position")=="absolute"&&R.offsetParent==R.ownerDocument.body);if(Q!=R){while(Q){S[0]+=Q.offsetLeft;S[1]+=Q.offsetTop;if(!P&&L&&B.Dom.getStyle(Q,"position")=="absolute"){P=true;}Q=Q.offsetParen!
 t;}}if(P){S[0]-=R.ownerDocument.body.offsetLeft;S[1]-=R.ownerDocument.body.offsetTop;}Q=R.parentNode;while(Q.tagName&&!E.ROOT_TAG.test(Q.tagName)){if(Q.scrollTop||Q.scrollLeft){if(!E.OP_SCROLL.test(B.Dom.getStyle(Q,"display"))){if(!C||B.Dom.getStyle(Q,"overflow")!=="visible"){S[0]-=Q.scrollLeft;S[1]-=Q.scrollTop;}}}Q=Q.parentNode;}return S;};}}();})();YAHOO.util.Region=function(C,D,A,B){this.top=C;this[1]=C;this.right=D;this.bottom=A;this.left=B;this[0]=B;};YAHOO.util.Region.prototype.contains=function(A){return(A.left>=this.left&&A.right<=this.right&&A.top>=this.top&&A.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(E){var C=Math.max(this.top,E.top);var D=Math.min(this.right,E.right);var A=Math.min(this.bottom,E.bottom);var B=Math.max(this.left,E.left);if(A>=C&&D>=B){return new YAHOO.util.Region(C,D,A,B);}else{return null;}};YAHOO.util.Region.prototy!
 pe.union=function(E){var C=Math.min(this.top,E.top);var D=Math!
 .max(thi
s.right,E.right);var A=Math.max(this.bottom,E.bottom);var B=Math.min(this.left,E.left);return new YAHOO.util.Region(C,D,A,B);};YAHOO.util.Region.prototype.toString=function(){return("Region {"+"top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+"}");};YAHOO.util.Region.getRegion=function(D){var F=YAHOO.util.Dom.getXY(D);var C=F[1];var E=F[0]+D.offsetWidth;var A=F[1]+D.offsetHeight;var B=F[0];return new YAHOO.util.Region(C,E,A,B);};YAHOO.util.Point=function(A,B){if(YAHOO.lang.isArray(A)){B=A[1];A=A[0];}this.x=this.right=this.left=this[0]=A;this.y=this.top=this.bottom=this[1]=B;};YAHOO.util.Point.prototype=new YAHOO.util.Region();YAHOO.register("dom",YAHOO.util.Dom,{version:"2.5.1",build:"984"});YAHOO.util.CustomEvent=function(D,B,C,A){this.type=D;this.scope=B||window;this.silent=C;this.signature=A||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){}var E="_YUICEOnSubscribe";if(D!==E){this.subscribeEvent=new YAHOO.util.CustomEve!
 nt(E,this,true);}this.lastError=null;};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(B,C,A){if(!B){throw new Error("Invalid callback for subscriber to '"+this.type+"'");}if(this.subscribeEvent){this.subscribeEvent.fire(B,C,A);}this.subscribers.push(new YAHOO.util.Subscriber(B,C,A));},unsubscribe:function(D,F){if(!D){return this.unsubscribeAll();}var E=false;for(var B=0,A=this.subscribers.length;B<A;++B){var C=this.subscribers[B];if(C&&C.contains(D,F)){this._delete(B);E=true;}}return E;},fire:function(){var D=this.subscribers.length;if(!D&&this.silent){return true;}var H=[].slice.call(arguments,0),F=true,C,I=false;if(!this.silent){}var B=this.subscribers.slice();for(C=0;C<D;++C){var K=B[C];if(!K){I=true;}else{if(!this.silent){}var J=K.getScope(this.scope);if(this.signature==YAHOO.util.CustomEvent.FLAT){var A=null;if(H.length>0){A=H[0];}try{F=K.fn.call(J,A,K.obj);}catch(E){this.lastError=E;}}else{try{F=K.fn.ca!
 ll(J,this.type,H,K.obj);}catch(G){this.lastError=G;}}if(false=!
 ==F){if(
!this.silent){}return false;}}}return true;},unsubscribeAll:function(){for(var A=this.subscribers.length-1;A>-1;A--){this._delete(A);}this.subscribers=[];return A;},_delete:function(A){var B=this.subscribers[A];if(B){delete B.fn;delete B.obj;}this.subscribers.splice(A,1);},toString:function(){return"CustomEvent: "+"'"+this.type+"', "+"scope: "+this.scope;}};YAHOO.util.Subscriber=function(B,C,A){this.fn=B;this.obj=YAHOO.lang.isUndefined(C)?null:C;this.override=A;};YAHOO.util.Subscriber.prototype.getScope=function(A){if(this.override){if(this.override===true){return this.obj;}else{return this.override;}}return A;};YAHOO.util.Subscriber.prototype.contains=function(A,B){if(B){return(this.fn==A&&this.obj==B);}else{return(this.fn==A);}};YAHOO.util.Subscriber.prototype.toString=function(){return"Subscriber { obj: "+this.obj+", override: "+(this.override||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var H=false;var I=[];var J=[];var G=[];var E=[];var C=0;var F=[];v!
 ar B=[];var A=0;var D={63232:38,63233:40,63234:37,63235:39,63276:33,63277:34,25:9};return{POLL_RETRYS:2000,POLL_INTERVAL:20,EL:0,TYPE:1,FN:2,WFN:3,UNLOAD_OBJ:3,ADJ_SCOPE:4,OBJ:5,OVERRIDE:6,lastError:null,isSafari:YAHOO.env.ua.webkit,webkit:YAHOO.env.ua.webkit,isIE:YAHOO.env.ua.ie,_interval:null,_dri:null,DOMReady:false,startInterval:function(){if(!this._interval){var K=this;var L=function(){K._tryPreloadAttach();};this._interval=setInterval(L,this.POLL_INTERVAL);}},onAvailable:function(P,M,Q,O,N){var K=(YAHOO.lang.isString(P))?[P]:P;for(var L=0;L<K.length;L=L+1){F.push({id:K[L],fn:M,obj:Q,override:O,checkReady:N});}C=this.POLL_RETRYS;this.startInterval();},onContentReady:function(M,K,N,L){this.onAvailable(M,K,N,L,true);},onDOMReady:function(K,M,L){if(this.DOMReady){setTimeout(function(){var N=window;if(L){if(L===true){N=M;}else{N=L;}}K.call(N,"DOMReady",[],M);},0);}else{this.DOMReadyEvent.subscribe(K,M,L);}},addListener:function(M,K,V,Q,L){if(!V||!V.call){return false;}if(t!
 his._isValidCollection(M)){var W=true;for(var R=0,T=M.length;R!
 <T;++R){
W=this.on(M[R],K,V,Q,L)&&W;}return W;}else{if(YAHOO.lang.isString(M)){var P=this.getEl(M);if(P){M=P;}else{this.onAvailable(M,function(){YAHOO.util.Event.on(M,K,V,Q,L);});return true;}}}if(!M){return false;}if("unload"==K&&Q!==this){J[J.length]=[M,K,V,Q,L];return true;}var Y=M;if(L){if(L===true){Y=Q;}else{Y=L;}}var N=function(Z){return V.call(Y,YAHOO.util.Event.getEvent(Z,M),Q);};var X=[M,K,V,N,Y,Q,L];var S=I.length;I[S]=X;if(this.useLegacyEvent(M,K)){var O=this.getLegacyIndex(M,K);if(O==-1||M!=G[O][0]){O=G.length;B[M.id+K]=O;G[O]=[M,K,M["on"+K]];E[O]=[];M["on"+K]=function(Z){YAHOO.util.Event.fireLegacyEvent(YAHOO.util.Event.getEvent(Z),O);};}E[O].push(X);}else{try{this._simpleAdd(M,K,N,false);}catch(U){this.lastError=U;this.removeListener(M,K,V);return false;}}return true;},fireLegacyEvent:function(O,M){var Q=true,K,S,R,T,P;S=E[M].slice();for(var L=0,N=S.length;L<N;++L){R=S[L];if(R&&R[this.WFN]){T=R[this.ADJ_SCOPE];P=R[this.WFN].call(T,O);Q=(Q&&P);}}K=G[M];if(K&&K[2]){K[2](O!
 );}return Q;},getLegacyIndex:function(L,M){var K=this.generateId(L)+M;if(typeof B[K]=="undefined"){return -1;}else{return B[K];}},useLegacyEvent:function(L,M){if(this.webkit&&("click"==M||"dblclick"==M)){var K=parseInt(this.webkit,10);if(!isNaN(K)&&K<418){return true;}}return false;},removeListener:function(L,K,T){var O,R,V;if(typeof L=="string"){L=this.getEl(L);}else{if(this._isValidCollection(L)){var U=true;for(O=L.length-1;O>-1;O--){U=(this.removeListener(L[O],K,T)&&U);}return U;}}if(!T||!T.call){return this.purgeElement(L,false,K);}if("unload"==K){for(O=J.length-1;O>-1;O--){V=J[O];if(V&&V[0]==L&&V[1]==K&&V[2]==T){J.splice(O,1);return true;}}return false;}var P=null;var Q=arguments[3];if("undefined"===typeof Q){Q=this._getCacheIndex(L,K,T);}if(Q>=0){P=I[Q];}if(!L||!P){return false;}if(this.useLegacyEvent(L,K)){var N=this.getLegacyIndex(L,K);var M=E[N];if(M){for(O=0,R=M.length;O<R;++O){V=M[O];if(V&&V[this.EL]==L&&V[this.TYPE]==K&&V[this.FN]==T){M.splice(O,1);break;}}}}els!
 e{try{this._simpleRemove(L,K,P[this.WFN],false);}catch(S){this!
 .lastErr
or=S;return false;}}delete I[Q][this.WFN];delete I[Q][this.FN];I.splice(Q,1);return true;},getTarget:function(M,L){var K=M.target||M.srcElement;return this.resolveTextNode(K);},resolveTextNode:function(L){try{if(L&&3==L.nodeType){return L.parentNode;}}catch(K){}return L;},getPageX:function(L){var K=L.pageX;if(!K&&0!==K){K=L.clientX||0;if(this.isIE){K+=this._getScrollLeft();}}return K;},getPageY:function(K){var L=K.pageY;if(!L&&0!==L){L=K.clientY||0;if(this.isIE){L+=this._getScrollTop();}}return L;},getXY:function(K){return[this.getPageX(K),this.getPageY(K)];},getRelatedTarget:function(L){var K=L.relatedTarget;
+if(!K){if(L.type=="mouseout"){K=L.toElement;}else{if(L.type=="mouseover"){K=L.fromElement;}}}return this.resolveTextNode(K);},getTime:function(M){if(!M.time){var L=new Date().getTime();try{M.time=L;}catch(K){this.lastError=K;return L;}}return M.time;},stopEvent:function(K){this.stopPropagation(K);this.preventDefault(K);},stopPropagation:function(K){if(K.stopPropagation){K.stopPropagation();}else{K.cancelBubble=true;}},preventDefault:function(K){if(K.preventDefault){K.preventDefault();}else{K.returnValue=false;}},getEvent:function(M,K){var L=M||window.event;if(!L){var N=this.getEvent.caller;while(N){L=N.arguments[0];if(L&&Event==L.constructor){break;}N=N.caller;}}return L;},getCharCode:function(L){var K=L.keyCode||L.charCode||0;if(YAHOO.env.ua.webkit&&(K in D)){K=D[K];}return K;},_getCacheIndex:function(O,P,N){for(var M=0,L=I.length;M<L;M=M+1){var K=I[M];if(K&&K[this.FN]==N&&K[this.EL]==O&&K[this.TYPE]==P){return M;}}return -1;},generateId:function(K){var L=K.id;if(!L){L="yu!
 ievtautoid-"+A;++A;K.id=L;}return L;},_isValidCollection:function(L){try{return(L&&typeof L!=="string"&&L.length&&!L.tagName&&!L.alert&&typeof L[0]!=="undefined");}catch(K){return false;}},elCache:{},getEl:function(K){return(typeof K==="string")?document.getElementById(K):K;},clearCache:function(){},DOMReadyEvent:new YAHOO.util.CustomEvent("DOMReady",this),_load:function(L){if(!H){H=true;var K=YAHOO.util.Event;K._ready();K._tryPreloadAttach();}},_ready:function(L){var K=YAHOO.util.Event;if(!K.DOMReady){K.DOMReady=true;K.DOMReadyEvent.fire();K._simpleRemove(document,"DOMContentLoaded",K._ready);}},_tryPreloadAttach:function(){if(F.length===0){C=0;clearInterval(this._interval);this._interval=null;return ;}if(this.locked){return ;}if(this.isIE){if(!this.DOMReady){this.startInterval();return ;}}this.locked=true;var Q=!H;if(!Q){Q=(C>0&&F.length>0);}var P=[];var R=function(T,U){var S=T;if(U.override){if(U.override===true){S=U.obj;}else{S=U.override;}}U.fn.call(S,U.obj);};var L,K,!
 O,N,M=[];for(L=0,K=F.length;L<K;L=L+1){O=F[L];if(O){N=this.get!
 El(O.id)
;if(N){if(O.checkReady){if(H||N.nextSibling||!Q){M.push(O);F[L]=null;}}else{R(N,O);F[L]=null;}}else{P.push(O);}}}for(L=0,K=M.length;L<K;L=L+1){O=M[L];R(this.getEl(O.id),O);}C--;if(Q){for(L=F.length-1;L>-1;L--){O=F[L];if(!O||!O.id){F.splice(L,1);}}this.startInterval();}else{clearInterval(this._interval);this._interval=null;}this.locked=false;},purgeElement:function(O,P,R){var M=(YAHOO.lang.isString(O))?this.getEl(O):O;var Q=this.getListeners(M,R),N,K;if(Q){for(N=Q.length-1;N>-1;N--){var L=Q[N];this.removeListener(M,L.type,L.fn);}}if(P&&M&&M.childNodes){for(N=0,K=M.childNodes.length;N<K;++N){this.purgeElement(M.childNodes[N],P,R);}}},getListeners:function(M,K){var P=[],L;if(!K){L=[I,J];}else{if(K==="unload"){L=[J];}else{L=[I];}}var R=(YAHOO.lang.isString(M))?this.getEl(M):M;for(var O=0;O<L.length;O=O+1){var T=L[O];if(T){for(var Q=0,S=T.length;Q<S;++Q){var N=T[Q];if(N&&N[this.EL]===R&&(!K||K===N[this.TYPE])){P.push({type:N[this.TYPE],fn:N[this.FN],obj:N[this.OBJ],adjust:N[this.!
 OVERRIDE],scope:N[this.ADJ_SCOPE],index:Q});}}}}return(P.length)?P:null;},_unload:function(Q){var K=YAHOO.util.Event,N,M,L,P,O,R=J.slice();for(N=0,P=J.length;N<P;++N){L=R[N];if(L){var S=window;if(L[K.ADJ_SCOPE]){if(L[K.ADJ_SCOPE]===true){S=L[K.UNLOAD_OBJ];}else{S=L[K.ADJ_SCOPE];}}L[K.FN].call(S,K.getEvent(Q,L[K.EL]),L[K.UNLOAD_OBJ]);R[N]=null;L=null;S=null;}}J=null;if(I){for(M=I.length-1;M>-1;M--){L=I[M];if(L){K.removeListener(L[K.EL],L[K.TYPE],L[K.FN],M);}}L=null;}G=null;K._simpleRemove(window,"unload",K._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var K=document.documentElement,L=document.body;if(K&&(K.scrollTop||K.scrollLeft)){return[K.scrollTop,K.scrollLeft];}else{if(L){return[L.scrollTop,L.scrollLeft];}else{return[0,0];}}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(M,N,L,K){M.addEventListener(N,L,(K));};}else{if(window.attachEvent!
 ){return function(M,N,L,K){M.attachEvent("on"+N,L);};}else{ret!
 urn func
tion(){};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(M,N,L,K){M.removeEventListener(N,L,(K));};}else{if(window.detachEvent){return function(L,M,K){L.detachEvent("on"+M,K);};}else{return function(){};}}}()};}();(function(){var EU=YAHOO.util.Event;EU.on=EU.addListener;
+/* DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller */
+if(EU.isIE){YAHOO.util.Event.onDOMReady(YAHOO.util.Event._tryPreloadAttach,YAHOO.util.Event,true);var n=document.createElement("p");EU._dri=setInterval(function(){try{n.doScroll("left");clearInterval(EU._dri);EU._dri=null;EU._ready();n=null;}catch(ex){}},EU.POLL_INTERVAL);}else{if(EU.webkit&&EU.webkit<525){EU._dri=setInterval(function(){var rs=document.readyState;if("loaded"==rs||"complete"==rs){clearInterval(EU._dri);EU._dri=null;EU._ready();}},EU.POLL_INTERVAL);}else{EU._simpleAdd(document,"DOMContentLoaded",EU._ready);}}EU._simpleAdd(window,"load",EU._load);EU._simpleAdd(window,"unload",EU._unload);EU._tryPreloadAttach();})();}YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null,__yui_subscribers:null,subscribe:function(A,C,F,E){this.__yui_events=this.__yui_events||{};var D=this.__yui_events[A];if(D){D.subscribe(C,F,E);}else{this.__yui_subscribers=this.__yui_subscribers||{};var B=this.__yui_subscribers;if(!B[A]){B[A]=[];}B[A].push({!
 fn:C,obj:F,override:E});}},unsubscribe:function(C,E,G){this.__yui_events=this.__yui_events||{};var A=this.__yui_events;if(C){var F=A[C];if(F){return F.unsubscribe(E,G);}}else{var B=true;for(var D in A){if(YAHOO.lang.hasOwnProperty(A,D)){B=B&&A[D].unsubscribe(E,G);}}return B;}return false;},unsubscribeAll:function(A){return this.unsubscribe(A);},createEvent:function(G,D){this.__yui_events=this.__yui_events||{};var A=D||{};var I=this.__yui_events;if(I[G]){}else{var H=A.scope||this;var E=(A.silent);var B=new YAHOO.util.CustomEvent(G,H,E,YAHOO.util.CustomEvent.FLAT);
+I[G]=B;if(A.onSubscribeCallback){B.subscribeEvent.subscribe(A.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};var F=this.__yui_subscribers[G];if(F){for(var C=0;C<F.length;++C){B.subscribe(F[C].fn,F[C].obj,F[C].override);}}}return I[G];},fireEvent:function(E,D,A,C){this.__yui_events=this.__yui_events||{};var G=this.__yui_events[E];if(!G){return null;}var B=[];for(var F=1;F<arguments.length;++F){B.push(arguments[F]);}return G.fire.apply(G,B);},hasEvent:function(A){if(this.__yui_events){if(this.__yui_events[A]){return true;}}return false;}};YAHOO.util.KeyListener=function(A,F,B,C){if(!A){}else{if(!F){}else{if(!B){}}}if(!C){C=YAHOO.util.KeyListener.KEYDOWN;}var D=new YAHOO.util.CustomEvent("keyPressed");this.enabledEvent=new YAHOO.util.CustomEvent("enabled");this.disabledEvent=new YAHOO.util.CustomEvent("disabled");if(typeof A=="string"){A=document.getElementById(A);}if(typeof B=="function"){D.subscribe(B);}else{D.subscribe(B.fn,B.scope,B.correctScope);}!
 function E(J,I){if(!F.shift){F.shift=false;}if(!F.alt){F.alt=false;}if(!F.ctrl){F.ctrl=false;}if(J.shiftKey==F.shift&&J.altKey==F.alt&&J.ctrlKey==F.ctrl){var G;if(F.keys instanceof Array){for(var H=0;H<F.keys.length;H++){G=F.keys[H];if(G==J.charCode){D.fire(J.charCode,J);break;}else{if(G==J.keyCode){D.fire(J.keyCode,J);break;}}}}else{G=F.keys;if(G==J.charCode){D.fire(J.charCode,J);}else{if(G==J.keyCode){D.fire(J.keyCode,J);}}}}}this.enable=function(){if(!this.enabled){YAHOO.util.Event.addListener(A,C,E);this.enabledEvent.fire(F);}this.enabled=true;};this.disable=function(){if(this.enabled){YAHOO.util.Event.removeListener(A,C,E);this.disabledEvent.fire(F);}this.enabled=false;};this.toString=function(){return"KeyListener ["+F.keys+"] "+A.tagName+(A.id?"["+A.id+"]":"");};};YAHOO.util.KeyListener.KEYDOWN="keydown";YAHOO.util.KeyListener.KEYUP="keyup";YAHOO.util.KeyListener.KEY={ALT:18,BACK_SPACE:8,CAPS_LOCK:20,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:!
 37,META:224,NUM_LOCK:144,PAGE_DOWN:34,PAGE_UP:33,PAUSE:19,PRIN!
 TSCREEN:
44,RIGHT:39,SCROLL_LOCK:145,SHIFT:16,SPACE:32,TAB:9,UP:38};YAHOO.register("event",YAHOO.util.Event,{version:"2.5.1",build:"984"});YAHOO.util.Connect={_msxml_progid:["Microsoft.XMLHTTP","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP"],_http_headers:{},_has_http_headers:false,_use_default_post_header:true,_default_post_header:"application/x-www-form-urlencoded; charset=UTF-8",_default_form_header:"application/x-www-form-urlencoded",_use_default_xhr_header:true,_default_xhr_header:"XMLHttpRequest",_has_default_headers:true,_default_headers:{},_isFormSubmit:false,_isFileUpload:false,_formNode:null,_sFormData:null,_poll:{},_timeOut:{},_polling_interval:50,_transaction_id:0,_submitElementValue:null,_hasSubmitListener:(function(){if(YAHOO.util.Event){YAHOO.util.Event.addListener(document,"click",function(B){var A=YAHOO.util.Event.getTarget(B);if(A.nodeName.toLowerCase()=="input"&&(A.type&&A.type.toLowerCase()=="submit")){YAHOO.util.Connect._submitElementValue=encodeURIComponent(A.name)+"="+e!
 ncodeURIComponent(A.value);}});return true;}return false;})(),startEvent:new YAHOO.util.CustomEvent("start"),completeEvent:new YAHOO.util.CustomEvent("complete"),successEvent:new YAHOO.util.CustomEvent("success"),failureEvent:new YAHOO.util.CustomEvent("failure"),uploadEvent:new YAHOO.util.CustomEvent("upload"),abortEvent:new YAHOO.util.CustomEvent("abort"),_customEvents:{onStart:["startEvent","start"],onComplete:["completeEvent","complete"],onSuccess:["successEvent","success"],onFailure:["failureEvent","failure"],onUpload:["uploadEvent","upload"],onAbort:["abortEvent","abort"]},setProgId:function(A){this._msxml_progid.unshift(A);},setDefaultPostHeader:function(A){if(typeof A=="string"){this._default_post_header=A;}else{if(typeof A=="boolean"){this._use_default_post_header=A;}}},setDefaultXhrHeader:function(A){if(typeof A=="string"){this._default_xhr_header=A;}else{this._use_default_xhr_header=A;}},setPollingInterval:function(A){if(typeof A=="number"&&isFinite(A)){this._pol!
 ling_interval=A;}},createXhrObject:function(E){var D,A;try{A=n!
 ew XMLHt
tpRequest();D={conn:A,tId:E};}catch(C){for(var B=0;B<this._msxml_progid.length;++B){try{A=new ActiveXObject(this._msxml_progid[B]);D={conn:A,tId:E};break;}catch(C){}}}finally{return D;}},getConnectionObject:function(A){var C;var D=this._transaction_id;try{if(!A){C=this.createXhrObject(D);}else{C={};C.tId=D;C.isUpload=true;}if(C){this._transaction_id++;}}catch(B){}finally{return C;}},asyncRequest:function(F,C,E,A){var D=(this._isFileUpload)?this.getConnectionObject(true):this.getConnectionObject();var B=(E&&E.argument)?E.argument:null;if(!D){return null;}else{if(E&&E.customevents){this.initCustomEvents(D,E);}if(this._isFormSubmit){if(this._isFileUpload){this.uploadFile(D,E,C,A);return D;}if(F.toUpperCase()=="GET"){if(this._sFormData.length!==0){C+=((C.indexOf("?")==-1)?"?":"&")+this._sFormData;}}else{if(F.toUpperCase()=="POST"){A=A?this._sFormData+"&"+A:this._sFormData;}}}if(F.toUpperCase()=="GET"&&(E&&E.cache===false)){C+=((C.indexOf("?")==-1)?"?":"&")+"rnd="+new Date().valu!
 eOf().toString();}D.conn.open(F,C,true);if(this._use_default_xhr_header){if(!this._default_headers["X-Requested-With"]){this.initHeader("X-Requested-With",this._default_xhr_header,true);}}if((F.toUpperCase()=="POST"&&this._use_default_post_header)&&this._isFormSubmit===false){this.initHeader("Content-Type",this._default_post_header);}if(this._has_default_headers||this._has_http_headers){this.setHeader(D);}this.handleReadyState(D,E);D.conn.send(A||"");if(this._isFormSubmit===true){this.resetFormState();}this.startEvent.fire(D,B);if(D.startEvent){D.startEvent.fire(D,B);}return D;}},initCustomEvents:function(A,C){for(var B in C.customevents){if(this._customEvents[B][0]){A[this._customEvents[B][0]]=new YAHOO.util.CustomEvent(this._customEvents[B][1],(C.scope)?C.scope:null);A[this._customEvents[B][0]].subscribe(C.customevents[B]);}}},handleReadyState:function(C,D){var B=this;var A=(D&&D.argument)?D.argument:null;if(D&&D.timeout){this._timeOut[C.tId]=window.setTimeout(function(){!
 B.abort(C,D,true);},D.timeout);}this._poll[C.tId]=window.setIn!
 terval(f
unction(){if(C.conn&&C.conn.readyState===4){window.clearInterval(B._poll[C.tId]);delete B._poll[C.tId];if(D&&D.timeout){window.clearTimeout(B._timeOut[C.tId]);delete B._timeOut[C.tId];}B.completeEvent.fire(C,A);if(C.completeEvent){C.completeEvent.fire(C,A);}B.handleTransactionResponse(C,D);}},this._polling_interval);},handleTransactionResponse:function(F,G,A){var D,C;var B=(G&&G.argument)?G.argument:null;try{if(F.conn.status!==undefined&&F.conn.status!==0){D=F.conn.status;}else{D=13030;}}catch(E){D=13030;}if(D>=200&&D<300||D===1223){C=this.createResponseObject(F,B);if(G&&G.success){if(!G.scope){G.success(C);}else{G.success.apply(G.scope,[C]);}}this.successEvent.fire(C);if(F.successEvent){F.successEvent.fire(C);}}else{switch(D){case 12002:case 12029:case 12030:case 12031:case 12152:case 13030:C=this.createExceptionObject(F.tId,B,(A?A:false));if(G&&G.failure){if(!G.scope){G.failure(C);}else{G.failure.apply(G.scope,[C]);}}break;default:C=this.createResponseObject(F,B);if(G&&G.f!
 ailure){if(!G.scope){G.failure(C);}else{G.failure.apply(G.scope,[C]);}}}this.failureEvent.fire(C);if(F.failureEvent){F.failureEvent.fire(C);}}this.releaseObject(F);C=null;},createResponseObject:function(A,G){var D={};var I={};try{var C=A.conn.getAllResponseHeaders();var F=C.split("\n");for(var E=0;E<F.length;E++){var B=F[E].indexOf(":");if(B!=-1){I[F[E].substring(0,B)]=F[E].substring(B+2);}}}catch(H){}D.tId=A.tId;D.status=(A.conn.status==1223)?204:A.conn.status;D.statusText=(A.conn.status==1223)?"No Content":A.conn.statusText;D.getResponseHeader=I;D.getAllResponseHeaders=C;D.responseText=A.conn.responseText;D.responseXML=A.conn.responseXML;if(G){D.argument=G;}return D;},createExceptionObject:function(H,D,A){var F=0;var G="communication failure";var C=-1;var B="transaction aborted";var E={};E.tId=H;if(A){E.status=C;E.statusText=B;}else{E.status=F;E.statusText=G;}if(D){E.argument=D;}return E;},initHeader:function(A,D,C){var B=(C)?this._default_headers:this._http_headers;B[A]=!
 D;if(C){this._has_default_headers=true;}else{this._has_http_he!
 aders=tr
ue;
+}},setHeader:function(A){if(this._has_default_headers){for(var B in this._default_headers){if(YAHOO.lang.hasOwnProperty(this._default_headers,B)){A.conn.setRequestHeader(B,this._default_headers[B]);}}}if(this._has_http_headers){for(var B in this._http_headers){if(YAHOO.lang.hasOwnProperty(this._http_headers,B)){A.conn.setRequestHeader(B,this._http_headers[B]);}}delete this._http_headers;this._http_headers={};this._has_http_headers=false;}},resetDefaultHeaders:function(){delete this._default_headers;this._default_headers={};this._has_default_headers=false;},setForm:function(K,E,B){this.resetFormState();var J;if(typeof K=="string"){J=(document.getElementById(K)||document.forms[K]);}else{if(typeof K=="object"){J=K;}else{return ;}}if(E){var F=this.createFrame((window.location.href.toLowerCase().indexOf("https")===0||B)?true:false);this._isFormSubmit=true;this._isFileUpload=true;this._formNode=J;return ;}var A,I,G,L;var H=false;for(var D=0;D<J.elements.length;D++){A=J.elements[D!
 ];L=A.disabled;I=A.name;G=A.value;if(!L&&I){switch(A.type){case"select-one":case"select-multiple":for(var C=0;C<A.options.length;C++){if(A.options[C].selected){if(window.ActiveXObject){this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(A.options[C].attributes["value"].specified?A.options[C].value:A.options[C].text)+"&";}else{this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(A.options[C].hasAttribute("value")?A.options[C].value:A.options[C].text)+"&";}}}break;case"radio":case"checkbox":if(A.checked){this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(G)+"&";}break;case"file":case undefined:case"reset":case"button":break;case"submit":if(H===false){if(this._hasSubmitListener&&this._submitElementValue){this._sFormData+=this._submitElementValue+"&";}else{this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(G)+"&";}H=true;}break;default:this._sFormData+=encodeURIComponent(I)+"="+encodeURIComponent(G)+"&";}}}this._isFormSubmit=true;this._s!
 FormData=this._sFormData.substr(0,this._sFormData.length-1);th!
 is.initH
eader("Content-Type",this._default_form_header);return this._sFormData;},resetFormState:function(){this._isFormSubmit=false;this._isFileUpload=false;this._formNode=null;this._sFormData="";},createFrame:function(A){var B="yuiIO"+this._transaction_id;var C;if(window.ActiveXObject){C=document.createElement("<iframe id=\""+B+"\" name=\""+B+"\" />");if(typeof A=="boolean"){C.src="javascript:false";}}else{C=document.createElement("iframe");C.id=B;C.name=B;}C.style.position="absolute";C.style.top="-1000px";C.style.left="-1000px";document.body.appendChild(C);},appendPostData:function(A){var D=[];var B=A.split("&");for(var C=0;C<B.length;C++){var E=B[C].indexOf("=");if(E!=-1){D[C]=document.createElement("input");D[C].type="hidden";D[C].name=B[C].substring(0,E);D[C].value=B[C].substring(E+1);this._formNode.appendChild(D[C]);}}return D;},uploadFile:function(D,M,E,C){var N=this;var H="yuiIO"+D.tId;var I="multipart/form-data";var K=document.getElementById(H);var J=(M&&M.argument)?M.argum!
 ent:null;var B={action:this._formNode.getAttribute("action"),method:this._formNode.getAttribute("method"),target:this._formNode.getAttribute("target")};this._formNode.setAttribute("action",E);this._formNode.setAttribute("method","POST");this._formNode.setAttribute("target",H);if(this._formNode.encoding){this._formNode.setAttribute("encoding",I);}else{this._formNode.setAttribute("enctype",I);}if(C){var L=this.appendPostData(C);}this._formNode.submit();this.startEvent.fire(D,J);if(D.startEvent){D.startEvent.fire(D,J);}if(M&&M.timeout){this._timeOut[D.tId]=window.setTimeout(function(){N.abort(D,M,true);},M.timeout);}if(L&&L.length>0){for(var G=0;G<L.length;G++){this._formNode.removeChild(L[G]);}}for(var A in B){if(YAHOO.lang.hasOwnProperty(B,A)){if(B[A]){this._formNode.setAttribute(A,B[A]);}else{this._formNode.removeAttribute(A);}}}this.resetFormState();var F=function(){if(M&&M.timeout){window.clearTimeout(N._timeOut[D.tId]);delete N._timeOut[D.tId];}N.completeEvent.fire(D,J);!
 if(D.completeEvent){D.completeEvent.fire(D,J);}var P={};P.tId=!
 D.tId;P.
argument=M.argument;try{P.responseText=K.contentWindow.document.body?K.contentWindow.document.body.innerHTML:K.contentWindow.document.documentElement.textContent;P.responseXML=K.contentWindow.document.XMLDocument?K.contentWindow.document.XMLDocument:K.contentWindow.document;}catch(O){}if(M&&M.upload){if(!M.scope){M.upload(P);}else{M.upload.apply(M.scope,[P]);}}N.uploadEvent.fire(P);if(D.uploadEvent){D.uploadEvent.fire(P);}YAHOO.util.Event.removeListener(K,"load",F);setTimeout(function(){document.body.removeChild(K);N.releaseObject(D);},100);};YAHOO.util.Event.addListener(K,"load",F);},abort:function(E,G,A){var D;var B=(G&&G.argument)?G.argument:null;if(E&&E.conn){if(this.isCallInProgress(E)){E.conn.abort();window.clearInterval(this._poll[E.tId]);delete this._poll[E.tId];if(A){window.clearTimeout(this._timeOut[E.tId]);delete this._timeOut[E.tId];}D=true;}}else{if(E&&E.isUpload===true){var C="yuiIO"+E.tId;var F=document.getElementById(C);if(F){YAHOO.util.Event.removeListener(F!
 ,"load");document.body.removeChild(F);if(A){window.clearTimeout(this._timeOut[E.tId]);delete this._timeOut[E.tId];}D=true;}}else{D=false;}}if(D===true){this.abortEvent.fire(E,B);if(E.abortEvent){E.abortEvent.fire(E,B);}this.handleTransactionResponse(E,G,true);}return D;},isCallInProgress:function(B){if(B&&B.conn){return B.conn.readyState!==4&&B.conn.readyState!==0;}else{if(B&&B.isUpload===true){var A="yuiIO"+B.tId;return document.getElementById(A)?true:false;}else{return false;}}},releaseObject:function(A){if(A&&A.conn){A.conn=null;A=null;}}};YAHOO.register("connection",YAHOO.util.Connect,{version:"2.5.1",build:"984"});(function(){var B=YAHOO.util;var A=function(D,C,E,F){if(!D){}this.init(D,C,E,F);};A.NAME="Anim";A.prototype={toString:function(){var C=this.getEl()||{};var D=C.id||C.tagName;return(this.constructor.NAME+": "+D);},patterns:{noNegatives:/width|height|opacity|padding/i,offsetAttribute:/^((width|height)|(top|left))$/,defaultUnit:/width|height|top$|bottom$|left$|r!
 ight$/i,offsetUnit:/\d+(em|%|en|ex|pt|in|cm|mm|pc)$/i},doMetho!
 d:functi
on(C,E,D){return this.method(this.currentFrame,E,D-E,this.totalFrames);},setAttribute:function(C,E,D){if(this.patterns.noNegatives.test(C)){E=(E>0)?E:0;}B.Dom.setStyle(this.getEl(),C,E+D);},getAttribute:function(C){var E=this.getEl();var G=B.Dom.getStyle(E,C);if(G!=="auto"&&!this.patterns.offsetUnit.test(G)){return parseFloat(G);}var D=this.patterns.offsetAttribute.exec(C)||[];var H=!!(D[3]);var F=!!(D[2]);if(F||(B.Dom.getStyle(E,"position")=="absolute"&&H)){G=E["offset"+D[0].charAt(0).toUpperCase()+D[0].substr(1)];}else{G=0;}return G;},getDefaultUnit:function(C){if(this.patterns.defaultUnit.test(C)){return"px";}return"";},setRuntimeAttribute:function(D){var I;var E;var F=this.attributes;this.runtimeAttributes[D]={};var H=function(J){return(typeof J!=="undefined");};if(!H(F[D]["to"])&&!H(F[D]["by"])){return false;}I=(H(F[D]["from"]))?F[D]["from"]:this.getAttribute(D);if(H(F[D]["to"])){E=F[D]["to"];}else{if(H(F[D]["by"])){if(I.constructor==Array){E=[];for(var G=0,C=I.length;G!
 <C;++G){E[G]=I[G]+F[D]["by"][G]*1;}}else{E=I+F[D]["by"]*1;}}}this.runtimeAttributes[D].start=I;this.runtimeAttributes[D].end=E;this.runtimeAttributes[D].unit=(H(F[D].unit))?F[D]["unit"]:this.getDefaultUnit(D);return true;},init:function(E,J,I,C){var D=false;var F=null;var H=0;E=B.Dom.get(E);this.attributes=J||{};this.duration=!YAHOO.lang.isUndefined(I)?I:1;this.method=C||B.Easing.easeNone;this.useSeconds=true;this.currentFrame=0;this.totalFrames=B.AnimMgr.fps;this.setEl=function(M){E=B.Dom.get(M);};this.getEl=function(){return E;};this.isAnimated=function(){return D;};this.getStartTime=function(){return F;};this.runtimeAttributes={};this.animate=function(){if(this.isAnimated()){return false;}this.currentFrame=0;this.totalFrames=(this.useSeconds)?Math.ceil(B.AnimMgr.fps*this.duration):this.duration;if(this.duration===0&&this.useSeconds){this.totalFrames=1;}B.AnimMgr.registerElement(this);return true;};this.stop=function(M){if(!this.isAnimated()){return false;}if(M){this.curr!
 entFrame=this.totalFrames;this._onTween.fire();}B.AnimMgr.stop!
 (this);}
;var L=function(){this.onStart.fire();this.runtimeAttributes={};for(var M in this.attributes){this.setRuntimeAttribute(M);}D=true;H=0;F=new Date();};var K=function(){var O={duration:new Date()-this.getStartTime(),currentFrame:this.currentFrame};O.toString=function(){return("duration: "+O.duration+", currentFrame: "+O.currentFrame);};this.onTween.fire(O);var N=this.runtimeAttributes;for(var M in N){this.setAttribute(M,this.doMethod(M,N[M].start,N[M].end),N[M].unit);}H+=1;};var G=function(){var M=(new Date()-F)/1000;var N={duration:M,frames:H,fps:H/M};N.toString=function(){return("duration: "+N.duration+", frames: "+N.frames+", fps: "+N.fps);};D=false;H=0;this.onComplete.fire(N);};this._onStart=new B.CustomEvent("_start",this,true);this.onStart=new B.CustomEvent("start",this);this.onTween=new B.CustomEvent("tween",this);this._onTween=new B.CustomEvent("_tween",this,true);this.onComplete=new B.CustomEvent("complete",this);this._onComplete=new B.CustomEvent("_complete",this,true!
 );this._onStart.subscribe(L);this._onTween.subscribe(K);this._onComplete.subscribe(G);}};B.Anim=A;})();YAHOO.util.AnimMgr=new function(){var C=null;var B=[];var A=0;this.fps=1000;this.delay=1;this.registerElement=function(F){B[B.length]=F;A+=1;F._onStart.fire();this.start();};this.unRegister=function(G,F){F=F||E(G);if(!G.isAnimated()||F==-1){return false;}G._onComplete.fire();B.splice(F,1);A-=1;if(A<=0){this.stop();}return true;};this.start=function(){if(C===null){C=setInterval(this.run,this.delay);}};this.stop=function(H){if(!H){clearInterval(C);for(var G=0,F=B.length;G<F;++G){this.unRegister(B[0],0);}B=[];C=null;A=0;}else{this.unRegister(H);}};this.run=function(){for(var H=0,F=B.length;H<F;++H){var G=B[H];if(!G||!G.isAnimated()){continue;}if(G.currentFrame<G.totalFrames||G.totalFrames===null){G.currentFrame+=1;if(G.useSeconds){D(G);}G._onTween.fire();}else{YAHOO.util.AnimMgr.stop(G,H);}}};var E=function(H){for(var G=0,F=B.length;G<F;++G){if(B[G]==H){return G;}}return -1;}!
 ;var D=function(G){var J=G.totalFrames;var I=G.currentFrame;va!
 r H=(G.c
urrentFrame*G.duration*1000/G.totalFrames);var F=(new Date()-G.getStartTime());var K=0;if(F<G.duration*1000){K=Math.round((F/H-1)*G.currentFrame);}else{K=J-(I+1);}if(K>0&&isFinite(K)){if(G.currentFrame+K>=J){K=J-(I+1);}G.currentFrame+=K;}};};YAHOO.util.Bezier=new function(){this.getPosition=function(E,D){var F=E.length;var C=[];for(var B=0;B<F;++B){C[B]=[E[B][0],E[B][1]];}for(var A=1;A<F;++A){for(B=0;B<F-A;++B){C[B][0]=(1-D)*C[B][0]+D*C[parseInt(B+1,10)][0];C[B][1]=(1-D)*C[B][1]+D*C[parseInt(B+1,10)][1];}}return[C[0][0],C[0][1]];};};(function(){var A=function(F,E,G,H){A.superclass.constructor.call(this,F,E,G,H);};A.NAME="ColorAnim";var C=YAHOO.util;YAHOO.extend(A,C.Anim);var D=A.superclass;var B=A.prototype;B.patterns.color=/color$/i;B.patterns.rgb=/^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i;B.patterns.hex=/^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i;B.patterns.hex3=/^#?([0-9A-F]{1})([0-9A-F]{1})([0-9A-F]{1})$/i;B.patterns.transparent=/^transparent|rgba\(0, 0, 0, 0\!
 )$/;B.parseColor=function(E){if(E.length==3){return E;}var F=this.patterns.hex.exec(E);if(F&&F.length==4){return[parseInt(F[1],16),parseInt(F[2],16),parseInt(F[3],16)];}F=this.patterns.rgb.exec(E);if(F&&F.length==4){return[parseInt(F[1],10),parseInt(F[2],10),parseInt(F[3],10)];}F=this.patterns.hex3.exec(E);if(F&&F.length==4){return[parseInt(F[1]+F[1],16),parseInt(F[2]+F[2],16),parseInt(F[3]+F[3],16)];}return null;};B.getAttribute=function(E){var G=this.getEl();if(this.patterns.color.test(E)){var H=YAHOO.util.Dom.getStyle(G,E);
+if(this.patterns.transparent.test(H)){var F=G.parentNode;H=C.Dom.getStyle(F,E);while(F&&this.patterns.transparent.test(H)){F=F.parentNode;H=C.Dom.getStyle(F,E);if(F.tagName.toUpperCase()=="HTML"){H="#fff";}}}}else{H=D.getAttribute.call(this,E);}return H;};B.doMethod=function(F,J,G){var I;if(this.patterns.color.test(F)){I=[];for(var H=0,E=J.length;H<E;++H){I[H]=D.doMethod.call(this,F,J[H],G[H]);}I="rgb("+Math.floor(I[0])+","+Math.floor(I[1])+","+Math.floor(I[2])+")";}else{I=D.doMethod.call(this,F,J,G);}return I;};B.setRuntimeAttribute=function(F){D.setRuntimeAttribute.call(this,F);if(this.patterns.color.test(F)){var H=this.attributes;var J=this.parseColor(this.runtimeAttributes[F].start);var G=this.parseColor(this.runtimeAttributes[F].end);if(typeof H[F]["to"]==="undefined"&&typeof H[F]["by"]!=="undefined"){G=this.parseColor(H[F].by);for(var I=0,E=J.length;I<E;++I){G[I]=J[I]+G[I];}}this.runtimeAttributes[F].start=J;this.runtimeAttributes[F].end=G;}};C.ColorAnim=A;})();
+/*
+TERMS OF USE - EASING EQUATIONS
+Open source under the BSD License.
+Copyright 2001 Robert Penner All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+YAHOO.util.Easing={easeNone:function(B,A,D,C){return D*B/C+A;},easeIn:function(B,A,D,C){return D*(B/=C)*B+A;},easeOut:function(B,A,D,C){return -D*(B/=C)*(B-2)+A;},easeBoth:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B+A;}return -D/2*((--B)*(B-2)-1)+A;},easeInStrong:function(B,A,D,C){return D*(B/=C)*B*B*B+A;},easeOutStrong:function(B,A,D,C){return -D*((B=B/C-1)*B*B*B-1)+A;},easeBothStrong:function(B,A,D,C){if((B/=C/2)<1){return D/2*B*B*B*B+A;}return -D/2*((B-=2)*B*B*B-2)+A;},elasticIn:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return -(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;},elasticOut:function(C,A,G,F,B,E){if(C==0){return A;}if((C/=F)==1){return A+G;}if(!E){E=F*0.3;}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}return B*Math.pow(2,-10*C)*Math.sin((C*F-D)*(2*Math.PI)/E)+G+A;},elasticBoth:function(C,A,G,F,!
 B,E){if(C==0){return A;}if((C/=F/2)==2){return A+G;}if(!E){E=F*(0.3*1.5);}if(!B||B<Math.abs(G)){B=G;var D=E/4;}else{var D=E/(2*Math.PI)*Math.asin(G/B);}if(C<1){return -0.5*(B*Math.pow(2,10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E))+A;}return B*Math.pow(2,-10*(C-=1))*Math.sin((C*F-D)*(2*Math.PI)/E)*0.5+G+A;},backIn:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*(B/=D)*B*((C+1)*B-C)+A;},backOut:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}return E*((B=B/D-1)*B*((C+1)*B+C)+1)+A;},backBoth:function(B,A,E,D,C){if(typeof C=="undefined"){C=1.70158;}if((B/=D/2)<1){return E/2*(B*B*(((C*=(1.525))+1)*B-C))+A;}return E/2*((B-=2)*B*(((C*=(1.525))+1)*B+C)+2)+A;},bounceIn:function(B,A,D,C){return D-YAHOO.util.Easing.bounceOut(C-B,0,D,C)+A;},bounceOut:function(B,A,D,C){if((B/=C)<(1/2.75)){return D*(7.5625*B*B)+A;}else{if(B<(2/2.75)){return D*(7.5625*(B-=(1.5/2.75))*B+0.75)+A;}else{if(B<(2.5/2.75)){return D*(7.5625*(B-=(2.25/2.75))*B+0.9375)+A;}}}return D*(7.562!
 5*(B-=(2.625/2.75))*B+0.984375)+A;},bounceBoth:function(B,A,D,!
 C){if(B<
C/2){return YAHOO.util.Easing.bounceIn(B*2,0,D,C)*0.5+A;}return YAHOO.util.Easing.bounceOut(B*2-C,0,D,C)*0.5+D*0.5+A;}};(function(){var A=function(H,G,I,J){if(H){A.superclass.constructor.call(this,H,G,I,J);}};A.NAME="Motion";var E=YAHOO.util;YAHOO.extend(A,E.ColorAnim);var F=A.superclass;var C=A.prototype;C.patterns.points=/^points$/i;C.setAttribute=function(G,I,H){if(this.patterns.points.test(G)){H=H||"px";F.setAttribute.call(this,"left",I[0],H);F.setAttribute.call(this,"top",I[1],H);}else{F.setAttribute.call(this,G,I,H);}};C.getAttribute=function(G){if(this.patterns.points.test(G)){var H=[F.getAttribute.call(this,"left"),F.getAttribute.call(this,"top")];}else{H=F.getAttribute.call(this,G);}return H;};C.doMethod=function(G,K,H){var J=null;if(this.patterns.points.test(G)){var I=this.method(this.currentFrame,0,100,this.totalFrames)/100;J=E.Bezier.getPosition(this.runtimeAttributes[G],I);}else{J=F.doMethod.call(this,G,K,H);}return J;};C.setRuntimeAttribute=function(P){if(this.!
 patterns.points.test(P)){var H=this.getEl();var J=this.attributes;var G;var L=J["points"]["control"]||[];var I;var M,O;if(L.length>0&&!(L[0] instanceof Array)){L=[L];}else{var K=[];for(M=0,O=L.length;M<O;++M){K[M]=L[M];}L=K;}if(E.Dom.getStyle(H,"position")=="static"){E.Dom.setStyle(H,"position","relative");}if(D(J["points"]["from"])){E.Dom.setXY(H,J["points"]["from"]);}else{E.Dom.setXY(H,E.Dom.getXY(H));}G=this.getAttribute("points");if(D(J["points"]["to"])){I=B.call(this,J["points"]["to"],G);
+var N=E.Dom.getXY(this.getEl());for(M=0,O=L.length;M<O;++M){L[M]=B.call(this,L[M],G);}}else{if(D(J["points"]["by"])){I=[G[0]+J["points"]["by"][0],G[1]+J["points"]["by"][1]];for(M=0,O=L.length;M<O;++M){L[M]=[G[0]+L[M][0],G[1]+L[M][1]];}}}this.runtimeAttributes[P]=[G];if(L.length>0){this.runtimeAttributes[P]=this.runtimeAttributes[P].concat(L);}this.runtimeAttributes[P][this.runtimeAttributes[P].length]=I;}else{F.setRuntimeAttribute.call(this,P);}};var B=function(G,I){var H=E.Dom.getXY(this.getEl());G=[G[0]-H[0]+I[0],G[1]-H[1]+I[1]];return G;};var D=function(G){return(typeof G!=="undefined");};E.Motion=A;})();(function(){var D=function(F,E,G,H){if(F){D.superclass.constructor.call(this,F,E,G,H);}};D.NAME="Scroll";var B=YAHOO.util;YAHOO.extend(D,B.ColorAnim);var C=D.superclass;var A=D.prototype;A.doMethod=function(E,H,F){var G=null;if(E=="scroll"){G=[this.method(this.currentFrame,H[0],F[0]-H[0],this.totalFrames),this.method(this.currentFrame,H[1],F[1]-H[1],this.totalFrames)];}e!
 lse{G=C.doMethod.call(this,E,H,F);}return G;};A.getAttribute=function(E){var G=null;var F=this.getEl();if(E=="scroll"){G=[F.scrollLeft,F.scrollTop];}else{G=C.getAttribute.call(this,E);}return G;};A.setAttribute=function(E,H,G){var F=this.getEl();if(E=="scroll"){F.scrollLeft=H[0];F.scrollTop=H[1];}else{C.setAttribute.call(this,E,H,G);}};B.Scroll=D;})();YAHOO.register("animation",YAHOO.util.Anim,{version:"2.5.1",build:"984"});if(!YAHOO.util.DragDropMgr){YAHOO.util.DragDropMgr=function(){var A=YAHOO.util.Event;return{ids:{},handleIds:{},dragCurrent:null,dragOvers:{},deltaX:0,deltaY:0,preventDefault:true,stopPropagation:true,initialized:false,locked:false,interactionInfo:null,init:function(){this.initialized=true;},POINT:0,INTERSECT:1,STRICT_INTERSECT:2,mode:0,_execOnAll:function(D,C){for(var E in this.ids){for(var B in this.ids[E]){var F=this.ids[E][B];if(!this.isTypeOfDD(F)){continue;}F[D].apply(F,C);}}},_onLoad:function(){this.init();A.on(document,"mouseup",this.handleMouseU!
 p,this,true);A.on(document,"mousemove",this.handleMouseMove,th!
 is,true)
;A.on(window,"unload",this._onUnload,this,true);A.on(window,"resize",this._onResize,this,true);},_onResize:function(B){this._execOnAll("resetConstraints",[]);},lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isLocked:function(){return this.locked;},locationCache:{},useCache:true,clickPixelThresh:3,clickTimeThresh:1000,dragThreshMet:false,clickTimeout:null,startX:0,startY:0,fromTimeout:false,regDragDrop:function(C,B){if(!this.initialized){this.init();}if(!this.ids[B]){this.ids[B]={};}this.ids[B][C.id]=C;},removeDDFromGroup:function(D,B){if(!this.ids[B]){this.ids[B]={};}var C=this.ids[B];if(C&&C[D.id]){delete C[D.id];}},_remove:function(C){for(var B in C.groups){if(B&&this.ids[B][C.id]){delete this.ids[B][C.id];}}delete this.handleIds[C.id];},regHandle:function(C,B){if(!this.handleIds[C]){this.handleIds[C]={};}this.handleIds[C][B]=B;},isDragDrop:function(B){return(this.getDDById(B))?true:false;},getRelated:function(G,C){var F=[];for(var E in G.groups){!
 for(var D in this.ids[E]){var B=this.ids[E][D];if(!this.isTypeOfDD(B)){continue;}if(!C||B.isTarget){F[F.length]=B;}}}return F;},isLegalTarget:function(F,E){var C=this.getRelated(F,true);for(var D=0,B=C.length;D<B;++D){if(C[D].id==E.id){return true;}}return false;},isTypeOfDD:function(B){return(B&&B.__ygDragDrop);},isHandle:function(C,B){return(this.handleIds[C]&&this.handleIds[C][B]);},getDDById:function(C){for(var B in this.ids){if(this.ids[B][C]){return this.ids[B][C];}}return null;},handleMouseDown:function(D,C){this.currentTarget=YAHOO.util.Event.getTarget(D);this.dragCurrent=C;var B=C.getEl();this.startX=YAHOO.util.Event.getPageX(D);this.startY=YAHOO.util.Event.getPageY(D);this.deltaX=this.startX-B.offsetLeft;this.deltaY=this.startY-B.offsetTop;this.dragThreshMet=false;this.clickTimeout=setTimeout(function(){var E=YAHOO.util.DDM;E.startDrag(E.startX,E.startY);E.fromTimeout=true;},this.clickTimeThresh);},startDrag:function(B,D){clearTimeout(this.clickTimeout);var C=this!
 .dragCurrent;if(C&&C.events.b4StartDrag){C.b4StartDrag(B,D);C.!
 fireEven
t("b4StartDragEvent",{x:B,y:D});}if(C&&C.events.startDrag){C.startDrag(B,D);C.fireEvent("startDragEvent",{x:B,y:D});}this.dragThreshMet=true;},handleMouseUp:function(B){if(this.dragCurrent){clearTimeout(this.clickTimeout);if(this.dragThreshMet){if(this.fromTimeout){this.handleMouseMove(B);}this.fromTimeout=false;this.fireEvents(B,true);}else{}this.stopDrag(B);this.stopEvent(B);}},stopEvent:function(B){if(this.stopPropagation){YAHOO.util.Event.stopPropagation(B);}if(this.preventDefault){YAHOO.util.Event.preventDefault(B);}},stopDrag:function(D,C){var B=this.dragCurrent;if(B&&!C){if(this.dragThreshMet){if(B.events.b4EndDrag){B.b4EndDrag(D);B.fireEvent("b4EndDragEvent",{e:D});}if(B.events.endDrag){B.endDrag(D);B.fireEvent("endDragEvent",{e:D});}}if(B.events.mouseUp){B.onMouseUp(D);B.fireEvent("mouseUpEvent",{e:D});}}this.dragCurrent=null;this.dragOvers={};},handleMouseMove:function(E){var B=this.dragCurrent;if(B){if(YAHOO.util.Event.isIE&&!E.button){this.stopEvent(E);return thi!
 s.handleMouseUp(E);}else{if(E.clientX<0||E.clientY<0){}}if(!this.dragThreshMet){var D=Math.abs(this.startX-YAHOO.util.Event.getPageX(E));var C=Math.abs(this.startY-YAHOO.util.Event.getPageY(E));if(D>this.clickPixelThresh||C>this.clickPixelThresh){this.startDrag(this.startX,this.startY);}}if(this.dragThreshMet){if(B&&B.events.b4Drag){B.b4Drag(E);B.fireEvent("b4DragEvent",{e:E});}if(B&&B.events.drag){B.onDrag(E);B.fireEvent("dragEvent",{e:E});}if(B){this.fireEvents(E,false);}}this.stopEvent(E);}},fireEvents:function(U,K){var Z=this.dragCurrent;if(!Z||Z.isLocked()||Z.dragOnly){return ;}var M=YAHOO.util.Event.getPageX(U),L=YAHOO.util.Event.getPageY(U),O=new YAHOO.util.Point(M,L),J=Z.getTargetCoord(O.x,O.y),E=Z.getDragEl(),D=["out","over","drop","enter"],T=new YAHOO.util.Region(J.y,J.x+E.offsetWidth,J.y+E.offsetHeight,J.x),H=[],C={},P=[],a={outEvts:[],overEvts:[],dropEvts:[],enterEvts:[]};for(var R in this.dragOvers){var c=this.dragOvers[R];if(!this.isTypeOfDD(c)){continue;}if(!!
 this.isOverTarget(O,c,this.mode,T)){a.outEvts.push(c);}H[R]=tr!
 ue;delet
e this.dragOvers[R];}for(var Q in Z.groups){if("string"!=typeof Q){continue;}for(R in this.ids[Q]){var F=this.ids[Q][R];if(!this.isTypeOfDD(F)){continue;}if(F.isTarget&&!F.isLocked()&&F!=Z){if(this.isOverTarget(O,F,this.mode,T)){C[Q]=true;if(K){a.dropEvts.push(F);}else{if(!H[F.id]){a.enterEvts.push(F);}else{a.overEvts.push(F);}this.dragOvers[F.id]=F;}}}}}this.interactionInfo={out:a.outEvts,enter:a.enterEvts,over:a.overEvts,drop:a.dropEvts,point:O,draggedRegion:T,sourceRegion:this.locationCache[Z.id],validDrop:K};for(var B in C){P.push(B);}if(K&&!a.dropEvts.length){this.interactionInfo.validDrop=false;if(Z.events.invalidDrop){Z.onInvalidDrop(U);Z.fireEvent("invalidDropEvent",{e:U});}}for(R=0;R<D.length;R++){var X=null;if(a[D[R]+"Evts"]){X=a[D[R]+"Evts"];}if(X&&X.length){var G=D[R].charAt(0).toUpperCase()+D[R].substr(1),W="onDrag"+G,I="b4Drag"+G,N="drag"+G+"Event",V="drag"+G;if(this.mode){if(Z.events[I]){Z[I](U,X,P);Z.fireEvent(I+"Event",{event:U,info:X,group:P});}if(Z.events[!
 V]){Z[W](U,X,P);Z.fireEvent(N,{event:U,info:X,group:P});}}else{for(var Y=0,S=X.length;Y<S;++Y){if(Z.events[I]){Z[I](U,X[Y].id,P[0]);Z.fireEvent(I+"Event",{event:U,info:X[Y].id,group:P[0]});}if(Z.events[V]){Z[W](U,X[Y].id,P[0]);Z.fireEvent(N,{event:U,info:X[Y].id,group:P[0]});}}}}}},getBestMatch:function(D){var F=null;
+var C=D.length;if(C==1){F=D[0];}else{for(var E=0;E<C;++E){var B=D[E];if(this.mode==this.INTERSECT&&B.cursorIsOver){F=B;break;}else{if(!F||!F.overlap||(B.overlap&&F.overlap.getArea()<B.overlap.getArea())){F=B;}}}}return F;},refreshCache:function(C){var E=C||this.ids;for(var B in E){if("string"!=typeof B){continue;}for(var D in this.ids[B]){var F=this.ids[B][D];if(this.isTypeOfDD(F)){var G=this.getLocation(F);if(G){this.locationCache[F.id]=G;}else{delete this.locationCache[F.id];}}}}},verifyEl:function(C){try{if(C){var B=C.offsetParent;if(B){return true;}}}catch(D){}return false;},getLocation:function(G){if(!this.isTypeOfDD(G)){return null;}var E=G.getEl(),J,D,C,L,K,M,B,I,F;try{J=YAHOO.util.Dom.getXY(E);}catch(H){}if(!J){return null;}D=J[0];C=D+E.offsetWidth;L=J[1];K=L+E.offsetHeight;M=L-G.padding[0];B=C+G.padding[1];I=K+G.padding[2];F=D-G.padding[3];return new YAHOO.util.Region(M,B,I,F);},isOverTarget:function(J,B,D,E){var F=this.locationCache[B.id];if(!F||!this.useCache){F=!
 this.getLocation(B);this.locationCache[B.id]=F;}if(!F){return false;}B.cursorIsOver=F.contains(J);var I=this.dragCurrent;if(!I||(!D&&!I.constrainX&&!I.constrainY)){return B.cursorIsOver;}B.overlap=null;if(!E){var G=I.getTargetCoord(J.x,J.y);var C=I.getDragEl();E=new YAHOO.util.Region(G.y,G.x+C.offsetWidth,G.y+C.offsetHeight,G.x);}var H=E.intersect(F);if(H){B.overlap=H;return(D)?true:B.cursorIsOver;}else{return false;}},_onUnload:function(C,B){this.unregAll();},unregAll:function(){if(this.dragCurrent){this.stopDrag();this.dragCurrent=null;}this._execOnAll("unreg",[]);this.ids={};},elementCache:{},getElWrapper:function(C){var B=this.elementCache[C];if(!B||!B.el){B=this.elementCache[C]=new this.ElementWrapper(YAHOO.util.Dom.get(C));}return B;},getElement:function(B){return YAHOO.util.Dom.get(B);},getCss:function(C){var B=YAHOO.util.Dom.get(C);return(B)?B.style:null;},ElementWrapper:function(B){this.el=B||null;this.id=this.el&&B.id;this.css=this.el&&B.style;},getPosX:function(B!
 ){return YAHOO.util.Dom.getX(B);},getPosY:function(B){return Y!
 AHOO.uti
l.Dom.getY(B);},swapNode:function(D,B){if(D.swapNode){D.swapNode(B);}else{var E=B.parentNode;var C=B.nextSibling;if(C==D){E.insertBefore(D,B);}else{if(B==D.nextSibling){E.insertBefore(B,D);}else{D.parentNode.replaceChild(B,D);E.insertBefore(D,C);}}}},getScroll:function(){var D,B,E=document.documentElement,C=document.body;if(E&&(E.scrollTop||E.scrollLeft)){D=E.scrollTop;B=E.scrollLeft;}else{if(C){D=C.scrollTop;B=C.scrollLeft;}else{}}return{top:D,left:B};},getStyle:function(C,B){return YAHOO.util.Dom.getStyle(C,B);},getScrollTop:function(){return this.getScroll().top;},getScrollLeft:function(){return this.getScroll().left;},moveToEl:function(B,D){var C=YAHOO.util.Dom.getXY(D);YAHOO.util.Dom.setXY(B,C);},getClientHeight:function(){return YAHOO.util.Dom.getViewportHeight();},getClientWidth:function(){return YAHOO.util.Dom.getViewportWidth();},numericSort:function(C,B){return(C-B);},_timeoutCount:0,_addListeners:function(){var B=YAHOO.util.DDM;if(YAHOO.util.Event&&document){B._on!
 Load();}else{if(B._timeoutCount>2000){}else{setTimeout(B._addListeners,10);if(document&&document.body){B._timeoutCount+=1;}}}},handleWasClicked:function(B,D){if(this.isHandle(D,B.id)){return true;}else{var C=B.parentNode;while(C){if(this.isHandle(D,C.id)){return true;}else{C=C.parentNode;}}}return false;}};}();YAHOO.util.DDM=YAHOO.util.DragDropMgr;YAHOO.util.DDM._addListeners();}(function(){var A=YAHOO.util.Event;var B=YAHOO.util.Dom;YAHOO.util.DragDrop=function(E,C,D){if(E){this.init(E,C,D);}};YAHOO.util.DragDrop.prototype={events:null,on:function(){this.subscribe.apply(this,arguments);},id:null,config:null,dragElId:null,handleElId:null,invalidHandleTypes:null,invalidHandleIds:null,invalidHandleClasses:null,startPageX:0,startPageY:0,groups:null,locked:false,lock:function(){this.locked=true;},unlock:function(){this.locked=false;},isTarget:true,padding:null,dragOnly:false,_domRef:null,__ygDragDrop:true,constrainX:false,constrainY:false,minX:0,maxX:0,minY:0,maxY:0,deltaX:0,de!
 ltaY:0,maintainOffset:false,xTicks:null,yTicks:null,primaryBut!
 tonOnly:
true,available:false,hasOuterHandles:false,cursorIsOver:false,overlap:null,b4StartDrag:function(C,D){},startDrag:function(C,D){},b4Drag:function(C){},onDrag:function(C){},onDragEnter:function(C,D){},b4DragOver:function(C){},onDragOver:function(C,D){},b4DragOut:function(C){},onDragOut:function(C,D){},b4DragDrop:function(C){},onDragDrop:function(C,D){},onInvalidDrop:function(C){},b4EndDrag:function(C){},endDrag:function(C){},b4MouseDown:function(C){},onMouseDown:function(C){},onMouseUp:function(C){},onAvailable:function(){},getEl:function(){if(!this._domRef){this._domRef=B.get(this.id);}return this._domRef;},getDragEl:function(){return B.get(this.dragElId);},init:function(F,C,D){this.initTarget(F,C,D);A.on(this._domRef||this.id,"mousedown",this.handleMouseDown,this,true);for(var E in this.events){this.createEvent(E+"Event");}},initTarget:function(E,C,D){this.config=D||{};this.events={};this.DDM=YAHOO.util.DDM;this.groups={};if(typeof E!=="string"){this._domRef=E;E=B.generateId!
 (E);}this.id=E;this.addToGroup((C)?C:"default");this.handleElId=E;A.onAvailable(E,this.handleOnAvailable,this,true);this.setDragElId(E);this.invalidHandleTypes={A:"A"};this.invalidHandleIds={};this.invalidHandleClasses=[];this.applyConfig();},applyConfig:function(){this.events={mouseDown:true,b4MouseDown:true,mouseUp:true,b4StartDrag:true,startDrag:true,b4EndDrag:true,endDrag:true,drag:true,b4Drag:true,invalidDrop:true,b4DragOut:true,dragOut:true,dragEnter:true,b4DragOver:true,dragOver:true,b4DragDrop:true,dragDrop:true};if(this.config.events){for(var C in this.config.events){if(this.config.events[C]===false){this.events[C]=false;}}}this.padding=this.config.padding||[0,0,0,0];this.isTarget=(this.config.isTarget!==false);this.maintainOffset=(this.config.maintainOffset);this.primaryButtonOnly=(this.config.primaryButtonOnly!==false);this.dragOnly=((this.config.dragOnly===true)?true:false);},handleOnAvailable:function(){this.available=true;
+this.resetConstraints();this.onAvailable();},setPadding:function(E,C,F,D){if(!C&&0!==C){this.padding=[E,E,E,E];}else{if(!F&&0!==F){this.padding=[E,C,E,C];}else{this.padding=[E,C,F,D];}}},setInitPosition:function(F,E){var G=this.getEl();if(!this.DDM.verifyEl(G)){if(G&&G.style&&(G.style.display=="none")){}else{}return ;}var D=F||0;var C=E||0;var H=B.getXY(G);this.initPageX=H[0]-D;this.initPageY=H[1]-C;this.lastPageX=H[0];this.lastPageY=H[1];this.setStartPosition(H);},setStartPosition:function(D){var C=D||B.getXY(this.getEl());this.deltaSetXY=null;this.startPageX=C[0];this.startPageY=C[1];},addToGroup:function(C){this.groups[C]=true;this.DDM.regDragDrop(this,C);},removeFromGroup:function(C){if(this.groups[C]){delete this.groups[C];}this.DDM.removeDDFromGroup(this,C);},setDragElId:function(C){this.dragElId=C;},setHandleElId:function(C){if(typeof C!=="string"){C=B.generateId(C);}this.handleElId=C;this.DDM.regHandle(this.id,C);},setOuterHandleElId:function(C){if(typeof C!=="strin!
 g"){C=B.generateId(C);}A.on(C,"mousedown",this.handleMouseDown,this,true);this.setHandleElId(C);this.hasOuterHandles=true;},unreg:function(){A.removeListener(this.id,"mousedown",this.handleMouseDown);this._domRef=null;this.DDM._remove(this);},isLocked:function(){return(this.DDM.isLocked()||this.locked);},handleMouseDown:function(H,G){var D=H.which||H.button;if(this.primaryButtonOnly&&D>1){return ;}if(this.isLocked()){return ;}var C=this.b4MouseDown(H);if(this.events.b4MouseDown){C=this.fireEvent("b4MouseDownEvent",H);}var E=this.onMouseDown(H);if(this.events.mouseDown){E=this.fireEvent("mouseDownEvent",H);}if((C===false)||(E===false)){return ;}this.DDM.refreshCache(this.groups);var F=new YAHOO.util.Point(A.getPageX(H),A.getPageY(H));if(!this.hasOuterHandles&&!this.DDM.isOverTarget(F,this)){}else{if(this.clickValidator(H)){this.setStartPosition();this.DDM.handleMouseDown(H,this);this.DDM.stopEvent(H);}else{}}},clickValidator:function(D){var C=YAHOO.util.Event.getTarget(D);re!
 turn(this.isValidHandleChild(C)&&(this.id==this.handleElId||th!
 is.DDM.h
andleWasClicked(C,this.id)));},getTargetCoord:function(E,D){var C=E-this.deltaX;var F=D-this.deltaY;if(this.constrainX){if(C<this.minX){C=this.minX;}if(C>this.maxX){C=this.maxX;}}if(this.constrainY){if(F<this.minY){F=this.minY;}if(F>this.maxY){F=this.maxY;}}C=this.getTick(C,this.xTicks);F=this.getTick(F,this.yTicks);return{x:C,y:F};},addInvalidHandleType:function(C){var D=C.toUpperCase();this.invalidHandleTypes[D]=D;},addInvalidHandleId:function(C){if(typeof C!=="string"){C=B.generateId(C);}this.invalidHandleIds[C]=C;},addInvalidHandleClass:function(C){this.invalidHandleClasses.push(C);},removeInvalidHandleType:function(C){var D=C.toUpperCase();delete this.invalidHandleTypes[D];},removeInvalidHandleId:function(C){if(typeof C!=="string"){C=B.generateId(C);}delete this.invalidHandleIds[C];},removeInvalidHandleClass:function(D){for(var E=0,C=this.invalidHandleClasses.length;E<C;++E){if(this.invalidHandleClasses[E]==D){delete this.invalidHandleClasses[E];}}},isValidHandleChild:f!
 unction(F){var E=true;var H;try{H=F.nodeName.toUpperCase();}catch(G){H=F.nodeName;}E=E&&!this.invalidHandleTypes[H];E=E&&!this.invalidHandleIds[F.id];for(var D=0,C=this.invalidHandleClasses.length;E&&D<C;++D){E=!B.hasClass(F,this.invalidHandleClasses[D]);}return E;},setXTicks:function(F,C){this.xTicks=[];this.xTickSize=C;var E={};for(var D=this.initPageX;D>=this.minX;D=D-C){if(!E[D]){this.xTicks[this.xTicks.length]=D;E[D]=true;}}for(D=this.initPageX;D<=this.maxX;D=D+C){if(!E[D]){this.xTicks[this.xTicks.length]=D;E[D]=true;}}this.xTicks.sort(this.DDM.numericSort);},setYTicks:function(F,C){this.yTicks=[];this.yTickSize=C;var E={};for(var D=this.initPageY;D>=this.minY;D=D-C){if(!E[D]){this.yTicks[this.yTicks.length]=D;E[D]=true;}}for(D=this.initPageY;D<=this.maxY;D=D+C){if(!E[D]){this.yTicks[this.yTicks.length]=D;E[D]=true;}}this.yTicks.sort(this.DDM.numericSort);},setXConstraint:function(E,D,C){this.leftConstraint=parseInt(E,10);this.rightConstraint=parseInt(D,10);this.minX=t!
 his.initPageX-this.leftConstraint;this.maxX=this.initPageX+thi!
 s.rightC
onstraint;if(C){this.setXTicks(this.initPageX,C);}this.constrainX=true;},clearConstraints:function(){this.constrainX=false;this.constrainY=false;this.clearTicks();},clearTicks:function(){this.xTicks=null;this.yTicks=null;this.xTickSize=0;this.yTickSize=0;},setYConstraint:function(C,E,D){this.topConstraint=parseInt(C,10);this.bottomConstraint=parseInt(E,10);this.minY=this.initPageY-this.topConstraint;this.maxY=this.initPageY+this.bottomConstraint;if(D){this.setYTicks(this.initPageY,D);}this.constrainY=true;},resetConstraints:function(){if(this.initPageX||this.initPageX===0){var D=(this.maintainOffset)?this.lastPageX-this.initPageX:0;var C=(this.maintainOffset)?this.lastPageY-this.initPageY:0;this.setInitPosition(D,C);}else{this.setInitPosition();}if(this.constrainX){this.setXConstraint(this.leftConstraint,this.rightConstraint,this.xTickSize);}if(this.constrainY){this.setYConstraint(this.topConstraint,this.bottomConstraint,this.yTickSize);}},getTick:function(I,F){if(!F){return!
  I;}else{if(F[0]>=I){return F[0];}else{for(var D=0,C=F.length;D<C;++D){var E=D+1;if(F[E]&&F[E]>=I){var H=I-F[D];var G=F[E]-I;return(G>H)?F[D]:F[E];}}return F[F.length-1];}}},toString:function(){return("DragDrop "+this.id);}};YAHOO.augment(YAHOO.util.DragDrop,YAHOO.util.EventProvider);})();YAHOO.util.DD=function(C,A,B){if(C){this.init(C,A,B);}};YAHOO.extend(YAHOO.util.DD,YAHOO.util.DragDrop,{scroll:true,autoOffset:function(C,B){var A=C-this.startPageX;var D=B-this.startPageY;this.setDelta(A,D);},setDelta:function(B,A){this.deltaX=B;this.deltaY=A;},setDragElPos:function(C,B){var A=this.getDragEl();this.alignElWithMouse(A,C,B);},alignElWithMouse:function(C,G,F){var E=this.getTargetCoord(G,F);if(!this.deltaSetXY){var H=[E.x,E.y];YAHOO.util.Dom.setXY(C,H);var D=parseInt(YAHOO.util.Dom.getStyle(C,"left"),10);var B=parseInt(YAHOO.util.Dom.getStyle(C,"top"),10);this.deltaSetXY=[D-E.x,B-E.y];}else{YAHOO.util.Dom.setStyle(C,"left",(E.x+this.deltaSetXY[0])+"px");
+YAHOO.util.Dom.setStyle(C,"top",(E.y+this.deltaSetXY[1])+"px");}this.cachePosition(E.x,E.y);var A=this;setTimeout(function(){A.autoScroll.call(A,E.x,E.y,C.offsetHeight,C.offsetWidth);},0);},cachePosition:function(B,A){if(B){this.lastPageX=B;this.lastPageY=A;}else{var C=YAHOO.util.Dom.getXY(this.getEl());this.lastPageX=C[0];this.lastPageY=C[1];}},autoScroll:function(J,I,E,K){if(this.scroll){var L=this.DDM.getClientHeight();var B=this.DDM.getClientWidth();var N=this.DDM.getScrollTop();var D=this.DDM.getScrollLeft();var H=E+I;var M=K+J;var G=(L+N-I-this.deltaY);var F=(B+D-J-this.deltaX);var C=40;var A=(document.all)?80:30;if(H>L&&G<C){window.scrollTo(D,N+A);}if(I<N&&N>0&&I-N<C){window.scrollTo(D,N-A);}if(M>B&&F<C){window.scrollTo(D+A,N);}if(J<D&&D>0&&J-D<C){window.scrollTo(D-A,N);}}},applyConfig:function(){YAHOO.util.DD.superclass.applyConfig.call(this);this.scroll=(this.config.scroll!==false);},b4MouseDown:function(A){this.setStartPosition();this.autoOffset(YAHOO.util.Event.g!
 etPageX(A),YAHOO.util.Event.getPageY(A));},b4Drag:function(A){this.setDragElPos(YAHOO.util.Event.getPageX(A),YAHOO.util.Event.getPageY(A));},toString:function(){return("DD "+this.id);}});YAHOO.util.DDProxy=function(C,A,B){if(C){this.init(C,A,B);this.initFrame();}};YAHOO.util.DDProxy.dragElId="ygddfdiv";YAHOO.extend(YAHOO.util.DDProxy,YAHOO.util.DD,{resizeFrame:true,centerFrame:false,createFrame:function(){var B=this,A=document.body;if(!A||!A.firstChild){setTimeout(function(){B.createFrame();},50);return ;}var G=this.getDragEl(),E=YAHOO.util.Dom;if(!G){G=document.createElement("div");G.id=this.dragElId;var D=G.style;D.position="absolute";D.visibility="hidden";D.cursor="move";D.border="2px solid #aaa";D.zIndex=999;D.height="25px";D.width="25px";var C=document.createElement("div");E.setStyle(C,"height","100%");E.setStyle(C,"width","100%");E.setStyle(C,"background-color","#ccc");E.setStyle(C,"opacity","0");G.appendChild(C);if(YAHOO.env.ua.ie){var F=document.createElement("ifram!
 e");F.setAttribute("src","about:blank");F.setAttribute("scroll!
 ing","no
");F.setAttribute("frameborder","0");G.insertBefore(F,G.firstChild);E.setStyle(F,"height","100%");E.setStyle(F,"width","100%");E.setStyle(F,"position","absolute");E.setStyle(F,"top","0");E.setStyle(F,"left","0");E.setStyle(F,"opacity","0");E.setStyle(F,"zIndex","-1");E.setStyle(F.nextSibling,"zIndex","2");}A.insertBefore(G,A.firstChild);}},initFrame:function(){this.createFrame();},applyConfig:function(){YAHOO.util.DDProxy.superclass.applyConfig.call(this);this.resizeFrame=(this.config.resizeFrame!==false);this.centerFrame=(this.config.centerFrame);this.setDragElId(this.config.dragElId||YAHOO.util.DDProxy.dragElId);},showFrame:function(E,D){var C=this.getEl();var A=this.getDragEl();var B=A.style;this._resizeProxy();if(this.centerFrame){this.setDelta(Math.round(parseInt(B.width,10)/2),Math.round(parseInt(B.height,10)/2));}this.setDragElPos(E,D);YAHOO.util.Dom.setStyle(A,"visibility","visible");},_resizeProxy:function(){if(this.resizeFrame){var H=YAHOO.util.Dom;var B=this.getEl!
 ();var C=this.getDragEl();var G=parseInt(H.getStyle(C,"borderTopWidth"),10);var I=parseInt(H.getStyle(C,"borderRightWidth"),10);var F=parseInt(H.getStyle(C,"borderBottomWidth"),10);var D=parseInt(H.getStyle(C,"borderLeftWidth"),10);if(isNaN(G)){G=0;}if(isNaN(I)){I=0;}if(isNaN(F)){F=0;}if(isNaN(D)){D=0;}var E=Math.max(0,B.offsetWidth-I-D);var A=Math.max(0,B.offsetHeight-G-F);H.setStyle(C,"width",E+"px");H.setStyle(C,"height",A+"px");}},b4MouseDown:function(B){this.setStartPosition();var A=YAHOO.util.Event.getPageX(B);var C=YAHOO.util.Event.getPageY(B);this.autoOffset(A,C);},b4StartDrag:function(A,B){this.showFrame(A,B);},b4EndDrag:function(A){YAHOO.util.Dom.setStyle(this.getDragEl(),"visibility","hidden");},endDrag:function(D){var C=YAHOO.util.Dom;var B=this.getEl();var A=this.getDragEl();C.setStyle(A,"visibility","");C.setStyle(B,"visibility","hidden");YAHOO.util.DDM.moveToEl(B,A);C.setStyle(A,"visibility","hidden");C.setStyle(B,"visibility","");},toString:function(){return!
 ("DDProxy "+this.id);}});YAHOO.util.DDTarget=function(C,A,B){i!
 f(C){thi
s.initTarget(C,A,B);}};YAHOO.extend(YAHOO.util.DDTarget,YAHOO.util.DragDrop,{toString:function(){return("DDTarget "+this.id);}});YAHOO.register("dragdrop",YAHOO.util.DragDropMgr,{version:"2.5.1",build:"984"});YAHOO.util.Attribute=function(B,A){if(A){this.owner=A;this.configure(B,true);}};YAHOO.util.Attribute.prototype={name:undefined,value:null,owner:null,readOnly:false,writeOnce:false,_initialConfig:null,_written:false,method:null,validator:null,getValue:function(){return this.value;},setValue:function(F,B){var E;var A=this.owner;var C=this.name;var D={type:C,prevValue:this.getValue(),newValue:F};if(this.readOnly||(this.writeOnce&&this._written)){return false;}if(this.validator&&!this.validator.call(A,F)){return false;}if(!B){E=A.fireBeforeChangeEvent(D);if(E===false){return false;}}if(this.method){this.method.call(A,F);}this.value=F;this._written=true;D.type=C;if(!B){this.owner.fireChangeEvent(D);}return true;},configure:function(B,C){B=B||{};this._written=false;this._init!
 ialConfig=this._initialConfig||{};for(var A in B){if(A&&YAHOO.lang.hasOwnProperty(B,A)){this[A]=B[A];if(C){this._initialConfig[A]=B[A];}}}},resetValue:function(){return this.setValue(this._initialConfig.value);},resetConfig:function(){this.configure(this._initialConfig);},refresh:function(A){this.setValue(this.value,A);}};(function(){var A=YAHOO.util.Lang;YAHOO.util.AttributeProvider=function(){};YAHOO.util.AttributeProvider.prototype={_configs:null,get:function(C){this._configs=this._configs||{};var B=this._configs[C];if(!B){return undefined;}return B.value;},set:function(D,E,B){this._configs=this._configs||{};var C=this._configs[D];if(!C){return false;}return C.setValue(E,B);},getAttributeKeys:function(){this._configs=this._configs;var D=[];var B;for(var C in this._configs){B=this._configs[C];if(A.hasOwnProperty(this._configs,C)&&!A.isUndefined(B)){D[D.length]=C;}}return D;},setAttributes:function(D,B){for(var C in D){if(A.hasOwnProperty(D,C)){this.set(C,D[C],B);}}},reset!
 Value:function(C,B){this._configs=this._configs||{};if(this._c!
 onfigs[C
]){this.set(C,this._configs[C]._initialConfig.value,B);return true;}return false;},refresh:function(E,C){this._configs=this._configs;E=((A.isString(E))?[E]:E)||this.getAttributeKeys();for(var D=0,B=E.length;D<B;++D){if(this._configs[E[D]]&&!A.isUndefined(this._configs[E[D]].value)&&!A.isNull(this._configs[E[D]].value)){this._configs[E[D]].refresh(C);}}},register:function(B,C){this.setAttributeConfig(B,C);},getAttributeConfig:function(C){this._configs=this._configs||{};var B=this._configs[C]||{};var D={};for(C in B){if(A.hasOwnProperty(B,C)){D[C]=B[C];}}return D;},setAttributeConfig:function(B,C,D){this._configs=this._configs||{};C=C||{};if(!this._configs[B]){C.name=B;this._configs[B]=this.createAttribute(C);}else{this._configs[B].configure(C,D);}},configureAttribute:function(B,C,D){this.setAttributeConfig(B,C,D);},resetAttributeConfig:function(B){this._configs=this._configs||{};this._configs[B].resetConfig();},subscribe:function(B,C){this._events=this._events||{};if(!(B in t!
 his._events)){this._events[B]=this.createEvent(B);}YAHOO.util.EventProvider.prototype.subscribe.apply(this,arguments);},on:function(){this.subscribe.apply(this,arguments);},addListener:function(){this.subscribe.apply(this,arguments);},fireBeforeChangeEvent:function(C){var B="before";B+=C.type.charAt(0).toUpperCase()+C.type.substr(1)+"Change";C.type=B;return this.fireEvent(C.type,C);},fireChangeEvent:function(B){B.type+="Change";return this.fireEvent(B.type,B);},createAttribute:function(B){return new YAHOO.util.Attribute(B,this);}};YAHOO.augment(YAHOO.util.AttributeProvider,YAHOO.util.EventProvider);})();(function(){var D=YAHOO.util.Dom,F=YAHOO.util.AttributeProvider;YAHOO.util.Element=function(G,H){if(arguments.length){this.init(G,H);}};YAHOO.util.Element.prototype={DOM_EVENTS:null,appendChild:function(G){G=G.get?G.get("element"):G;this.get("element").appendChild(G);},getElementsByTagName:function(G){return this.get("element").getElementsByTagName(G);},hasChildNodes:functio!
 n(){return this.get("element").hasChildNodes();},insertBefore:!
 function
(G,H){G=G.get?G.get("element"):G;H=(H&&H.get)?H.get("element"):H;this.get("element").insertBefore(G,H);},removeChild:function(G){G=G.get?G.get("element"):G;this.get("element").removeChild(G);return true;},replaceChild:function(G,H){G=G.get?G.get("element"):G;H=H.get?H.get("element"):H;return this.get("element").replaceChild(G,H);},initAttributes:function(G){},addListener:function(K,J,L,I){var H=this.get("element");I=I||this;H=this.get("id")||H;var G=this;if(!this._events[K]){if(this.DOM_EVENTS[K]){YAHOO.util.Event.addListener(H,K,function(M){if(M.srcElement&&!M.target){M.target=M.srcElement;}G.fireEvent(K,M);},L,I);}this.createEvent(K,this);}YAHOO.util.EventProvider.prototype.subscribe.apply(this,arguments);},on:function(){this.addListener.apply(this,arguments);},subscribe:function(){this.addListener.apply(this,arguments);},removeListener:function(H,G){this.unsubscribe.apply(this,arguments);},addClass:function(G){D.addClass(this.get("element"),G);},getElementsByClassName:fun!
 ction(H,G){return D.getElementsByClassName(H,G,this.get("element"));},hasClass:function(G){return D.hasClass(this.get("element"),G);},removeClass:function(G){return D.removeClass(this.get("element"),G);},replaceClass:function(H,G){return D.replaceClass(this.get("element"),H,G);},setStyle:function(I,H){var G=this.get("element");if(!G){return this._queue[this._queue.length]=["setStyle",arguments];}return D.setStyle(G,I,H);},getStyle:function(G){return D.getStyle(this.get("element"),G);},fireQueue:function(){var H=this._queue;for(var I=0,G=H.length;I<G;++I){this[H[I][0]].apply(this,H[I][1]);}},appendTo:function(H,I){H=(H.get)?H.get("element"):D.get(H);this.fireEvent("beforeAppendTo",{type:"beforeAppendTo",target:H});I=(I&&I.get)?I.get("element"):D.get(I);var G=this.get("element");if(!G){return false;}if(!H){return false;}if(G.parent!=H){if(I){H.insertBefore(G,I);}else{H.appendChild(G);}}this.fireEvent("appendTo",{type:"appendTo",target:H});},get:function(G){var I=this._configs!
 ||{};var H=I.element;if(H&&!I[G]&&!YAHOO.lang.isUndefined(H.va!
 lue[G]))
{return H.value[G];}return F.prototype.get.call(this,G);},setAttributes:function(L,H){var K=this.get("element");
+for(var J in L){if(!this._configs[J]&&!YAHOO.lang.isUndefined(K[J])){this.setAttributeConfig(J);}}for(var I=0,G=this._configOrder.length;I<G;++I){if(L[this._configOrder[I]]!==undefined){this.set(this._configOrder[I],L[this._configOrder[I]],H);}}},set:function(H,J,G){var I=this.get("element");if(!I){this._queue[this._queue.length]=["set",arguments];if(this._configs[H]){this._configs[H].value=J;}return ;}if(!this._configs[H]&&!YAHOO.lang.isUndefined(I[H])){C.call(this,H);}return F.prototype.set.apply(this,arguments);},setAttributeConfig:function(G,I,J){var H=this.get("element");if(H&&!this._configs[G]&&!YAHOO.lang.isUndefined(H[G])){C.call(this,G,I);}else{F.prototype.setAttributeConfig.apply(this,arguments);}this._configOrder.push(G);},getAttributeKeys:function(){var H=this.get("element");var I=F.prototype.getAttributeKeys.call(this);for(var G in H){if(!this._configs[G]){I[G]=I[G]||H[G];}}return I;},createEvent:function(H,G){this._events[H]=true;F.prototype.createEvent.apply(!
 this,arguments);},init:function(H,G){A.apply(this,arguments);}};var A=function(H,G){this._queue=this._queue||[];this._events=this._events||{};this._configs=this._configs||{};this._configOrder=[];G=G||{};G.element=G.element||H||null;this.DOM_EVENTS={"click":true,"dblclick":true,"keydown":true,"keypress":true,"keyup":true,"mousedown":true,"mousemove":true,"mouseout":true,"mouseover":true,"mouseup":true,"focus":true,"blur":true,"submit":true};var I=false;if(YAHOO.lang.isString(H)){C.call(this,"id",{value:G.element});}if(D.get(H)){I=true;E.call(this,G);B.call(this,G);}YAHOO.util.Event.onAvailable(G.element,function(){if(!I){E.call(this,G);}this.fireEvent("available",{type:"available",target:G.element});},this,true);YAHOO.util.Event.onContentReady(G.element,function(){if(!I){B.call(this,G);}this.fireEvent("contentReady",{type:"contentReady",target:G.element});},this,true);};var E=function(G){this.setAttributeConfig("element",{value:D.get(G.element),readOnly:true});};var B=functi!
 on(G){this.initAttributes(G);this.setAttributes(G,true);this.f!
 ireQueue
();};var C=function(G,I){var H=this.get("element");I=I||{};I.name=G;I.method=I.method||function(J){H[G]=J;};I.value=I.value||H[G];this._configs[G]=new YAHOO.util.Attribute(I,this);};YAHOO.augment(YAHOO.util.Element,F);})();YAHOO.register("element",YAHOO.util.Element,{version:"2.5.1",build:"984"});YAHOO.register("utilities", YAHOO, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/yahoo/README
===================================================================
--- trunk/root/static/yui/yahoo/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yahoo/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,13 +1,16 @@
 YAHOO Global - Release Notes
 
-2.4.1
+2.5.1
+  * Added Adobe AIR detection.
 
-No change
+2.5.0
+  * API doc updates
 
 2.4.0
   * Added YAHOO.env.ua.mobile
   * Removed the hasOwnProperty check in isArray to make it perform a bit better.
   * YAHOO will be created/overwritten if YAHOO is undefined or the defined YAHOO is falsy
+  * YAHOO.lang is now preserved when YAHOO is included a second time.
 
 2.3.1
   * YAHOO.lang.dump casts primitives to strings

Modified: trunk/root/static/yui/yahoo/yahoo-debug.js
===================================================================
--- trunk/root/static/yui/yahoo/yahoo-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yahoo/yahoo-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The YAHOO object is the single global object used by YUI Library.  It
@@ -272,16 +272,25 @@
          * Safari 2.0.4:         418     <-- preventDefault fixed
          * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
          *                                   different versions of webkit
-         * Safari 2.0.4 (419.3): 419     <-- Current Safari release
-         * Webkit 212 nightly:   522+    <-- Safari 3.0 (with native SVG) should
-         *                                   be higher than this
+         * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
+         *                                   updated, but not updated
+         *                                   to the latest patch.
+         * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native SVG
+         *                                   and many major issues fixed).  
+         * 3.x yahoo.com, flickr:422     <-- Safari 3.x hacks the user agent
+         *                                   string when hitting yahoo.com and 
+         *                                   flickr.com.
+         * Safari 3.0.4 (523.12):523.12  <-- First Tiger release - automatic update
+         *                                   from 2.x via the 10.4.11 OS patch
+         * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
+         *                                   yahoo.com user agent hack removed.
          *                                   
          * </pre>
          * http://developer.apple.com/internet/safari/uamatrix.html
          * @property webkit
          * @type float
          */
-        webkit:0,
+        webkit: 0,
 
         /**
          * The mobile property will be set to a string containing any relevant
@@ -291,7 +300,16 @@
          * @property mobile 
          * @type string
          */
-        mobile: null 
+        mobile: null,
+
+        /**
+         * Adobe AIR version number or 0.  Only populated if webkit is detected.
+         * Example: 1.0
+         * @property air
+         * @type float
+         */
+        air: 0
+
     };
 
     var ua=navigator.userAgent, m;
@@ -315,6 +333,11 @@
             }
         }
 
+        m=ua.match(/AdobeAIR\/([^\s]*)/);
+        if (m) {
+            o.air = m[0]; // Adobe AIR 1.0 or better
+        }
+
     }
 
     if (!o.webkit) { // not webkit
@@ -388,10 +411,9 @@
      * properties.
      * @method isArray
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isArray: function(o) { 
-
         if (o) {
            var l = YAHOO.lang;
            return l.isNumber(o.length) && l.isFunction(o.splice);
@@ -403,7 +425,7 @@
      * Determines whether or not the provided object is a boolean
      * @method isBoolean
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isBoolean: function(o) {
         return typeof o === 'boolean';
@@ -413,7 +435,7 @@
      * Determines whether or not the provided object is a function
      * @method isFunction
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isFunction: function(o) {
         return typeof o === 'function';
@@ -423,7 +445,7 @@
      * Determines whether or not the provided object is null
      * @method isNull
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isNull: function(o) {
         return o === null;
@@ -433,7 +455,7 @@
      * Determines whether or not the provided object is a legal number
      * @method isNumber
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isNumber: function(o) {
         return typeof o === 'number' && isFinite(o);
@@ -444,7 +466,7 @@
      * or function
      * @method isObject
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */  
     isObject: function(o) {
 return (o && (typeof o === 'object' || YAHOO.lang.isFunction(o))) || false;
@@ -454,7 +476,7 @@
      * Determines whether or not the provided object is a string
      * @method isString
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isString: function(o) {
         return typeof o === 'string';
@@ -464,7 +486,7 @@
      * Determines whether or not the provided object is undefined
      * @method isUndefined
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isUndefined: function(o) {
         return typeof o === 'undefined';
@@ -488,7 +510,7 @@
      * </pre>
      * @method hasOwnProperty
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     hasOwnProperty: function(o, prop) {
         if (Object.prototype.hasOwnProperty) {
@@ -827,14 +849,14 @@
     },
 
     /**
-     * Executes the supplied function in the scope of the supplied 
+     * Executes the supplied function in the context of the supplied 
      * object 'when' milliseconds later.  Executes the function a 
      * single time unless periodic is set to true.
      * @method later
      * @since 2.4.0
      * @param when {int} the number of milliseconds to wait until the fn 
      * is executed
-     * @param o the scope object
+     * @param o the context object
      * @param fn {Function|String} the function to execute or the name of 
      * the method in the 'o' object to execute
      * @param data [Array] data that is provided to the function.  This accepts
@@ -881,7 +903,7 @@
             }
         };
     },
-
+    
     /**
      * A convenience method for detecting a legitimate non-null value.
      * Returns false for null/undefined/NaN, true for other values, 
@@ -949,4 +971,4 @@
  */
 YAHOO.extend = YAHOO.lang.extend;
 
-YAHOO.register("yahoo", YAHOO, {version: "2.4.1", build: "742"});
+YAHOO.register("yahoo", YAHOO, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/yahoo/yahoo-min.js
===================================================================
--- trunk/root/static/yui/yahoo/yahoo-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yahoo/yahoo-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var A=arguments,E=null,C,B,D;for(C=0;C<A.length;C=C+1){D=A[C].split(".");E=YAHOO;for(B=(D[0]=="YAHOO")?1:0;B<D.length;B=B+1){E[D[B]]=E[D[B]]||{};E=E[D[B]];}}return E;};YAHOO.log=function(D,A,C){var B=YAHOO.widget.Logger;if(B&&B.log){return B.log(D,A,C);}else{return false;}};YAHOO.register=function(A,E,D){var I=YAHOO.env.modules;if(!I[A]){I[A]={versions:[],builds:[]};}var B=I[A],H=D.version,G=D.build,F=YAHOO.env.listeners;B.name=A;B.version=H;B.build=G;B.versions.push(H);B.builds.push(G);B.mainClass=E;for(var C=0;C<F.length;C=C+1){F[C](B);}if(E){E.VERSION=H;E.BUILD=G;}else{YAHOO.log("mainClass is undefined for module "+A,"warn");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[]};YAHOO.env.getVersion=function(A){return YAHOO.env.modules[A]||null;};YAHOO.env.ua=function(){var C={ie:0,opera:0,gecko:0,webkit:0,mobile:null};var B=navigator.userAgent,A;if((/KHTML/).test(B)){C.webkit=1;}A=B.match(/AppleWe!
 bKit\/([^\s]*)/);if(A&&A[1]){C.webkit=parseFloat(A[1]);if(/ Mobile\//.test(B)){C.mobile="Apple";}else{A=B.match(/NokiaN[^\/]*/);if(A){C.mobile=A[0];}}}if(!C.webkit){A=B.match(/Opera[\s\/]([^\s]*)/);if(A&&A[1]){C.opera=parseFloat(A[1]);A=B.match(/Opera Mini[^;]*/);if(A){C.mobile=A[0];}}else{A=B.match(/MSIE\s([^;]*)/);if(A&&A[1]){C.ie=parseFloat(A[1]);}else{A=B.match(/Gecko\/([^\s]*)/);if(A){C.gecko=1;A=B.match(/rv:([^\s\)]*)/);if(A&&A[1]){C.gecko=parseFloat(A[1]);}}}}}return C;}();(function(){YAHOO.namespace("util","widget","example");if("undefined"!==typeof YAHOO_config){var B=YAHOO_config.listener,A=YAHOO.env.listeners,D=true,C;if(B){for(C=0;C<A.length;C=C+1){if(A[C]==B){D=false;break;}}if(D){A.push(B);}}}})();YAHOO.lang=YAHOO.lang||{isArray:function(B){if(B){var A=YAHOO.lang;return A.isNumber(B.length)&&A.isFunction(B.splice);}return false;},isBoolean:function(A){return typeof A==="boolean";},isFunction:function(A){return typeof A==="function";},isNull:function(A){return !
 A===null;},isNumber:function(A){return typeof A==="number"&&is!
 Finite(A
);},isObject:function(A){return(A&&(typeof A==="object"||YAHOO.lang.isFunction(A)))||false;},isString:function(A){return typeof A==="string";},isUndefined:function(A){return typeof A==="undefined";},hasOwnProperty:function(A,B){if(Object.prototype.hasOwnProperty){return A.hasOwnProperty(B);}return !YAHOO.lang.isUndefined(A[B])&&A.constructor.prototype[B]!==A[B];},_IEEnumFix:function(C,B){if(YAHOO.env.ua.ie){var E=["toString","valueOf"],A;for(A=0;A<E.length;A=A+1){var F=E[A],D=B[F];if(YAHOO.lang.isFunction(D)&&D!=Object.prototype[F]){C[F]=D;}}}},extend:function(D,E,C){if(!E||!D){throw new Error("YAHOO.lang.extend failed, please check that all dependencies are included.");}var B=function(){};B.prototype=E.prototype;D.prototype=new B();D.prototype.constructor=D;D.superclass=E.prototype;if(E.prototype.constructor==Object.prototype.constructor){E.prototype.constructor=E;}if(C){for(var A in C){D.prototype[A]=C[A];}YAHOO.lang._IEEnumFix(D.prototype,C);}},augmentObject:function(E,D)!
 {if(!D||!E){throw new Error("Absorb failed, verify dependencies.");}var A=arguments,C,F,B=A[2];if(B&&B!==true){for(C=2;C<A.length;C=C+1){E[A[C]]=D[A[C]];}}else{for(F in D){if(B||!E[F]){E[F]=D[F];}}YAHOO.lang._IEEnumFix(E,D);}},augmentProto:function(D,C){if(!C||!D){throw new Error("Augment failed, verify dependencies.");}var A=[D.prototype,C.prototype];for(var B=2;B<arguments.length;B=B+1){A.push(arguments[B]);}YAHOO.lang.augmentObject.apply(this,A);},dump:function(A,G){var C=YAHOO.lang,D,F,I=[],J="{...}",B="f(){...}",H=", ",E=" => ";if(!C.isObject(A)){return A+"";}else{if(A instanceof Date||("nodeType" in A&&"tagName" in A)){return A;}else{if(C.isFunction(A)){return B;}}}G=(C.isNumber(G))?G:3;if(C.isArray(A)){I.push("[");for(D=0,F=A.length;D<F;D=D+1){if(C.isObject(A[D])){I.push((G>0)?C.dump(A[D],G-1):J);}else{I.push(A[D]);}I.push(H);}if(I.length>1){I.pop();}I.push("]");}else{I.push("{");for(D in A){if(C.hasOwnProperty(A,D)){I.push(D+E);if(C.isObject(A[D])){I.push((G>0)?C.du!
 mp(A[D],G-1):J);}else{I.push(A[D]);}I.push(H);}}if(I.length>1)!
 {I.pop()
;}I.push("}");}return I.join("");},substitute:function(Q,B,J){var G,F,E,M,N,P,D=YAHOO.lang,L=[],C,H="dump",K=" ",A="{",O="}";for(;;){G=Q.lastIndexOf(A);if(G<0){break;}F=Q.indexOf(O,G);if(G+1>=F){break;}C=Q.substring(G+1,F);M=C;P=null;E=M.indexOf(K);if(E>-1){P=M.substring(E+1);M=M.substring(0,E);}N=B[M];if(J){N=J(M,N,P);}if(D.isObject(N)){if(D.isArray(N)){N=D.dump(N,parseInt(P,10));}else{P=P||"";var I=P.indexOf(H);if(I>-1){P=P.substring(4);}if(N.toString===Object.prototype.toString||I>-1){N=D.dump(N,parseInt(P,10));}else{N=N.toString();}}}else{if(!D.isString(N)&&!D.isNumber(N)){N="~-"+L.length+"-~";L[L.length]=C;}}Q=Q.substring(0,G)+N+Q.substring(F+1);}for(G=L.length-1;G>=0;G=G-1){Q=Q.replace(new RegExp("~-"+G+"-~"),"{"+L[G]+"}","g");}return Q;},trim:function(A){try{return A.replace(/^\s+|\s+$/g,"");}catch(B){return A;}},merge:function(){var D={},B=arguments;for(var C=0,A=B.length;C<A;C=C+1){YAHOO.lang.augmentObject(D,B[C],true);}return D;},later:function(H,B,I,D,E){H=H||0;B=!
 B||{};var C=I,G=D,F,A;if(YAHOO.lang.isString(I)){C=B[I];}if(!C){throw new TypeError("method undefined");}if(!YAHOO.lang.isArray(G)){G=[D];}F=function(){C.apply(B,G);};A=(E)?setInterval(F,H):setTimeout(F,H);return{interval:E,cancel:function(){if(this.interval){clearInterval(A);}else{clearTimeout(A);}}};},isValue:function(B){var A=YAHOO.lang;return(A.isObject(B)||A.isString(B)||A.isNumber(B)||A.isBoolean(B));}};YAHOO.util.Lang=YAHOO.lang;YAHOO.lang.augment=YAHOO.lang.augmentProto;YAHOO.augment=YAHOO.lang.augmentProto;YAHOO.extend=YAHOO.lang.extend;YAHOO.register("yahoo",YAHOO,{version:"2.4.1",build:"742"});
\ No newline at end of file
+if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var A=arguments,E=null,C,B,D;for(C=0;C<A.length;C=C+1){D=A[C].split(".");E=YAHOO;for(B=(D[0]=="YAHOO")?1:0;B<D.length;B=B+1){E[D[B]]=E[D[B]]||{};E=E[D[B]];}}return E;};YAHOO.log=function(D,A,C){var B=YAHOO.widget.Logger;if(B&&B.log){return B.log(D,A,C);}else{return false;}};YAHOO.register=function(A,E,D){var I=YAHOO.env.modules;if(!I[A]){I[A]={versions:[],builds:[]};}var B=I[A],H=D.version,G=D.build,F=YAHOO.env.listeners;B.name=A;B.version=H;B.build=G;B.versions.push(H);B.builds.push(G);B.mainClass=E;for(var C=0;C<F.length;C=C+1){F[C](B);}if(E){E.VERSION=H;E.BUILD=G;}else{YAHOO.log("mainClass is undefined for module "+A,"warn");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[]};YAHOO.env.getVersion=function(A){return YAHOO.env.modules[A]||null;};YAHOO.env.ua=function(){var C={ie:0,opera:0,gecko:0,webkit:0,mobile:null,air:0};var B=navigator.userAgent,A;if((/KHTML/).test(B)){C.webkit=1;}A=B.match(/A!
 ppleWebKit\/([^\s]*)/);if(A&&A[1]){C.webkit=parseFloat(A[1]);if(/ Mobile\//.test(B)){C.mobile="Apple";}else{A=B.match(/NokiaN[^\/]*/);if(A){C.mobile=A[0];}}A=B.match(/AdobeAIR\/([^\s]*)/);if(A){C.air=A[0];}}if(!C.webkit){A=B.match(/Opera[\s\/]([^\s]*)/);if(A&&A[1]){C.opera=parseFloat(A[1]);A=B.match(/Opera Mini[^;]*/);if(A){C.mobile=A[0];}}else{A=B.match(/MSIE\s([^;]*)/);if(A&&A[1]){C.ie=parseFloat(A[1]);}else{A=B.match(/Gecko\/([^\s]*)/);if(A){C.gecko=1;A=B.match(/rv:([^\s\)]*)/);if(A&&A[1]){C.gecko=parseFloat(A[1]);}}}}}return C;}();(function(){YAHOO.namespace("util","widget","example");if("undefined"!==typeof YAHOO_config){var B=YAHOO_config.listener,A=YAHOO.env.listeners,D=true,C;if(B){for(C=0;C<A.length;C=C+1){if(A[C]==B){D=false;break;}}if(D){A.push(B);}}}})();YAHOO.lang=YAHOO.lang||{isArray:function(B){if(B){var A=YAHOO.lang;return A.isNumber(B.length)&&A.isFunction(B.splice);}return false;},isBoolean:function(A){return typeof A==="boolean";},isFunction:function(A){r!
 eturn typeof A==="function";},isNull:function(A){return A===nu!
 ll;},isN
umber:function(A){return typeof A==="number"&&isFinite(A);},isObject:function(A){return(A&&(typeof A==="object"||YAHOO.lang.isFunction(A)))||false;},isString:function(A){return typeof A==="string";},isUndefined:function(A){return typeof A==="undefined";},hasOwnProperty:function(A,B){if(Object.prototype.hasOwnProperty){return A.hasOwnProperty(B);}return !YAHOO.lang.isUndefined(A[B])&&A.constructor.prototype[B]!==A[B];},_IEEnumFix:function(C,B){if(YAHOO.env.ua.ie){var E=["toString","valueOf"],A;for(A=0;A<E.length;A=A+1){var F=E[A],D=B[F];if(YAHOO.lang.isFunction(D)&&D!=Object.prototype[F]){C[F]=D;}}}},extend:function(D,E,C){if(!E||!D){throw new Error("YAHOO.lang.extend failed, please check that "+"all dependencies are included.");}var B=function(){};B.prototype=E.prototype;D.prototype=new B();D.prototype.constructor=D;D.superclass=E.prototype;if(E.prototype.constructor==Object.prototype.constructor){E.prototype.constructor=E;}if(C){for(var A in C){D.prototype[A]=C[A];}YAHOO.la!
 ng._IEEnumFix(D.prototype,C);}},augmentObject:function(E,D){if(!D||!E){throw new Error("Absorb failed, verify dependencies.");}var A=arguments,C,F,B=A[2];if(B&&B!==true){for(C=2;C<A.length;C=C+1){E[A[C]]=D[A[C]];}}else{for(F in D){if(B||!E[F]){E[F]=D[F];}}YAHOO.lang._IEEnumFix(E,D);}},augmentProto:function(D,C){if(!C||!D){throw new Error("Augment failed, verify dependencies.");}var A=[D.prototype,C.prototype];for(var B=2;B<arguments.length;B=B+1){A.push(arguments[B]);}YAHOO.lang.augmentObject.apply(this,A);},dump:function(A,G){var C=YAHOO.lang,D,F,I=[],J="{...}",B="f(){...}",H=", ",E=" => ";if(!C.isObject(A)){return A+"";}else{if(A instanceof Date||("nodeType" in A&&"tagName" in A)){return A;}else{if(C.isFunction(A)){return B;}}}G=(C.isNumber(G))?G:3;if(C.isArray(A)){I.push("[");for(D=0,F=A.length;D<F;D=D+1){if(C.isObject(A[D])){I.push((G>0)?C.dump(A[D],G-1):J);}else{I.push(A[D]);}I.push(H);}if(I.length>1){I.pop();}I.push("]");}else{I.push("{");for(D in A){if(C.hasOwnProper!
 ty(A,D)){I.push(D+E);if(C.isObject(A[D])){I.push((G>0)?C.dump(!
 A[D],G-1
):J);}else{I.push(A[D]);}I.push(H);}}if(I.length>1){I.pop();}I.push("}");}return I.join("");},substitute:function(Q,B,J){var G,F,E,M,N,P,D=YAHOO.lang,L=[],C,H="dump",K=" ",A="{",O="}";for(;;){G=Q.lastIndexOf(A);if(G<0){break;}F=Q.indexOf(O,G);if(G+1>=F){break;}C=Q.substring(G+1,F);M=C;P=null;E=M.indexOf(K);if(E>-1){P=M.substring(E+1);M=M.substring(0,E);}N=B[M];if(J){N=J(M,N,P);}if(D.isObject(N)){if(D.isArray(N)){N=D.dump(N,parseInt(P,10));}else{P=P||"";var I=P.indexOf(H);if(I>-1){P=P.substring(4);}if(N.toString===Object.prototype.toString||I>-1){N=D.dump(N,parseInt(P,10));}else{N=N.toString();}}}else{if(!D.isString(N)&&!D.isNumber(N)){N="~-"+L.length+"-~";L[L.length]=C;}}Q=Q.substring(0,G)+N+Q.substring(F+1);}for(G=L.length-1;G>=0;G=G-1){Q=Q.replace(new RegExp("~-"+G+"-~"),"{"+L[G]+"}","g");}return Q;},trim:function(A){try{return A.replace(/^\s+|\s+$/g,"");}catch(B){return A;}},merge:function(){var D={},B=arguments;for(var C=0,A=B.length;C<A;C=C+1){YAHOO.lang.augmentObject(D!
 ,B[C],true);}return D;},later:function(H,B,I,D,E){H=H||0;B=B||{};var C=I,G=D,F,A;if(YAHOO.lang.isString(I)){C=B[I];}if(!C){throw new TypeError("method undefined");}if(!YAHOO.lang.isArray(G)){G=[D];}F=function(){C.apply(B,G);};A=(E)?setInterval(F,H):setTimeout(F,H);return{interval:E,cancel:function(){if(this.interval){clearInterval(A);}else{clearTimeout(A);}}};},isValue:function(B){var A=YAHOO.lang;return(A.isObject(B)||A.isString(B)||A.isNumber(B)||A.isBoolean(B));}};YAHOO.util.Lang=YAHOO.lang;YAHOO.lang.augment=YAHOO.lang.augmentProto;YAHOO.augment=YAHOO.lang.augmentProto;YAHOO.extend=YAHOO.lang.extend;YAHOO.register("yahoo",YAHOO,{version:"2.5.1",build:"984"});
\ No newline at end of file

Modified: trunk/root/static/yui/yahoo/yahoo.js
===================================================================
--- trunk/root/static/yui/yahoo/yahoo.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yahoo/yahoo.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The YAHOO object is the single global object used by YUI Library.  It
@@ -272,16 +272,25 @@
          * Safari 2.0.4:         418     <-- preventDefault fixed
          * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
          *                                   different versions of webkit
-         * Safari 2.0.4 (419.3): 419     <-- Current Safari release
-         * Webkit 212 nightly:   522+    <-- Safari 3.0 (with native SVG) should
-         *                                   be higher than this
+         * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
+         *                                   updated, but not updated
+         *                                   to the latest patch.
+         * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native SVG
+         *                                   and many major issues fixed).  
+         * 3.x yahoo.com, flickr:422     <-- Safari 3.x hacks the user agent
+         *                                   string when hitting yahoo.com and 
+         *                                   flickr.com.
+         * Safari 3.0.4 (523.12):523.12  <-- First Tiger release - automatic update
+         *                                   from 2.x via the 10.4.11 OS patch
+         * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
+         *                                   yahoo.com user agent hack removed.
          *                                   
          * </pre>
          * http://developer.apple.com/internet/safari/uamatrix.html
          * @property webkit
          * @type float
          */
-        webkit:0,
+        webkit: 0,
 
         /**
          * The mobile property will be set to a string containing any relevant
@@ -291,7 +300,16 @@
          * @property mobile 
          * @type string
          */
-        mobile: null 
+        mobile: null,
+
+        /**
+         * Adobe AIR version number or 0.  Only populated if webkit is detected.
+         * Example: 1.0
+         * @property air
+         * @type float
+         */
+        air: 0
+
     };
 
     var ua=navigator.userAgent, m;
@@ -315,6 +333,11 @@
             }
         }
 
+        m=ua.match(/AdobeAIR\/([^\s]*)/);
+        if (m) {
+            o.air = m[0]; // Adobe AIR 1.0 or better
+        }
+
     }
 
     if (!o.webkit) { // not webkit
@@ -388,10 +411,9 @@
      * properties.
      * @method isArray
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isArray: function(o) { 
-
         if (o) {
            var l = YAHOO.lang;
            return l.isNumber(o.length) && l.isFunction(o.splice);
@@ -403,7 +425,7 @@
      * Determines whether or not the provided object is a boolean
      * @method isBoolean
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isBoolean: function(o) {
         return typeof o === 'boolean';
@@ -413,7 +435,7 @@
      * Determines whether or not the provided object is a function
      * @method isFunction
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isFunction: function(o) {
         return typeof o === 'function';
@@ -423,7 +445,7 @@
      * Determines whether or not the provided object is null
      * @method isNull
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isNull: function(o) {
         return o === null;
@@ -433,7 +455,7 @@
      * Determines whether or not the provided object is a legal number
      * @method isNumber
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isNumber: function(o) {
         return typeof o === 'number' && isFinite(o);
@@ -444,7 +466,7 @@
      * or function
      * @method isObject
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */  
     isObject: function(o) {
 return (o && (typeof o === 'object' || YAHOO.lang.isFunction(o))) || false;
@@ -454,7 +476,7 @@
      * Determines whether or not the provided object is a string
      * @method isString
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isString: function(o) {
         return typeof o === 'string';
@@ -464,7 +486,7 @@
      * Determines whether or not the provided object is undefined
      * @method isUndefined
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isUndefined: function(o) {
         return typeof o === 'undefined';
@@ -488,7 +510,7 @@
      * </pre>
      * @method hasOwnProperty
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     hasOwnProperty: function(o, prop) {
         if (Object.prototype.hasOwnProperty) {
@@ -827,14 +849,14 @@
     },
 
     /**
-     * Executes the supplied function in the scope of the supplied 
+     * Executes the supplied function in the context of the supplied 
      * object 'when' milliseconds later.  Executes the function a 
      * single time unless periodic is set to true.
      * @method later
      * @since 2.4.0
      * @param when {int} the number of milliseconds to wait until the fn 
      * is executed
-     * @param o the scope object
+     * @param o the context object
      * @param fn {Function|String} the function to execute or the name of 
      * the method in the 'o' object to execute
      * @param data [Array] data that is provided to the function.  This accepts
@@ -881,7 +903,7 @@
             }
         };
     },
-
+    
     /**
      * A convenience method for detecting a legitimate non-null value.
      * Returns false for null/undefined/NaN, true for other values, 
@@ -949,4 +971,4 @@
  */
 YAHOO.extend = YAHOO.lang.extend;
 
-YAHOO.register("yahoo", YAHOO, {version: "2.4.1", build: "742"});
+YAHOO.register("yahoo", YAHOO, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/yahoo-dom-event/yahoo-dom-event.js
===================================================================
--- trunk/root/static/yui/yahoo-dom-event/yahoo-dom-event.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yahoo-dom-event/yahoo-dom-event.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,10 +1,12 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var A=arguments,E=null,C,B,D;for(C=0;C<A.length;C=C+1){D=A[C].split(".");E=YAHOO;for(B=(D[0]=="YAHOO")?1:0;B<D.length;B=B+1){E[D[B]]=E[D[B]]||{};E=E[D[B]];}}return E;};YAHOO.log=function(D,A,C){var B=YAHOO.widget.Logger;if(B&&B.log){return B.log(D,A,C);}else{return false;}};YAHOO.register=function(A,E,D){var I=YAHOO.env.modules;if(!I[A]){I[A]={versions:[],builds:[]};}var B=I[A],H=D.version,G=D.build,F=YAHOO.env.listeners;B.name=A;B.version=H;B.build=G;B.versions.push(H);B.builds.push(G);B.mainClass=E;for(var C=0;C<F.length;C=C+1){F[C](B);}if(E){E.VERSION=H;E.BUILD=G;}else{YAHOO.log("mainClass is undefined for module "+A,"warn");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[]};YAHOO.env.getVersion=function(A){return YAHOO.env.modules[A]||null;};YAHOO.env.ua=function(){var C={ie:0,opera:0,gecko:0,webkit:0,mobile:null};var B=navigator.userAgent,A;if((/KHTML/).test(B)){C.webkit=1;}A=B.match(/AppleWe!
 bKit\/([^\s]*)/);if(A&&A[1]){C.webkit=parseFloat(A[1]);if(/ Mobile\//.test(B)){C.mobile="Apple";}else{A=B.match(/NokiaN[^\/]*/);if(A){C.mobile=A[0];}}}if(!C.webkit){A=B.match(/Opera[\s\/]([^\s]*)/);if(A&&A[1]){C.opera=parseFloat(A[1]);A=B.match(/Opera Mini[^;]*/);if(A){C.mobile=A[0];}}else{A=B.match(/MSIE\s([^;]*)/);if(A&&A[1]){C.ie=parseFloat(A[1]);}else{A=B.match(/Gecko\/([^\s]*)/);if(A){C.gecko=1;A=B.match(/rv:([^\s\)]*)/);if(A&&A[1]){C.gecko=parseFloat(A[1]);}}}}}return C;}();(function(){YAHOO.namespace("util","widget","example");if("undefined"!==typeof YAHOO_config){var B=YAHOO_config.listener,A=YAHOO.env.listeners,D=true,C;if(B){for(C=0;C<A.length;C=C+1){if(A[C]==B){D=false;break;}}if(D){A.push(B);}}}})();YAHOO.lang=YAHOO.lang||{isArray:function(B){if(B){var A=YAHOO.lang;return A.isNumber(B.length)&&A.isFunction(B.splice);}return false;},isBoolean:function(A){return typeof A==="boolean";},isFunction:function(A){return typeof A==="function";},isNull:function(A){return !
 A===null;},isNumber:function(A){return typeof A==="number"&&is!
 Finite(A
);},isObject:function(A){return(A&&(typeof A==="object"||YAHOO.lang.isFunction(A)))||false;},isString:function(A){return typeof A==="string";},isUndefined:function(A){return typeof A==="undefined";},hasOwnProperty:function(A,B){if(Object.prototype.hasOwnProperty){return A.hasOwnProperty(B);}return !YAHOO.lang.isUndefined(A[B])&&A.constructor.prototype[B]!==A[B];},_IEEnumFix:function(C,B){if(YAHOO.env.ua.ie){var E=["toString","valueOf"],A;for(A=0;A<E.length;A=A+1){var F=E[A],D=B[F];if(YAHOO.lang.isFunction(D)&&D!=Object.prototype[F]){C[F]=D;}}}},extend:function(D,E,C){if(!E||!D){throw new Error("YAHOO.lang.extend failed, please check that all dependencies are included.");}var B=function(){};B.prototype=E.prototype;D.prototype=new B();D.prototype.constructor=D;D.superclass=E.prototype;if(E.prototype.constructor==Object.prototype.constructor){E.prototype.constructor=E;}if(C){for(var A in C){D.prototype[A]=C[A];}YAHOO.lang._IEEnumFix(D.prototype,C);}},augmentObject:function(E,D)!
 {if(!D||!E){throw new Error("Absorb failed, verify dependencies.");}var A=arguments,C,F,B=A[2];if(B&&B!==true){for(C=2;C<A.length;C=C+1){E[A[C]]=D[A[C]];}}else{for(F in D){if(B||!E[F]){E[F]=D[F];}}YAHOO.lang._IEEnumFix(E,D);}},augmentProto:function(D,C){if(!C||!D){throw new Error("Augment failed, verify dependencies.");}var A=[D.prototype,C.prototype];for(var B=2;B<arguments.length;B=B+1){A.push(arguments[B]);}YAHOO.lang.augmentObject.apply(this,A);},dump:function(A,G){var C=YAHOO.lang,D,F,I=[],J="{...}",B="f(){...}",H=", ",E=" => ";if(!C.isObject(A)){return A+"";}else{if(A instanceof Date||("nodeType" in A&&"tagName" in A)){return A;}else{if(C.isFunction(A)){return B;}}}G=(C.isNumber(G))?G:3;if(C.isArray(A)){I.push("[");for(D=0,F=A.length;D<F;D=D+1){if(C.isObject(A[D])){I.push((G>0)?C.dump(A[D],G-1):J);}else{I.push(A[D]);}I.push(H);}if(I.length>1){I.pop();}I.push("]");}else{I.push("{");for(D in A){if(C.hasOwnProperty(A,D)){I.push(D+E);if(C.isObject(A[D])){I.push((G>0)?C.du!
 mp(A[D],G-1):J);}else{I.push(A[D]);}I.push(H);}}if(I.length>1)!
 {I.pop()
;}I.push("}");}return I.join("");},substitute:function(Q,B,J){var G,F,E,M,N,P,D=YAHOO.lang,L=[],C,H="dump",K=" ",A="{",O="}";for(;;){G=Q.lastIndexOf(A);if(G<0){break;}F=Q.indexOf(O,G);if(G+1>=F){break;}C=Q.substring(G+1,F);M=C;P=null;E=M.indexOf(K);if(E>-1){P=M.substring(E+1);M=M.substring(0,E);}N=B[M];if(J){N=J(M,N,P);}if(D.isObject(N)){if(D.isArray(N)){N=D.dump(N,parseInt(P,10));}else{P=P||"";var I=P.indexOf(H);if(I>-1){P=P.substring(4);}if(N.toString===Object.prototype.toString||I>-1){N=D.dump(N,parseInt(P,10));}else{N=N.toString();}}}else{if(!D.isString(N)&&!D.isNumber(N)){N="~-"+L.length+"-~";L[L.length]=C;}}Q=Q.substring(0,G)+N+Q.substring(F+1);}for(G=L.length-1;G>=0;G=G-1){Q=Q.replace(new RegExp("~-"+G+"-~"),"{"+L[G]+"}","g");}return Q;},trim:function(A){try{return A.replace(/^\s+|\s+$/g,"");}catch(B){return A;}},merge:function(){var D={},B=arguments;for(var C=0,A=B.length;C<A;C=C+1){YAHOO.lang.augmentObject(D,B[C],true);}return D;},later:function(H,B,I,D,E){H=H||0;B=!
 B||{};var C=I,G=D,F,A;if(YAHOO.lang.isString(I)){C=B[I];}if(!C){throw new TypeError("method undefined");}if(!YAHOO.lang.isArray(G)){G=[D];}F=function(){C.apply(B,G);};A=(E)?setInterval(F,H):setTimeout(F,H);return{interval:E,cancel:function(){if(this.interval){clearInterval(A);}else{clearTimeout(A);}}};},isValue:function(B){var A=YAHOO.lang;return(A.isObject(B)||A.isString(B)||A.isNumber(B)||A.isBoolean(B));}};YAHOO.util.Lang=YAHOO.lang;YAHOO.lang.augment=YAHOO.lang.augmentProto;YAHOO.augment=YAHOO.lang.augmentProto;YAHOO.extend=YAHOO.lang.extend;YAHOO.register("yahoo",YAHOO,{version:"2.4.1",build:"742"});(function(){var B=YAHOO.util,L,J,H=0,K={},F={},N=window.document;var C=YAHOO.env.ua.opera,M=YAHOO.env.ua.webkit,A=YAHOO.env.ua.gecko,G=YAHOO.env.ua.ie;var E={HYPHEN:/(-[a-z])/i,ROOT_TAG:/^body|html$/i};var O=function(Q){if(!E.HYPHEN.test(Q)){return Q;}if(K[Q]){return K[Q];}var R=Q;while(E.HYPHEN.exec(R)){R=R.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());}K[Q]=R;retur!
 n R;};var P=function(R){var Q=F[R];if(!Q){Q=new RegExp("(?:^|\!
 \s+)"+R+
"(?:\\s+|$)");F[R]=Q;}return Q;};if(N.defaultView&&N.defaultView.getComputedStyle){L=function(Q,T){var S=null;if(T=="float"){T="cssFloat";}var R=N.defaultView.getComputedStyle(Q,"");if(R){S=R[O(T)];}return Q.style[T]||S;};}else{if(N.documentElement.currentStyle&&G){L=function(Q,S){switch(O(S)){case"opacity":var U=100;try{U=Q.filters["DXImageTransform.Microsoft.Alpha"].opacity;}catch(T){try{U=Q.filters("alpha").opacity;}catch(T){}}return U/100;case"float":S="styleFloat";default:var R=Q.currentStyle?Q.currentStyle[S]:null;return(Q.style[S]||R);}};}else{L=function(Q,R){return Q.style[R];};}}if(G){J=function(Q,R,S){switch(R){case"opacity":if(YAHOO.lang.isString(Q.style.filter)){Q.style.filter="alpha(opacity="+S*100+")";if(!Q.currentStyle||!Q.currentStyle.hasLayout){Q.style.zoom=1;}}break;case"float":R="styleFloat";default:Q.style[R]=S;}};}else{J=function(Q,R,S){if(R=="float"){R="cssFloat";}Q.style[R]=S;};}var D=function(Q,R){return Q&&Q.nodeType==1&&(!R||R(Q));};YAHOO.util.Dom={!
 get:function(S){if(S&&(S.tagName||S.item)){return S;}if(YAHOO.lang.isString(S)||!S){return N.getElementById(S);}if(S.length!==undefined){var T=[];for(var R=0,Q=S.length;R<Q;++R){T[T.length]=B.Dom.get(S[R]);}return T;}return S;},getStyle:function(Q,S){S=O(S);var R=function(T){return L(T,S);};return B.Dom.batch(Q,R,B.Dom,true);},setStyle:function(Q,S,T){S=O(S);var R=function(U){J(U,S,T);};B.Dom.batch(Q,R,B.Dom,true);},getXY:function(Q){var R=function(S){if((S.parentNode===null||S.offsetParent===null||this.getStyle(S,"display")=="none")&&S!=S.ownerDocument.body){return false;}return I(S);};return B.Dom.batch(Q,R,B.Dom,true);},getX:function(Q){var R=function(S){return B.Dom.getXY(S)[0];};return B.Dom.batch(Q,R,B.Dom,true);},getY:function(Q){var R=function(S){return B.Dom.getXY(S)[1];};return B.Dom.batch(Q,R,B.Dom,true);},setXY:function(Q,T,S){var R=function(W){var V=this.getStyle(W,"position");if(V=="static"){this.setStyle(W,"position","relative");V="relative";}var Y=this.getXY!
 (W);if(Y===false){return false;}var X=[parseInt(this.getStyle(!
 W,"left"
),10),parseInt(this.getStyle(W,"top"),10)];if(isNaN(X[0])){X[0]=(V=="relative")?0:W.offsetLeft;}if(isNaN(X[1])){X[1]=(V=="relative")?0:W.offsetTop;}if(T[0]!==null){W.style.left=T[0]-Y[0]+X[0]+"px";}if(T[1]!==null){W.style.top=T[1]-Y[1]+X[1]+"px";}if(!S){var U=this.getXY(W);if((T[0]!==null&&U[0]!=T[0])||(T[1]!==null&&U[1]!=T[1])){this.setXY(W,T,true);}}};B.Dom.batch(Q,R,B.Dom,true);},setX:function(R,Q){B.Dom.setXY(R,[Q,null]);},setY:function(Q,R){B.Dom.setXY(Q,[null,R]);},getRegion:function(Q){var R=function(S){if((S.parentNode===null||S.offsetParent===null||this.getStyle(S,"display")=="none")&&S!=N.body){return false;}var T=B.Region.getRegion(S);return T;};return B.Dom.batch(Q,R,B.Dom,true);},getClientWidth:function(){return B.Dom.getViewportWidth();},getClientHeight:function(){return B.Dom.getViewportHeight();},getElementsByClassName:function(U,Y,V,W){Y=Y||"*";V=(V)?B.Dom.get(V):null||N;if(!V){return[];}var R=[],Q=V.getElementsByTagName(Y),X=P(U);for(var S=0,T=Q.length;S<T;!
 ++S){if(X.test(Q[S].className)){R[R.length]=Q[S];if(W){W.call(Q[S],Q[S]);}}}return R;},hasClass:function(S,R){var Q=P(R);var T=function(U){return Q.test(U.className);};return B.Dom.batch(S,T,B.Dom,true);},addClass:function(R,Q){var S=function(T){if(this.hasClass(T,Q)){return false;}T.className=YAHOO.lang.trim([T.className,Q].join(" "));return true;};return B.Dom.batch(R,S,B.Dom,true);},removeClass:function(S,R){var Q=P(R);var T=function(U){if(!this.hasClass(U,R)){return false;}var V=U.className;U.className=V.replace(Q," ");if(this.hasClass(U,R)){this.removeClass(U,R);}U.className=YAHOO.lang.trim(U.className);return true;};return B.Dom.batch(S,T,B.Dom,true);},replaceClass:function(T,R,Q){if(!Q||R===Q){return false;}var S=P(R);var U=function(V){if(!this.hasClass(V,R)){this.addClass(V,Q);return true;}V.className=V.className.replace(S," "+Q+" ");if(this.hasClass(V,R)){this.replaceClass(V,R,Q);}V.className=YAHOO.lang.trim(V.className);return true;};return B.Dom.batch(T,U,B.Dom,t!
 rue);},generateId:function(Q,S){S=S||"yui-gen";var R=function(!
 T){if(T&
&T.id){return T.id;}var U=S+H++;if(T){T.id=U;}return U;};return B.Dom.batch(Q,R,B.Dom,true)||R.apply(B.Dom,arguments);},isAncestor:function(Q,R){Q=B.Dom.get(Q);R=B.Dom.get(R);if(!Q||!R){return false;}if(Q.contains&&R.nodeType&&!M){return Q.contains(R);}else{if(Q.compareDocumentPosition&&R.nodeType){return !!(Q.compareDocumentPosition(R)&16);}else{if(R.nodeType){return !!this.getAncestorBy(R,function(S){return S==Q;});}}}return false;},inDocument:function(Q){return this.isAncestor(N.documentElement,Q);},getElementsBy:function(X,R,S,U){R=R||"*";S=(S)?B.Dom.get(S):null||N;if(!S){return[];}var T=[],W=S.getElementsByTagName(R);for(var V=0,Q=W.length;V<Q;++V){if(X(W[V])){T[T.length]=W[V];if(U){U(W[V]);}}}return T;},batch:function(U,X,W,S){U=(U&&(U.tagName||U.item))?U:B.Dom.get(U);if(!U||!X){return false;}var T=(S)?W:window;if(U.tagName||U.length===undefined){return X.call(T,U,W);}var V=[];for(var R=0,Q=U.length;R<Q;++R){V[V.length]=X.call(T,U[R],W);}return V;},getDocumentHeight:fu!
 nction(){var R=(N.compatMode!="CSS1Compat")?N.body.scrollHeight:N.documentElement.scrollHeight;var Q=Math.max(R,B.Dom.getViewportHeight());return Q;},getDocumentWidth:function(){var R=(N.compatMode!="CSS1Compat")?N.body.scrollWidth:N.documentElement.scrollWidth;var Q=Math.max(R,B.Dom.getViewportWidth());return Q;},getViewportHeight:function(){var Q=self.innerHeight;var R=N.compatMode;if((R||G)&&!C){Q=(R=="CSS1Compat")?N.documentElement.clientHeight:N.body.clientHeight;
-}return Q;},getViewportWidth:function(){var Q=self.innerWidth;var R=N.compatMode;if(R||G){Q=(R=="CSS1Compat")?N.documentElement.clientWidth:N.body.clientWidth;}return Q;},getAncestorBy:function(Q,R){while(Q=Q.parentNode){if(D(Q,R)){return Q;}}return null;},getAncestorByClassName:function(R,Q){R=B.Dom.get(R);if(!R){return null;}var S=function(T){return B.Dom.hasClass(T,Q);};return B.Dom.getAncestorBy(R,S);},getAncestorByTagName:function(R,Q){R=B.Dom.get(R);if(!R){return null;}var S=function(T){return T.tagName&&T.tagName.toUpperCase()==Q.toUpperCase();};return B.Dom.getAncestorBy(R,S);},getPreviousSiblingBy:function(Q,R){while(Q){Q=Q.previousSibling;if(D(Q,R)){return Q;}}return null;},getPreviousSibling:function(Q){Q=B.Dom.get(Q);if(!Q){return null;}return B.Dom.getPreviousSiblingBy(Q);},getNextSiblingBy:function(Q,R){while(Q){Q=Q.nextSibling;if(D(Q,R)){return Q;}}return null;},getNextSibling:function(Q){Q=B.Dom.get(Q);if(!Q){return null;}return B.Dom.getNextSiblingBy(Q);},g!
 etFirstChildBy:function(Q,S){var R=(D(Q.firstChild,S))?Q.firstChild:null;return R||B.Dom.getNextSiblingBy(Q.firstChild,S);},getFirstChild:function(Q,R){Q=B.Dom.get(Q);if(!Q){return null;}return B.Dom.getFirstChildBy(Q);},getLastChildBy:function(Q,S){if(!Q){return null;}var R=(D(Q.lastChild,S))?Q.lastChild:null;return R||B.Dom.getPreviousSiblingBy(Q.lastChild,S);},getLastChild:function(Q){Q=B.Dom.get(Q);return B.Dom.getLastChildBy(Q);},getChildrenBy:function(R,T){var S=B.Dom.getFirstChildBy(R,T);var Q=S?[S]:[];B.Dom.getNextSiblingBy(S,function(U){if(!T||T(U)){Q[Q.length]=U;}return false;});return Q;},getChildren:function(Q){Q=B.Dom.get(Q);if(!Q){}return B.Dom.getChildrenBy(Q);},getDocumentScrollLeft:function(Q){Q=Q||N;return Math.max(Q.documentElement.scrollLeft,Q.body.scrollLeft);},getDocumentScrollTop:function(Q){Q=Q||N;return Math.max(Q.documentElement.scrollTop,Q.body.scrollTop);},insertBefore:function(R,Q){R=B.Dom.get(R);Q=B.Dom.get(Q);if(!R||!Q||!Q.parentNode){return n!
 ull;}return Q.parentNode.insertBefore(R,Q);},insertAfter:funct!
 ion(R,Q)
{R=B.Dom.get(R);Q=B.Dom.get(Q);if(!R||!Q||!Q.parentNode){return null;}if(Q.nextSibling){return Q.parentNode.insertBefore(R,Q.nextSibling);}else{return Q.parentNode.appendChild(R);}},getClientRegion:function(){var S=B.Dom.getDocumentScrollTop(),R=B.Dom.getDocumentScrollLeft(),T=B.Dom.getViewportWidth()+R,Q=B.Dom.getViewportHeight()+S;return new B.Region(S,T,Q,R);}};var I=function(){if(N.documentElement.getBoundingClientRect){return function(R){var S=R.getBoundingClientRect();var Q=R.ownerDocument;return[S.left+B.Dom.getDocumentScrollLeft(Q),S.top+B.Dom.getDocumentScrollTop(Q)];};}else{return function(S){var T=[S.offsetLeft,S.offsetTop];var R=S.offsetParent;var Q=(M&&B.Dom.getStyle(S,"position")=="absolute"&&S.offsetParent==S.ownerDocument.body);if(R!=S){while(R){T[0]+=R.offsetLeft;T[1]+=R.offsetTop;if(!Q&&M&&B.Dom.getStyle(R,"position")=="absolute"){Q=true;}R=R.offsetParent;}}if(Q){T[0]-=S.ownerDocument.body.offsetLeft;T[1]-=S.ownerDocument.body.offsetTop;}R=S.parentNode;whil!
 e(R.tagName&&!E.ROOT_TAG.test(R.tagName)){if(B.Dom.getStyle(R,"display").search(/^inline|table-row.*$/i)){T[0]-=R.scrollLeft;T[1]-=R.scrollTop;}R=R.parentNode;}return T;};}}();})();YAHOO.util.Region=function(C,D,A,B){this.top=C;this[1]=C;this.right=D;this.bottom=A;this.left=B;this[0]=B;};YAHOO.util.Region.prototype.contains=function(A){return(A.left>=this.left&&A.right<=this.right&&A.top>=this.top&&A.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(E){var C=Math.max(this.top,E.top);var D=Math.min(this.right,E.right);var A=Math.min(this.bottom,E.bottom);var B=Math.max(this.left,E.left);if(A>=C&&D>=B){return new YAHOO.util.Region(C,D,A,B);}else{return null;}};YAHOO.util.Region.prototype.union=function(E){var C=Math.min(this.top,E.top);var D=Math.max(this.right,E.right);var A=Math.max(this.bottom,E.bottom);var B=Math.min(this.left,E.left);return new YAHOO!
 .util.Region(C,D,A,B);};YAHOO.util.Region.prototype.toString=f!
 unction(
){return("Region {top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+"}");};YAHOO.util.Region.getRegion=function(D){var F=YAHOO.util.Dom.getXY(D);var C=F[1];var E=F[0]+D.offsetWidth;var A=F[1]+D.offsetHeight;var B=F[0];return new YAHOO.util.Region(C,E,A,B);};YAHOO.util.Point=function(A,B){if(YAHOO.lang.isArray(A)){B=A[1];A=A[0];}this.x=this.right=this.left=this[0]=A;this.y=this.top=this.bottom=this[1]=B;};YAHOO.util.Point.prototype=new YAHOO.util.Region();YAHOO.register("dom",YAHOO.util.Dom,{version:"2.4.1",build:"742"});YAHOO.util.CustomEvent=function(D,B,C,A){this.type=D;this.scope=B||window;this.silent=C;this.signature=A||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){}var E="_YUICEOnSubscribe";if(D!==E){this.subscribeEvent=new YAHOO.util.CustomEvent(E,this,true);}this.lastError=null;};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(B,C,A){if(!B){throw new !
 Error("Invalid callback for subscriber to '"+this.type+"'");}if(this.subscribeEvent){this.subscribeEvent.fire(B,C,A);}this.subscribers.push(new YAHOO.util.Subscriber(B,C,A));},unsubscribe:function(D,F){if(!D){return this.unsubscribeAll();}var E=false;for(var B=0,A=this.subscribers.length;B<A;++B){var C=this.subscribers[B];if(C&&C.contains(D,F)){this._delete(B);E=true;}}return E;},fire:function(){var D=this.subscribers.length;if(!D&&this.silent){return true;}var H=[],F=true,C,I=false;for(C=0;C<arguments.length;++C){H.push(arguments[C]);}if(!this.silent){}for(C=0;C<D;++C){var L=this.subscribers[C];if(!L){I=true;}else{if(!this.silent){}var K=L.getScope(this.scope);if(this.signature==YAHOO.util.CustomEvent.FLAT){var A=null;if(H.length>0){A=H[0];}try{F=L.fn.call(K,A,L.obj);}catch(E){this.lastError=E;}}else{try{F=L.fn.call(K,this.type,H,L.obj);}catch(G){this.lastError=G;}}if(false===F){if(!this.silent){}return false;}}}if(I){var J=[],B=this.subscribers;for(C=0,D=B.length;C<D;C=C+!
 1){J.push(B[C]);}this.subscribers=J;}return true;},unsubscribe!
 All:func
tion(){for(var B=0,A=this.subscribers.length;B<A;++B){this._delete(A-1-B);}this.subscribers=[];return B;},_delete:function(A){var B=this.subscribers[A];if(B){delete B.fn;delete B.obj;}this.subscribers[A]=null;},toString:function(){return"CustomEvent: '"+this.type+"', scope: "+this.scope;}};YAHOO.util.Subscriber=function(B,C,A){this.fn=B;this.obj=YAHOO.lang.isUndefined(C)?null:C;this.override=A;};YAHOO.util.Subscriber.prototype.getScope=function(A){if(this.override){if(this.override===true){return this.obj;}else{return this.override;}}return A;};YAHOO.util.Subscriber.prototype.contains=function(A,B){if(B){return(this.fn==A&&this.obj==B);}else{return(this.fn==A);}};YAHOO.util.Subscriber.prototype.toString=function(){return"Subscriber { obj: "+this.obj+", override: "+(this.override||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var H=false;var I=[];var J=[];var G=[];var E=[];var C=0;var F=[];var B=[];var A=0;var D={63232:38,63233:40,63234:37,63235:39,63276:33,6!
 3277:34,25:9};return{POLL_RETRYS:4000,POLL_INTERVAL:10,EL:0,TYPE:1,FN:2,WFN:3,UNLOAD_OBJ:3,ADJ_SCOPE:4,OBJ:5,OVERRIDE:6,lastError:null,isSafari:YAHOO.env.ua.webkit,webkit:YAHOO.env.ua.webkit,isIE:YAHOO.env.ua.ie,_interval:null,_dri:null,DOMReady:false,startInterval:function(){if(!this._interval){var K=this;var L=function(){K._tryPreloadAttach();};this._interval=setInterval(L,this.POLL_INTERVAL);}},onAvailable:function(P,M,Q,O,N){var K=(YAHOO.lang.isString(P))?[P]:P;for(var L=0;L<K.length;L=L+1){F.push({id:K[L],fn:M,obj:Q,override:O,checkReady:N});}C=this.POLL_RETRYS;this.startInterval();},onContentReady:function(M,K,N,L){this.onAvailable(M,K,N,L,true);},onDOMReady:function(K,M,L){if(this.DOMReady){setTimeout(function(){var N=window;if(L){if(L===true){N=M;}else{N=L;}}K.call(N,"DOMReady",[],M);},0);}else{this.DOMReadyEvent.subscribe(K,M,L);}},addListener:function(M,K,V,Q,L){if(!V||!V.call){return false;}if(this._isValidCollection(M)){var W=true;for(var R=0,T=M.length;R<T;++R)!
 {W=this.on(M[R],K,V,Q,L)&&W;}return W;}else{if(YAHOO.lang.isSt!
 ring(M))
{var P=this.getEl(M);if(P){M=P;}else{this.onAvailable(M,function(){YAHOO.util.Event.on(M,K,V,Q,L);});return true;}}}if(!M){return false;}if("unload"==K&&Q!==this){J[J.length]=[M,K,V,Q,L];return true;}var Y=M;if(L){if(L===true){Y=Q;}else{Y=L;}}var N=function(Z){return V.call(Y,YAHOO.util.Event.getEvent(Z,M),Q);};var X=[M,K,V,N,Y,Q,L];var S=I.length;I[S]=X;if(this.useLegacyEvent(M,K)){var O=this.getLegacyIndex(M,K);if(O==-1||M!=G[O][0]){O=G.length;B[M.id+K]=O;G[O]=[M,K,M["on"+K]];E[O]=[];M["on"+K]=function(Z){YAHOO.util.Event.fireLegacyEvent(YAHOO.util.Event.getEvent(Z),O);};}E[O].push(X);}else{try{this._simpleAdd(M,K,N,false);}catch(U){this.lastError=U;this.removeListener(M,K,V);return false;}}return true;},fireLegacyEvent:function(O,M){var Q=true,K,S,R,T,P;S=E[M];for(var L=0,N=S.length;L<N;++L){R=S[L];if(R&&R[this.WFN]){T=R[this.ADJ_SCOPE];P=R[this.WFN].call(T,O);Q=(Q&&P);}}K=G[M];if(K&&K[2]){K[2](O);}return Q;},getLegacyIndex:function(L,M){var K=this.generateId(L)+M;if(type!
 of B[K]=="undefined"){return -1;}else{return B[K];}},useLegacyEvent:function(L,M){if(this.webkit&&("click"==M||"dblclick"==M)){var K=parseInt(this.webkit,10);if(!isNaN(K)&&K<418){return true;}}return false;},removeListener:function(L,K,T){var O,R,V;if(typeof L=="string"){L=this.getEl(L);}else{if(this._isValidCollection(L)){var U=true;for(O=0,R=L.length;O<R;++O){U=(this.removeListener(L[O],K,T)&&U);}return U;}}if(!T||!T.call){return this.purgeElement(L,false,K);}if("unload"==K){for(O=0,R=J.length;O<R;O++){V=J[O];if(V&&V[0]==L&&V[1]==K&&V[2]==T){J[O]=null;return true;}}return false;}var P=null;var Q=arguments[3];if("undefined"===typeof Q){Q=this._getCacheIndex(L,K,T);}if(Q>=0){P=I[Q];}if(!L||!P){return false;}if(this.useLegacyEvent(L,K)){var N=this.getLegacyIndex(L,K);var M=E[N];if(M){for(O=0,R=M.length;O<R;++O){V=M[O];if(V&&V[this.EL]==L&&V[this.TYPE]==K&&V[this.FN]==T){M[O]=null;break;}}}}else{try{this._simpleRemove(L,K,P[this.WFN],false);}catch(S){this.lastError=S;return f!
 alse;}}delete I[Q][this.WFN];delete I[Q][this.FN];I[Q]=null;re!
 turn tru
e;},getTarget:function(M,L){var K=M.target||M.srcElement;return this.resolveTextNode(K);},resolveTextNode:function(K){if(K&&3==K.nodeType){return K.parentNode;}else{return K;}},getPageX:function(L){var K=L.pageX;if(!K&&0!==K){K=L.clientX||0;if(this.isIE){K+=this._getScrollLeft();}}return K;},getPageY:function(K){var L=K.pageY;if(!L&&0!==L){L=K.clientY||0;if(this.isIE){L+=this._getScrollTop();}}return L;},getXY:function(K){return[this.getPageX(K),this.getPageY(K)];
-},getRelatedTarget:function(L){var K=L.relatedTarget;if(!K){if(L.type=="mouseout"){K=L.toElement;}else{if(L.type=="mouseover"){K=L.fromElement;}}}return this.resolveTextNode(K);},getTime:function(M){if(!M.time){var L=new Date().getTime();try{M.time=L;}catch(K){this.lastError=K;return L;}}return M.time;},stopEvent:function(K){this.stopPropagation(K);this.preventDefault(K);},stopPropagation:function(K){if(K.stopPropagation){K.stopPropagation();}else{K.cancelBubble=true;}},preventDefault:function(K){if(K.preventDefault){K.preventDefault();}else{K.returnValue=false;}},getEvent:function(M,K){var L=M||window.event;if(!L){var N=this.getEvent.caller;while(N){L=N.arguments[0];if(L&&Event==L.constructor){break;}N=N.caller;}}return L;},getCharCode:function(L){var K=L.keyCode||L.charCode||0;if(YAHOO.env.ua.webkit&&(K in D)){K=D[K];}return K;},_getCacheIndex:function(O,P,N){for(var M=0,L=I.length;M<L;++M){var K=I[M];if(K&&K[this.FN]==N&&K[this.EL]==O&&K[this.TYPE]==P){return M;}}return !
 -1;},generateId:function(K){var L=K.id;if(!L){L="yuievtautoid-"+A;++A;K.id=L;}return L;},_isValidCollection:function(L){try{return(L&&typeof L!=="string"&&L.length&&!L.tagName&&!L.alert&&typeof L[0]!=="undefined");}catch(K){return false;}},elCache:{},getEl:function(K){return(typeof K==="string")?document.getElementById(K):K;},clearCache:function(){},DOMReadyEvent:new YAHOO.util.CustomEvent("DOMReady",this),_load:function(L){if(!H){H=true;var K=YAHOO.util.Event;K._ready();K._tryPreloadAttach();}},_ready:function(L){var K=YAHOO.util.Event;if(!K.DOMReady){K.DOMReady=true;K.DOMReadyEvent.fire();K._simpleRemove(document,"DOMContentLoaded",K._ready);}},_tryPreloadAttach:function(){if(this.locked){return false;}if(this.isIE){if(!this.DOMReady){this.startInterval();return false;}}this.locked=true;var P=!H;if(!P){P=(C>0);}var O=[];var Q=function(S,T){var R=S;if(T.override){if(T.override===true){R=T.obj;}else{R=T.override;}}T.fn.call(R,T.obj);};var L,K,N,M;for(L=0,K=F.length;L<K;++L)!
 {N=F[L];if(N&&!N.checkReady){M=this.getEl(N.id);if(M){Q(M,N);F!
 [L]=null
;}else{O.push(N);}}}for(L=0,K=F.length;L<K;++L){N=F[L];if(N&&N.checkReady){M=this.getEl(N.id);if(M){if(H||M.nextSibling){Q(M,N);F[L]=null;}}else{O.push(N);}}}C=(O.length===0)?0:C-1;if(P){this.startInterval();}else{clearInterval(this._interval);this._interval=null;}this.locked=false;return true;},purgeElement:function(O,P,R){var M=(YAHOO.lang.isString(O))?this.getEl(O):O;var Q=this.getListeners(M,R),N,K;if(Q){for(N=0,K=Q.length;N<K;++N){var L=Q[N];this.removeListener(M,L.type,L.fn,L.index);}}if(P&&M&&M.childNodes){for(N=0,K=M.childNodes.length;N<K;++N){this.purgeElement(M.childNodes[N],P,R);}}},getListeners:function(M,K){var P=[],L;if(!K){L=[I,J];}else{if(K==="unload"){L=[J];}else{L=[I];}}var R=(YAHOO.lang.isString(M))?this.getEl(M):M;for(var O=0;O<L.length;O=O+1){var T=L[O];if(T&&T.length>0){for(var Q=0,S=T.length;Q<S;++Q){var N=T[Q];if(N&&N[this.EL]===R&&(!K||K===N[this.TYPE])){P.push({type:N[this.TYPE],fn:N[this.FN],obj:N[this.OBJ],adjust:N[this.OVERRIDE],scope:N[this.ADJ_!
 SCOPE],index:Q});}}}}return(P.length)?P:null;},_unload:function(R){var Q=YAHOO.util.Event,O,N,L,K,M;for(O=0,K=J.length;O<K;++O){L=J[O];if(L){var P=window;if(L[Q.ADJ_SCOPE]){if(L[Q.ADJ_SCOPE]===true){P=L[Q.UNLOAD_OBJ];}else{P=L[Q.ADJ_SCOPE];}}L[Q.FN].call(P,Q.getEvent(R,L[Q.EL]),L[Q.UNLOAD_OBJ]);J[O]=null;L=null;P=null;}}J=null;if(YAHOO.env.ua.ie&&I&&I.length>0){N=I.length;while(N){M=N-1;L=I[M];if(L){Q.removeListener(L[Q.EL],L[Q.TYPE],L[Q.FN],M);}N--;}L=null;}G=null;Q._simpleRemove(window,"unload",Q._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var K=document.documentElement,L=document.body;if(K&&(K.scrollTop||K.scrollLeft)){return[K.scrollTop,K.scrollLeft];}else{if(L){return[L.scrollTop,L.scrollLeft];}else{return[0,0];}}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(M,N,L,K){M.addEventListener(N,L,(K));};}else{if(window.attachEvent){retur!
 n function(M,N,L,K){M.attachEvent("on"+N,L);};}else{return fun!
 ction(){
};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(M,N,L,K){M.removeEventListener(N,L,(K));};}else{if(window.detachEvent){return function(L,M,K){L.detachEvent("on"+M,K);};}else{return function(){};}}}()};}();(function(){var A=YAHOO.util.Event;A.on=A.addListener;if(A.isIE){YAHOO.util.Event.onDOMReady(YAHOO.util.Event._tryPreloadAttach,YAHOO.util.Event,true);A._dri=setInterval(function(){var C=document.createElement("p");try{C.doScroll("left");clearInterval(A._dri);A._dri=null;A._ready();C=null;}catch(B){C=null;}},A.POLL_INTERVAL);}else{if(A.webkit){A._dri=setInterval(function(){var B=document.readyState;if("loaded"==B||"complete"==B){clearInterval(A._dri);A._dri=null;A._ready();}},A.POLL_INTERVAL);}else{A._simpleAdd(document,"DOMContentLoaded",A._ready);}}A._simpleAdd(window,"load",A._load);A._simpleAdd(window,"unload",A._unload);A._tryPreloadAttach();})();}YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null!
 ,__yui_subscribers:null,subscribe:function(A,C,F,E){this.__yui_events=this.__yui_events||{};var D=this.__yui_events[A];if(D){D.subscribe(C,F,E);}else{this.__yui_subscribers=this.__yui_subscribers||{};var B=this.__yui_subscribers;if(!B[A]){B[A]=[];}B[A].push({fn:C,obj:F,override:E});}},unsubscribe:function(C,E,G){this.__yui_events=this.__yui_events||{};var A=this.__yui_events;if(C){var F=A[C];if(F){return F.unsubscribe(E,G);}}else{var B=true;for(var D in A){if(YAHOO.lang.hasOwnProperty(A,D)){B=B&&A[D].unsubscribe(E,G);}}return B;}return false;},unsubscribeAll:function(A){return this.unsubscribe(A);},createEvent:function(G,D){this.__yui_events=this.__yui_events||{};var A=D||{};var I=this.__yui_events;if(I[G]){}else{var H=A.scope||this;var E=(A.silent);var B=new YAHOO.util.CustomEvent(G,H,E,YAHOO.util.CustomEvent.FLAT);I[G]=B;if(A.onSubscribeCallback){B.subscribeEvent.subscribe(A.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};
-var F=this.__yui_subscribers[G];if(F){for(var C=0;C<F.length;++C){B.subscribe(F[C].fn,F[C].obj,F[C].override);}}}return I[G];},fireEvent:function(E,D,A,C){this.__yui_events=this.__yui_events||{};var G=this.__yui_events[E];if(!G){return null;}var B=[];for(var F=1;F<arguments.length;++F){B.push(arguments[F]);}return G.fire.apply(G,B);},hasEvent:function(A){if(this.__yui_events){if(this.__yui_events[A]){return true;}}return false;}};YAHOO.util.KeyListener=function(A,F,B,C){if(!A){}else{if(!F){}else{if(!B){}}}if(!C){C=YAHOO.util.KeyListener.KEYDOWN;}var D=new YAHOO.util.CustomEvent("keyPressed");this.enabledEvent=new YAHOO.util.CustomEvent("enabled");this.disabledEvent=new YAHOO.util.CustomEvent("disabled");if(typeof A=="string"){A=document.getElementById(A);}if(typeof B=="function"){D.subscribe(B);}else{D.subscribe(B.fn,B.scope,B.correctScope);}function E(J,I){if(!F.shift){F.shift=false;}if(!F.alt){F.alt=false;}if(!F.ctrl){F.ctrl=false;}if(J.shiftKey==F.shift&&J.altKey==F.alt&!
 &J.ctrlKey==F.ctrl){var G;if(F.keys instanceof Array){for(var H=0;H<F.keys.length;H++){G=F.keys[H];if(G==J.charCode){D.fire(J.charCode,J);break;}else{if(G==J.keyCode){D.fire(J.keyCode,J);break;}}}}else{G=F.keys;if(G==J.charCode){D.fire(J.charCode,J);}else{if(G==J.keyCode){D.fire(J.keyCode,J);}}}}}this.enable=function(){if(!this.enabled){YAHOO.util.Event.addListener(A,C,E);this.enabledEvent.fire(F);}this.enabled=true;};this.disable=function(){if(this.enabled){YAHOO.util.Event.removeListener(A,C,E);this.disabledEvent.fire(F);}this.enabled=false;};this.toString=function(){return"KeyListener ["+F.keys+"] "+A.tagName+(A.id?"["+A.id+"]":"");};};YAHOO.util.KeyListener.KEYDOWN="keydown";YAHOO.util.KeyListener.KEYUP="keyup";YAHOO.util.KeyListener.KEY={ALT:18,BACK_SPACE:8,CAPS_LOCK:20,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,META:224,NUM_LOCK:144,PAGE_DOWN:34,PAGE_UP:33,PAUSE:19,PRINTSCREEN:44,RIGHT:39,SCROLL_LOCK:145,SHIFT:16,SPACE:32,TAB:9,UP:38};YAHOO!
 .register("event",YAHOO.util.Event,{version:"2.4.1",build:"742!
 "});YAHO
O.register("yahoo-dom-event", YAHOO, {version: "2.4.1", build: "742"});
+if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var A=arguments,E=null,C,B,D;for(C=0;C<A.length;C=C+1){D=A[C].split(".");E=YAHOO;for(B=(D[0]=="YAHOO")?1:0;B<D.length;B=B+1){E[D[B]]=E[D[B]]||{};E=E[D[B]];}}return E;};YAHOO.log=function(D,A,C){var B=YAHOO.widget.Logger;if(B&&B.log){return B.log(D,A,C);}else{return false;}};YAHOO.register=function(A,E,D){var I=YAHOO.env.modules;if(!I[A]){I[A]={versions:[],builds:[]};}var B=I[A],H=D.version,G=D.build,F=YAHOO.env.listeners;B.name=A;B.version=H;B.build=G;B.versions.push(H);B.builds.push(G);B.mainClass=E;for(var C=0;C<F.length;C=C+1){F[C](B);}if(E){E.VERSION=H;E.BUILD=G;}else{YAHOO.log("mainClass is undefined for module "+A,"warn");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[]};YAHOO.env.getVersion=function(A){return YAHOO.env.modules[A]||null;};YAHOO.env.ua=function(){var C={ie:0,opera:0,gecko:0,webkit:0,mobile:null,air:0};var B=navigator.userAgent,A;if((/KHTML/).test(B)){C.webkit=1;}A=B.match(/A!
 ppleWebKit\/([^\s]*)/);if(A&&A[1]){C.webkit=parseFloat(A[1]);if(/ Mobile\//.test(B)){C.mobile="Apple";}else{A=B.match(/NokiaN[^\/]*/);if(A){C.mobile=A[0];}}A=B.match(/AdobeAIR\/([^\s]*)/);if(A){C.air=A[0];}}if(!C.webkit){A=B.match(/Opera[\s\/]([^\s]*)/);if(A&&A[1]){C.opera=parseFloat(A[1]);A=B.match(/Opera Mini[^;]*/);if(A){C.mobile=A[0];}}else{A=B.match(/MSIE\s([^;]*)/);if(A&&A[1]){C.ie=parseFloat(A[1]);}else{A=B.match(/Gecko\/([^\s]*)/);if(A){C.gecko=1;A=B.match(/rv:([^\s\)]*)/);if(A&&A[1]){C.gecko=parseFloat(A[1]);}}}}}return C;}();(function(){YAHOO.namespace("util","widget","example");if("undefined"!==typeof YAHOO_config){var B=YAHOO_config.listener,A=YAHOO.env.listeners,D=true,C;if(B){for(C=0;C<A.length;C=C+1){if(A[C]==B){D=false;break;}}if(D){A.push(B);}}}})();YAHOO.lang=YAHOO.lang||{isArray:function(B){if(B){var A=YAHOO.lang;return A.isNumber(B.length)&&A.isFunction(B.splice);}return false;},isBoolean:function(A){return typeof A==="boolean";},isFunction:function(A){r!
 eturn typeof A==="function";},isNull:function(A){return A===nu!
 ll;},isN
umber:function(A){return typeof A==="number"&&isFinite(A);},isObject:function(A){return(A&&(typeof A==="object"||YAHOO.lang.isFunction(A)))||false;},isString:function(A){return typeof A==="string";},isUndefined:function(A){return typeof A==="undefined";},hasOwnProperty:function(A,B){if(Object.prototype.hasOwnProperty){return A.hasOwnProperty(B);}return !YAHOO.lang.isUndefined(A[B])&&A.constructor.prototype[B]!==A[B];},_IEEnumFix:function(C,B){if(YAHOO.env.ua.ie){var E=["toString","valueOf"],A;for(A=0;A<E.length;A=A+1){var F=E[A],D=B[F];if(YAHOO.lang.isFunction(D)&&D!=Object.prototype[F]){C[F]=D;}}}},extend:function(D,E,C){if(!E||!D){throw new Error("YAHOO.lang.extend failed, please check that "+"all dependencies are included.");}var B=function(){};B.prototype=E.prototype;D.prototype=new B();D.prototype.constructor=D;D.superclass=E.prototype;if(E.prototype.constructor==Object.prototype.constructor){E.prototype.constructor=E;}if(C){for(var A in C){D.prototype[A]=C[A];}YAHOO.la!
 ng._IEEnumFix(D.prototype,C);}},augmentObject:function(E,D){if(!D||!E){throw new Error("Absorb failed, verify dependencies.");}var A=arguments,C,F,B=A[2];if(B&&B!==true){for(C=2;C<A.length;C=C+1){E[A[C]]=D[A[C]];}}else{for(F in D){if(B||!E[F]){E[F]=D[F];}}YAHOO.lang._IEEnumFix(E,D);}},augmentProto:function(D,C){if(!C||!D){throw new Error("Augment failed, verify dependencies.");}var A=[D.prototype,C.prototype];for(var B=2;B<arguments.length;B=B+1){A.push(arguments[B]);}YAHOO.lang.augmentObject.apply(this,A);},dump:function(A,G){var C=YAHOO.lang,D,F,I=[],J="{...}",B="f(){...}",H=", ",E=" => ";if(!C.isObject(A)){return A+"";}else{if(A instanceof Date||("nodeType" in A&&"tagName" in A)){return A;}else{if(C.isFunction(A)){return B;}}}G=(C.isNumber(G))?G:3;if(C.isArray(A)){I.push("[");for(D=0,F=A.length;D<F;D=D+1){if(C.isObject(A[D])){I.push((G>0)?C.dump(A[D],G-1):J);}else{I.push(A[D]);}I.push(H);}if(I.length>1){I.pop();}I.push("]");}else{I.push("{");for(D in A){if(C.hasOwnProper!
 ty(A,D)){I.push(D+E);if(C.isObject(A[D])){I.push((G>0)?C.dump(!
 A[D],G-1
):J);}else{I.push(A[D]);}I.push(H);}}if(I.length>1){I.pop();}I.push("}");}return I.join("");},substitute:function(Q,B,J){var G,F,E,M,N,P,D=YAHOO.lang,L=[],C,H="dump",K=" ",A="{",O="}";for(;;){G=Q.lastIndexOf(A);if(G<0){break;}F=Q.indexOf(O,G);if(G+1>=F){break;}C=Q.substring(G+1,F);M=C;P=null;E=M.indexOf(K);if(E>-1){P=M.substring(E+1);M=M.substring(0,E);}N=B[M];if(J){N=J(M,N,P);}if(D.isObject(N)){if(D.isArray(N)){N=D.dump(N,parseInt(P,10));}else{P=P||"";var I=P.indexOf(H);if(I>-1){P=P.substring(4);}if(N.toString===Object.prototype.toString||I>-1){N=D.dump(N,parseInt(P,10));}else{N=N.toString();}}}else{if(!D.isString(N)&&!D.isNumber(N)){N="~-"+L.length+"-~";L[L.length]=C;}}Q=Q.substring(0,G)+N+Q.substring(F+1);}for(G=L.length-1;G>=0;G=G-1){Q=Q.replace(new RegExp("~-"+G+"-~"),"{"+L[G]+"}","g");}return Q;},trim:function(A){try{return A.replace(/^\s+|\s+$/g,"");}catch(B){return A;}},merge:function(){var D={},B=arguments;for(var C=0,A=B.length;C<A;C=C+1){YAHOO.lang.augmentObject(D!
 ,B[C],true);}return D;},later:function(H,B,I,D,E){H=H||0;B=B||{};var C=I,G=D,F,A;if(YAHOO.lang.isString(I)){C=B[I];}if(!C){throw new TypeError("method undefined");}if(!YAHOO.lang.isArray(G)){G=[D];}F=function(){C.apply(B,G);};A=(E)?setInterval(F,H):setTimeout(F,H);return{interval:E,cancel:function(){if(this.interval){clearInterval(A);}else{clearTimeout(A);}}};},isValue:function(B){var A=YAHOO.lang;return(A.isObject(B)||A.isString(B)||A.isNumber(B)||A.isBoolean(B));}};YAHOO.util.Lang=YAHOO.lang;YAHOO.lang.augment=YAHOO.lang.augmentProto;YAHOO.augment=YAHOO.lang.augmentProto;YAHOO.extend=YAHOO.lang.extend;YAHOO.register("yahoo",YAHOO,{version:"2.5.1",build:"984"});(function(){var B=YAHOO.util,K,I,J={},F={},M=window.document;YAHOO.env._id_counter=YAHOO.env._id_counter||0;var C=YAHOO.env.ua.opera,L=YAHOO.env.ua.webkit,A=YAHOO.env.ua.gecko,G=YAHOO.env.ua.ie;var E={HYPHEN:/(-[a-z])/i,ROOT_TAG:/^body|html$/i,OP_SCROLL:/^(?:inline|table-row)$/i};var N=function(P){if(!E.HYPHEN.test(!
 P)){return P;}if(J[P]){return J[P];}var Q=P;while(E.HYPHEN.exe!
 c(Q)){Q=
Q.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());}J[P]=Q;return Q;};var O=function(Q){var P=F[Q];if(!P){P=new RegExp("(?:^|\\s+)"+Q+"(?:\\s+|$)");F[Q]=P;}return P;};if(M.defaultView&&M.defaultView.getComputedStyle){K=function(P,S){var R=null;if(S=="float"){S="cssFloat";}var Q=P.ownerDocument.defaultView.getComputedStyle(P,"");if(Q){R=Q[N(S)];}return P.style[S]||R;};}else{if(M.documentElement.currentStyle&&G){K=function(P,R){switch(N(R)){case"opacity":var T=100;try{T=P.filters["DXImageTransform.Microsoft.Alpha"].opacity;}catch(S){try{T=P.filters("alpha").opacity;}catch(S){}}return T/100;case"float":R="styleFloat";default:var Q=P.currentStyle?P.currentStyle[R]:null;return(P.style[R]||Q);}};}else{K=function(P,Q){return P.style[Q];};}}if(G){I=function(P,Q,R){switch(Q){case"opacity":if(YAHOO.lang.isString(P.style.filter)){P.style.filter="alpha(opacity="+R*100+")";if(!P.currentStyle||!P.currentStyle.hasLayout){P.style.zoom=1;}}break;case"float":Q="styleFloat";default:P.style!
 [Q]=R;}};}else{I=function(P,Q,R){if(Q=="float"){Q="cssFloat";}P.style[Q]=R;};}var D=function(P,Q){return P&&P.nodeType==1&&(!Q||Q(P));};YAHOO.util.Dom={get:function(R){if(R&&(R.nodeType||R.item)){return R;}if(YAHOO.lang.isString(R)||!R){return M.getElementById(R);}if(R.length!==undefined){var S=[];for(var Q=0,P=R.length;Q<P;++Q){S[S.length]=B.Dom.get(R[Q]);}return S;}return R;},getStyle:function(P,R){R=N(R);var Q=function(S){return K(S,R);};return B.Dom.batch(P,Q,B.Dom,true);},setStyle:function(P,R,S){R=N(R);var Q=function(T){I(T,R,S);};B.Dom.batch(P,Q,B.Dom,true);},getXY:function(P){var Q=function(R){if((R.parentNode===null||R.offsetParent===null||this.getStyle(R,"display")=="none")&&R!=R.ownerDocument.body){return false;}return H(R);};return B.Dom.batch(P,Q,B.Dom,true);},getX:function(P){var Q=function(R){return B.Dom.getXY(R)[0];};return B.Dom.batch(P,Q,B.Dom,true);},getY:function(P){var Q=function(R){return B.Dom.getXY(R)[1];};return B.Dom.batch(P,Q,B.Dom,true);},setXY:!
 function(P,S,R){var Q=function(V){var U=this.getStyle(V,"posit!
 ion");if
(U=="static"){this.setStyle(V,"position","relative");U="relative";}var X=this.getXY(V);if(X===false){return false;}var W=[parseInt(this.getStyle(V,"left"),10),parseInt(this.getStyle(V,"top"),10)];if(isNaN(W[0])){W[0]=(U=="relative")?0:V.offsetLeft;}if(isNaN(W[1])){W[1]=(U=="relative")?0:V.offsetTop;}if(S[0]!==null){V.style.left=S[0]-X[0]+W[0]+"px";}if(S[1]!==null){V.style.top=S[1]-X[1]+W[1]+"px";}if(!R){var T=this.getXY(V);if((S[0]!==null&&T[0]!=S[0])||(S[1]!==null&&T[1]!=S[1])){this.setXY(V,S,true);}}};B.Dom.batch(P,Q,B.Dom,true);},setX:function(Q,P){B.Dom.setXY(Q,[P,null]);},setY:function(P,Q){B.Dom.setXY(P,[null,Q]);},getRegion:function(P){var Q=function(R){if((R.parentNode===null||R.offsetParent===null||this.getStyle(R,"display")=="none")&&R!=R.ownerDocument.body){return false;}var S=B.Region.getRegion(R);return S;};return B.Dom.batch(P,Q,B.Dom,true);},getClientWidth:function(){return B.Dom.getViewportWidth();},getClientHeight:function(){return B.Dom.getViewportHeight();!
 },getElementsByClassName:function(T,X,U,V){X=X||"*";U=(U)?B.Dom.get(U):null||M;if(!U){return[];}var Q=[],P=U.getElementsByTagName(X),W=O(T);for(var R=0,S=P.length;R<S;++R){if(W.test(P[R].className)){Q[Q.length]=P[R];if(V){V.call(P[R],P[R]);}}}return Q;},hasClass:function(R,Q){var P=O(Q);var S=function(T){return P.test(T.className);};return B.Dom.batch(R,S,B.Dom,true);},addClass:function(Q,P){var R=function(S){if(this.hasClass(S,P)){return false;}S.className=YAHOO.lang.trim([S.className,P].join(" "));return true;};return B.Dom.batch(Q,R,B.Dom,true);},removeClass:function(R,Q){var P=O(Q);var S=function(T){if(!Q||!this.hasClass(T,Q)){return false;}var U=T.className;T.className=U.replace(P," ");if(this.hasClass(T,Q)){this.removeClass(T,Q);}T.className=YAHOO.lang.trim(T.className);return true;};return B.Dom.batch(R,S,B.Dom,true);},replaceClass:function(S,Q,P){if(!P||Q===P){return false;}var R=O(Q);var T=function(U){if(!this.hasClass(U,Q)){this.addClass(U,P);return true;}U.classN!
 ame=U.className.replace(R," "+P+" ");if(this.hasClass(U,Q)){th!
 is.repla
ceClass(U,Q,P);}U.className=YAHOO.lang.trim(U.className);return true;};return B.Dom.batch(S,T,B.Dom,true);},generateId:function(P,R){R=R||"yui-gen";var Q=function(S){if(S&&S.id){return S.id;}var T=R+YAHOO.env._id_counter++;if(S){S.id=T;}return T;};return B.Dom.batch(P,Q,B.Dom,true)||Q.apply(B.Dom,arguments);},isAncestor:function(P,Q){P=B.Dom.get(P);Q=B.Dom.get(Q);if(!P||!Q){return false;}if(P.contains&&Q.nodeType&&!L){return P.contains(Q);}else{if(P.compareDocumentPosition&&Q.nodeType){return !!(P.compareDocumentPosition(Q)&16);}else{if(Q.nodeType){return !!this.getAncestorBy(Q,function(R){return R==P;});}}}return false;},inDocument:function(P){return this.isAncestor(M.documentElement,P);},getElementsBy:function(W,Q,R,T){Q=Q||"*";R=(R)?B.Dom.get(R):null||M;if(!R){return[];}var S=[],V=R.getElementsByTagName(Q);for(var U=0,P=V.length;U<P;++U){if(W(V[U])){S[S.length]=V[U];if(T){T(V[U]);}}}return S;},batch:function(T,W,V,R){T=(T&&(T.tagName||T.item))?T:B.Dom.get(T);if(!T||!W){re!
 turn false;}var S=(R)?V:window;if(T.tagName||T.length===undefined){return W.call(S,T,V);}var U=[];for(var Q=0,P=T.length;Q<P;++Q){U[U.length]=W.call(S,T[Q],V);}return U;},getDocumentHeight:function(){var Q=(M.compatMode!="CSS1Compat")?M.body.scrollHeight:M.documentElement.scrollHeight;var P=Math.max(Q,B.Dom.getViewportHeight());return P;},getDocumentWidth:function(){var Q=(M.compatMode!="CSS1Compat")?M.body.scrollWidth:M.documentElement.scrollWidth;var P=Math.max(Q,B.Dom.getViewportWidth());return P;},getViewportHeight:function(){var P=self.innerHeight;
+var Q=M.compatMode;if((Q||G)&&!C){P=(Q=="CSS1Compat")?M.documentElement.clientHeight:M.body.clientHeight;}return P;},getViewportWidth:function(){var P=self.innerWidth;var Q=M.compatMode;if(Q||G){P=(Q=="CSS1Compat")?M.documentElement.clientWidth:M.body.clientWidth;}return P;},getAncestorBy:function(P,Q){while(P=P.parentNode){if(D(P,Q)){return P;}}return null;},getAncestorByClassName:function(Q,P){Q=B.Dom.get(Q);if(!Q){return null;}var R=function(S){return B.Dom.hasClass(S,P);};return B.Dom.getAncestorBy(Q,R);},getAncestorByTagName:function(Q,P){Q=B.Dom.get(Q);if(!Q){return null;}var R=function(S){return S.tagName&&S.tagName.toUpperCase()==P.toUpperCase();};return B.Dom.getAncestorBy(Q,R);},getPreviousSiblingBy:function(P,Q){while(P){P=P.previousSibling;if(D(P,Q)){return P;}}return null;},getPreviousSibling:function(P){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getPreviousSiblingBy(P);},getNextSiblingBy:function(P,Q){while(P){P=P.nextSibling;if(D(P,Q)){return P;}}return !
 null;},getNextSibling:function(P){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getNextSiblingBy(P);},getFirstChildBy:function(P,R){var Q=(D(P.firstChild,R))?P.firstChild:null;return Q||B.Dom.getNextSiblingBy(P.firstChild,R);},getFirstChild:function(P,Q){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getFirstChildBy(P);},getLastChildBy:function(P,R){if(!P){return null;}var Q=(D(P.lastChild,R))?P.lastChild:null;return Q||B.Dom.getPreviousSiblingBy(P.lastChild,R);},getLastChild:function(P){P=B.Dom.get(P);return B.Dom.getLastChildBy(P);},getChildrenBy:function(Q,S){var R=B.Dom.getFirstChildBy(Q,S);var P=R?[R]:[];B.Dom.getNextSiblingBy(R,function(T){if(!S||S(T)){P[P.length]=T;}return false;});return P;},getChildren:function(P){P=B.Dom.get(P);if(!P){}return B.Dom.getChildrenBy(P);},getDocumentScrollLeft:function(P){P=P||M;return Math.max(P.documentElement.scrollLeft,P.body.scrollLeft);},getDocumentScrollTop:function(P){P=P||M;return Math.max(P.documentElement.scrollTop,P.body!
 .scrollTop);},insertBefore:function(Q,P){Q=B.Dom.get(Q);P=B.Do!
 m.get(P)
;if(!Q||!P||!P.parentNode){return null;}return P.parentNode.insertBefore(Q,P);},insertAfter:function(Q,P){Q=B.Dom.get(Q);P=B.Dom.get(P);if(!Q||!P||!P.parentNode){return null;}if(P.nextSibling){return P.parentNode.insertBefore(Q,P.nextSibling);}else{return P.parentNode.appendChild(Q);}},getClientRegion:function(){var R=B.Dom.getDocumentScrollTop(),Q=B.Dom.getDocumentScrollLeft(),S=B.Dom.getViewportWidth()+Q,P=B.Dom.getViewportHeight()+R;return new B.Region(R,S,P,Q);}};var H=function(){if(M.documentElement.getBoundingClientRect){return function(Q){var R=Q.getBoundingClientRect();var P=Q.ownerDocument;return[R.left+B.Dom.getDocumentScrollLeft(P),R.top+B.Dom.getDocumentScrollTop(P)];};}else{return function(R){var S=[R.offsetLeft,R.offsetTop];var Q=R.offsetParent;var P=(L&&B.Dom.getStyle(R,"position")=="absolute"&&R.offsetParent==R.ownerDocument.body);if(Q!=R){while(Q){S[0]+=Q.offsetLeft;S[1]+=Q.offsetTop;if(!P&&L&&B.Dom.getStyle(Q,"position")=="absolute"){P=true;}Q=Q.offsetParen!
 t;}}if(P){S[0]-=R.ownerDocument.body.offsetLeft;S[1]-=R.ownerDocument.body.offsetTop;}Q=R.parentNode;while(Q.tagName&&!E.ROOT_TAG.test(Q.tagName)){if(Q.scrollTop||Q.scrollLeft){if(!E.OP_SCROLL.test(B.Dom.getStyle(Q,"display"))){if(!C||B.Dom.getStyle(Q,"overflow")!=="visible"){S[0]-=Q.scrollLeft;S[1]-=Q.scrollTop;}}}Q=Q.parentNode;}return S;};}}();})();YAHOO.util.Region=function(C,D,A,B){this.top=C;this[1]=C;this.right=D;this.bottom=A;this.left=B;this[0]=B;};YAHOO.util.Region.prototype.contains=function(A){return(A.left>=this.left&&A.right<=this.right&&A.top>=this.top&&A.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(E){var C=Math.max(this.top,E.top);var D=Math.min(this.right,E.right);var A=Math.min(this.bottom,E.bottom);var B=Math.max(this.left,E.left);if(A>=C&&D>=B){return new YAHOO.util.Region(C,D,A,B);}else{return null;}};YAHOO.util.Region.prototy!
 pe.union=function(E){var C=Math.min(this.top,E.top);var D=Math!
 .max(thi
s.right,E.right);var A=Math.max(this.bottom,E.bottom);var B=Math.min(this.left,E.left);return new YAHOO.util.Region(C,D,A,B);};YAHOO.util.Region.prototype.toString=function(){return("Region {"+"top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+"}");};YAHOO.util.Region.getRegion=function(D){var F=YAHOO.util.Dom.getXY(D);var C=F[1];var E=F[0]+D.offsetWidth;var A=F[1]+D.offsetHeight;var B=F[0];return new YAHOO.util.Region(C,E,A,B);};YAHOO.util.Point=function(A,B){if(YAHOO.lang.isArray(A)){B=A[1];A=A[0];}this.x=this.right=this.left=this[0]=A;this.y=this.top=this.bottom=this[1]=B;};YAHOO.util.Point.prototype=new YAHOO.util.Region();YAHOO.register("dom",YAHOO.util.Dom,{version:"2.5.1",build:"984"});YAHOO.util.CustomEvent=function(D,B,C,A){this.type=D;this.scope=B||window;this.silent=C;this.signature=A||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){}var E="_YUICEOnSubscribe";if(D!==E){this.subscribeEvent=new YAHOO.util.CustomEve!
 nt(E,this,true);}this.lastError=null;};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(B,C,A){if(!B){throw new Error("Invalid callback for subscriber to '"+this.type+"'");}if(this.subscribeEvent){this.subscribeEvent.fire(B,C,A);}this.subscribers.push(new YAHOO.util.Subscriber(B,C,A));},unsubscribe:function(D,F){if(!D){return this.unsubscribeAll();}var E=false;for(var B=0,A=this.subscribers.length;B<A;++B){var C=this.subscribers[B];if(C&&C.contains(D,F)){this._delete(B);E=true;}}return E;},fire:function(){var D=this.subscribers.length;if(!D&&this.silent){return true;}var H=[].slice.call(arguments,0),F=true,C,I=false;if(!this.silent){}var B=this.subscribers.slice();for(C=0;C<D;++C){var K=B[C];if(!K){I=true;}else{if(!this.silent){}var J=K.getScope(this.scope);if(this.signature==YAHOO.util.CustomEvent.FLAT){var A=null;if(H.length>0){A=H[0];}try{F=K.fn.call(J,A,K.obj);}catch(E){this.lastError=E;}}else{try{F=K.fn.ca!
 ll(J,this.type,H,K.obj);}catch(G){this.lastError=G;}}if(false=!
 ==F){if(
!this.silent){}return false;}}}return true;},unsubscribeAll:function(){for(var A=this.subscribers.length-1;A>-1;A--){this._delete(A);}this.subscribers=[];return A;},_delete:function(A){var B=this.subscribers[A];if(B){delete B.fn;delete B.obj;}this.subscribers.splice(A,1);},toString:function(){return"CustomEvent: "+"'"+this.type+"', "+"scope: "+this.scope;}};YAHOO.util.Subscriber=function(B,C,A){this.fn=B;this.obj=YAHOO.lang.isUndefined(C)?null:C;this.override=A;};YAHOO.util.Subscriber.prototype.getScope=function(A){if(this.override){if(this.override===true){return this.obj;}else{return this.override;}}return A;};YAHOO.util.Subscriber.prototype.contains=function(A,B){if(B){return(this.fn==A&&this.obj==B);}else{return(this.fn==A);}};YAHOO.util.Subscriber.prototype.toString=function(){return"Subscriber { obj: "+this.obj+", override: "+(this.override||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var H=false;var I=[];var J=[];var G=[];var E=[];var C=0;var F=[];v!
 ar B=[];var A=0;var D={63232:38,63233:40,63234:37,63235:39,63276:33,63277:34,25:9};return{POLL_RETRYS:2000,POLL_INTERVAL:20,EL:0,TYPE:1,FN:2,WFN:3,UNLOAD_OBJ:3,ADJ_SCOPE:4,OBJ:5,OVERRIDE:6,lastError:null,isSafari:YAHOO.env.ua.webkit,webkit:YAHOO.env.ua.webkit,isIE:YAHOO.env.ua.ie,_interval:null,_dri:null,DOMReady:false,startInterval:function(){if(!this._interval){var K=this;var L=function(){K._tryPreloadAttach();};this._interval=setInterval(L,this.POLL_INTERVAL);}},onAvailable:function(P,M,Q,O,N){var K=(YAHOO.lang.isString(P))?[P]:P;for(var L=0;L<K.length;L=L+1){F.push({id:K[L],fn:M,obj:Q,override:O,checkReady:N});}C=this.POLL_RETRYS;this.startInterval();},onContentReady:function(M,K,N,L){this.onAvailable(M,K,N,L,true);},onDOMReady:function(K,M,L){if(this.DOMReady){setTimeout(function(){var N=window;if(L){if(L===true){N=M;}else{N=L;}}K.call(N,"DOMReady",[],M);},0);}else{this.DOMReadyEvent.subscribe(K,M,L);}},addListener:function(M,K,V,Q,L){if(!V||!V.call){return false;}if(t!
 his._isValidCollection(M)){var W=true;for(var R=0,T=M.length;R!
 <T;++R){
W=this.on(M[R],K,V,Q,L)&&W;}return W;}else{if(YAHOO.lang.isString(M)){var P=this.getEl(M);if(P){M=P;}else{this.onAvailable(M,function(){YAHOO.util.Event.on(M,K,V,Q,L);});return true;}}}if(!M){return false;}if("unload"==K&&Q!==this){J[J.length]=[M,K,V,Q,L];return true;}var Y=M;if(L){if(L===true){Y=Q;}else{Y=L;}}var N=function(Z){return V.call(Y,YAHOO.util.Event.getEvent(Z,M),Q);};var X=[M,K,V,N,Y,Q,L];var S=I.length;I[S]=X;if(this.useLegacyEvent(M,K)){var O=this.getLegacyIndex(M,K);if(O==-1||M!=G[O][0]){O=G.length;B[M.id+K]=O;G[O]=[M,K,M["on"+K]];E[O]=[];M["on"+K]=function(Z){YAHOO.util.Event.fireLegacyEvent(YAHOO.util.Event.getEvent(Z),O);};}E[O].push(X);}else{try{this._simpleAdd(M,K,N,false);}catch(U){this.lastError=U;this.removeListener(M,K,V);return false;}}return true;},fireLegacyEvent:function(O,M){var Q=true,K,S,R,T,P;S=E[M].slice();for(var L=0,N=S.length;L<N;++L){R=S[L];if(R&&R[this.WFN]){T=R[this.ADJ_SCOPE];P=R[this.WFN].call(T,O);Q=(Q&&P);}}K=G[M];if(K&&K[2]){K[2](O!
 );}return Q;},getLegacyIndex:function(L,M){var K=this.generateId(L)+M;if(typeof B[K]=="undefined"){return -1;}else{return B[K];}},useLegacyEvent:function(L,M){if(this.webkit&&("click"==M||"dblclick"==M)){var K=parseInt(this.webkit,10);if(!isNaN(K)&&K<418){return true;}}return false;},removeListener:function(L,K,T){var O,R,V;if(typeof L=="string"){L=this.getEl(L);}else{if(this._isValidCollection(L)){var U=true;for(O=L.length-1;O>-1;O--){U=(this.removeListener(L[O],K,T)&&U);}return U;}}if(!T||!T.call){return this.purgeElement(L,false,K);}if("unload"==K){for(O=J.length-1;O>-1;O--){V=J[O];if(V&&V[0]==L&&V[1]==K&&V[2]==T){J.splice(O,1);return true;}}return false;}var P=null;var Q=arguments[3];if("undefined"===typeof Q){Q=this._getCacheIndex(L,K,T);}if(Q>=0){P=I[Q];}if(!L||!P){return false;}if(this.useLegacyEvent(L,K)){var N=this.getLegacyIndex(L,K);var M=E[N];if(M){for(O=0,R=M.length;O<R;++O){V=M[O];if(V&&V[this.EL]==L&&V[this.TYPE]==K&&V[this.FN]==T){M.splice(O,1);break;}}}}els!
 e{try{this._simpleRemove(L,K,P[this.WFN],false);}catch(S){this!
 .lastErr
or=S;return false;}}delete I[Q][this.WFN];delete I[Q][this.FN];I.splice(Q,1);return true;},getTarget:function(M,L){var K=M.target||M.srcElement;return this.resolveTextNode(K);},resolveTextNode:function(L){try{if(L&&3==L.nodeType){return L.parentNode;}}catch(K){}return L;},getPageX:function(L){var K=L.pageX;if(!K&&0!==K){K=L.clientX||0;if(this.isIE){K+=this._getScrollLeft();}}return K;},getPageY:function(K){var L=K.pageY;if(!L&&0!==L){L=K.clientY||0;if(this.isIE){L+=this._getScrollTop();}}return L;},getXY:function(K){return[this.getPageX(K),this.getPageY(K)];},getRelatedTarget:function(L){var K=L.relatedTarget;
+if(!K){if(L.type=="mouseout"){K=L.toElement;}else{if(L.type=="mouseover"){K=L.fromElement;}}}return this.resolveTextNode(K);},getTime:function(M){if(!M.time){var L=new Date().getTime();try{M.time=L;}catch(K){this.lastError=K;return L;}}return M.time;},stopEvent:function(K){this.stopPropagation(K);this.preventDefault(K);},stopPropagation:function(K){if(K.stopPropagation){K.stopPropagation();}else{K.cancelBubble=true;}},preventDefault:function(K){if(K.preventDefault){K.preventDefault();}else{K.returnValue=false;}},getEvent:function(M,K){var L=M||window.event;if(!L){var N=this.getEvent.caller;while(N){L=N.arguments[0];if(L&&Event==L.constructor){break;}N=N.caller;}}return L;},getCharCode:function(L){var K=L.keyCode||L.charCode||0;if(YAHOO.env.ua.webkit&&(K in D)){K=D[K];}return K;},_getCacheIndex:function(O,P,N){for(var M=0,L=I.length;M<L;M=M+1){var K=I[M];if(K&&K[this.FN]==N&&K[this.EL]==O&&K[this.TYPE]==P){return M;}}return -1;},generateId:function(K){var L=K.id;if(!L){L="yu!
 ievtautoid-"+A;++A;K.id=L;}return L;},_isValidCollection:function(L){try{return(L&&typeof L!=="string"&&L.length&&!L.tagName&&!L.alert&&typeof L[0]!=="undefined");}catch(K){return false;}},elCache:{},getEl:function(K){return(typeof K==="string")?document.getElementById(K):K;},clearCache:function(){},DOMReadyEvent:new YAHOO.util.CustomEvent("DOMReady",this),_load:function(L){if(!H){H=true;var K=YAHOO.util.Event;K._ready();K._tryPreloadAttach();}},_ready:function(L){var K=YAHOO.util.Event;if(!K.DOMReady){K.DOMReady=true;K.DOMReadyEvent.fire();K._simpleRemove(document,"DOMContentLoaded",K._ready);}},_tryPreloadAttach:function(){if(F.length===0){C=0;clearInterval(this._interval);this._interval=null;return ;}if(this.locked){return ;}if(this.isIE){if(!this.DOMReady){this.startInterval();return ;}}this.locked=true;var Q=!H;if(!Q){Q=(C>0&&F.length>0);}var P=[];var R=function(T,U){var S=T;if(U.override){if(U.override===true){S=U.obj;}else{S=U.override;}}U.fn.call(S,U.obj);};var L,K,!
 O,N,M=[];for(L=0,K=F.length;L<K;L=L+1){O=F[L];if(O){N=this.get!
 El(O.id)
;if(N){if(O.checkReady){if(H||N.nextSibling||!Q){M.push(O);F[L]=null;}}else{R(N,O);F[L]=null;}}else{P.push(O);}}}for(L=0,K=M.length;L<K;L=L+1){O=M[L];R(this.getEl(O.id),O);}C--;if(Q){for(L=F.length-1;L>-1;L--){O=F[L];if(!O||!O.id){F.splice(L,1);}}this.startInterval();}else{clearInterval(this._interval);this._interval=null;}this.locked=false;},purgeElement:function(O,P,R){var M=(YAHOO.lang.isString(O))?this.getEl(O):O;var Q=this.getListeners(M,R),N,K;if(Q){for(N=Q.length-1;N>-1;N--){var L=Q[N];this.removeListener(M,L.type,L.fn);}}if(P&&M&&M.childNodes){for(N=0,K=M.childNodes.length;N<K;++N){this.purgeElement(M.childNodes[N],P,R);}}},getListeners:function(M,K){var P=[],L;if(!K){L=[I,J];}else{if(K==="unload"){L=[J];}else{L=[I];}}var R=(YAHOO.lang.isString(M))?this.getEl(M):M;for(var O=0;O<L.length;O=O+1){var T=L[O];if(T){for(var Q=0,S=T.length;Q<S;++Q){var N=T[Q];if(N&&N[this.EL]===R&&(!K||K===N[this.TYPE])){P.push({type:N[this.TYPE],fn:N[this.FN],obj:N[this.OBJ],adjust:N[this.!
 OVERRIDE],scope:N[this.ADJ_SCOPE],index:Q});}}}}return(P.length)?P:null;},_unload:function(Q){var K=YAHOO.util.Event,N,M,L,P,O,R=J.slice();for(N=0,P=J.length;N<P;++N){L=R[N];if(L){var S=window;if(L[K.ADJ_SCOPE]){if(L[K.ADJ_SCOPE]===true){S=L[K.UNLOAD_OBJ];}else{S=L[K.ADJ_SCOPE];}}L[K.FN].call(S,K.getEvent(Q,L[K.EL]),L[K.UNLOAD_OBJ]);R[N]=null;L=null;S=null;}}J=null;if(I){for(M=I.length-1;M>-1;M--){L=I[M];if(L){K.removeListener(L[K.EL],L[K.TYPE],L[K.FN],M);}}L=null;}G=null;K._simpleRemove(window,"unload",K._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var K=document.documentElement,L=document.body;if(K&&(K.scrollTop||K.scrollLeft)){return[K.scrollTop,K.scrollLeft];}else{if(L){return[L.scrollTop,L.scrollLeft];}else{return[0,0];}}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(M,N,L,K){M.addEventListener(N,L,(K));};}else{if(window.attachEvent!
 ){return function(M,N,L,K){M.attachEvent("on"+N,L);};}else{ret!
 urn func
tion(){};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(M,N,L,K){M.removeEventListener(N,L,(K));};}else{if(window.detachEvent){return function(L,M,K){L.detachEvent("on"+M,K);};}else{return function(){};}}}()};}();(function(){var EU=YAHOO.util.Event;EU.on=EU.addListener;
+/* DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller */
+if(EU.isIE){YAHOO.util.Event.onDOMReady(YAHOO.util.Event._tryPreloadAttach,YAHOO.util.Event,true);var n=document.createElement("p");EU._dri=setInterval(function(){try{n.doScroll("left");clearInterval(EU._dri);EU._dri=null;EU._ready();n=null;}catch(ex){}},EU.POLL_INTERVAL);}else{if(EU.webkit&&EU.webkit<525){EU._dri=setInterval(function(){var rs=document.readyState;if("loaded"==rs||"complete"==rs){clearInterval(EU._dri);EU._dri=null;EU._ready();}},EU.POLL_INTERVAL);}else{EU._simpleAdd(document,"DOMContentLoaded",EU._ready);}}EU._simpleAdd(window,"load",EU._load);EU._simpleAdd(window,"unload",EU._unload);EU._tryPreloadAttach();})();}YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null,__yui_subscribers:null,subscribe:function(A,C,F,E){this.__yui_events=this.__yui_events||{};var D=this.__yui_events[A];if(D){D.subscribe(C,F,E);}else{this.__yui_subscribers=this.__yui_subscribers||{};var B=this.__yui_subscribers;if(!B[A]){B[A]=[];}B[A].push({!
 fn:C,obj:F,override:E});}},unsubscribe:function(C,E,G){this.__yui_events=this.__yui_events||{};var A=this.__yui_events;if(C){var F=A[C];if(F){return F.unsubscribe(E,G);}}else{var B=true;for(var D in A){if(YAHOO.lang.hasOwnProperty(A,D)){B=B&&A[D].unsubscribe(E,G);}}return B;}return false;},unsubscribeAll:function(A){return this.unsubscribe(A);},createEvent:function(G,D){this.__yui_events=this.__yui_events||{};var A=D||{};var I=this.__yui_events;if(I[G]){}else{var H=A.scope||this;var E=(A.silent);var B=new YAHOO.util.CustomEvent(G,H,E,YAHOO.util.CustomEvent.FLAT);
+I[G]=B;if(A.onSubscribeCallback){B.subscribeEvent.subscribe(A.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};var F=this.__yui_subscribers[G];if(F){for(var C=0;C<F.length;++C){B.subscribe(F[C].fn,F[C].obj,F[C].override);}}}return I[G];},fireEvent:function(E,D,A,C){this.__yui_events=this.__yui_events||{};var G=this.__yui_events[E];if(!G){return null;}var B=[];for(var F=1;F<arguments.length;++F){B.push(arguments[F]);}return G.fire.apply(G,B);},hasEvent:function(A){if(this.__yui_events){if(this.__yui_events[A]){return true;}}return false;}};YAHOO.util.KeyListener=function(A,F,B,C){if(!A){}else{if(!F){}else{if(!B){}}}if(!C){C=YAHOO.util.KeyListener.KEYDOWN;}var D=new YAHOO.util.CustomEvent("keyPressed");this.enabledEvent=new YAHOO.util.CustomEvent("enabled");this.disabledEvent=new YAHOO.util.CustomEvent("disabled");if(typeof A=="string"){A=document.getElementById(A);}if(typeof B=="function"){D.subscribe(B);}else{D.subscribe(B.fn,B.scope,B.correctScope);}!
 function E(J,I){if(!F.shift){F.shift=false;}if(!F.alt){F.alt=false;}if(!F.ctrl){F.ctrl=false;}if(J.shiftKey==F.shift&&J.altKey==F.alt&&J.ctrlKey==F.ctrl){var G;if(F.keys instanceof Array){for(var H=0;H<F.keys.length;H++){G=F.keys[H];if(G==J.charCode){D.fire(J.charCode,J);break;}else{if(G==J.keyCode){D.fire(J.keyCode,J);break;}}}}else{G=F.keys;if(G==J.charCode){D.fire(J.charCode,J);}else{if(G==J.keyCode){D.fire(J.keyCode,J);}}}}}this.enable=function(){if(!this.enabled){YAHOO.util.Event.addListener(A,C,E);this.enabledEvent.fire(F);}this.enabled=true;};this.disable=function(){if(this.enabled){YAHOO.util.Event.removeListener(A,C,E);this.disabledEvent.fire(F);}this.enabled=false;};this.toString=function(){return"KeyListener ["+F.keys+"] "+A.tagName+(A.id?"["+A.id+"]":"");};};YAHOO.util.KeyListener.KEYDOWN="keydown";YAHOO.util.KeyListener.KEYUP="keyup";YAHOO.util.KeyListener.KEY={ALT:18,BACK_SPACE:8,CAPS_LOCK:20,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:!
 37,META:224,NUM_LOCK:144,PAGE_DOWN:34,PAGE_UP:33,PAUSE:19,PRIN!
 TSCREEN:
44,RIGHT:39,SCROLL_LOCK:145,SHIFT:16,SPACE:32,TAB:9,UP:38};YAHOO.register("event",YAHOO.util.Event,{version:"2.5.1",build:"984"});YAHOO.register("yahoo-dom-event", YAHOO, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/yuiloader/README
===================================================================
--- trunk/root/static/yui/yuiloader/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuiloader/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,5 +1,32 @@
 yuiloader - Release Notes
 
+2.5.1
+   * Updated metadata for 2.5.1.
+   * Added the get utility's support for 'insertBefore'.
+   * Added the get utility's support for 'charset'.
+   * Fixed profilerviewer's dependency list.
+   * Increased rollup threshold for reset-fonts-grids so reset-fonts will be 
+     selected when appropriate.
+   * yuiloader supersedes yahoo and get.
+   * Modules now can have an 'after' property that can be used to specify
+     a list of modules that are not dependencies, but need to be included
+     above the module if they are present.
+   * base will always be included after reset, fonts, and grids. Skin css
+     will be included after all of the above.
+   * Added a new rollup: yuiloader-dom-event (yuiloader includes yahoo and get as well).
+   * utilities.js now includes yuiloader and get.
+   * loaded modules which supersede other modules but don't allow automatic 
+     rollup work correctly (the superseded modules won't load).
+   * Addessed a source order issue when logger is included after a component
+     which tries to instantiate it at load time.
+   * The filter property can be set on the instance.
+   * Custom css modules are always sorted below YUI css.
+   * The loader will not attempt to rollup the skin css for custom skinnable modules.
+
+2.5.0
+   * Updated metadata for 2.5.0
+   * (from the get utility) fixed autopurge.
+
 2.4.1
    * Updated metadata for 2.4.1
 

Modified: trunk/root/static/yui/yuiloader/yuiloader-beta-debug.js
===================================================================
--- trunk/root/static/yui/yuiloader/yuiloader-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuiloader/yuiloader-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The YAHOO object is the single global object used by YUI Library.  It
@@ -272,16 +272,25 @@
          * Safari 2.0.4:         418     <-- preventDefault fixed
          * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
          *                                   different versions of webkit
-         * Safari 2.0.4 (419.3): 419     <-- Current Safari release
-         * Webkit 212 nightly:   522+    <-- Safari 3.0 (with native SVG) should
-         *                                   be higher than this
+         * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
+         *                                   updated, but not updated
+         *                                   to the latest patch.
+         * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native SVG
+         *                                   and many major issues fixed).  
+         * 3.x yahoo.com, flickr:422     <-- Safari 3.x hacks the user agent
+         *                                   string when hitting yahoo.com and 
+         *                                   flickr.com.
+         * Safari 3.0.4 (523.12):523.12  <-- First Tiger release - automatic update
+         *                                   from 2.x via the 10.4.11 OS patch
+         * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
+         *                                   yahoo.com user agent hack removed.
          *                                   
          * </pre>
          * http://developer.apple.com/internet/safari/uamatrix.html
          * @property webkit
          * @type float
          */
-        webkit:0,
+        webkit: 0,
 
         /**
          * The mobile property will be set to a string containing any relevant
@@ -291,7 +300,16 @@
          * @property mobile 
          * @type string
          */
-        mobile: null 
+        mobile: null,
+
+        /**
+         * Adobe AIR version number or 0.  Only populated if webkit is detected.
+         * Example: 1.0
+         * @property air
+         * @type float
+         */
+        air: 0
+
     };
 
     var ua=navigator.userAgent, m;
@@ -315,6 +333,11 @@
             }
         }
 
+        m=ua.match(/AdobeAIR\/([^\s]*)/);
+        if (m) {
+            o.air = m[0]; // Adobe AIR 1.0 or better
+        }
+
     }
 
     if (!o.webkit) { // not webkit
@@ -388,10 +411,9 @@
      * properties.
      * @method isArray
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isArray: function(o) { 
-
         if (o) {
            var l = YAHOO.lang;
            return l.isNumber(o.length) && l.isFunction(o.splice);
@@ -403,7 +425,7 @@
      * Determines whether or not the provided object is a boolean
      * @method isBoolean
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isBoolean: function(o) {
         return typeof o === 'boolean';
@@ -413,7 +435,7 @@
      * Determines whether or not the provided object is a function
      * @method isFunction
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isFunction: function(o) {
         return typeof o === 'function';
@@ -423,7 +445,7 @@
      * Determines whether or not the provided object is null
      * @method isNull
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isNull: function(o) {
         return o === null;
@@ -433,7 +455,7 @@
      * Determines whether or not the provided object is a legal number
      * @method isNumber
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isNumber: function(o) {
         return typeof o === 'number' && isFinite(o);
@@ -444,7 +466,7 @@
      * or function
      * @method isObject
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */  
     isObject: function(o) {
 return (o && (typeof o === 'object' || YAHOO.lang.isFunction(o))) || false;
@@ -454,7 +476,7 @@
      * Determines whether or not the provided object is a string
      * @method isString
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isString: function(o) {
         return typeof o === 'string';
@@ -464,7 +486,7 @@
      * Determines whether or not the provided object is undefined
      * @method isUndefined
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isUndefined: function(o) {
         return typeof o === 'undefined';
@@ -488,7 +510,7 @@
      * </pre>
      * @method hasOwnProperty
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     hasOwnProperty: function(o, prop) {
         if (Object.prototype.hasOwnProperty) {
@@ -827,14 +849,14 @@
     },
 
     /**
-     * Executes the supplied function in the scope of the supplied 
+     * Executes the supplied function in the context of the supplied 
      * object 'when' milliseconds later.  Executes the function a 
      * single time unless periodic is set to true.
      * @method later
      * @since 2.4.0
      * @param when {int} the number of milliseconds to wait until the fn 
      * is executed
-     * @param o the scope object
+     * @param o the context object
      * @param fn {Function|String} the function to execute or the name of 
      * the method in the 'o' object to execute
      * @param data [Array] data that is provided to the function.  This accepts
@@ -881,7 +903,7 @@
             }
         };
     },
-
+    
     /**
      * A convenience method for detecting a legitimate non-null value.
      * Returns false for null/undefined/NaN, true for other values, 
@@ -949,7 +971,7 @@
  */
 YAHOO.extend = YAHOO.lang.extend;
 
-YAHOO.register("yahoo", YAHOO, {version: "2.4.1", build: "742"});
+YAHOO.register("yahoo", YAHOO, {version: "2.5.1", build: "984"});
 /**
  * Provides a mechanism to fetch remote resources and
  * insert them into a document
@@ -1033,12 +1055,14 @@
      * @return {HTMLElement} the generated node
      * @private
      */
-    var _linkNode = function(url, win) {
+    var _linkNode = function(url, win, charset) {
+        var c = charset || "utf-8";
         return _node("link", {
-                "id": "yui__dyn_" + (nidx++),
-                "type": "text/css",
-                "rel": "stylesheet",
-                "href": url
+                "id":      "yui__dyn_" + (nidx++),
+                "type":    "text/css",
+                "charset": c,
+                "rel":     "stylesheet",
+                "href":    url
             }, win);
     };
 
@@ -1050,11 +1074,13 @@
      * @return {HTMLElement} the generated node
      * @private
      */
-    var _scriptNode = function(url, win) {
+    var _scriptNode = function(url, win, charset) {
+        var c = charset || "utf-8";
         return _node("script", {
-                "id": "yui__dyn_" + (nidx++),
-                "type": "text/javascript",
-                "src": url
+                "id":      "yui__dyn_" + (nidx++),
+                "type":    "text/javascript",
+                "charset": c,
+                "src":     url
             }, win);
     };
 
@@ -1063,18 +1089,29 @@
      * @method _returnData
      * @private
      */
-    var _returnData = function(q) {
+    var _returnData = function(q, msg) {
         return {
                 tId: q.tId,
                 win: q.win,
                 data: q.data,
                 nodes: q.nodes,
+                msg: msg,
                 purge: function() {
                     _purge(this.tId);
                 }
             };
     };
 
+    var _get = function(nId, tId) {
+        var q = queues[tId],
+            n = (lang.isString(nId)) ? q.win.document.getElementById(nId) : nId;
+        if (!n) {
+            _fail(tId, "target node not found: " + nId);
+        }
+
+        return n;
+    };
+
     /*
      * The request failed, execute fail handler with whatever
      * was accomplished.  There isn't a failure case at the
@@ -1083,12 +1120,12 @@
      * @param id {string} the id of the request
      * @private
      */
-    var _fail = function(id) {
+    var _fail = function(id, msg) {
         var q = queues[id];
         // execute failure callback
         if (q.onFailure) {
             var sc=q.scope || q.win;
-            q.onFailure.call(sc, _returnData(q));
+            q.onFailure.call(sc, _returnData(q, msg));
         }
     };
 
@@ -1103,7 +1140,8 @@
         q.finished = true;
 
         if (q.aborted) {
-            _fail(id);
+            var msg = "transaction " + id + " was aborted";
+            _fail(id, msg);
             return;
         }
 
@@ -1125,7 +1163,8 @@
         var q = queues[id];
 
         if (q.aborted) {
-            _fail(id);
+            var msg = "transaction " + id + " was aborted";
+            _fail(id, msg);
             return;
         }
 
@@ -1158,7 +1197,7 @@
                 // arbitrary timeout.  It is possible that the browser does
                 // block subsequent script execution in this case for a limited
                 // time.
-                var extra = _scriptNode(null, q.win);
+                var extra = _scriptNode(null, q.win, q.charset);
                 extra.innerHTML='YAHOO.util.Get._finalize("' + id + '");';
                 q.nodes.push(extra); h.appendChild(extra);
 
@@ -1173,9 +1212,9 @@
         var url = q.url[0];
 
         if (q.type === "script") {
-            n = _scriptNode(url, w);
+            n = _scriptNode(url, w, q.charset);
         } else {
-            n = _linkNode(url, w);
+            n = _linkNode(url, w, q.charset);
         }
 
         // track this node's load progress
@@ -1184,8 +1223,15 @@
         // add the node to the queue so we can return it to the user supplied callback
         q.nodes.push(n);
 
-        // add it to the head
-        h.appendChild(n);
+        // add it to the head or insert it before 'insertBefore'
+        if (q.insertBefore) {
+            var s = _get(q.insertBefore, id);
+            if (s) {
+                s.parentNode.insertBefore(n, s);
+            }
+        } else {
+            h.appendChild(n);
+        }
         
 
         // FireFox does not support the onload event for link nodes, so there is
@@ -1213,6 +1259,7 @@
             var q = queues[i];
             if (q.autopurge && q.finished) {
                 _purge(q.tId);
+                delete queues[i];
             }
         }
 
@@ -1229,10 +1276,19 @@
         if (q) {
             var n=q.nodes, l=n.length, d=q.win.document, 
                 h=d.getElementsByTagName("head")[0];
+
+            if (q.insertBefore) {
+                var s = _get(q.insertBefore, tId);
+                if (s) {
+                    h = s.parentNode;
+                }
+            }
+
             for (var i=0; i<l; i=i+1) {
                 h.removeChild(n[i]);
             }
         }
+        q.nodes = [];
     };
 
     /**
@@ -1308,7 +1364,7 @@
             if (type === "script") {
 
                 // Safari 3.x supports the load event for script nodes (DOM2)
-                if (ua.webkit > 419) {
+                if (ua.webkit >= 420) {
 
                     n.addEventListener("load", function() {
                         f(id, url);
@@ -1339,8 +1395,9 @@
                                     // if we have exausted our attempts, give up
                                     this.attempts++;
                                     if (this.attempts++ > this.maxattempts) {
+                                        var msg = "Over retry limit, giving up";
                                         q.timer.cancel();
-                                        _fail(id);
+                                        _fail(id, msg);
                                     } else {
                                     }
                                     return;
@@ -1493,7 +1550,11 @@
          * must supply an array that contains the variable name for
          * each script.
          * </dd>
+         * <dt>insertBefore</dt>
+         * <dd>node or node id that will become the new node's nextSibling</dd>
          * </dl>
+         * <dt>charset</dt>
+         * <dd>Node charset, default utf-8</dd>
          * <pre>
          * // assumes yahoo, dom, and event are already on the page
          *   YAHOO.util.Get.script(
@@ -1553,6 +1614,10 @@
          * data that is supplied to the callbacks when the nodes(s) are
          * loaded.
          * </dd>
+         * <dt>insertBefore</dt>
+         * <dd>node or node id that will become the new node's nextSibling</dd>
+         * <dt>charset</dt>
+         * <dd>Node charset, default utf-8</dd>
          * </dl>
          * <pre>
          *      YAHOO.util.Get.css("http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css");
@@ -1568,7 +1633,7 @@
     };
 }();
 
-YAHOO.register("get", YAHOO.util.Get, {version: "2.4.1", build: "742"});
+YAHOO.register("get", YAHOO.util.Get, {version: "2.5.1", build: "984"});
 /**
  * Provides dynamic loading for the YUI library.  It includes the dependency
  * info for the library, and will automatically pull in dependencies for
@@ -1589,7 +1654,9 @@
  */
 (function() {
 
-    var Y=YAHOO, util=Y.util, lang=Y.lang, env=Y.env;
+    var Y=YAHOO, util=Y.util, lang=Y.lang, env=Y.env,
+        PROV = "_provides", SUPER = "_supersedes",
+        REQ = "expanded", AFTER = "_after";
  
     var YUI = {
 
@@ -1602,16 +1669,18 @@
          * @static
          */
         info: {
+    'base': 'http://yui.yahooapis.com/2.5.1/build/',
 
-    'base': 'http://yui.yahooapis.com/2.4.1/build/',
-
     'skin': {
         'defaultSkin': 'sam',
         'base': 'assets/skins/',
         'path': 'skin.css',
+        'after': ['reset', 'fonts', 'grids', 'base'],
         'rollup': 3
     },
 
+    dupsAllowed: ['yahoo', 'get'],
+
     'moduleInfo': {
 
         'animation': {
@@ -1630,7 +1699,8 @@
 
         'base': {
             'type': 'css',
-            'path': 'base/base-min.css'
+            'path': 'base/base-min.css',
+            'after': ['reset', 'fonts', 'grids']
         },
 
         'button': {
@@ -1656,7 +1726,7 @@
 
         'colorpicker': {
             'type': 'js',
-            'path': 'colorpicker/colorpicker-beta-min.js',
+            'path': 'colorpicker/colorpicker-min.js',
             'requires': ['slider', 'element'],
             'optional': ['animation'],
             'skinnable': true
@@ -1672,8 +1742,9 @@
             'type': 'js',
             'path': 'container/container-min.js',
             'requires': ['dom', 'event'],
-            // button is optional, but creates a circular dep
-            //'optional': ['dragdrop', 'animation', 'connection', 'connection', 'button'],
+            // button is also optional, but this creates a circular 
+            // dependency when loadOptional is specified.  button
+            // optionally includes menu, menu requires container.
             'optional': ['dragdrop', 'animation', 'connection'],
             'supersedes': ['containercore'],
             'skinnable': true
@@ -1686,6 +1757,12 @@
             'pkg': 'container'
         },
 
+        'cookie': {
+            'type': 'js',
+            'path': 'cookie/cookie-beta-min.js',
+            'requires': ['yahoo']
+        },
+
         'datasource': {
             'type': 'js',
             'path': 'datasource/datasource-beta-min.js',
@@ -1740,7 +1817,7 @@
 
         'get': {
             'type': 'js',
-            'path': 'get/get-beta-min.js',
+            'path': 'get/get-min.js',
             'requires': ['yahoo']
         },
 
@@ -1757,18 +1834,33 @@
             'requires': ['event']
         },
 
-        'imageloader': {
+         'imagecropper': {
+             'type': 'js',
+             'path': 'imagecropper/imagecropper-beta-min.js',
+             'requires': ['dom', 'event', 'dragdrop', 'element', 'resize'],
+             'skinnable': true
+         },
+
+         'imageloader': {
             'type': 'js',
-            'path': 'imageloader/imageloader-beta-min.js',
+            'path': 'imageloader/imageloader-min.js',
             'requires': ['event', 'dom']
-        },
+         },
 
-        'json': {
+         'json': {
             'type': 'js',
-            'path': 'json/json-beta-min.js',
+            'path': 'json/json-min.js',
             'requires': ['yahoo']
-        },
+         },
 
+         'layout': {
+             'type': 'js',
+             'path': 'layout/layout-beta-min.js',
+             'requires': ['dom', 'event', 'element'],
+             'optional': ['animation', 'dragdrop', 'resize', 'selector'],
+             'skinnable': true
+         }, 
+
         'logger': {
             'type': 'js',
             'path': 'logger/logger-min.js',
@@ -1784,6 +1876,20 @@
             'skinnable': true
         },
 
+        'profiler': {
+            'type': 'js',
+            'path': 'profiler/profiler-beta-min.js',
+            'requires': ['yahoo']
+        },
+
+
+        'profilerviewer': {
+            'type': 'js',
+            'path': 'profilerviewer/profilerviewer-beta-min.js',
+            'requires': ['profiler', 'yuiloader', 'element'],
+            'skinnable': true
+        },
+
         'reset': {
             'type': 'css',
             'path': 'reset/reset-min.css'
@@ -1793,7 +1899,7 @@
             'type': 'css',
             'path': 'reset-fonts-grids/reset-fonts-grids.css',
             'supersedes': ['reset', 'fonts', 'grids', 'reset-fonts'],
-            'rollup': 3
+            'rollup': 4
         },
 
         'reset-fonts': {
@@ -1803,6 +1909,14 @@
             'rollup': 2
         },
 
+         'resize': {
+             'type': 'js',
+             'path': 'resize/resize-beta-min.js',
+             'requires': ['dom', 'event', 'dragdrop', 'element'],
+             'optional': ['animation'],
+             'skinnable': true
+         },
+
         'selector': {
             'type': 'js',
             'path': 'selector/selector-beta-min.js',
@@ -1840,11 +1954,17 @@
             'skinnable': true
         },
 
+        'uploader': {
+            'type': 'js',
+            'path': 'uploader/uploader-experimental.js',
+            'requires': ['yahoo']
+        },
+
         'utilities': {
             'type': 'js',
             'path': 'utilities/utilities.js',
-            'supersedes': ['yahoo', 'event', 'dragdrop', 'animation', 'dom', 'connection', 'element', 'yahoo-dom-event'],
-            'rollup': 6
+            'supersedes': ['yahoo', 'event', 'dragdrop', 'animation', 'dom', 'connection', 'element', 'yahoo-dom-event', 'get', 'yuiloader', 'yuiloader-dom-event'],
+            'rollup': 8
         },
 
         'yahoo': {
@@ -1861,12 +1981,20 @@
 
         'yuiloader': {
             'type': 'js',
-            'path': 'yuiloader/yuiloader-beta-min.js'
+            'path': 'yuiloader/yuiloader-beta-min.js',
+            'supersedes': ['yahoo', 'get']
         },
 
+        'yuiloader-dom-event': {
+            'type': 'js',
+            'path': 'yuiloader-dom-event/yuiloader-dom-event.js',
+            'supersedes': ['yahoo', 'dom', 'event', 'get', 'yuiloader', 'yahoo-dom-event'],
+            'rollup': 5
+        },
+
         'yuitest': {
             'type': 'js',
-            'path': 'yuitest/yuitest-beta-min.js',
+            'path': 'yuitest/yuitest-min.js',
             'requires': ['logger'],
             'skinnable': true
         }
@@ -1990,6 +2118,21 @@
         this.data = null;
 
         /**
+         * Node reference or id where new nodes should be inserted before
+         * @property insertBefore
+         * @type string|HTMLElement
+         */
+        this.insertBefore = null;
+
+        /**
+         * The charset attribute for inserted nodes
+         * @property charset
+         * @type string
+         * @default utf-8
+         */
+        this.charset = null;
+
+        /**
          * The name of the variable in a sandbox or script node 
          * (for external script support in Safari 2.x and earlier)
          * to reference when the load is complete.  If this variable 
@@ -2020,7 +2163,7 @@
          * A list of modules that should always be loaded, even
          * if they have already been inserted into the page.
          * @property force
-         * @type string
+         * @type string[]
          */
         this.force = null;
 
@@ -2191,44 +2334,43 @@
 
         _config: function(o) {
 
-            if (!o) {
-                return;
-            }
-
-            // lang.augmentObject(this, o);
-
             // apply config values
-            for (var i in o) {
-                if (lang.hasOwnProperty(o, i)) {
-                    switch (i) {
-                        case "require":
+            if (o) {
+                for (var i in o) {
+                    if (lang.hasOwnProperty(o, i)) {
+                        if (i == "require") {
                             this.require(o[i]);
-                            break;
+                        } else {
+                            this[i] = o[i];
+                        }
+                    }
+                }
+            }
 
-                        case "filter":
-                            var f = o[i];
+            // fix filter
+            var f = this.filter;
 
-                            if (typeof f === "string") {
-                                f = f.toUpperCase();
+            if (lang.isString(f)) {
+                f = f.toUpperCase();
 
-                                // the logger must be available in order to use the debug
-                                // versions of the library
-                                if (f === "DEBUG") {
-                                    this.require("logger");
-                                }
+                // the logger must be available in order to use the debug
+                // versions of the library
+                if (f === "DEBUG") {
+                    this.require("logger");
+                }
 
-                                this.filter = this.FILTERS[f];
-                            } else {
-                                this.filter = f;
-                            }
+                // hack to handle a a bug where LogWriter is being instantiated
+                // at load time, and the loader has no way to sort above it
+                // at the moment.
+                if (!Y.widget.LogWriter) {
+                    Y.widget.LogWriter = function() {
+                        return Y;
+                    };
+                }
 
-                            break;
+                this.filter = this.FILTERS[f];
+            }
 
-                        default:
-                            this[i] = o[i];
-                    }
-                }
-            }
         },
 
         /** Add a new module to the component metadata.         
@@ -2236,9 +2378,10 @@
          *     <dt>name:</dt>       <dd>required, the component name</dd>
          *     <dt>type:</dt>       <dd>required, the component type (js or css)</dd>
          *     <dt>path:</dt>       <dd>required, the path to the script from "base"</dd>
-         *     <dt>requires:</dt>   <dd>the modules required by this component</dd>
-         *     <dt>optional:</dt>   <dd>the optional modules for this component</dd>
-         *     <dt>supersedes:</dt> <dd>the modules this component replaces</dd>
+         *     <dt>requires:</dt>   <dd>array of modules required by this component</dd>
+         *     <dt>optional:</dt>   <dd>array of optional modules for this component</dd>
+         *     <dt>supersedes:</dt> <dd>array of the modules this component replaces</dd>
+         *     <dt>after:</dt>      <dd>array of modules the components which, if present, should be sorted above this one</dd>
          *     <dt>rollup:</dt>     <dd>the number of superseded modules required for automatic rollup</dd>
          *     <dt>fullpath:</dt>   <dd>If fullpath is specified, this is used instead of the configured base + path</dd>
          *     <dt>skinnable:</dt>  <dd>flag to determine if skin assets should automatically be pulled in</dd>
@@ -2254,6 +2397,9 @@
                 return false;
             }
 
+            o.ext = ('ext' in o) ? o.ext : true;
+            o.requires = o.requires || [];
+
             this.moduleInfo[o.name] = o;
             this.dirty = true;
 
@@ -2267,54 +2413,55 @@
          */
         require: function(what) {
             var a = (typeof what === "string") ? arguments : what;
-
             this.dirty = true;
-
-            for (var i=0; i<a.length; i=i+1) {
-                this.required[a[i]] = true;
-                var s = this.parseSkin(a[i]);
-                if (s) {
-                    this._addSkin(s.skin, s.module);
-                }
-            }
             YUI.ObjectUtil.appendArray(this.required, a);
         },
 
-
         /**
          * Adds the skin def to the module info
          * @method _addSkin
+         * @param skin {string} the name of the skin
+         * @param mod {string} the name of the module
+         * @return {string} the module name for the skin
          * @private
          */
         _addSkin: function(skin, mod) {
 
             // Add a module definition for the skin rollup css
-            var name = this.formatSkin(skin);
-            if (!this.moduleInfo[name]) {
+            var name = this.formatSkin(skin), info = this.moduleInfo,
+                sinf = this.skin, ext = info[mod] && info[mod].ext;
+
+            // Y.log('ext? ' + mod + ": " + ext);
+            if (!info[name]) {
+                // Y.log('adding skin ' + name);
                 this.addModule({
                     'name': name,
                     'type': 'css',
-                    'path': this.skin.base + skin + "/" + this.skin.path,
+                    'path': sinf.base + skin + '/' + sinf.path,
                     //'supersedes': '*',
-                    'rollup': this.skin.rollup
+                    'after': sinf.after,
+                    'rollup': sinf.rollup,
+                    'ext': ext
                 });
             }
 
             // Add a module definition for the module-specific skin css
             if (mod) {
                 name = this.formatSkin(skin, mod);
-                if (!this.moduleInfo[name]) {
-                    var mdef = this.moduleInfo[mod];
-                    var pkg = mdef.pkg || mod;
+                if (!info[name]) {
+                    var mdef = info[mod], pkg = mdef.pkg || mod;
+                    // Y.log('adding skin ' + name);
                     this.addModule({
                         'name': name,
                         'type': 'css',
-                        //'path': this.skin.base + skin + "/" + mod + ".css"
-                        // 'path': mod + '/' + this.skin.base + skin + "/" + mod + ".css"
-                        'path': pkg + '/' + this.skin.base + skin + "/" + mod + ".css"
+                        'after': sinf.after,
+                        'path': pkg + '/' + sinf.base + skin + '/' + mod + '.css',
+                        'ext': ext
                     });
                 }
             }
+
+            return name;
         },
 
         /**
@@ -2324,15 +2471,35 @@
          * @param mod The module definition from moduleInfo
          */
         getRequires: function(mod) {
+            if (!mod) {
+                return [];
+            }
+
             if (!this.dirty && mod.expanded) {
                 return mod.expanded;
             }
 
             mod.requires=mod.requires || [];
-            var i, d=[], r=mod.requires, o=mod.optional, info=this.moduleInfo;
+            var i, d=[], r=mod.requires, o=mod.optional, info=this.moduleInfo, m;
             for (i=0; i<r.length; i=i+1) {
                 d.push(r[i]);
-                YUI.ArrayUtil.appendArray(d, this.getRequires(info[r[i]]));
+                m = info[r[i]];
+                YUI.ArrayUtil.appendArray(d, this.getRequires(m));
+
+                // add existing skins for skinnable modules as well.  The only
+                // way to do this is go through the list of required items (this
+                // assumes that _skin is called before getRequires is called on
+                // the module.
+                // if (m.skinnable) {
+                //     var req=this.required, l=req.length;
+                //     for (var j=0; j<l; j=j+1) {
+                //         // YAHOO.log('checking ' + r[j]);
+                //         if (req[j].indexOf(r[j]) > -1) {
+                //             // YAHOO.log('adding ' + r[j]);
+                //             d.push(req[j]);
+                //         }
+                //     }
+                // }
             }
 
             if (o && this.loadOptional) {
@@ -2347,27 +2514,64 @@
             return mod.expanded;
         },
 
+
         /**
          * Returns an object literal of the modules the supplied module satisfies
          * @method getProvides
-         * @param mod The module definition from moduleInfo
+         * @param name{string} The name of the module
+         * @param notMe {string} don't add this module name, only include superseded modules
          * @return what this module provides
          */
-        getProvides: function(name) {
-            var mod = this.moduleInfo[name];
+        getProvides: function(name, notMe) {
+            var addMe = !(notMe), ckey = (addMe) ? PROV : SUPER,
+                m = this.moduleInfo[name], o = {};
 
-            var o = {};
-            o[name] = true;
+            if (!m) {
+                return o;
+            }
 
-            var s = mod && mod.supersedes;
+            if (m[ckey]) {
+// Y.log('cached: ' + name + ' ' + ckey + ' ' + lang.dump(this.moduleInfo[name][ckey], 0));
+                return m[ckey];
+            }
 
-            YUI.ObjectUtil.appendArray(o, s);
+            var s = m.supersedes, done={}, me = this;
 
-            // console.log(this.sorted + ", " + name + " provides " + YUI.ObjectUtil.keys(o));
+            // use worker to break cycles
+            var add = function(mm) {
+                if (!done[mm]) {
+                    // Y.log(name + ' provides worker trying: ' + mm);
+                    done[mm] = true;
+                    // we always want the return value normal behavior 
+                    // (provides) for superseded modules.
+                    lang.augmentObject(o, me.getProvides(mm));
+                } 
+                
+                // else {
+                // Y.log(name + ' provides worker skipping done: ' + mm);
+                // }
+            };
 
-            return o;
+            // calculate superseded modules
+            if (s) {
+                for (var i=0; i<s.length; i=i+1) {
+                    add(s[i]);
+                }
+            }
+
+            // supersedes cache
+            m[SUPER] = o;
+            // provides cache
+            m[PROV] = lang.merge(o);
+            m[PROV][name] = true;
+
+// Y.log(name + " supersedes " + lang.dump(m[SUPER], 0));
+// Y.log(name + " provides " + lang.dump(m[PROV], 0));
+
+            return m[ckey];
         },
 
+
         /**
          * Calculates the dependency tree, the result is stored in the sorted 
          * property
@@ -2379,7 +2583,7 @@
                 this._config(o);
                 this._setup();
                 this._explode();
-                this._skin();
+                // this._skin(); // deprecated
                 if (this.allowRollup) {
                     this._rollup();
                 }
@@ -2401,27 +2605,61 @@
          */
         _setup: function() {
 
-            this.loaded = lang.merge(this.inserted); // shallow clone
+            var info = this.moduleInfo, name, i, j;
+
+            // Create skin modules
+            for (name in info) {
+                var m = info[name];
+                if (m && m.skinnable) {
+                    // Y.log("skinning: " + name);
+                    var o=this.skin.overrides, smod;
+                    if (o && o[name]) {
+                        for (i=0; i<o[name].length; i=i+1) {
+                            smod = this._addSkin(o[name][i], name);
+                        }
+                    } else {
+                        smod = this._addSkin(this.skin.defaultSkin, name);
+                    }
+
+                    m.requires.push(smod);
+                }
+
+            }
+
+            var l = lang.merge(this.inserted); // shallow clone
             
             if (!this._sandbox) {
-                this.loaded = lang.merge(this.loaded, env.modules);
+                l = lang.merge(l, env.modules);
             }
 
-            // Y.log("already loaded stuff: " + lang.dump(this.loaded, 0));
+            // Y.log("Already loaded stuff: " + lang.dump(l, 0));
 
             // add the ignore list to the list of loaded packages
             if (this.ignore) {
-                YUI.ObjectUtil.appendArray(this.loaded, this.ignore);
+                YUI.ObjectUtil.appendArray(l, this.ignore);
             }
 
             // remove modules on the force list from the loaded list
             if (this.force) {
-                for (var i=0; i<this.force.length; i=i+1) {
-                    if (this.force[i] in this.loaded) {
-                        delete this.loaded[this.force[i]];
+                for (i=0; i<this.force.length; i=i+1) {
+                    if (this.force[i] in l) {
+                        delete l[this.force[i]];
                     }
                 }
             }
+
+            // expand the list to include superseded modules
+            for (j in l) {
+                // Y.log("expanding: " + j);
+                if (lang.hasOwnProperty(l, j)) {
+                    lang.augmentObject(l, this.getProvides(j));
+                }
+            }
+
+            // Y.log("loaded expanded: " + lang.dump(l, 0));
+
+            this.loaded = l;
+
         },
         
 
@@ -2454,24 +2692,12 @@
          * requested modules are skinnable
          * @method _skin
          * @private
+         * @deprecated skin modules are generated for all skinnable
+         *             components during _setup(), and the components
+         *             are configured to require the skin.
          */
         _skin: function() {
 
-            var r=this.required, i, mod;
-
-            for (i in r) {
-                mod = this.moduleInfo[i];
-                if (mod && mod.skinnable) {
-                    var o=this.skin.overrides, j;
-                    if (o && o[i]) {
-                        for (j=0; j<o[i].length; j=j+1) {
-                            this.require(this.formatSkin(o[i][j], i));
-                        }
-                    } else {
-                        this.require(this.formatSkin(this.skin.defaultSkin, i));
-                    }
-                }
-            }
         },
 
         /**
@@ -2550,9 +2776,10 @@
                             continue;
                         }
 
-                        var skin = this.parseSkin(i), c = 0;
+                        var skin = (m.ext) ? false : this.parseSkin(i), c = 0;
+
+                        // Y.log('skin? ' + i + ": " + skin);
                         if (skin) {
-
                             for (j in r) {
                                 if (i !== j && this.parseSkin(j)) {
                                     c++;
@@ -2626,14 +2853,16 @@
                     var skinDef = this.parseSkin(i);
 
                     if (skinDef) {
-                        //console.log("skin found in reduce: " + skinDef.skin + ", " + skinDef.module);
+                        //YAHOO.log("skin found in reduce: " + skinDef.skin + ", " + skinDef.module);
                         // the skin rollup will not have a module name
                         if (!skinDef.module) {
                             var skin_pre = this.SKIN_PREFIX + skinDef.skin;
-                            //console.log("skin_pre: " + skin_pre);
+                            //YAHOO.log("skin_pre: " + skin_pre);
                             for (j in r) {
-                                if (j !== i && j.indexOf(skin_pre) > -1) {
-                                    //console.log ("removing component skin: " + j);
+                                m = this.moduleInfo[j];
+                                var ext = m && m.ext;
+                                if (!ext && j !== i && j.indexOf(skin_pre) > -1) {
+                                    // Y.log ("removing component skin: " + j);
                                     delete r[j];
                                 }
                             }
@@ -2643,7 +2872,7 @@
                          m = this.moduleInfo[i];
                          s = m && m.supersedes;
                          if (s) {
-                             for (j=0;j<s.length;j=j+1) {
+                             for (j=0; j<s.length; j=j+1) {
                                  if (s[j] in r) {
                                      delete r[s[j]];
                                  }
@@ -2661,7 +2890,8 @@
          */
         _sort: function() {
             // create an indexed list
-            var s=[], info=this.moduleInfo, loaded=this.loaded;
+            var s=[], info=this.moduleInfo, loaded=this.loaded,
+                me = this;
 
             // returns true if b is not loaded, and is required
             // directly or by means of modules it supersedes.
@@ -2670,12 +2900,20 @@
                     return false;
                 }
 
-                var ii, mm=info[aa], rr=mm && mm.expanded;
+                var ii, mm=info[aa], rr=mm && mm.expanded, 
+                    after = mm && mm.after, other=info[bb];
 
+                // check if this module requires the other directly
                 if (rr && YUI.ArrayUtil.indexOf(rr, bb) > -1) {
                     return true;
                 }
 
+                // check if this module should be sorted after the other
+                if (after && YUI.ArrayUtil.indexOf(after, bb) > -1) {
+                    return true;
+                }
+
+                // check if this module requires one the other supersedes
                 var ss=info[bb] && info[bb].supersedes;
                 if (ss) {
                     for (ii=0; ii<ss.length; ii=ii+1) {
@@ -2685,6 +2923,20 @@
                     }
                 }
 
+                // var ss=me.getProvides(bb, true);
+                // if (ss) {
+                //     for (ii in ss) {
+                //         if (requires(aa, ii)) {
+                //             return true;
+                //         }
+                //     }
+                // }
+
+                // external css files should be sorted below yui css
+                if (mm.ext && mm.type == 'css' && (!other.ext)) {
+                    return true;
+                }
+
                 return false;
             };
 
@@ -2843,6 +3095,8 @@
                     base: this.base,
                     filter: this.filter,
                     require: "connection",
+                    insertBefore: this.insertBefore,
+                    charset: this.charset,
                     onSuccess: function() {
                         this.sandbox(null, "js");
                     },
@@ -3054,6 +3308,8 @@
                     fn(url, {
                         data: s[i],
                         onSuccess: c,
+                        insertBefore: this.insertBefore,
+                        charset: this.charset,
                         varName: m.varName,
                         scope: self 
                     });
@@ -3106,12 +3362,12 @@
             u = u + path;
 
             if (f) {
-                // console.log("filter: " + f + ", " + f.searchExp + 
+                // YAHOO.log("filter: " + f + ", " + f.searchExp + 
                 // ", " + f.replaceStr);
                 u = u.replace(new RegExp(f.searchExp), f.replaceStr);
             }
 
-            // console.log(u);
+            // YAHOO.log(u);
 
             return u;
         }

Modified: trunk/root/static/yui/yuiloader/yuiloader-beta-min.js
===================================================================
--- trunk/root/static/yui/yuiloader/yuiloader-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuiloader/yuiloader-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,10 +1,10 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
-if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var A=arguments,E=null,C,B,D;for(C=0;C<A.length;C=C+1){D=A[C].split(".");E=YAHOO;for(B=(D[0]=="YAHOO")?1:0;B<D.length;B=B+1){E[D[B]]=E[D[B]]||{};E=E[D[B]];}}return E;};YAHOO.log=function(D,A,C){var B=YAHOO.widget.Logger;if(B&&B.log){return B.log(D,A,C);}else{return false;}};YAHOO.register=function(A,E,D){var I=YAHOO.env.modules;if(!I[A]){I[A]={versions:[],builds:[]};}var B=I[A],H=D.version,G=D.build,F=YAHOO.env.listeners;B.name=A;B.version=H;B.build=G;B.versions.push(H);B.builds.push(G);B.mainClass=E;for(var C=0;C<F.length;C=C+1){F[C](B);}if(E){E.VERSION=H;E.BUILD=G;}else{YAHOO.log("mainClass is undefined for module "+A,"warn");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[]};YAHOO.env.getVersion=function(A){return YAHOO.env.modules[A]||null;};YAHOO.env.ua=function(){var C={ie:0,opera:0,gecko:0,webkit:0,mobile:null};var B=navigator.userAgent,A;if((/KHTML/).test(B)){C.webkit=1;}A=B.match(/AppleWe!
 bKit\/([^\s]*)/);if(A&&A[1]){C.webkit=parseFloat(A[1]);if(/ Mobile\//.test(B)){C.mobile="Apple";}else{A=B.match(/NokiaN[^\/]*/);if(A){C.mobile=A[0];}}}if(!C.webkit){A=B.match(/Opera[\s\/]([^\s]*)/);if(A&&A[1]){C.opera=parseFloat(A[1]);A=B.match(/Opera Mini[^;]*/);if(A){C.mobile=A[0];}}else{A=B.match(/MSIE\s([^;]*)/);if(A&&A[1]){C.ie=parseFloat(A[1]);}else{A=B.match(/Gecko\/([^\s]*)/);if(A){C.gecko=1;A=B.match(/rv:([^\s\)]*)/);if(A&&A[1]){C.gecko=parseFloat(A[1]);}}}}}return C;}();(function(){YAHOO.namespace("util","widget","example");if("undefined"!==typeof YAHOO_config){var B=YAHOO_config.listener,A=YAHOO.env.listeners,D=true,C;if(B){for(C=0;C<A.length;C=C+1){if(A[C]==B){D=false;break;}}if(D){A.push(B);}}}})();YAHOO.lang=YAHOO.lang||{isArray:function(B){if(B){var A=YAHOO.lang;return A.isNumber(B.length)&&A.isFunction(B.splice);}return false;},isBoolean:function(A){return typeof A==="boolean";},isFunction:function(A){return typeof A==="function";},isNull:function(A){return !
 A===null;},isNumber:function(A){return typeof A==="number"&&is!
 Finite(A
);},isObject:function(A){return(A&&(typeof A==="object"||YAHOO.lang.isFunction(A)))||false;},isString:function(A){return typeof A==="string";},isUndefined:function(A){return typeof A==="undefined";},hasOwnProperty:function(A,B){if(Object.prototype.hasOwnProperty){return A.hasOwnProperty(B);}return !YAHOO.lang.isUndefined(A[B])&&A.constructor.prototype[B]!==A[B];},_IEEnumFix:function(C,B){if(YAHOO.env.ua.ie){var E=["toString","valueOf"],A;for(A=0;A<E.length;A=A+1){var F=E[A],D=B[F];if(YAHOO.lang.isFunction(D)&&D!=Object.prototype[F]){C[F]=D;}}}},extend:function(D,E,C){if(!E||!D){throw new Error("YAHOO.lang.extend failed, please check that all dependencies are included.");}var B=function(){};B.prototype=E.prototype;D.prototype=new B();D.prototype.constructor=D;D.superclass=E.prototype;if(E.prototype.constructor==Object.prototype.constructor){E.prototype.constructor=E;}if(C){for(var A in C){D.prototype[A]=C[A];}YAHOO.lang._IEEnumFix(D.prototype,C);}},augmentObject:function(E,D)!
 {if(!D||!E){throw new Error("Absorb failed, verify dependencies.");}var A=arguments,C,F,B=A[2];if(B&&B!==true){for(C=2;C<A.length;C=C+1){E[A[C]]=D[A[C]];}}else{for(F in D){if(B||!E[F]){E[F]=D[F];}}YAHOO.lang._IEEnumFix(E,D);}},augmentProto:function(D,C){if(!C||!D){throw new Error("Augment failed, verify dependencies.");}var A=[D.prototype,C.prototype];for(var B=2;B<arguments.length;B=B+1){A.push(arguments[B]);}YAHOO.lang.augmentObject.apply(this,A);},dump:function(A,G){var C=YAHOO.lang,D,F,I=[],J="{...}",B="f(){...}",H=", ",E=" => ";if(!C.isObject(A)){return A+"";}else{if(A instanceof Date||("nodeType" in A&&"tagName" in A)){return A;}else{if(C.isFunction(A)){return B;}}}G=(C.isNumber(G))?G:3;if(C.isArray(A)){I.push("[");for(D=0,F=A.length;D<F;D=D+1){if(C.isObject(A[D])){I.push((G>0)?C.dump(A[D],G-1):J);}else{I.push(A[D]);}I.push(H);}if(I.length>1){I.pop();}I.push("]");}else{I.push("{");for(D in A){if(C.hasOwnProperty(A,D)){I.push(D+E);if(C.isObject(A[D])){I.push((G>0)?C.du!
 mp(A[D],G-1):J);}else{I.push(A[D]);}I.push(H);}}if(I.length>1)!
 {I.pop()
;}I.push("}");}return I.join("");},substitute:function(Q,B,J){var G,F,E,M,N,P,D=YAHOO.lang,L=[],C,H="dump",K=" ",A="{",O="}";for(;;){G=Q.lastIndexOf(A);if(G<0){break;}F=Q.indexOf(O,G);if(G+1>=F){break;}C=Q.substring(G+1,F);M=C;P=null;E=M.indexOf(K);if(E>-1){P=M.substring(E+1);M=M.substring(0,E);}N=B[M];if(J){N=J(M,N,P);}if(D.isObject(N)){if(D.isArray(N)){N=D.dump(N,parseInt(P,10));}else{P=P||"";var I=P.indexOf(H);if(I>-1){P=P.substring(4);}if(N.toString===Object.prototype.toString||I>-1){N=D.dump(N,parseInt(P,10));}else{N=N.toString();}}}else{if(!D.isString(N)&&!D.isNumber(N)){N="~-"+L.length+"-~";L[L.length]=C;}}Q=Q.substring(0,G)+N+Q.substring(F+1);}for(G=L.length-1;G>=0;G=G-1){Q=Q.replace(new RegExp("~-"+G+"-~"),"{"+L[G]+"}","g");}return Q;},trim:function(A){try{return A.replace(/^\s+|\s+$/g,"");}catch(B){return A;}},merge:function(){var D={},B=arguments;for(var C=0,A=B.length;C<A;C=C+1){YAHOO.lang.augmentObject(D,B[C],true);}return D;},later:function(H,B,I,D,E){H=H||0;B=!
 B||{};var C=I,G=D,F,A;if(YAHOO.lang.isString(I)){C=B[I];}if(!C){throw new TypeError("method undefined");}if(!YAHOO.lang.isArray(G)){G=[D];}F=function(){C.apply(B,G);};A=(E)?setInterval(F,H):setTimeout(F,H);return{interval:E,cancel:function(){if(this.interval){clearInterval(A);}else{clearTimeout(A);}}};},isValue:function(B){var A=YAHOO.lang;return(A.isObject(B)||A.isString(B)||A.isNumber(B)||A.isBoolean(B));}};YAHOO.util.Lang=YAHOO.lang;YAHOO.lang.augment=YAHOO.lang.augmentProto;YAHOO.augment=YAHOO.lang.augmentProto;YAHOO.extend=YAHOO.lang.extend;YAHOO.register("yahoo",YAHOO,{version:"2.4.1",build:"742"});YAHOO.util.Get=function(){var I={},H=0,B=0,O=false,A=YAHOO.env.ua,D=YAHOO.lang;var Q=function(U,R,V){var S=V||window,W=S.document,X=W.createElement(U);for(var T in R){if(R[T]&&YAHOO.lang.hasOwnProperty(R,T)){X.setAttribute(T,R[T]);}}return X;};var N=function(R,S){return Q("link",{"id":"yui__dyn_"+(B++),"type":"text/css","rel":"stylesheet","href":R},S);
-};var M=function(R,S){return Q("script",{"id":"yui__dyn_"+(B++),"type":"text/javascript","src":R},S);};var K=function(R){return{tId:R.tId,win:R.win,data:R.data,nodes:R.nodes,purge:function(){J(this.tId);}};};var P=function(T){var R=I[T];if(R.onFailure){var S=R.scope||R.win;R.onFailure.call(S,K(R));}};var F=function(T){var R=I[T];R.finished=true;if(R.aborted){P(T);return ;}if(R.onSuccess){var S=R.scope||R.win;R.onSuccess.call(S,K(R));}};var E=function(T,W){var S=I[T];if(S.aborted){P(T);return ;}if(W){S.url.shift();if(S.varName){S.varName.shift();}}else{S.url=(D.isString(S.url))?[S.url]:S.url;if(S.varName){S.varName=(D.isString(S.varName))?[S.varName]:S.varName;}}var Z=S.win,Y=Z.document,X=Y.getElementsByTagName("head")[0],U;if(S.url.length===0){if(S.type==="script"&&A.webkit&&A.webkit<420&&!S.finalpass&&!S.varName){var V=M(null,S.win);V.innerHTML="YAHOO.util.Get._finalize(\""+T+"\");";S.nodes.push(V);X.appendChild(V);}else{F(T);}return ;}var R=S.url[0];if(S.type==="script"){!
 U=M(R,Z);}else{U=N(R,Z);}G(S.type,U,T,R,Z,S.url.length);S.nodes.push(U);X.appendChild(U);if((A.webkit||A.gecko)&&S.type==="css"){E(T,R);}};var C=function(){if(O){return ;}O=true;for(var R in I){var S=I[R];if(S.autopurge&&S.finished){J(S.tId);}}O=false;};var J=function(X){var U=I[X];if(U){var W=U.nodes,R=W.length,V=U.win.document,T=V.getElementsByTagName("head")[0];for(var S=0;S<R;S=S+1){T.removeChild(W[S]);}}};var L=function(S,R,T){var V="q"+(H++);T=T||{};if(H%YAHOO.util.Get.PURGE_THRESH===0){C();}I[V]=D.merge(T,{tId:V,type:S,url:R,finished:false,nodes:[]});var U=I[V];U.win=U.win||window;U.scope=U.scope||U.win;U.autopurge=("autopurge" in U)?U.autopurge:(S==="script")?true:false;D.later(0,U,E,V);return{tId:V};};var G=function(a,V,U,S,W,X,Z){var Y=Z||E;if(A.ie){V.onreadystatechange=function(){var b=this.readyState;if("loaded"===b||"complete"===b){Y(U,S);}};}else{if(A.webkit){if(a==="script"){if(A.webkit>419){V.addEventListener("load",function(){Y(U,S);});}else{var R=I[U];if(R!
 .varName){var T=YAHOO.util.Get.POLL_FREQ;R.maxattempts=YAHOO.u!
 til.Get.
TIMEOUT/T;R.attempts=0;R._cache=R.varName[0].split(".");R.timer=D.later(T,R,function(f){var d=this._cache,c=d.length,b=this.win,e;for(e=0;e<c;e=e+1){b=b[d[e]];if(!b){this.attempts++;if(this.attempts++>this.maxattempts){R.timer.cancel();P(U);}else{}return ;}}R.timer.cancel();Y(U,S);},null,true);}else{D.later(YAHOO.util.Get.POLL_FREQ,null,Y,[U,S]);}}}}else{V.onload=function(){Y(U,S);};}}};return{POLL_FREQ:10,PURGE_THRESH:20,TIMEOUT:2000,_finalize:function(R){D.later(0,null,F,R);},abort:function(S){var T=(D.isString(S))?S:S.tId;var R=I[T];if(R){R.aborted=true;}},script:function(R,S){return L("script",R,S);},css:function(R,S){return L("css",R,S);}};}();YAHOO.register("get",YAHOO.util.Get,{version:"2.4.1",build:"742"});(function(){var Y=YAHOO,util=Y.util,lang=Y.lang,env=Y.env;var YUI={dupsAllowed:{"yahoo":true,"get":true},info:{"base":"http://yui.yahooapis.com/2.4.1/build/","skin":{"defaultSkin":"sam","base":"assets/skins/","path":"skin.css","rollup":3},"moduleInfo":{"animation":!
 {"type":"js","path":"animation/animation-min.js","requires":["dom","event"]},"autocomplete":{"type":"js","path":"autocomplete/autocomplete-min.js","requires":["dom","event"],"optional":["connection","animation"],"skinnable":true},"base":{"type":"css","path":"base/base-min.css"},"button":{"type":"js","path":"button/button-min.js","requires":["element"],"optional":["menu"],"skinnable":true},"calendar":{"type":"js","path":"calendar/calendar-min.js","requires":["event","dom"],"skinnable":true},"charts":{"type":"js","path":"charts/charts-experimental-min.js","requires":["element","json","datasource"]},"colorpicker":{"type":"js","path":"colorpicker/colorpicker-beta-min.js","requires":["slider","element"],"optional":["animation"],"skinnable":true},"connection":{"type":"js","path":"connection/connection-min.js","requires":["event"]},"container":{"type":"js","path":"container/container-min.js","requires":["dom","event"],"optional":["dragdrop","animation","connection"],"supersedes":[!
 "containercore"],"skinnable":true},"containercore":{"type":"js!
 ","path"
:"container/container_core-min.js","requires":["dom","event"],"pkg":"container"},"datasource":{"type":"js","path":"datasource/datasource-beta-min.js","requires":["event"],"optional":["connection"]},"datatable":{"type":"js","path":"datatable/datatable-beta-min.js","requires":["element","datasource"],"optional":["calendar","dragdrop"],"skinnable":true},"dom":{"type":"js","path":"dom/dom-min.js","requires":["yahoo"]},"dragdrop":{"type":"js","path":"dragdrop/dragdrop-min.js","requires":["dom","event"]},"editor":{"type":"js","path":"editor/editor-beta-min.js","requires":["menu","element","button"],"optional":["animation","dragdrop"],"skinnable":true},"element":{"type":"js","path":"element/element-beta-min.js","requires":["dom","event"]},"event":{"type":"js","path":"event/event-min.js","requires":["yahoo"]},"fonts":{"type":"css","path":"fonts/fonts-min.css"},"get":{"type":"js","path":"get/get-beta-min.js","requires":["yahoo"]},"grids":{"type":"css","path":"grids/grids-min.css","re!
 quires":["fonts"],"optional":["reset"]},"history":{"type":"js","path":"history/history-min.js","requires":["event"]},"imageloader":{"type":"js","path":"imageloader/imageloader-beta-min.js","requires":["event","dom"]},"json":{"type":"js","path":"json/json-beta-min.js","requires":["yahoo"]},"logger":{"type":"js","path":"logger/logger-min.js","requires":["event","dom"],"optional":["dragdrop"],"skinnable":true},"menu":{"type":"js","path":"menu/menu-min.js","requires":["containercore"],"skinnable":true},"reset":{"type":"css","path":"reset/reset-min.css"},"reset-fonts-grids":{"type":"css","path":"reset-fonts-grids/reset-fonts-grids.css","supersedes":["reset","fonts","grids","reset-fonts"],"rollup":3},"reset-fonts":{"type":"css","path":"reset-fonts/reset-fonts.css","supersedes":["reset","fonts"],"rollup":2},"selector":{"type":"js","path":"selector/selector-beta-min.js","requires":["yahoo","dom"]},"simpleeditor":{"type":"js","path":"editor/simpleeditor-beta-min.js","requires":["ele!
 ment"],"optional":["containercore","menu","button","animation"!
 ,"dragdr
op"],"skinnable":true,"pkg":"editor"},"slider":{"type":"js","path":"slider/slider-min.js","requires":["dragdrop"],"optional":["animation"]},"tabview":{"type":"js","path":"tabview/tabview-min.js","requires":["element"],"optional":["connection"],"skinnable":true},"treeview":{"type":"js","path":"treeview/treeview-min.js","requires":["event"],"skinnable":true},"utilities":{"type":"js","path":"utilities/utilities.js","supersedes":["yahoo","event","dragdrop","animation","dom","connection","element","yahoo-dom-event"],"rollup":6},"yahoo":{"type":"js","path":"yahoo/yahoo-min.js"},"yahoo-dom-event":{"type":"js","path":"yahoo-dom-event/yahoo-dom-event.js","supersedes":["yahoo","event","dom"],"rollup":3},"yuiloader":{"type":"js","path":"yuiloader/yuiloader-beta-min.js"},"yuitest":{"type":"js","path":"yuitest/yuitest-beta-min.js","requires":["logger"],"skinnable":true}}},ObjectUtil:{appendArray:function(o,a){if(a){for(var i=0;
-i<a.length;i=i+1){o[a[i]]=true;}}},keys:function(o,ordered){var a=[],i;for(i in o){if(lang.hasOwnProperty(o,i)){a.push(i);}}return a;}},ArrayUtil:{appendArray:function(a1,a2){Array.prototype.push.apply(a1,a2);},indexOf:function(a,val){for(var i=0;i<a.length;i=i+1){if(a[i]===val){return i;}}return -1;},toObject:function(a){var o={};for(var i=0;i<a.length;i=i+1){o[a[i]]=true;}return o;},uniq:function(a){return YUI.ObjectUtil.keys(YUI.ArrayUtil.toObject(a));}}};YAHOO.util.YUILoader=function(o){this._internalCallback=null;this._useYahooListener=false;this.onSuccess=null;this.onFailure=Y.log;this.onProgress=null;this.scope=this;this.data=null;this.varName=null;this.base=YUI.info.base;this.ignore=null;this.force=null;this.allowRollup=true;this.filter=null;this.required={};this.moduleInfo=lang.merge(YUI.info.moduleInfo);this.rollups=null;this.loadOptional=false;this.sorted=[];this.loaded={};this.dirty=true;this.inserted={};var self=this;env.listeners.push(function(m){if(self._useY!
 ahooListener){self.loadNext(m.name);}});this.skin=lang.merge(YUI.info.skin);this._config(o);};Y.util.YUILoader.prototype={FILTERS:{RAW:{"searchExp":"-min\\.js","replaceStr":".js"},DEBUG:{"searchExp":"-min\\.js","replaceStr":"-debug.js"}},SKIN_PREFIX:"skin-",_config:function(o){if(!o){return ;}for(var i in o){if(lang.hasOwnProperty(o,i)){switch(i){case"require":this.require(o[i]);break;case"filter":var f=o[i];if(typeof f==="string"){f=f.toUpperCase();if(f==="DEBUG"){this.require("logger");}this.filter=this.FILTERS[f];}else{this.filter=f;}break;default:this[i]=o[i];}}}},addModule:function(o){if(!o||!o.name||!o.type||(!o.path&&!o.fullpath)){return false;}this.moduleInfo[o.name]=o;this.dirty=true;return true;},require:function(what){var a=(typeof what==="string")?arguments:what;this.dirty=true;for(var i=0;i<a.length;i=i+1){this.required[a[i]]=true;var s=this.parseSkin(a[i]);if(s){this._addSkin(s.skin,s.module);}}YUI.ObjectUtil.appendArray(this.required,a);},_addSkin:function(sk!
 in,mod){var name=this.formatSkin(skin);if(!this.moduleInfo[nam!
 e]){this
.addModule({"name":name,"type":"css","path":this.skin.base+skin+"/"+this.skin.path,"rollup":this.skin.rollup});}if(mod){name=this.formatSkin(skin,mod);if(!this.moduleInfo[name]){var mdef=this.moduleInfo[mod];var pkg=mdef.pkg||mod;this.addModule({"name":name,"type":"css","path":pkg+"/"+this.skin.base+skin+"/"+mod+".css"});}}},getRequires:function(mod){if(!this.dirty&&mod.expanded){return mod.expanded;}mod.requires=mod.requires||[];var i,d=[],r=mod.requires,o=mod.optional,info=this.moduleInfo;for(i=0;i<r.length;i=i+1){d.push(r[i]);YUI.ArrayUtil.appendArray(d,this.getRequires(info[r[i]]));}if(o&&this.loadOptional){for(i=0;i<o.length;i=i+1){d.push(o[i]);YUI.ArrayUtil.appendArray(d,this.getRequires(info[o[i]]));}}mod.expanded=YUI.ArrayUtil.uniq(d);return mod.expanded;},getProvides:function(name){var mod=this.moduleInfo[name];var o={};o[name]=true;var s=mod&&mod.supersedes;YUI.ObjectUtil.appendArray(o,s);return o;},calculate:function(o){if(this.dirty){this._config(o);this._setup()!
 ;this._explode();this._skin();if(this.allowRollup){this._rollup();}this._reduce();this._sort();this.dirty=false;}},_setup:function(){this.loaded=lang.merge(this.inserted);if(!this._sandbox){this.loaded=lang.merge(this.loaded,env.modules);}if(this.ignore){YUI.ObjectUtil.appendArray(this.loaded,this.ignore);}if(this.force){for(var i=0;i<this.force.length;i=i+1){if(this.force[i] in this.loaded){delete this.loaded[this.force[i]];}}}},_explode:function(){var r=this.required,i,mod;for(i in r){mod=this.moduleInfo[i];if(mod){var req=this.getRequires(mod);if(req){YUI.ObjectUtil.appendArray(r,req);}}}},_skin:function(){var r=this.required,i,mod;for(i in r){mod=this.moduleInfo[i];if(mod&&mod.skinnable){var o=this.skin.overrides,j;if(o&&o[i]){for(j=0;j<o[i].length;j=j+1){this.require(this.formatSkin(o[i][j],i));}}else{this.require(this.formatSkin(this.skin.defaultSkin,i));}}}},formatSkin:function(skin,mod){var s=this.SKIN_PREFIX+skin;if(mod){s=s+"-"+mod;}return s;},parseSkin:function(m!
 od){if(mod.indexOf(this.SKIN_PREFIX)===0){var a=mod.split("-")!
 ;return{
skin:a[1],module:a[2]};}return null;},_rollup:function(){var i,j,m,s,rollups={},r=this.required,roll;if(this.dirty||!this.rollups){for(i in this.moduleInfo){m=this.moduleInfo[i];if(m&&m.rollup){rollups[i]=m;}}this.rollups=rollups;}for(;;){var rolled=false;for(i in rollups){if(!r[i]&&!this.loaded[i]){m=this.moduleInfo[i];s=m.supersedes;roll=false;if(!m.rollup){continue;}var skin=this.parseSkin(i),c=0;if(skin){for(j in r){if(i!==j&&this.parseSkin(j)){c++;roll=(c>=m.rollup);if(roll){break;}}}}else{for(j=0;j<s.length;j=j+1){if(this.loaded[s[j]]&&(!YUI.dupsAllowed[s[j]])){roll=false;break;}else{if(r[s[j]]){c++;roll=(c>=m.rollup);if(roll){break;}}}}}if(roll){r[i]=true;rolled=true;this.getRequires(m);}}}if(!rolled){break;}}},_reduce:function(){var i,j,s,m,r=this.required;for(i in r){if(i in this.loaded){delete r[i];}else{var skinDef=this.parseSkin(i);if(skinDef){if(!skinDef.module){var skin_pre=this.SKIN_PREFIX+skinDef.skin;for(j in r){if(j!==i&&j.indexOf(skin_pre)>-1){delete r[j];!
 }}}}else{m=this.moduleInfo[i];s=m&&m.supersedes;if(s){for(j=0;j<s.length;j=j+1){if(s[j] in r){delete r[s[j]];}}}}}}},_sort:function(){var s=[],info=this.moduleInfo,loaded=this.loaded;var requires=function(aa,bb){if(loaded[bb]){return false;}var ii,mm=info[aa],rr=mm&&mm.expanded;if(rr&&YUI.ArrayUtil.indexOf(rr,bb)>-1){return true;}var ss=info[bb]&&info[bb].supersedes;if(ss){for(ii=0;ii<ss.length;ii=ii+1){if(requires(aa,ss[ii])){return true;}}}return false;};for(var i in this.required){s.push(i);}var p=0;for(;;){var l=s.length,a,b,j,k,moved=false;for(j=p;j<l;j=j+1){a=s[j];for(k=j+1;k<l;k=k+1){if(requires(a,s[k])){b=s.splice(k,1);s.splice(j,0,b[0]);moved=true;break;}}if(moved){break;}else{p=p+1;}}if(!moved){break;}}this.sorted=s;},toString:function(){var o={type:"YUILoader",base:this.base,filter:this.filter,required:this.required,loaded:this.loaded,inserted:this.inserted};lang.dump(o,1);},insert:function(o,type){this.calculate(o);
-if(!type){var self=this;this._internalCallback=function(){self._internalCallback=null;self.insert(null,"js");};this.insert(null,"css");return ;}this._loading=true;this.loadType=type;this.loadNext();},sandbox:function(o,type){if(o){}else{}this._config(o);if(!this.onSuccess){throw new Error("You must supply an onSuccess handler for your sandbox");}this._sandbox=true;var self=this;if(!type||type!=="js"){this._internalCallback=function(){self._internalCallback=null;self.sandbox(null,"js");};this.insert(null,"css");return ;}if(!util.Connect){var ld=new YAHOO.util.YUILoader();ld.insert({base:this.base,filter:this.filter,require:"connection",onSuccess:function(){this.sandbox(null,"js");},scope:this},"js");return ;}this._scriptText=[];this._loadCount=0;this._stopCount=this.sorted.length;this._xhr=[];this.calculate();var s=this.sorted,l=s.length,i,m,url;for(i=0;i<l;i=i+1){m=this.moduleInfo[s[i]];if(!m){this.onFailure.call(this.scope,{msg:"undefined module "+m,data:this.data});for(va!
 r j=0;j<this._xhr.length;j=j+1){this._xhr[j].abort();}return ;}if(m.type!=="js"){this._loadCount++;continue;}url=m.fullpath||this._url(m.path);var xhrData={success:function(o){var idx=o.argument[0],name=o.argument[2];this._scriptText[idx]=o.responseText;if(this.onProgress){this.onProgress.call(this.scope,{name:name,scriptText:o.responseText,xhrResponse:o,data:this.data});}this._loadCount++;if(this._loadCount>=this._stopCount){var v=this.varName||"YAHOO";var t="(function() {\n";var b="\nreturn "+v+";\n})();";var ref=eval(t+this._scriptText.join("\n")+b);this._pushEvents(ref);if(ref){this.onSuccess.call(this.scope,{reference:ref,data:this.data});}else{this.onFailure.call(this.scope,{msg:this.varName+" reference failure",data:this.data});}}},failure:function(o){this.onFailure.call(this.scope,{msg:"XHR failure",xhrResponse:o,data:this.data});},scope:this,argument:[i,url,s[i]]};this._xhr.push(util.Connect.asyncRequest("GET",url,xhrData));}},loadNext:function(mname){if(!this._loa!
 ding){return ;}if(mname){if(mname!==this._loading){return ;}th!
 is.inser
ted[mname]=true;if(this.onProgress){this.onProgress.call(this.scope,{name:mname,data:this.data});}}var s=this.sorted,len=s.length,i,m;for(i=0;i<len;i=i+1){if(s[i] in this.inserted){continue;}if(s[i]===this._loading){return ;}m=this.moduleInfo[s[i]];if(!m){this.onFailure.call(this.scope,{msg:"undefined module "+m,data:this.data});return ;}if(!this.loadType||this.loadType===m.type){this._loading=s[i];var fn=(m.type==="css")?util.Get.css:util.Get.script,url=m.fullpath||this._url(m.path),self=this,c=function(o){self.loadNext(o.data);};if(env.ua.webkit&&env.ua.webkit<420&&m.type==="js"&&!m.varName){c=null;this._useYahooListener=true;}fn(url,{data:s[i],onSuccess:c,varName:m.varName,scope:self});return ;}}this._loading=null;if(this._internalCallback){var f=this._internalCallback;this._internalCallback=null;f.call(this);}else{if(this.onSuccess){this._pushEvents();this.onSuccess.call(this.scope,{data:this.data});}}},_pushEvents:function(ref){var r=ref||YAHOO;if(r.util&&r.util.Event){!
 r.util.Event._load();}},_url:function(path){var u=this.base||"",f=this.filter;u=u+path;if(f){u=u.replace(new RegExp(f.searchExp),f.replaceStr);}return u;}};})();
\ No newline at end of file
+if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var A=arguments,E=null,C,B,D;for(C=0;C<A.length;C=C+1){D=A[C].split(".");E=YAHOO;for(B=(D[0]=="YAHOO")?1:0;B<D.length;B=B+1){E[D[B]]=E[D[B]]||{};E=E[D[B]];}}return E;};YAHOO.log=function(D,A,C){var B=YAHOO.widget.Logger;if(B&&B.log){return B.log(D,A,C);}else{return false;}};YAHOO.register=function(A,E,D){var I=YAHOO.env.modules;if(!I[A]){I[A]={versions:[],builds:[]};}var B=I[A],H=D.version,G=D.build,F=YAHOO.env.listeners;B.name=A;B.version=H;B.build=G;B.versions.push(H);B.builds.push(G);B.mainClass=E;for(var C=0;C<F.length;C=C+1){F[C](B);}if(E){E.VERSION=H;E.BUILD=G;}else{YAHOO.log("mainClass is undefined for module "+A,"warn");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[]};YAHOO.env.getVersion=function(A){return YAHOO.env.modules[A]||null;};YAHOO.env.ua=function(){var C={ie:0,opera:0,gecko:0,webkit:0,mobile:null,air:0};var B=navigator.userAgent,A;if((/KHTML/).test(B)){C.webkit=1;}A=B.match(/A!
 ppleWebKit\/([^\s]*)/);if(A&&A[1]){C.webkit=parseFloat(A[1]);if(/ Mobile\//.test(B)){C.mobile="Apple";}else{A=B.match(/NokiaN[^\/]*/);if(A){C.mobile=A[0];}}A=B.match(/AdobeAIR\/([^\s]*)/);if(A){C.air=A[0];}}if(!C.webkit){A=B.match(/Opera[\s\/]([^\s]*)/);if(A&&A[1]){C.opera=parseFloat(A[1]);A=B.match(/Opera Mini[^;]*/);if(A){C.mobile=A[0];}}else{A=B.match(/MSIE\s([^;]*)/);if(A&&A[1]){C.ie=parseFloat(A[1]);}else{A=B.match(/Gecko\/([^\s]*)/);if(A){C.gecko=1;A=B.match(/rv:([^\s\)]*)/);if(A&&A[1]){C.gecko=parseFloat(A[1]);}}}}}return C;}();(function(){YAHOO.namespace("util","widget","example");if("undefined"!==typeof YAHOO_config){var B=YAHOO_config.listener,A=YAHOO.env.listeners,D=true,C;if(B){for(C=0;C<A.length;C=C+1){if(A[C]==B){D=false;break;}}if(D){A.push(B);}}}})();YAHOO.lang=YAHOO.lang||{isArray:function(B){if(B){var A=YAHOO.lang;return A.isNumber(B.length)&&A.isFunction(B.splice);}return false;},isBoolean:function(A){return typeof A==="boolean";},isFunction:function(A){r!
 eturn typeof A==="function";},isNull:function(A){return A===nu!
 ll;},isN
umber:function(A){return typeof A==="number"&&isFinite(A);},isObject:function(A){return(A&&(typeof A==="object"||YAHOO.lang.isFunction(A)))||false;},isString:function(A){return typeof A==="string";},isUndefined:function(A){return typeof A==="undefined";},hasOwnProperty:function(A,B){if(Object.prototype.hasOwnProperty){return A.hasOwnProperty(B);}return !YAHOO.lang.isUndefined(A[B])&&A.constructor.prototype[B]!==A[B];},_IEEnumFix:function(C,B){if(YAHOO.env.ua.ie){var E=["toString","valueOf"],A;for(A=0;A<E.length;A=A+1){var F=E[A],D=B[F];if(YAHOO.lang.isFunction(D)&&D!=Object.prototype[F]){C[F]=D;}}}},extend:function(D,E,C){if(!E||!D){throw new Error("YAHOO.lang.extend failed, please check that "+"all dependencies are included.");}var B=function(){};B.prototype=E.prototype;D.prototype=new B();D.prototype.constructor=D;D.superclass=E.prototype;if(E.prototype.constructor==Object.prototype.constructor){E.prototype.constructor=E;}if(C){for(var A in C){D.prototype[A]=C[A];}YAHOO.la!
 ng._IEEnumFix(D.prototype,C);}},augmentObject:function(E,D){if(!D||!E){throw new Error("Absorb failed, verify dependencies.");}var A=arguments,C,F,B=A[2];if(B&&B!==true){for(C=2;C<A.length;C=C+1){E[A[C]]=D[A[C]];}}else{for(F in D){if(B||!E[F]){E[F]=D[F];}}YAHOO.lang._IEEnumFix(E,D);}},augmentProto:function(D,C){if(!C||!D){throw new Error("Augment failed, verify dependencies.");}var A=[D.prototype,C.prototype];for(var B=2;B<arguments.length;B=B+1){A.push(arguments[B]);}YAHOO.lang.augmentObject.apply(this,A);},dump:function(A,G){var C=YAHOO.lang,D,F,I=[],J="{...}",B="f(){...}",H=", ",E=" => ";if(!C.isObject(A)){return A+"";}else{if(A instanceof Date||("nodeType" in A&&"tagName" in A)){return A;}else{if(C.isFunction(A)){return B;}}}G=(C.isNumber(G))?G:3;if(C.isArray(A)){I.push("[");for(D=0,F=A.length;D<F;D=D+1){if(C.isObject(A[D])){I.push((G>0)?C.dump(A[D],G-1):J);}else{I.push(A[D]);}I.push(H);}if(I.length>1){I.pop();}I.push("]");}else{I.push("{");for(D in A){if(C.hasOwnProper!
 ty(A,D)){I.push(D+E);if(C.isObject(A[D])){I.push((G>0)?C.dump(!
 A[D],G-1
):J);}else{I.push(A[D]);}I.push(H);}}if(I.length>1){I.pop();}I.push("}");}return I.join("");},substitute:function(Q,B,J){var G,F,E,M,N,P,D=YAHOO.lang,L=[],C,H="dump",K=" ",A="{",O="}";for(;;){G=Q.lastIndexOf(A);if(G<0){break;}F=Q.indexOf(O,G);if(G+1>=F){break;}C=Q.substring(G+1,F);M=C;P=null;E=M.indexOf(K);if(E>-1){P=M.substring(E+1);M=M.substring(0,E);}N=B[M];if(J){N=J(M,N,P);}if(D.isObject(N)){if(D.isArray(N)){N=D.dump(N,parseInt(P,10));}else{P=P||"";var I=P.indexOf(H);if(I>-1){P=P.substring(4);}if(N.toString===Object.prototype.toString||I>-1){N=D.dump(N,parseInt(P,10));}else{N=N.toString();}}}else{if(!D.isString(N)&&!D.isNumber(N)){N="~-"+L.length+"-~";L[L.length]=C;}}Q=Q.substring(0,G)+N+Q.substring(F+1);}for(G=L.length-1;G>=0;G=G-1){Q=Q.replace(new RegExp("~-"+G+"-~"),"{"+L[G]+"}","g");}return Q;},trim:function(A){try{return A.replace(/^\s+|\s+$/g,"");}catch(B){return A;}},merge:function(){var D={},B=arguments;for(var C=0,A=B.length;C<A;C=C+1){YAHOO.lang.augmentObject(D!
 ,B[C],true);}return D;},later:function(H,B,I,D,E){H=H||0;B=B||{};var C=I,G=D,F,A;if(YAHOO.lang.isString(I)){C=B[I];}if(!C){throw new TypeError("method undefined");}if(!YAHOO.lang.isArray(G)){G=[D];}F=function(){C.apply(B,G);};A=(E)?setInterval(F,H):setTimeout(F,H);return{interval:E,cancel:function(){if(this.interval){clearInterval(A);}else{clearTimeout(A);}}};},isValue:function(B){var A=YAHOO.lang;return(A.isObject(B)||A.isString(B)||A.isNumber(B)||A.isBoolean(B));}};YAHOO.util.Lang=YAHOO.lang;YAHOO.lang.augment=YAHOO.lang.augmentProto;YAHOO.augment=YAHOO.lang.augmentProto;YAHOO.extend=YAHOO.lang.extend;YAHOO.register("yahoo",YAHOO,{version:"2.5.1",build:"984"});YAHOO.util.Get=function(){var M={},L=0,Q=0,E=false,N=YAHOO.env.ua,R=YAHOO.lang;var J=function(V,S,W){var T=W||window,X=T.document,Y=X.createElement(V);for(var U in S){if(S[U]&&YAHOO.lang.hasOwnProperty(S,U)){Y.setAttribute(U,S[U]);}}return Y;
+};var H=function(S,T,V){var U=V||"utf-8";return J("link",{"id":"yui__dyn_"+(Q++),"type":"text/css","charset":U,"rel":"stylesheet","href":S},T);};var O=function(S,T,V){var U=V||"utf-8";return J("script",{"id":"yui__dyn_"+(Q++),"type":"text/javascript","charset":U,"src":S},T);};var A=function(S,T){return{tId:S.tId,win:S.win,data:S.data,nodes:S.nodes,msg:T,purge:function(){D(this.tId);}};};var B=function(S,V){var T=M[V],U=(R.isString(S))?T.win.document.getElementById(S):S;if(!U){P(V,"target node not found: "+S);}return U;};var P=function(V,U){var S=M[V];if(S.onFailure){var T=S.scope||S.win;S.onFailure.call(T,A(S,U));}};var C=function(V){var S=M[V];S.finished=true;if(S.aborted){var U="transaction "+V+" was aborted";P(V,U);return ;}if(S.onSuccess){var T=S.scope||S.win;S.onSuccess.call(T,A(S));}};var G=function(U,Y){var T=M[U];if(T.aborted){var W="transaction "+U+" was aborted";P(U,W);return ;}if(Y){T.url.shift();if(T.varName){T.varName.shift();}}else{T.url=(R.isString(T.url))?[T!
 .url]:T.url;if(T.varName){T.varName=(R.isString(T.varName))?[T.varName]:T.varName;}}var b=T.win,a=b.document,Z=a.getElementsByTagName("head")[0],V;if(T.url.length===0){if(T.type==="script"&&N.webkit&&N.webkit<420&&!T.finalpass&&!T.varName){var X=O(null,T.win,T.charset);X.innerHTML='YAHOO.util.Get._finalize("'+U+'");';T.nodes.push(X);Z.appendChild(X);}else{C(U);}return ;}var S=T.url[0];if(T.type==="script"){V=O(S,b,T.charset);}else{V=H(S,b,T.charset);}F(T.type,V,U,S,b,T.url.length);T.nodes.push(V);if(T.insertBefore){var c=B(T.insertBefore,U);if(c){c.parentNode.insertBefore(V,c);}}else{Z.appendChild(V);}if((N.webkit||N.gecko)&&T.type==="css"){G(U,S);}};var K=function(){if(E){return ;}E=true;for(var S in M){var T=M[S];if(T.autopurge&&T.finished){D(T.tId);delete M[S];}}E=false;};var D=function(Z){var W=M[Z];if(W){var Y=W.nodes,S=Y.length,X=W.win.document,V=X.getElementsByTagName("head")[0];if(W.insertBefore){var U=B(W.insertBefore,Z);if(U){V=U.parentNode;}}for(var T=0;T<S;T=T+1!
 ){V.removeChild(Y[T]);}}W.nodes=[];};var I=function(T,S,U){var!
  W="q"+(
L++);U=U||{};if(L%YAHOO.util.Get.PURGE_THRESH===0){K();}M[W]=R.merge(U,{tId:W,type:T,url:S,finished:false,nodes:[]});var V=M[W];V.win=V.win||window;V.scope=V.scope||V.win;V.autopurge=("autopurge" in V)?V.autopurge:(T==="script")?true:false;R.later(0,V,G,W);return{tId:W};};var F=function(b,W,V,T,X,Y,a){var Z=a||G;if(N.ie){W.onreadystatechange=function(){var c=this.readyState;if("loaded"===c||"complete"===c){Z(V,T);}};}else{if(N.webkit){if(b==="script"){if(N.webkit>=420){W.addEventListener("load",function(){Z(V,T);});}else{var S=M[V];if(S.varName){var U=YAHOO.util.Get.POLL_FREQ;S.maxattempts=YAHOO.util.Get.TIMEOUT/U;S.attempts=0;S._cache=S.varName[0].split(".");S.timer=R.later(U,S,function(h){var e=this._cache,d=e.length,c=this.win,f;for(f=0;f<d;f=f+1){c=c[e[f]];if(!c){this.attempts++;if(this.attempts++>this.maxattempts){var g="Over retry limit, giving up";S.timer.cancel();P(V,g);}else{}return ;}}S.timer.cancel();Z(V,T);},null,true);}else{R.later(YAHOO.util.Get.POLL_FREQ,null,!
 Z,[V,T]);}}}}else{W.onload=function(){Z(V,T);};}}};return{POLL_FREQ:10,PURGE_THRESH:20,TIMEOUT:2000,_finalize:function(S){R.later(0,null,C,S);},abort:function(T){var U=(R.isString(T))?T:T.tId;var S=M[U];if(S){S.aborted=true;}},script:function(S,T){return I("script",S,T);},css:function(S,T){return I("css",S,T);}};}();YAHOO.register("get",YAHOO.util.Get,{version:"2.5.1",build:"984"});(function(){var Y=YAHOO,util=Y.util,lang=Y.lang,env=Y.env,PROV="_provides",SUPER="_supersedes",REQ="expanded",AFTER="_after";var YUI={dupsAllowed:{"yahoo":true,"get":true},info:{"base":"http://yui.yahooapis.com/2.5.1/build/","skin":{"defaultSkin":"sam","base":"assets/skins/","path":"skin.css","after":["reset","fonts","grids","base"],"rollup":3},dupsAllowed:["yahoo","get"],"moduleInfo":{"animation":{"type":"js","path":"animation/animation-min.js","requires":["dom","event"]},"autocomplete":{"type":"js","path":"autocomplete/autocomplete-min.js","requires":["dom","event"],"optional":["connection","an!
 imation"],"skinnable":true},"base":{"type":"css","path":"base/!
 base-min
.css","after":["reset","fonts","grids"]},"button":{"type":"js","path":"button/button-min.js","requires":["element"],"optional":["menu"],"skinnable":true},"calendar":{"type":"js","path":"calendar/calendar-min.js","requires":["event","dom"],"skinnable":true},"charts":{"type":"js","path":"charts/charts-experimental-min.js","requires":["element","json","datasource"]},"colorpicker":{"type":"js","path":"colorpicker/colorpicker-min.js","requires":["slider","element"],"optional":["animation"],"skinnable":true},"connection":{"type":"js","path":"connection/connection-min.js","requires":["event"]},"container":{"type":"js","path":"container/container-min.js","requires":["dom","event"],"optional":["dragdrop","animation","connection"],"supersedes":["containercore"],"skinnable":true},"containercore":{"type":"js","path":"container/container_core-min.js","requires":["dom","event"],"pkg":"container"},"cookie":{"type":"js","path":"cookie/cookie-beta-min.js","requires":["yahoo"]},"datasource":{!
 "type":"js","path":"datasource/datasource-beta-min.js","requires":["event"],"optional":["connection"]},"datatable":{"type":"js","path":"datatable/datatable-beta-min.js","requires":["element","datasource"],"optional":["calendar","dragdrop"],"skinnable":true},"dom":{"type":"js","path":"dom/dom-min.js","requires":["yahoo"]},"dragdrop":{"type":"js","path":"dragdrop/dragdrop-min.js","requires":["dom","event"]},"editor":{"type":"js","path":"editor/editor-beta-min.js","requires":["menu","element","button"],"optional":["animation","dragdrop"],"skinnable":true},"element":{"type":"js","path":"element/element-beta-min.js","requires":["dom","event"]},"event":{"type":"js","path":"event/event-min.js","requires":["yahoo"]},"fonts":{"type":"css","path":"fonts/fonts-min.css"},"get":{"type":"js","path":"get/get-min.js","requires":["yahoo"]},"grids":{"type":"css","path":"grids/grids-min.css","requires":["fonts"],"optional":["reset"]},"history":{"type":"js","path":"history/history-min.js","req!
 uires":["event"]},"imagecropper":{"type":"js","path":"imagecro!
 pper/ima
gecropper-beta-min.js","requires":["dom","event","dragdrop","element","resize"],"skinnable":true},"imageloader":{"type":"js","path":"imageloader/imageloader-min.js","requires":["event","dom"]},"json":{"type":"js","path":"json/json-min.js","requires":["yahoo"]},"layout":{"type":"js","path":"layout/layout-beta-min.js","requires":["dom","event","element"],"optional":["animation","dragdrop","resize","selector"],"skinnable":true},"logger":{"type":"js","path":"logger/logger-min.js","requires":["event","dom"],"optional":["dragdrop"],"skinnable":true},"menu":{"type":"js","path":"menu/menu-min.js","requires":["containercore"],"skinnable":true},"profiler":{"type":"js","path":"profiler/profiler-beta-min.js","requires":["yahoo"]},"profilerviewer":{"type":"js","path":"profilerviewer/profilerviewer-beta-min.js","requires":["profiler","yuiloader","element"],"skinnable":true},"reset":{"type":"css","path":"reset/reset-min.css"},"reset-fonts-grids":{"type":"css","path":"reset-fonts-grids/rese!
 t-fonts-grids.css","supersedes":["reset","fonts","grids","reset-fonts"],"rollup":4},"reset-fonts":{"type":"css","path":"reset-fonts/reset-fonts.css","supersedes":["reset","fonts"],"rollup":2},"resize":{"type":"js","path":"resize/resize-beta-min.js","requires":["dom","event","dragdrop","element"],"optional":["animation"],"skinnable":true},"selector":{"type":"js","path":"selector/selector-beta-min.js","requires":["yahoo","dom"]},"simpleeditor":{"type":"js","path":"editor/simpleeditor-beta-min.js","requires":["element"],"optional":["containercore","menu","button","animation","dragdrop"],"skinnable":true,"pkg":"editor"},"slider":{"type":"js","path":"slider/slider-min.js","requires":["dragdrop"],"optional":["animation"]},"tabview":{"type":"js","path":"tabview/tabview-min.js","requires":["element"],"optional":["connection"],"skinnable":true},"treeview":{"type":"js","path":"treeview/treeview-min.js","requires":["event"],"skinnable":true},"uploader":{"type":"js","path":"uploader/up!
 loader-experimental.js","requires":["yahoo"]},"utilities":{"ty!
 pe":"js"
,"path":"utilities/utilities.js","supersedes":["yahoo","event","dragdrop","animation","dom","connection","element","yahoo-dom-event","get","yuiloader","yuiloader-dom-event"],"rollup":8},"yahoo":{"type":"js","path":"yahoo/yahoo-min.js"},"yahoo-dom-event":{"type":"js","path":"yahoo-dom-event/yahoo-dom-event.js","supersedes":["yahoo","event","dom"],"rollup":3},"yuiloader":{"type":"js","path":"yuiloader/yuiloader-beta-min.js","supersedes":["yahoo","get"]},"yuiloader-dom-event":{"type":"js","path":"yuiloader-dom-event/yuiloader-dom-event.js","supersedes":["yahoo","dom","event","get","yuiloader","yahoo-dom-event"],"rollup":5},"yuitest":{"type":"js","path":"yuitest/yuitest-min.js","requires":["logger"],"skinnable":true}}},ObjectUtil:{appendArray:function(o,a){if(a){for(var i=0;
+i<a.length;i=i+1){o[a[i]]=true;}}},keys:function(o,ordered){var a=[],i;for(i in o){if(lang.hasOwnProperty(o,i)){a.push(i);}}return a;}},ArrayUtil:{appendArray:function(a1,a2){Array.prototype.push.apply(a1,a2);},indexOf:function(a,val){for(var i=0;i<a.length;i=i+1){if(a[i]===val){return i;}}return -1;},toObject:function(a){var o={};for(var i=0;i<a.length;i=i+1){o[a[i]]=true;}return o;},uniq:function(a){return YUI.ObjectUtil.keys(YUI.ArrayUtil.toObject(a));}}};YAHOO.util.YUILoader=function(o){this._internalCallback=null;this._useYahooListener=false;this.onSuccess=null;this.onFailure=Y.log;this.onProgress=null;this.scope=this;this.data=null;this.insertBefore=null;this.charset=null;this.varName=null;this.base=YUI.info.base;this.ignore=null;this.force=null;this.allowRollup=true;this.filter=null;this.required={};this.moduleInfo=lang.merge(YUI.info.moduleInfo);this.rollups=null;this.loadOptional=false;this.sorted=[];this.loaded={};this.dirty=true;this.inserted={};var self=this;env!
 .listeners.push(function(m){if(self._useYahooListener){self.loadNext(m.name);}});this.skin=lang.merge(YUI.info.skin);this._config(o);};Y.util.YUILoader.prototype={FILTERS:{RAW:{"searchExp":"-min\\.js","replaceStr":".js"},DEBUG:{"searchExp":"-min\\.js","replaceStr":"-debug.js"}},SKIN_PREFIX:"skin-",_config:function(o){if(o){for(var i in o){if(lang.hasOwnProperty(o,i)){if(i=="require"){this.require(o[i]);}else{this[i]=o[i];}}}}var f=this.filter;if(lang.isString(f)){f=f.toUpperCase();if(f==="DEBUG"){this.require("logger");}if(!Y.widget.LogWriter){Y.widget.LogWriter=function(){return Y;};}this.filter=this.FILTERS[f];}},addModule:function(o){if(!o||!o.name||!o.type||(!o.path&&!o.fullpath)){return false;}o.ext=("ext" in o)?o.ext:true;o.requires=o.requires||[];this.moduleInfo[o.name]=o;this.dirty=true;return true;},require:function(what){var a=(typeof what==="string")?arguments:what;this.dirty=true;YUI.ObjectUtil.appendArray(this.required,a);},_addSkin:function(skin,mod){var name=!
 this.formatSkin(skin),info=this.moduleInfo,sinf=this.skin,ext=!
 info[mod
]&&info[mod].ext;if(!info[name]){this.addModule({"name":name,"type":"css","path":sinf.base+skin+"/"+sinf.path,"after":sinf.after,"rollup":sinf.rollup,"ext":ext});}if(mod){name=this.formatSkin(skin,mod);if(!info[name]){var mdef=info[mod],pkg=mdef.pkg||mod;this.addModule({"name":name,"type":"css","after":sinf.after,"path":pkg+"/"+sinf.base+skin+"/"+mod+".css","ext":ext});}}return name;},getRequires:function(mod){if(!mod){return[];}if(!this.dirty&&mod.expanded){return mod.expanded;}mod.requires=mod.requires||[];var i,d=[],r=mod.requires,o=mod.optional,info=this.moduleInfo,m;for(i=0;i<r.length;i=i+1){d.push(r[i]);m=info[r[i]];YUI.ArrayUtil.appendArray(d,this.getRequires(m));}if(o&&this.loadOptional){for(i=0;i<o.length;i=i+1){d.push(o[i]);YUI.ArrayUtil.appendArray(d,this.getRequires(info[o[i]]));}}mod.expanded=YUI.ArrayUtil.uniq(d);return mod.expanded;},getProvides:function(name,notMe){var addMe=!(notMe),ckey=(addMe)?PROV:SUPER,m=this.moduleInfo[name],o={};if(!m){return o;}if(m[c!
 key]){return m[ckey];}var s=m.supersedes,done={},me=this;var add=function(mm){if(!done[mm]){done[mm]=true;lang.augmentObject(o,me.getProvides(mm));}};if(s){for(var i=0;i<s.length;i=i+1){add(s[i]);}}m[SUPER]=o;m[PROV]=lang.merge(o);m[PROV][name]=true;return m[ckey];},calculate:function(o){if(this.dirty){this._config(o);this._setup();this._explode();if(this.allowRollup){this._rollup();}this._reduce();this._sort();this.dirty=false;}},_setup:function(){var info=this.moduleInfo,name,i,j;for(name in info){var m=info[name];if(m&&m.skinnable){var o=this.skin.overrides,smod;if(o&&o[name]){for(i=0;i<o[name].length;i=i+1){smod=this._addSkin(o[name][i],name);}}else{smod=this._addSkin(this.skin.defaultSkin,name);}m.requires.push(smod);}}var l=lang.merge(this.inserted);if(!this._sandbox){l=lang.merge(l,env.modules);}if(this.ignore){YUI.ObjectUtil.appendArray(l,this.ignore);}if(this.force){for(i=0;i<this.force.length;i=i+1){if(this.force[i] in l){delete l[this.force[i]];}}}for(j in l){if(!
 lang.hasOwnProperty(l,j)){lang.augmentObject(l,this.getProvide!
 s(j));}}
this.loaded=l;},_explode:function(){var r=this.required,i,mod;for(i in r){mod=this.moduleInfo[i];if(mod){var req=this.getRequires(mod);if(req){YUI.ObjectUtil.appendArray(r,req);}}}},_skin:function(){},formatSkin:function(skin,mod){var s=this.SKIN_PREFIX+skin;if(mod){s=s+"-"+mod;}return s;},parseSkin:function(mod){if(mod.indexOf(this.SKIN_PREFIX)===0){var a=mod.split("-");return{skin:a[1],module:a[2]};}return null;},_rollup:function(){var i,j,m,s,rollups={},r=this.required,roll;if(this.dirty||!this.rollups){for(i in this.moduleInfo){m=this.moduleInfo[i];if(m&&m.rollup){rollups[i]=m;}}this.rollups=rollups;}for(;;){var rolled=false;for(i in rollups){if(!r[i]&&!this.loaded[i]){m=this.moduleInfo[i];s=m.supersedes;roll=false;if(!m.rollup){continue;}var skin=(m.ext)?false:this.parseSkin(i),c=0;if(skin){for(j in r){if(i!==j&&this.parseSkin(j)){c++;roll=(c>=m.rollup);if(roll){break;}}}}else{for(j=0;j<s.length;j=j+1){if(this.loaded[s[j]]&&(!YUI.dupsAllowed[s[j]])){roll=false;break;}el!
 se{if(r[s[j]]){c++;roll=(c>=m.rollup);if(roll){break;}}}}}if(roll){r[i]=true;rolled=true;this.getRequires(m);}}}if(!rolled){break;}}},_reduce:function(){var i,j,s,m,r=this.required;for(i in r){if(i in this.loaded){delete r[i];}else{var skinDef=this.parseSkin(i);if(skinDef){if(!skinDef.module){var skin_pre=this.SKIN_PREFIX+skinDef.skin;for(j in r){m=this.moduleInfo[j];var ext=m&&m.ext;if(!ext&&j!==i&&j.indexOf(skin_pre)>-1){delete r[j];}}}}else{m=this.moduleInfo[i];s=m&&m.supersedes;if(s){for(j=0;j<s.length;j=j+1){if(s[j] in r){delete r[s[j]];}}}}}}},_sort:function(){var s=[],info=this.moduleInfo,loaded=this.loaded,me=this;var requires=function(aa,bb){if(loaded[bb]){return false;}var ii,mm=info[aa],rr=mm&&mm.expanded,after=mm&&mm.after,other=info[bb];if(rr&&YUI.ArrayUtil.indexOf(rr,bb)>-1){return true;}if(after&&YUI.ArrayUtil.indexOf(after,bb)>-1){return true;}var ss=info[bb]&&info[bb].supersedes;if(ss){for(ii=0;
+ii<ss.length;ii=ii+1){if(requires(aa,ss[ii])){return true;}}}if(mm.ext&&mm.type=="css"&&(!other.ext)){return true;}return false;};for(var i in this.required){s.push(i);}var p=0;for(;;){var l=s.length,a,b,j,k,moved=false;for(j=p;j<l;j=j+1){a=s[j];for(k=j+1;k<l;k=k+1){if(requires(a,s[k])){b=s.splice(k,1);s.splice(j,0,b[0]);moved=true;break;}}if(moved){break;}else{p=p+1;}}if(!moved){break;}}this.sorted=s;},toString:function(){var o={type:"YUILoader",base:this.base,filter:this.filter,required:this.required,loaded:this.loaded,inserted:this.inserted};lang.dump(o,1);},insert:function(o,type){this.calculate(o);if(!type){var self=this;this._internalCallback=function(){self._internalCallback=null;self.insert(null,"js");};this.insert(null,"css");return ;}this._loading=true;this.loadType=type;this.loadNext();},sandbox:function(o,type){if(o){}else{}this._config(o);if(!this.onSuccess){throw new Error("You must supply an onSuccess handler for your sandbox");}this._sandbox=true;var self=th!
 is;if(!type||type!=="js"){this._internalCallback=function(){self._internalCallback=null;self.sandbox(null,"js");};this.insert(null,"css");return ;}if(!util.Connect){var ld=new YAHOO.util.YUILoader();ld.insert({base:this.base,filter:this.filter,require:"connection",insertBefore:this.insertBefore,charset:this.charset,onSuccess:function(){this.sandbox(null,"js");},scope:this},"js");return ;}this._scriptText=[];this._loadCount=0;this._stopCount=this.sorted.length;this._xhr=[];this.calculate();var s=this.sorted,l=s.length,i,m,url;for(i=0;i<l;i=i+1){m=this.moduleInfo[s[i]];if(!m){this.onFailure.call(this.scope,{msg:"undefined module "+m,data:this.data});for(var j=0;j<this._xhr.length;j=j+1){this._xhr[j].abort();}return ;}if(m.type!=="js"){this._loadCount++;continue;}url=m.fullpath||this._url(m.path);var xhrData={success:function(o){var idx=o.argument[0],name=o.argument[2];this._scriptText[idx]=o.responseText;if(this.onProgress){this.onProgress.call(this.scope,{name:name,scriptTex!
 t:o.responseText,xhrResponse:o,data:this.data});}this._loadCou!
 nt++;if(
this._loadCount>=this._stopCount){var v=this.varName||"YAHOO";var t="(function() {\n";var b="\nreturn "+v+";\n})();";var ref=eval(t+this._scriptText.join("\n")+b);this._pushEvents(ref);if(ref){this.onSuccess.call(this.scope,{reference:ref,data:this.data});}else{this.onFailure.call(this.scope,{msg:this.varName+" reference failure",data:this.data});}}},failure:function(o){this.onFailure.call(this.scope,{msg:"XHR failure",xhrResponse:o,data:this.data});},scope:this,argument:[i,url,s[i]]};this._xhr.push(util.Connect.asyncRequest("GET",url,xhrData));}},loadNext:function(mname){if(!this._loading){return ;}if(mname){if(mname!==this._loading){return ;}this.inserted[mname]=true;if(this.onProgress){this.onProgress.call(this.scope,{name:mname,data:this.data});}}var s=this.sorted,len=s.length,i,m;for(i=0;i<len;i=i+1){if(s[i] in this.inserted){continue;}if(s[i]===this._loading){return ;}m=this.moduleInfo[s[i]];if(!m){this.onFailure.call(this.scope,{msg:"undefined module "+m,data:this.dat!
 a});return ;}if(!this.loadType||this.loadType===m.type){this._loading=s[i];var fn=(m.type==="css")?util.Get.css:util.Get.script,url=m.fullpath||this._url(m.path),self=this,c=function(o){self.loadNext(o.data);};if(env.ua.webkit&&env.ua.webkit<420&&m.type==="js"&&!m.varName){c=null;this._useYahooListener=true;}fn(url,{data:s[i],onSuccess:c,insertBefore:this.insertBefore,charset:this.charset,varName:m.varName,scope:self});return ;}}this._loading=null;if(this._internalCallback){var f=this._internalCallback;this._internalCallback=null;f.call(this);}else{if(this.onSuccess){this._pushEvents();this.onSuccess.call(this.scope,{data:this.data});}}},_pushEvents:function(ref){var r=ref||YAHOO;if(r.util&&r.util.Event){r.util.Event._load();}},_url:function(path){var u=this.base||"",f=this.filter;u=u+path;if(f){u=u.replace(new RegExp(f.searchExp),f.replaceStr);}return u;}};})();
\ No newline at end of file

Modified: trunk/root/static/yui/yuiloader/yuiloader-beta.js
===================================================================
--- trunk/root/static/yui/yuiloader/yuiloader-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuiloader/yuiloader-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 /**
  * The YAHOO object is the single global object used by YUI Library.  It
@@ -272,16 +272,25 @@
          * Safari 2.0.4:         418     <-- preventDefault fixed
          * Safari 2.0.4 (419.3): 418.9.1 <-- One version of Safari may run
          *                                   different versions of webkit
-         * Safari 2.0.4 (419.3): 419     <-- Current Safari release
-         * Webkit 212 nightly:   522+    <-- Safari 3.0 (with native SVG) should
-         *                                   be higher than this
+         * Safari 2.0.4 (419.3): 419     <-- Tiger installations that have been
+         *                                   updated, but not updated
+         *                                   to the latest patch.
+         * Webkit 212 nightly:   522+    <-- Safari 3.0 precursor (with native SVG
+         *                                   and many major issues fixed).  
+         * 3.x yahoo.com, flickr:422     <-- Safari 3.x hacks the user agent
+         *                                   string when hitting yahoo.com and 
+         *                                   flickr.com.
+         * Safari 3.0.4 (523.12):523.12  <-- First Tiger release - automatic update
+         *                                   from 2.x via the 10.4.11 OS patch
+         * Webkit nightly 1/2008:525+    <-- Supports DOMContentLoaded event.
+         *                                   yahoo.com user agent hack removed.
          *                                   
          * </pre>
          * http://developer.apple.com/internet/safari/uamatrix.html
          * @property webkit
          * @type float
          */
-        webkit:0,
+        webkit: 0,
 
         /**
          * The mobile property will be set to a string containing any relevant
@@ -291,7 +300,16 @@
          * @property mobile 
          * @type string
          */
-        mobile: null 
+        mobile: null,
+
+        /**
+         * Adobe AIR version number or 0.  Only populated if webkit is detected.
+         * Example: 1.0
+         * @property air
+         * @type float
+         */
+        air: 0
+
     };
 
     var ua=navigator.userAgent, m;
@@ -315,6 +333,11 @@
             }
         }
 
+        m=ua.match(/AdobeAIR\/([^\s]*)/);
+        if (m) {
+            o.air = m[0]; // Adobe AIR 1.0 or better
+        }
+
     }
 
     if (!o.webkit) { // not webkit
@@ -388,10 +411,9 @@
      * properties.
      * @method isArray
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isArray: function(o) { 
-
         if (o) {
            var l = YAHOO.lang;
            return l.isNumber(o.length) && l.isFunction(o.splice);
@@ -403,7 +425,7 @@
      * Determines whether or not the provided object is a boolean
      * @method isBoolean
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isBoolean: function(o) {
         return typeof o === 'boolean';
@@ -413,7 +435,7 @@
      * Determines whether or not the provided object is a function
      * @method isFunction
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isFunction: function(o) {
         return typeof o === 'function';
@@ -423,7 +445,7 @@
      * Determines whether or not the provided object is null
      * @method isNull
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isNull: function(o) {
         return o === null;
@@ -433,7 +455,7 @@
      * Determines whether or not the provided object is a legal number
      * @method isNumber
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isNumber: function(o) {
         return typeof o === 'number' && isFinite(o);
@@ -444,7 +466,7 @@
      * or function
      * @method isObject
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */  
     isObject: function(o) {
 return (o && (typeof o === 'object' || YAHOO.lang.isFunction(o))) || false;
@@ -454,7 +476,7 @@
      * Determines whether or not the provided object is a string
      * @method isString
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isString: function(o) {
         return typeof o === 'string';
@@ -464,7 +486,7 @@
      * Determines whether or not the provided object is undefined
      * @method isUndefined
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     isUndefined: function(o) {
         return typeof o === 'undefined';
@@ -488,7 +510,7 @@
      * </pre>
      * @method hasOwnProperty
      * @param {any} o The object being testing
-     * @return Boolean
+     * @return {boolean} the result
      */
     hasOwnProperty: function(o, prop) {
         if (Object.prototype.hasOwnProperty) {
@@ -827,14 +849,14 @@
     },
 
     /**
-     * Executes the supplied function in the scope of the supplied 
+     * Executes the supplied function in the context of the supplied 
      * object 'when' milliseconds later.  Executes the function a 
      * single time unless periodic is set to true.
      * @method later
      * @since 2.4.0
      * @param when {int} the number of milliseconds to wait until the fn 
      * is executed
-     * @param o the scope object
+     * @param o the context object
      * @param fn {Function|String} the function to execute or the name of 
      * the method in the 'o' object to execute
      * @param data [Array] data that is provided to the function.  This accepts
@@ -881,7 +903,7 @@
             }
         };
     },
-
+    
     /**
      * A convenience method for detecting a legitimate non-null value.
      * Returns false for null/undefined/NaN, true for other values, 
@@ -949,7 +971,7 @@
  */
 YAHOO.extend = YAHOO.lang.extend;
 
-YAHOO.register("yahoo", YAHOO, {version: "2.4.1", build: "742"});
+YAHOO.register("yahoo", YAHOO, {version: "2.5.1", build: "984"});
 /**
  * Provides a mechanism to fetch remote resources and
  * insert them into a document
@@ -1033,12 +1055,14 @@
      * @return {HTMLElement} the generated node
      * @private
      */
-    var _linkNode = function(url, win) {
+    var _linkNode = function(url, win, charset) {
+        var c = charset || "utf-8";
         return _node("link", {
-                "id": "yui__dyn_" + (nidx++),
-                "type": "text/css",
-                "rel": "stylesheet",
-                "href": url
+                "id":      "yui__dyn_" + (nidx++),
+                "type":    "text/css",
+                "charset": c,
+                "rel":     "stylesheet",
+                "href":    url
             }, win);
     };
 
@@ -1050,11 +1074,13 @@
      * @return {HTMLElement} the generated node
      * @private
      */
-    var _scriptNode = function(url, win) {
+    var _scriptNode = function(url, win, charset) {
+        var c = charset || "utf-8";
         return _node("script", {
-                "id": "yui__dyn_" + (nidx++),
-                "type": "text/javascript",
-                "src": url
+                "id":      "yui__dyn_" + (nidx++),
+                "type":    "text/javascript",
+                "charset": c,
+                "src":     url
             }, win);
     };
 
@@ -1063,18 +1089,29 @@
      * @method _returnData
      * @private
      */
-    var _returnData = function(q) {
+    var _returnData = function(q, msg) {
         return {
                 tId: q.tId,
                 win: q.win,
                 data: q.data,
                 nodes: q.nodes,
+                msg: msg,
                 purge: function() {
                     _purge(this.tId);
                 }
             };
     };
 
+    var _get = function(nId, tId) {
+        var q = queues[tId],
+            n = (lang.isString(nId)) ? q.win.document.getElementById(nId) : nId;
+        if (!n) {
+            _fail(tId, "target node not found: " + nId);
+        }
+
+        return n;
+    };
+
     /*
      * The request failed, execute fail handler with whatever
      * was accomplished.  There isn't a failure case at the
@@ -1083,12 +1120,12 @@
      * @param id {string} the id of the request
      * @private
      */
-    var _fail = function(id) {
+    var _fail = function(id, msg) {
         var q = queues[id];
         // execute failure callback
         if (q.onFailure) {
             var sc=q.scope || q.win;
-            q.onFailure.call(sc, _returnData(q));
+            q.onFailure.call(sc, _returnData(q, msg));
         }
     };
 
@@ -1103,7 +1140,8 @@
         q.finished = true;
 
         if (q.aborted) {
-            _fail(id);
+            var msg = "transaction " + id + " was aborted";
+            _fail(id, msg);
             return;
         }
 
@@ -1125,7 +1163,8 @@
         var q = queues[id];
 
         if (q.aborted) {
-            _fail(id);
+            var msg = "transaction " + id + " was aborted";
+            _fail(id, msg);
             return;
         }
 
@@ -1158,7 +1197,7 @@
                 // arbitrary timeout.  It is possible that the browser does
                 // block subsequent script execution in this case for a limited
                 // time.
-                var extra = _scriptNode(null, q.win);
+                var extra = _scriptNode(null, q.win, q.charset);
                 extra.innerHTML='YAHOO.util.Get._finalize("' + id + '");';
                 q.nodes.push(extra); h.appendChild(extra);
 
@@ -1173,9 +1212,9 @@
         var url = q.url[0];
 
         if (q.type === "script") {
-            n = _scriptNode(url, w);
+            n = _scriptNode(url, w, q.charset);
         } else {
-            n = _linkNode(url, w);
+            n = _linkNode(url, w, q.charset);
         }
 
         // track this node's load progress
@@ -1184,8 +1223,15 @@
         // add the node to the queue so we can return it to the user supplied callback
         q.nodes.push(n);
 
-        // add it to the head
-        h.appendChild(n);
+        // add it to the head or insert it before 'insertBefore'
+        if (q.insertBefore) {
+            var s = _get(q.insertBefore, id);
+            if (s) {
+                s.parentNode.insertBefore(n, s);
+            }
+        } else {
+            h.appendChild(n);
+        }
         
 
         // FireFox does not support the onload event for link nodes, so there is
@@ -1213,6 +1259,7 @@
             var q = queues[i];
             if (q.autopurge && q.finished) {
                 _purge(q.tId);
+                delete queues[i];
             }
         }
 
@@ -1229,10 +1276,19 @@
         if (q) {
             var n=q.nodes, l=n.length, d=q.win.document, 
                 h=d.getElementsByTagName("head")[0];
+
+            if (q.insertBefore) {
+                var s = _get(q.insertBefore, tId);
+                if (s) {
+                    h = s.parentNode;
+                }
+            }
+
             for (var i=0; i<l; i=i+1) {
                 h.removeChild(n[i]);
             }
         }
+        q.nodes = [];
     };
 
     /**
@@ -1308,7 +1364,7 @@
             if (type === "script") {
 
                 // Safari 3.x supports the load event for script nodes (DOM2)
-                if (ua.webkit > 419) {
+                if (ua.webkit >= 420) {
 
                     n.addEventListener("load", function() {
                         f(id, url);
@@ -1339,8 +1395,9 @@
                                     // if we have exausted our attempts, give up
                                     this.attempts++;
                                     if (this.attempts++ > this.maxattempts) {
+                                        var msg = "Over retry limit, giving up";
                                         q.timer.cancel();
-                                        _fail(id);
+                                        _fail(id, msg);
                                     } else {
                                     }
                                     return;
@@ -1493,7 +1550,11 @@
          * must supply an array that contains the variable name for
          * each script.
          * </dd>
+         * <dt>insertBefore</dt>
+         * <dd>node or node id that will become the new node's nextSibling</dd>
          * </dl>
+         * <dt>charset</dt>
+         * <dd>Node charset, default utf-8</dd>
          * <pre>
          * // assumes yahoo, dom, and event are already on the page
          *   YAHOO.util.Get.script(
@@ -1553,6 +1614,10 @@
          * data that is supplied to the callbacks when the nodes(s) are
          * loaded.
          * </dd>
+         * <dt>insertBefore</dt>
+         * <dd>node or node id that will become the new node's nextSibling</dd>
+         * <dt>charset</dt>
+         * <dd>Node charset, default utf-8</dd>
          * </dl>
          * <pre>
          *      YAHOO.util.Get.css("http://yui.yahooapis.com/2.3.1/build/menu/assets/skins/sam/menu.css");
@@ -1568,7 +1633,7 @@
     };
 }();
 
-YAHOO.register("get", YAHOO.util.Get, {version: "2.4.1", build: "742"});
+YAHOO.register("get", YAHOO.util.Get, {version: "2.5.1", build: "984"});
 /**
  * Provides dynamic loading for the YUI library.  It includes the dependency
  * info for the library, and will automatically pull in dependencies for
@@ -1589,7 +1654,9 @@
  */
 (function() {
 
-    var Y=YAHOO, util=Y.util, lang=Y.lang, env=Y.env;
+    var Y=YAHOO, util=Y.util, lang=Y.lang, env=Y.env,
+        PROV = "_provides", SUPER = "_supersedes",
+        REQ = "expanded", AFTER = "_after";
  
     var YUI = {
 
@@ -1602,16 +1669,18 @@
          * @static
          */
         info: {
+    'base': 'http://yui.yahooapis.com/2.5.1/build/',
 
-    'base': 'http://yui.yahooapis.com/2.4.1/build/',
-
     'skin': {
         'defaultSkin': 'sam',
         'base': 'assets/skins/',
         'path': 'skin.css',
+        'after': ['reset', 'fonts', 'grids', 'base'],
         'rollup': 3
     },
 
+    dupsAllowed: ['yahoo', 'get'],
+
     'moduleInfo': {
 
         'animation': {
@@ -1630,7 +1699,8 @@
 
         'base': {
             'type': 'css',
-            'path': 'base/base-min.css'
+            'path': 'base/base-min.css',
+            'after': ['reset', 'fonts', 'grids']
         },
 
         'button': {
@@ -1656,7 +1726,7 @@
 
         'colorpicker': {
             'type': 'js',
-            'path': 'colorpicker/colorpicker-beta-min.js',
+            'path': 'colorpicker/colorpicker-min.js',
             'requires': ['slider', 'element'],
             'optional': ['animation'],
             'skinnable': true
@@ -1672,8 +1742,9 @@
             'type': 'js',
             'path': 'container/container-min.js',
             'requires': ['dom', 'event'],
-            // button is optional, but creates a circular dep
-            //'optional': ['dragdrop', 'animation', 'connection', 'connection', 'button'],
+            // button is also optional, but this creates a circular 
+            // dependency when loadOptional is specified.  button
+            // optionally includes menu, menu requires container.
             'optional': ['dragdrop', 'animation', 'connection'],
             'supersedes': ['containercore'],
             'skinnable': true
@@ -1686,6 +1757,12 @@
             'pkg': 'container'
         },
 
+        'cookie': {
+            'type': 'js',
+            'path': 'cookie/cookie-beta-min.js',
+            'requires': ['yahoo']
+        },
+
         'datasource': {
             'type': 'js',
             'path': 'datasource/datasource-beta-min.js',
@@ -1740,7 +1817,7 @@
 
         'get': {
             'type': 'js',
-            'path': 'get/get-beta-min.js',
+            'path': 'get/get-min.js',
             'requires': ['yahoo']
         },
 
@@ -1757,18 +1834,33 @@
             'requires': ['event']
         },
 
-        'imageloader': {
+         'imagecropper': {
+             'type': 'js',
+             'path': 'imagecropper/imagecropper-beta-min.js',
+             'requires': ['dom', 'event', 'dragdrop', 'element', 'resize'],
+             'skinnable': true
+         },
+
+         'imageloader': {
             'type': 'js',
-            'path': 'imageloader/imageloader-beta-min.js',
+            'path': 'imageloader/imageloader-min.js',
             'requires': ['event', 'dom']
-        },
+         },
 
-        'json': {
+         'json': {
             'type': 'js',
-            'path': 'json/json-beta-min.js',
+            'path': 'json/json-min.js',
             'requires': ['yahoo']
-        },
+         },
 
+         'layout': {
+             'type': 'js',
+             'path': 'layout/layout-beta-min.js',
+             'requires': ['dom', 'event', 'element'],
+             'optional': ['animation', 'dragdrop', 'resize', 'selector'],
+             'skinnable': true
+         }, 
+
         'logger': {
             'type': 'js',
             'path': 'logger/logger-min.js',
@@ -1784,6 +1876,20 @@
             'skinnable': true
         },
 
+        'profiler': {
+            'type': 'js',
+            'path': 'profiler/profiler-beta-min.js',
+            'requires': ['yahoo']
+        },
+
+
+        'profilerviewer': {
+            'type': 'js',
+            'path': 'profilerviewer/profilerviewer-beta-min.js',
+            'requires': ['profiler', 'yuiloader', 'element'],
+            'skinnable': true
+        },
+
         'reset': {
             'type': 'css',
             'path': 'reset/reset-min.css'
@@ -1793,7 +1899,7 @@
             'type': 'css',
             'path': 'reset-fonts-grids/reset-fonts-grids.css',
             'supersedes': ['reset', 'fonts', 'grids', 'reset-fonts'],
-            'rollup': 3
+            'rollup': 4
         },
 
         'reset-fonts': {
@@ -1803,6 +1909,14 @@
             'rollup': 2
         },
 
+         'resize': {
+             'type': 'js',
+             'path': 'resize/resize-beta-min.js',
+             'requires': ['dom', 'event', 'dragdrop', 'element'],
+             'optional': ['animation'],
+             'skinnable': true
+         },
+
         'selector': {
             'type': 'js',
             'path': 'selector/selector-beta-min.js',
@@ -1840,11 +1954,17 @@
             'skinnable': true
         },
 
+        'uploader': {
+            'type': 'js',
+            'path': 'uploader/uploader-experimental.js',
+            'requires': ['yahoo']
+        },
+
         'utilities': {
             'type': 'js',
             'path': 'utilities/utilities.js',
-            'supersedes': ['yahoo', 'event', 'dragdrop', 'animation', 'dom', 'connection', 'element', 'yahoo-dom-event'],
-            'rollup': 6
+            'supersedes': ['yahoo', 'event', 'dragdrop', 'animation', 'dom', 'connection', 'element', 'yahoo-dom-event', 'get', 'yuiloader', 'yuiloader-dom-event'],
+            'rollup': 8
         },
 
         'yahoo': {
@@ -1861,12 +1981,20 @@
 
         'yuiloader': {
             'type': 'js',
-            'path': 'yuiloader/yuiloader-beta-min.js'
+            'path': 'yuiloader/yuiloader-beta-min.js',
+            'supersedes': ['yahoo', 'get']
         },
 
+        'yuiloader-dom-event': {
+            'type': 'js',
+            'path': 'yuiloader-dom-event/yuiloader-dom-event.js',
+            'supersedes': ['yahoo', 'dom', 'event', 'get', 'yuiloader', 'yahoo-dom-event'],
+            'rollup': 5
+        },
+
         'yuitest': {
             'type': 'js',
-            'path': 'yuitest/yuitest-beta-min.js',
+            'path': 'yuitest/yuitest-min.js',
             'requires': ['logger'],
             'skinnable': true
         }
@@ -1990,6 +2118,21 @@
         this.data = null;
 
         /**
+         * Node reference or id where new nodes should be inserted before
+         * @property insertBefore
+         * @type string|HTMLElement
+         */
+        this.insertBefore = null;
+
+        /**
+         * The charset attribute for inserted nodes
+         * @property charset
+         * @type string
+         * @default utf-8
+         */
+        this.charset = null;
+
+        /**
          * The name of the variable in a sandbox or script node 
          * (for external script support in Safari 2.x and earlier)
          * to reference when the load is complete.  If this variable 
@@ -2020,7 +2163,7 @@
          * A list of modules that should always be loaded, even
          * if they have already been inserted into the page.
          * @property force
-         * @type string
+         * @type string[]
          */
         this.force = null;
 
@@ -2191,44 +2334,43 @@
 
         _config: function(o) {
 
-            if (!o) {
-                return;
-            }
-
-            // lang.augmentObject(this, o);
-
             // apply config values
-            for (var i in o) {
-                if (lang.hasOwnProperty(o, i)) {
-                    switch (i) {
-                        case "require":
+            if (o) {
+                for (var i in o) {
+                    if (lang.hasOwnProperty(o, i)) {
+                        if (i == "require") {
                             this.require(o[i]);
-                            break;
+                        } else {
+                            this[i] = o[i];
+                        }
+                    }
+                }
+            }
 
-                        case "filter":
-                            var f = o[i];
+            // fix filter
+            var f = this.filter;
 
-                            if (typeof f === "string") {
-                                f = f.toUpperCase();
+            if (lang.isString(f)) {
+                f = f.toUpperCase();
 
-                                // the logger must be available in order to use the debug
-                                // versions of the library
-                                if (f === "DEBUG") {
-                                    this.require("logger");
-                                }
+                // the logger must be available in order to use the debug
+                // versions of the library
+                if (f === "DEBUG") {
+                    this.require("logger");
+                }
 
-                                this.filter = this.FILTERS[f];
-                            } else {
-                                this.filter = f;
-                            }
+                // hack to handle a a bug where LogWriter is being instantiated
+                // at load time, and the loader has no way to sort above it
+                // at the moment.
+                if (!Y.widget.LogWriter) {
+                    Y.widget.LogWriter = function() {
+                        return Y;
+                    };
+                }
 
-                            break;
+                this.filter = this.FILTERS[f];
+            }
 
-                        default:
-                            this[i] = o[i];
-                    }
-                }
-            }
         },
 
         /** Add a new module to the component metadata.         
@@ -2236,9 +2378,10 @@
          *     <dt>name:</dt>       <dd>required, the component name</dd>
          *     <dt>type:</dt>       <dd>required, the component type (js or css)</dd>
          *     <dt>path:</dt>       <dd>required, the path to the script from "base"</dd>
-         *     <dt>requires:</dt>   <dd>the modules required by this component</dd>
-         *     <dt>optional:</dt>   <dd>the optional modules for this component</dd>
-         *     <dt>supersedes:</dt> <dd>the modules this component replaces</dd>
+         *     <dt>requires:</dt>   <dd>array of modules required by this component</dd>
+         *     <dt>optional:</dt>   <dd>array of optional modules for this component</dd>
+         *     <dt>supersedes:</dt> <dd>array of the modules this component replaces</dd>
+         *     <dt>after:</dt>      <dd>array of modules the components which, if present, should be sorted above this one</dd>
          *     <dt>rollup:</dt>     <dd>the number of superseded modules required for automatic rollup</dd>
          *     <dt>fullpath:</dt>   <dd>If fullpath is specified, this is used instead of the configured base + path</dd>
          *     <dt>skinnable:</dt>  <dd>flag to determine if skin assets should automatically be pulled in</dd>
@@ -2254,6 +2397,9 @@
                 return false;
             }
 
+            o.ext = ('ext' in o) ? o.ext : true;
+            o.requires = o.requires || [];
+
             this.moduleInfo[o.name] = o;
             this.dirty = true;
 
@@ -2267,54 +2413,55 @@
          */
         require: function(what) {
             var a = (typeof what === "string") ? arguments : what;
-
             this.dirty = true;
-
-            for (var i=0; i<a.length; i=i+1) {
-                this.required[a[i]] = true;
-                var s = this.parseSkin(a[i]);
-                if (s) {
-                    this._addSkin(s.skin, s.module);
-                }
-            }
             YUI.ObjectUtil.appendArray(this.required, a);
         },
 
-
         /**
          * Adds the skin def to the module info
          * @method _addSkin
+         * @param skin {string} the name of the skin
+         * @param mod {string} the name of the module
+         * @return {string} the module name for the skin
          * @private
          */
         _addSkin: function(skin, mod) {
 
             // Add a module definition for the skin rollup css
-            var name = this.formatSkin(skin);
-            if (!this.moduleInfo[name]) {
+            var name = this.formatSkin(skin), info = this.moduleInfo,
+                sinf = this.skin, ext = info[mod] && info[mod].ext;
+
+            // Y.log('ext? ' + mod + ": " + ext);
+            if (!info[name]) {
+                // Y.log('adding skin ' + name);
                 this.addModule({
                     'name': name,
                     'type': 'css',
-                    'path': this.skin.base + skin + "/" + this.skin.path,
+                    'path': sinf.base + skin + '/' + sinf.path,
                     //'supersedes': '*',
-                    'rollup': this.skin.rollup
+                    'after': sinf.after,
+                    'rollup': sinf.rollup,
+                    'ext': ext
                 });
             }
 
             // Add a module definition for the module-specific skin css
             if (mod) {
                 name = this.formatSkin(skin, mod);
-                if (!this.moduleInfo[name]) {
-                    var mdef = this.moduleInfo[mod];
-                    var pkg = mdef.pkg || mod;
+                if (!info[name]) {
+                    var mdef = info[mod], pkg = mdef.pkg || mod;
+                    // Y.log('adding skin ' + name);
                     this.addModule({
                         'name': name,
                         'type': 'css',
-                        //'path': this.skin.base + skin + "/" + mod + ".css"
-                        // 'path': mod + '/' + this.skin.base + skin + "/" + mod + ".css"
-                        'path': pkg + '/' + this.skin.base + skin + "/" + mod + ".css"
+                        'after': sinf.after,
+                        'path': pkg + '/' + sinf.base + skin + '/' + mod + '.css',
+                        'ext': ext
                     });
                 }
             }
+
+            return name;
         },
 
         /**
@@ -2324,15 +2471,35 @@
          * @param mod The module definition from moduleInfo
          */
         getRequires: function(mod) {
+            if (!mod) {
+                return [];
+            }
+
             if (!this.dirty && mod.expanded) {
                 return mod.expanded;
             }
 
             mod.requires=mod.requires || [];
-            var i, d=[], r=mod.requires, o=mod.optional, info=this.moduleInfo;
+            var i, d=[], r=mod.requires, o=mod.optional, info=this.moduleInfo, m;
             for (i=0; i<r.length; i=i+1) {
                 d.push(r[i]);
-                YUI.ArrayUtil.appendArray(d, this.getRequires(info[r[i]]));
+                m = info[r[i]];
+                YUI.ArrayUtil.appendArray(d, this.getRequires(m));
+
+                // add existing skins for skinnable modules as well.  The only
+                // way to do this is go through the list of required items (this
+                // assumes that _skin is called before getRequires is called on
+                // the module.
+                // if (m.skinnable) {
+                //     var req=this.required, l=req.length;
+                //     for (var j=0; j<l; j=j+1) {
+                //         // YAHOO.log('checking ' + r[j]);
+                //         if (req[j].indexOf(r[j]) > -1) {
+                //             // YAHOO.log('adding ' + r[j]);
+                //             d.push(req[j]);
+                //         }
+                //     }
+                // }
             }
 
             if (o && this.loadOptional) {
@@ -2347,27 +2514,64 @@
             return mod.expanded;
         },
 
+
         /**
          * Returns an object literal of the modules the supplied module satisfies
          * @method getProvides
-         * @param mod The module definition from moduleInfo
+         * @param name{string} The name of the module
+         * @param notMe {string} don't add this module name, only include superseded modules
          * @return what this module provides
          */
-        getProvides: function(name) {
-            var mod = this.moduleInfo[name];
+        getProvides: function(name, notMe) {
+            var addMe = !(notMe), ckey = (addMe) ? PROV : SUPER,
+                m = this.moduleInfo[name], o = {};
 
-            var o = {};
-            o[name] = true;
+            if (!m) {
+                return o;
+            }
 
-            var s = mod && mod.supersedes;
+            if (m[ckey]) {
+// Y.log('cached: ' + name + ' ' + ckey + ' ' + lang.dump(this.moduleInfo[name][ckey], 0));
+                return m[ckey];
+            }
 
-            YUI.ObjectUtil.appendArray(o, s);
+            var s = m.supersedes, done={}, me = this;
 
-            // console.log(this.sorted + ", " + name + " provides " + YUI.ObjectUtil.keys(o));
+            // use worker to break cycles
+            var add = function(mm) {
+                if (!done[mm]) {
+                    // Y.log(name + ' provides worker trying: ' + mm);
+                    done[mm] = true;
+                    // we always want the return value normal behavior 
+                    // (provides) for superseded modules.
+                    lang.augmentObject(o, me.getProvides(mm));
+                } 
+                
+                // else {
+                // Y.log(name + ' provides worker skipping done: ' + mm);
+                // }
+            };
 
-            return o;
+            // calculate superseded modules
+            if (s) {
+                for (var i=0; i<s.length; i=i+1) {
+                    add(s[i]);
+                }
+            }
+
+            // supersedes cache
+            m[SUPER] = o;
+            // provides cache
+            m[PROV] = lang.merge(o);
+            m[PROV][name] = true;
+
+// Y.log(name + " supersedes " + lang.dump(m[SUPER], 0));
+// Y.log(name + " provides " + lang.dump(m[PROV], 0));
+
+            return m[ckey];
         },
 
+
         /**
          * Calculates the dependency tree, the result is stored in the sorted 
          * property
@@ -2379,7 +2583,7 @@
                 this._config(o);
                 this._setup();
                 this._explode();
-                this._skin();
+                // this._skin(); // deprecated
                 if (this.allowRollup) {
                     this._rollup();
                 }
@@ -2401,27 +2605,61 @@
          */
         _setup: function() {
 
-            this.loaded = lang.merge(this.inserted); // shallow clone
+            var info = this.moduleInfo, name, i, j;
+
+            // Create skin modules
+            for (name in info) {
+                var m = info[name];
+                if (m && m.skinnable) {
+                    // Y.log("skinning: " + name);
+                    var o=this.skin.overrides, smod;
+                    if (o && o[name]) {
+                        for (i=0; i<o[name].length; i=i+1) {
+                            smod = this._addSkin(o[name][i], name);
+                        }
+                    } else {
+                        smod = this._addSkin(this.skin.defaultSkin, name);
+                    }
+
+                    m.requires.push(smod);
+                }
+
+            }
+
+            var l = lang.merge(this.inserted); // shallow clone
             
             if (!this._sandbox) {
-                this.loaded = lang.merge(this.loaded, env.modules);
+                l = lang.merge(l, env.modules);
             }
 
-            // Y.log("already loaded stuff: " + lang.dump(this.loaded, 0));
+            // Y.log("Already loaded stuff: " + lang.dump(l, 0));
 
             // add the ignore list to the list of loaded packages
             if (this.ignore) {
-                YUI.ObjectUtil.appendArray(this.loaded, this.ignore);
+                YUI.ObjectUtil.appendArray(l, this.ignore);
             }
 
             // remove modules on the force list from the loaded list
             if (this.force) {
-                for (var i=0; i<this.force.length; i=i+1) {
-                    if (this.force[i] in this.loaded) {
-                        delete this.loaded[this.force[i]];
+                for (i=0; i<this.force.length; i=i+1) {
+                    if (this.force[i] in l) {
+                        delete l[this.force[i]];
                     }
                 }
             }
+
+            // expand the list to include superseded modules
+            for (j in l) {
+                // Y.log("expanding: " + j);
+                if (lang.hasOwnProperty(l, j)) {
+                    lang.augmentObject(l, this.getProvides(j));
+                }
+            }
+
+            // Y.log("loaded expanded: " + lang.dump(l, 0));
+
+            this.loaded = l;
+
         },
         
 
@@ -2454,24 +2692,12 @@
          * requested modules are skinnable
          * @method _skin
          * @private
+         * @deprecated skin modules are generated for all skinnable
+         *             components during _setup(), and the components
+         *             are configured to require the skin.
          */
         _skin: function() {
 
-            var r=this.required, i, mod;
-
-            for (i in r) {
-                mod = this.moduleInfo[i];
-                if (mod && mod.skinnable) {
-                    var o=this.skin.overrides, j;
-                    if (o && o[i]) {
-                        for (j=0; j<o[i].length; j=j+1) {
-                            this.require(this.formatSkin(o[i][j], i));
-                        }
-                    } else {
-                        this.require(this.formatSkin(this.skin.defaultSkin, i));
-                    }
-                }
-            }
         },
 
         /**
@@ -2550,9 +2776,10 @@
                             continue;
                         }
 
-                        var skin = this.parseSkin(i), c = 0;
+                        var skin = (m.ext) ? false : this.parseSkin(i), c = 0;
+
+                        // Y.log('skin? ' + i + ": " + skin);
                         if (skin) {
-
                             for (j in r) {
                                 if (i !== j && this.parseSkin(j)) {
                                     c++;
@@ -2626,14 +2853,16 @@
                     var skinDef = this.parseSkin(i);
 
                     if (skinDef) {
-                        //console.log("skin found in reduce: " + skinDef.skin + ", " + skinDef.module);
+                        //YAHOO.log("skin found in reduce: " + skinDef.skin + ", " + skinDef.module);
                         // the skin rollup will not have a module name
                         if (!skinDef.module) {
                             var skin_pre = this.SKIN_PREFIX + skinDef.skin;
-                            //console.log("skin_pre: " + skin_pre);
+                            //YAHOO.log("skin_pre: " + skin_pre);
                             for (j in r) {
-                                if (j !== i && j.indexOf(skin_pre) > -1) {
-                                    //console.log ("removing component skin: " + j);
+                                m = this.moduleInfo[j];
+                                var ext = m && m.ext;
+                                if (!ext && j !== i && j.indexOf(skin_pre) > -1) {
+                                    // Y.log ("removing component skin: " + j);
                                     delete r[j];
                                 }
                             }
@@ -2643,7 +2872,7 @@
                          m = this.moduleInfo[i];
                          s = m && m.supersedes;
                          if (s) {
-                             for (j=0;j<s.length;j=j+1) {
+                             for (j=0; j<s.length; j=j+1) {
                                  if (s[j] in r) {
                                      delete r[s[j]];
                                  }
@@ -2661,7 +2890,8 @@
          */
         _sort: function() {
             // create an indexed list
-            var s=[], info=this.moduleInfo, loaded=this.loaded;
+            var s=[], info=this.moduleInfo, loaded=this.loaded,
+                me = this;
 
             // returns true if b is not loaded, and is required
             // directly or by means of modules it supersedes.
@@ -2670,12 +2900,20 @@
                     return false;
                 }
 
-                var ii, mm=info[aa], rr=mm && mm.expanded;
+                var ii, mm=info[aa], rr=mm && mm.expanded, 
+                    after = mm && mm.after, other=info[bb];
 
+                // check if this module requires the other directly
                 if (rr && YUI.ArrayUtil.indexOf(rr, bb) > -1) {
                     return true;
                 }
 
+                // check if this module should be sorted after the other
+                if (after && YUI.ArrayUtil.indexOf(after, bb) > -1) {
+                    return true;
+                }
+
+                // check if this module requires one the other supersedes
                 var ss=info[bb] && info[bb].supersedes;
                 if (ss) {
                     for (ii=0; ii<ss.length; ii=ii+1) {
@@ -2685,6 +2923,20 @@
                     }
                 }
 
+                // var ss=me.getProvides(bb, true);
+                // if (ss) {
+                //     for (ii in ss) {
+                //         if (requires(aa, ii)) {
+                //             return true;
+                //         }
+                //     }
+                // }
+
+                // external css files should be sorted below yui css
+                if (mm.ext && mm.type == 'css' && (!other.ext)) {
+                    return true;
+                }
+
                 return false;
             };
 
@@ -2843,6 +3095,8 @@
                     base: this.base,
                     filter: this.filter,
                     require: "connection",
+                    insertBefore: this.insertBefore,
+                    charset: this.charset,
                     onSuccess: function() {
                         this.sandbox(null, "js");
                     },
@@ -3054,6 +3308,8 @@
                     fn(url, {
                         data: s[i],
                         onSuccess: c,
+                        insertBefore: this.insertBefore,
+                        charset: this.charset,
                         varName: m.varName,
                         scope: self 
                     });
@@ -3106,12 +3362,12 @@
             u = u + path;
 
             if (f) {
-                // console.log("filter: " + f + ", " + f.searchExp + 
+                // YAHOO.log("filter: " + f + ", " + f.searchExp + 
                 // ", " + f.replaceStr);
                 u = u.replace(new RegExp(f.searchExp), f.replaceStr);
             }
 
-            // console.log(u);
+            // YAHOO.log(u);
 
             return u;
         }

Added: trunk/root/static/yui/yuiloader-dom-event/README
===================================================================
--- trunk/root/static/yui/yuiloader-dom-event/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuiloader-dom-event/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,13 @@
+yuiloader-event-dom.js Release Notes
+
+*** NOTE ***
+
+This document is not updated with each release.  Changes to
+the yuiloader-dom-event.js source are noted in the README
+file for each component that comprises this aggregate:
+
+yahoo/README
+dom/README
+event/README
+get/README
+yuiloader/README

Added: trunk/root/static/yui/yuiloader-dom-event/yuiloader-dom-event.js
===================================================================
--- trunk/root/static/yui/yuiloader-dom-event/yuiloader-dom-event.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuiloader-dom-event/yuiloader-dom-event.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,15 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var A=arguments,E=null,C,B,D;for(C=0;C<A.length;C=C+1){D=A[C].split(".");E=YAHOO;for(B=(D[0]=="YAHOO")?1:0;B<D.length;B=B+1){E[D[B]]=E[D[B]]||{};E=E[D[B]];}}return E;};YAHOO.log=function(D,A,C){var B=YAHOO.widget.Logger;if(B&&B.log){return B.log(D,A,C);}else{return false;}};YAHOO.register=function(A,E,D){var I=YAHOO.env.modules;if(!I[A]){I[A]={versions:[],builds:[]};}var B=I[A],H=D.version,G=D.build,F=YAHOO.env.listeners;B.name=A;B.version=H;B.build=G;B.versions.push(H);B.builds.push(G);B.mainClass=E;for(var C=0;C<F.length;C=C+1){F[C](B);}if(E){E.VERSION=H;E.BUILD=G;}else{YAHOO.log("mainClass is undefined for module "+A,"warn");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[]};YAHOO.env.getVersion=function(A){return YAHOO.env.modules[A]||null;};YAHOO.env.ua=function(){var C={ie:0,opera:0,gecko:0,webkit:0,mobile:null,air:0};var B=navigator.userAgent,A;if((/KHTML/).test(B)){C.webkit=1;}A=B.match(/A!
 ppleWebKit\/([^\s]*)/);if(A&&A[1]){C.webkit=parseFloat(A[1]);if(/ Mobile\//.test(B)){C.mobile="Apple";}else{A=B.match(/NokiaN[^\/]*/);if(A){C.mobile=A[0];}}A=B.match(/AdobeAIR\/([^\s]*)/);if(A){C.air=A[0];}}if(!C.webkit){A=B.match(/Opera[\s\/]([^\s]*)/);if(A&&A[1]){C.opera=parseFloat(A[1]);A=B.match(/Opera Mini[^;]*/);if(A){C.mobile=A[0];}}else{A=B.match(/MSIE\s([^;]*)/);if(A&&A[1]){C.ie=parseFloat(A[1]);}else{A=B.match(/Gecko\/([^\s]*)/);if(A){C.gecko=1;A=B.match(/rv:([^\s\)]*)/);if(A&&A[1]){C.gecko=parseFloat(A[1]);}}}}}return C;}();(function(){YAHOO.namespace("util","widget","example");if("undefined"!==typeof YAHOO_config){var B=YAHOO_config.listener,A=YAHOO.env.listeners,D=true,C;if(B){for(C=0;C<A.length;C=C+1){if(A[C]==B){D=false;break;}}if(D){A.push(B);}}}})();YAHOO.lang=YAHOO.lang||{isArray:function(B){if(B){var A=YAHOO.lang;return A.isNumber(B.length)&&A.isFunction(B.splice);}return false;},isBoolean:function(A){return typeof A==="boolean";},isFunction:function(A){r!
 eturn typeof A==="function";},isNull:function(A){return A===nu!
 ll;},isN
umber:function(A){return typeof A==="number"&&isFinite(A);},isObject:function(A){return(A&&(typeof A==="object"||YAHOO.lang.isFunction(A)))||false;},isString:function(A){return typeof A==="string";},isUndefined:function(A){return typeof A==="undefined";},hasOwnProperty:function(A,B){if(Object.prototype.hasOwnProperty){return A.hasOwnProperty(B);}return !YAHOO.lang.isUndefined(A[B])&&A.constructor.prototype[B]!==A[B];},_IEEnumFix:function(C,B){if(YAHOO.env.ua.ie){var E=["toString","valueOf"],A;for(A=0;A<E.length;A=A+1){var F=E[A],D=B[F];if(YAHOO.lang.isFunction(D)&&D!=Object.prototype[F]){C[F]=D;}}}},extend:function(D,E,C){if(!E||!D){throw new Error("YAHOO.lang.extend failed, please check that "+"all dependencies are included.");}var B=function(){};B.prototype=E.prototype;D.prototype=new B();D.prototype.constructor=D;D.superclass=E.prototype;if(E.prototype.constructor==Object.prototype.constructor){E.prototype.constructor=E;}if(C){for(var A in C){D.prototype[A]=C[A];}YAHOO.la!
 ng._IEEnumFix(D.prototype,C);}},augmentObject:function(E,D){if(!D||!E){throw new Error("Absorb failed, verify dependencies.");}var A=arguments,C,F,B=A[2];if(B&&B!==true){for(C=2;C<A.length;C=C+1){E[A[C]]=D[A[C]];}}else{for(F in D){if(B||!E[F]){E[F]=D[F];}}YAHOO.lang._IEEnumFix(E,D);}},augmentProto:function(D,C){if(!C||!D){throw new Error("Augment failed, verify dependencies.");}var A=[D.prototype,C.prototype];for(var B=2;B<arguments.length;B=B+1){A.push(arguments[B]);}YAHOO.lang.augmentObject.apply(this,A);},dump:function(A,G){var C=YAHOO.lang,D,F,I=[],J="{...}",B="f(){...}",H=", ",E=" => ";if(!C.isObject(A)){return A+"";}else{if(A instanceof Date||("nodeType" in A&&"tagName" in A)){return A;}else{if(C.isFunction(A)){return B;}}}G=(C.isNumber(G))?G:3;if(C.isArray(A)){I.push("[");for(D=0,F=A.length;D<F;D=D+1){if(C.isObject(A[D])){I.push((G>0)?C.dump(A[D],G-1):J);}else{I.push(A[D]);}I.push(H);}if(I.length>1){I.pop();}I.push("]");}else{I.push("{");for(D in A){if(C.hasOwnProper!
 ty(A,D)){I.push(D+E);if(C.isObject(A[D])){I.push((G>0)?C.dump(!
 A[D],G-1
):J);}else{I.push(A[D]);}I.push(H);}}if(I.length>1){I.pop();}I.push("}");}return I.join("");},substitute:function(Q,B,J){var G,F,E,M,N,P,D=YAHOO.lang,L=[],C,H="dump",K=" ",A="{",O="}";for(;;){G=Q.lastIndexOf(A);if(G<0){break;}F=Q.indexOf(O,G);if(G+1>=F){break;}C=Q.substring(G+1,F);M=C;P=null;E=M.indexOf(K);if(E>-1){P=M.substring(E+1);M=M.substring(0,E);}N=B[M];if(J){N=J(M,N,P);}if(D.isObject(N)){if(D.isArray(N)){N=D.dump(N,parseInt(P,10));}else{P=P||"";var I=P.indexOf(H);if(I>-1){P=P.substring(4);}if(N.toString===Object.prototype.toString||I>-1){N=D.dump(N,parseInt(P,10));}else{N=N.toString();}}}else{if(!D.isString(N)&&!D.isNumber(N)){N="~-"+L.length+"-~";L[L.length]=C;}}Q=Q.substring(0,G)+N+Q.substring(F+1);}for(G=L.length-1;G>=0;G=G-1){Q=Q.replace(new RegExp("~-"+G+"-~"),"{"+L[G]+"}","g");}return Q;},trim:function(A){try{return A.replace(/^\s+|\s+$/g,"");}catch(B){return A;}},merge:function(){var D={},B=arguments;for(var C=0,A=B.length;C<A;C=C+1){YAHOO.lang.augmentObject(D!
 ,B[C],true);}return D;},later:function(H,B,I,D,E){H=H||0;B=B||{};var C=I,G=D,F,A;if(YAHOO.lang.isString(I)){C=B[I];}if(!C){throw new TypeError("method undefined");}if(!YAHOO.lang.isArray(G)){G=[D];}F=function(){C.apply(B,G);};A=(E)?setInterval(F,H):setTimeout(F,H);return{interval:E,cancel:function(){if(this.interval){clearInterval(A);}else{clearTimeout(A);}}};},isValue:function(B){var A=YAHOO.lang;return(A.isObject(B)||A.isString(B)||A.isNumber(B)||A.isBoolean(B));}};YAHOO.util.Lang=YAHOO.lang;YAHOO.lang.augment=YAHOO.lang.augmentProto;YAHOO.augment=YAHOO.lang.augmentProto;YAHOO.extend=YAHOO.lang.extend;YAHOO.register("yahoo",YAHOO,{version:"2.5.1",build:"984"});YAHOO.util.Get=function(){var M={},L=0,Q=0,E=false,N=YAHOO.env.ua,R=YAHOO.lang;var J=function(V,S,W){var T=W||window,X=T.document,Y=X.createElement(V);for(var U in S){if(S[U]&&YAHOO.lang.hasOwnProperty(S,U)){Y.setAttribute(U,S[U]);}}return Y;
+};var H=function(S,T,V){var U=V||"utf-8";return J("link",{"id":"yui__dyn_"+(Q++),"type":"text/css","charset":U,"rel":"stylesheet","href":S},T);};var O=function(S,T,V){var U=V||"utf-8";return J("script",{"id":"yui__dyn_"+(Q++),"type":"text/javascript","charset":U,"src":S},T);};var A=function(S,T){return{tId:S.tId,win:S.win,data:S.data,nodes:S.nodes,msg:T,purge:function(){D(this.tId);}};};var B=function(S,V){var T=M[V],U=(R.isString(S))?T.win.document.getElementById(S):S;if(!U){P(V,"target node not found: "+S);}return U;};var P=function(V,U){var S=M[V];if(S.onFailure){var T=S.scope||S.win;S.onFailure.call(T,A(S,U));}};var C=function(V){var S=M[V];S.finished=true;if(S.aborted){var U="transaction "+V+" was aborted";P(V,U);return ;}if(S.onSuccess){var T=S.scope||S.win;S.onSuccess.call(T,A(S));}};var G=function(U,Y){var T=M[U];if(T.aborted){var W="transaction "+U+" was aborted";P(U,W);return ;}if(Y){T.url.shift();if(T.varName){T.varName.shift();}}else{T.url=(R.isString(T.url))?[T!
 .url]:T.url;if(T.varName){T.varName=(R.isString(T.varName))?[T.varName]:T.varName;}}var b=T.win,a=b.document,Z=a.getElementsByTagName("head")[0],V;if(T.url.length===0){if(T.type==="script"&&N.webkit&&N.webkit<420&&!T.finalpass&&!T.varName){var X=O(null,T.win,T.charset);X.innerHTML='YAHOO.util.Get._finalize("'+U+'");';T.nodes.push(X);Z.appendChild(X);}else{C(U);}return ;}var S=T.url[0];if(T.type==="script"){V=O(S,b,T.charset);}else{V=H(S,b,T.charset);}F(T.type,V,U,S,b,T.url.length);T.nodes.push(V);if(T.insertBefore){var c=B(T.insertBefore,U);if(c){c.parentNode.insertBefore(V,c);}}else{Z.appendChild(V);}if((N.webkit||N.gecko)&&T.type==="css"){G(U,S);}};var K=function(){if(E){return ;}E=true;for(var S in M){var T=M[S];if(T.autopurge&&T.finished){D(T.tId);delete M[S];}}E=false;};var D=function(Z){var W=M[Z];if(W){var Y=W.nodes,S=Y.length,X=W.win.document,V=X.getElementsByTagName("head")[0];if(W.insertBefore){var U=B(W.insertBefore,Z);if(U){V=U.parentNode;}}for(var T=0;T<S;T=T+1!
 ){V.removeChild(Y[T]);}}W.nodes=[];};var I=function(T,S,U){var!
  W="q"+(
L++);U=U||{};if(L%YAHOO.util.Get.PURGE_THRESH===0){K();}M[W]=R.merge(U,{tId:W,type:T,url:S,finished:false,nodes:[]});var V=M[W];V.win=V.win||window;V.scope=V.scope||V.win;V.autopurge=("autopurge" in V)?V.autopurge:(T==="script")?true:false;R.later(0,V,G,W);return{tId:W};};var F=function(b,W,V,T,X,Y,a){var Z=a||G;if(N.ie){W.onreadystatechange=function(){var c=this.readyState;if("loaded"===c||"complete"===c){Z(V,T);}};}else{if(N.webkit){if(b==="script"){if(N.webkit>=420){W.addEventListener("load",function(){Z(V,T);});}else{var S=M[V];if(S.varName){var U=YAHOO.util.Get.POLL_FREQ;S.maxattempts=YAHOO.util.Get.TIMEOUT/U;S.attempts=0;S._cache=S.varName[0].split(".");S.timer=R.later(U,S,function(h){var e=this._cache,d=e.length,c=this.win,f;for(f=0;f<d;f=f+1){c=c[e[f]];if(!c){this.attempts++;if(this.attempts++>this.maxattempts){var g="Over retry limit, giving up";S.timer.cancel();P(V,g);}else{}return ;}}S.timer.cancel();Z(V,T);},null,true);}else{R.later(YAHOO.util.Get.POLL_FREQ,null,!
 Z,[V,T]);}}}}else{W.onload=function(){Z(V,T);};}}};return{POLL_FREQ:10,PURGE_THRESH:20,TIMEOUT:2000,_finalize:function(S){R.later(0,null,C,S);},abort:function(T){var U=(R.isString(T))?T:T.tId;var S=M[U];if(S){S.aborted=true;}},script:function(S,T){return I("script",S,T);},css:function(S,T){return I("css",S,T);}};}();YAHOO.register("get",YAHOO.util.Get,{version:"2.5.1",build:"984"});(function(){var Y=YAHOO,util=Y.util,lang=Y.lang,env=Y.env,PROV="_provides",SUPER="_supersedes",REQ="expanded",AFTER="_after";var YUI={dupsAllowed:{"yahoo":true,"get":true},info:{"base":"http://yui.yahooapis.com/2.5.1/build/","skin":{"defaultSkin":"sam","base":"assets/skins/","path":"skin.css","after":["reset","fonts","grids","base"],"rollup":3},dupsAllowed:["yahoo","get"],"moduleInfo":{"animation":{"type":"js","path":"animation/animation-min.js","requires":["dom","event"]},"autocomplete":{"type":"js","path":"autocomplete/autocomplete-min.js","requires":["dom","event"],"optional":["connection","an!
 imation"],"skinnable":true},"base":{"type":"css","path":"base/!
 base-min
.css","after":["reset","fonts","grids"]},"button":{"type":"js","path":"button/button-min.js","requires":["element"],"optional":["menu"],"skinnable":true},"calendar":{"type":"js","path":"calendar/calendar-min.js","requires":["event","dom"],"skinnable":true},"charts":{"type":"js","path":"charts/charts-experimental-min.js","requires":["element","json","datasource"]},"colorpicker":{"type":"js","path":"colorpicker/colorpicker-min.js","requires":["slider","element"],"optional":["animation"],"skinnable":true},"connection":{"type":"js","path":"connection/connection-min.js","requires":["event"]},"container":{"type":"js","path":"container/container-min.js","requires":["dom","event"],"optional":["dragdrop","animation","connection"],"supersedes":["containercore"],"skinnable":true},"containercore":{"type":"js","path":"container/container_core-min.js","requires":["dom","event"],"pkg":"container"},"cookie":{"type":"js","path":"cookie/cookie-beta-min.js","requires":["yahoo"]},"datasource":{!
 "type":"js","path":"datasource/datasource-beta-min.js","requires":["event"],"optional":["connection"]},"datatable":{"type":"js","path":"datatable/datatable-beta-min.js","requires":["element","datasource"],"optional":["calendar","dragdrop"],"skinnable":true},"dom":{"type":"js","path":"dom/dom-min.js","requires":["yahoo"]},"dragdrop":{"type":"js","path":"dragdrop/dragdrop-min.js","requires":["dom","event"]},"editor":{"type":"js","path":"editor/editor-beta-min.js","requires":["menu","element","button"],"optional":["animation","dragdrop"],"skinnable":true},"element":{"type":"js","path":"element/element-beta-min.js","requires":["dom","event"]},"event":{"type":"js","path":"event/event-min.js","requires":["yahoo"]},"fonts":{"type":"css","path":"fonts/fonts-min.css"},"get":{"type":"js","path":"get/get-min.js","requires":["yahoo"]},"grids":{"type":"css","path":"grids/grids-min.css","requires":["fonts"],"optional":["reset"]},"history":{"type":"js","path":"history/history-min.js","req!
 uires":["event"]},"imagecropper":{"type":"js","path":"imagecro!
 pper/ima
gecropper-beta-min.js","requires":["dom","event","dragdrop","element","resize"],"skinnable":true},"imageloader":{"type":"js","path":"imageloader/imageloader-min.js","requires":["event","dom"]},"json":{"type":"js","path":"json/json-min.js","requires":["yahoo"]},"layout":{"type":"js","path":"layout/layout-beta-min.js","requires":["dom","event","element"],"optional":["animation","dragdrop","resize","selector"],"skinnable":true},"logger":{"type":"js","path":"logger/logger-min.js","requires":["event","dom"],"optional":["dragdrop"],"skinnable":true},"menu":{"type":"js","path":"menu/menu-min.js","requires":["containercore"],"skinnable":true},"profiler":{"type":"js","path":"profiler/profiler-beta-min.js","requires":["yahoo"]},"profilerviewer":{"type":"js","path":"profilerviewer/profilerviewer-beta-min.js","requires":["profiler","yuiloader","element"],"skinnable":true},"reset":{"type":"css","path":"reset/reset-min.css"},"reset-fonts-grids":{"type":"css","path":"reset-fonts-grids/rese!
 t-fonts-grids.css","supersedes":["reset","fonts","grids","reset-fonts"],"rollup":4},"reset-fonts":{"type":"css","path":"reset-fonts/reset-fonts.css","supersedes":["reset","fonts"],"rollup":2},"resize":{"type":"js","path":"resize/resize-beta-min.js","requires":["dom","event","dragdrop","element"],"optional":["animation"],"skinnable":true},"selector":{"type":"js","path":"selector/selector-beta-min.js","requires":["yahoo","dom"]},"simpleeditor":{"type":"js","path":"editor/simpleeditor-beta-min.js","requires":["element"],"optional":["containercore","menu","button","animation","dragdrop"],"skinnable":true,"pkg":"editor"},"slider":{"type":"js","path":"slider/slider-min.js","requires":["dragdrop"],"optional":["animation"]},"tabview":{"type":"js","path":"tabview/tabview-min.js","requires":["element"],"optional":["connection"],"skinnable":true},"treeview":{"type":"js","path":"treeview/treeview-min.js","requires":["event"],"skinnable":true},"uploader":{"type":"js","path":"uploader/up!
 loader-experimental.js","requires":["yahoo"]},"utilities":{"ty!
 pe":"js"
,"path":"utilities/utilities.js","supersedes":["yahoo","event","dragdrop","animation","dom","connection","element","yahoo-dom-event","get","yuiloader","yuiloader-dom-event"],"rollup":8},"yahoo":{"type":"js","path":"yahoo/yahoo-min.js"},"yahoo-dom-event":{"type":"js","path":"yahoo-dom-event/yahoo-dom-event.js","supersedes":["yahoo","event","dom"],"rollup":3},"yuiloader":{"type":"js","path":"yuiloader/yuiloader-beta-min.js","supersedes":["yahoo","get"]},"yuiloader-dom-event":{"type":"js","path":"yuiloader-dom-event/yuiloader-dom-event.js","supersedes":["yahoo","dom","event","get","yuiloader","yahoo-dom-event"],"rollup":5},"yuitest":{"type":"js","path":"yuitest/yuitest-min.js","requires":["logger"],"skinnable":true}}},ObjectUtil:{appendArray:function(o,a){if(a){for(var i=0;
+i<a.length;i=i+1){o[a[i]]=true;}}},keys:function(o,ordered){var a=[],i;for(i in o){if(lang.hasOwnProperty(o,i)){a.push(i);}}return a;}},ArrayUtil:{appendArray:function(a1,a2){Array.prototype.push.apply(a1,a2);},indexOf:function(a,val){for(var i=0;i<a.length;i=i+1){if(a[i]===val){return i;}}return -1;},toObject:function(a){var o={};for(var i=0;i<a.length;i=i+1){o[a[i]]=true;}return o;},uniq:function(a){return YUI.ObjectUtil.keys(YUI.ArrayUtil.toObject(a));}}};YAHOO.util.YUILoader=function(o){this._internalCallback=null;this._useYahooListener=false;this.onSuccess=null;this.onFailure=Y.log;this.onProgress=null;this.scope=this;this.data=null;this.insertBefore=null;this.charset=null;this.varName=null;this.base=YUI.info.base;this.ignore=null;this.force=null;this.allowRollup=true;this.filter=null;this.required={};this.moduleInfo=lang.merge(YUI.info.moduleInfo);this.rollups=null;this.loadOptional=false;this.sorted=[];this.loaded={};this.dirty=true;this.inserted={};var self=this;env!
 .listeners.push(function(m){if(self._useYahooListener){self.loadNext(m.name);}});this.skin=lang.merge(YUI.info.skin);this._config(o);};Y.util.YUILoader.prototype={FILTERS:{RAW:{"searchExp":"-min\\.js","replaceStr":".js"},DEBUG:{"searchExp":"-min\\.js","replaceStr":"-debug.js"}},SKIN_PREFIX:"skin-",_config:function(o){if(o){for(var i in o){if(lang.hasOwnProperty(o,i)){if(i=="require"){this.require(o[i]);}else{this[i]=o[i];}}}}var f=this.filter;if(lang.isString(f)){f=f.toUpperCase();if(f==="DEBUG"){this.require("logger");}if(!Y.widget.LogWriter){Y.widget.LogWriter=function(){return Y;};}this.filter=this.FILTERS[f];}},addModule:function(o){if(!o||!o.name||!o.type||(!o.path&&!o.fullpath)){return false;}o.ext=("ext" in o)?o.ext:true;o.requires=o.requires||[];this.moduleInfo[o.name]=o;this.dirty=true;return true;},require:function(what){var a=(typeof what==="string")?arguments:what;this.dirty=true;YUI.ObjectUtil.appendArray(this.required,a);},_addSkin:function(skin,mod){var name=!
 this.formatSkin(skin),info=this.moduleInfo,sinf=this.skin,ext=!
 info[mod
]&&info[mod].ext;if(!info[name]){this.addModule({"name":name,"type":"css","path":sinf.base+skin+"/"+sinf.path,"after":sinf.after,"rollup":sinf.rollup,"ext":ext});}if(mod){name=this.formatSkin(skin,mod);if(!info[name]){var mdef=info[mod],pkg=mdef.pkg||mod;this.addModule({"name":name,"type":"css","after":sinf.after,"path":pkg+"/"+sinf.base+skin+"/"+mod+".css","ext":ext});}}return name;},getRequires:function(mod){if(!mod){return[];}if(!this.dirty&&mod.expanded){return mod.expanded;}mod.requires=mod.requires||[];var i,d=[],r=mod.requires,o=mod.optional,info=this.moduleInfo,m;for(i=0;i<r.length;i=i+1){d.push(r[i]);m=info[r[i]];YUI.ArrayUtil.appendArray(d,this.getRequires(m));}if(o&&this.loadOptional){for(i=0;i<o.length;i=i+1){d.push(o[i]);YUI.ArrayUtil.appendArray(d,this.getRequires(info[o[i]]));}}mod.expanded=YUI.ArrayUtil.uniq(d);return mod.expanded;},getProvides:function(name,notMe){var addMe=!(notMe),ckey=(addMe)?PROV:SUPER,m=this.moduleInfo[name],o={};if(!m){return o;}if(m[c!
 key]){return m[ckey];}var s=m.supersedes,done={},me=this;var add=function(mm){if(!done[mm]){done[mm]=true;lang.augmentObject(o,me.getProvides(mm));}};if(s){for(var i=0;i<s.length;i=i+1){add(s[i]);}}m[SUPER]=o;m[PROV]=lang.merge(o);m[PROV][name]=true;return m[ckey];},calculate:function(o){if(this.dirty){this._config(o);this._setup();this._explode();if(this.allowRollup){this._rollup();}this._reduce();this._sort();this.dirty=false;}},_setup:function(){var info=this.moduleInfo,name,i,j;for(name in info){var m=info[name];if(m&&m.skinnable){var o=this.skin.overrides,smod;if(o&&o[name]){for(i=0;i<o[name].length;i=i+1){smod=this._addSkin(o[name][i],name);}}else{smod=this._addSkin(this.skin.defaultSkin,name);}m.requires.push(smod);}}var l=lang.merge(this.inserted);if(!this._sandbox){l=lang.merge(l,env.modules);}if(this.ignore){YUI.ObjectUtil.appendArray(l,this.ignore);}if(this.force){for(i=0;i<this.force.length;i=i+1){if(this.force[i] in l){delete l[this.force[i]];}}}for(j in l){if(!
 lang.hasOwnProperty(l,j)){lang.augmentObject(l,this.getProvide!
 s(j));}}
this.loaded=l;},_explode:function(){var r=this.required,i,mod;for(i in r){mod=this.moduleInfo[i];if(mod){var req=this.getRequires(mod);if(req){YUI.ObjectUtil.appendArray(r,req);}}}},_skin:function(){},formatSkin:function(skin,mod){var s=this.SKIN_PREFIX+skin;if(mod){s=s+"-"+mod;}return s;},parseSkin:function(mod){if(mod.indexOf(this.SKIN_PREFIX)===0){var a=mod.split("-");return{skin:a[1],module:a[2]};}return null;},_rollup:function(){var i,j,m,s,rollups={},r=this.required,roll;if(this.dirty||!this.rollups){for(i in this.moduleInfo){m=this.moduleInfo[i];if(m&&m.rollup){rollups[i]=m;}}this.rollups=rollups;}for(;;){var rolled=false;for(i in rollups){if(!r[i]&&!this.loaded[i]){m=this.moduleInfo[i];s=m.supersedes;roll=false;if(!m.rollup){continue;}var skin=(m.ext)?false:this.parseSkin(i),c=0;if(skin){for(j in r){if(i!==j&&this.parseSkin(j)){c++;roll=(c>=m.rollup);if(roll){break;}}}}else{for(j=0;j<s.length;j=j+1){if(this.loaded[s[j]]&&(!YUI.dupsAllowed[s[j]])){roll=false;break;}el!
 se{if(r[s[j]]){c++;roll=(c>=m.rollup);if(roll){break;}}}}}if(roll){r[i]=true;rolled=true;this.getRequires(m);}}}if(!rolled){break;}}},_reduce:function(){var i,j,s,m,r=this.required;for(i in r){if(i in this.loaded){delete r[i];}else{var skinDef=this.parseSkin(i);if(skinDef){if(!skinDef.module){var skin_pre=this.SKIN_PREFIX+skinDef.skin;for(j in r){m=this.moduleInfo[j];var ext=m&&m.ext;if(!ext&&j!==i&&j.indexOf(skin_pre)>-1){delete r[j];}}}}else{m=this.moduleInfo[i];s=m&&m.supersedes;if(s){for(j=0;j<s.length;j=j+1){if(s[j] in r){delete r[s[j]];}}}}}}},_sort:function(){var s=[],info=this.moduleInfo,loaded=this.loaded,me=this;var requires=function(aa,bb){if(loaded[bb]){return false;}var ii,mm=info[aa],rr=mm&&mm.expanded,after=mm&&mm.after,other=info[bb];if(rr&&YUI.ArrayUtil.indexOf(rr,bb)>-1){return true;}if(after&&YUI.ArrayUtil.indexOf(after,bb)>-1){return true;}var ss=info[bb]&&info[bb].supersedes;if(ss){for(ii=0;
+ii<ss.length;ii=ii+1){if(requires(aa,ss[ii])){return true;}}}if(mm.ext&&mm.type=="css"&&(!other.ext)){return true;}return false;};for(var i in this.required){s.push(i);}var p=0;for(;;){var l=s.length,a,b,j,k,moved=false;for(j=p;j<l;j=j+1){a=s[j];for(k=j+1;k<l;k=k+1){if(requires(a,s[k])){b=s.splice(k,1);s.splice(j,0,b[0]);moved=true;break;}}if(moved){break;}else{p=p+1;}}if(!moved){break;}}this.sorted=s;},toString:function(){var o={type:"YUILoader",base:this.base,filter:this.filter,required:this.required,loaded:this.loaded,inserted:this.inserted};lang.dump(o,1);},insert:function(o,type){this.calculate(o);if(!type){var self=this;this._internalCallback=function(){self._internalCallback=null;self.insert(null,"js");};this.insert(null,"css");return ;}this._loading=true;this.loadType=type;this.loadNext();},sandbox:function(o,type){if(o){}else{}this._config(o);if(!this.onSuccess){throw new Error("You must supply an onSuccess handler for your sandbox");}this._sandbox=true;var self=th!
 is;if(!type||type!=="js"){this._internalCallback=function(){self._internalCallback=null;self.sandbox(null,"js");};this.insert(null,"css");return ;}if(!util.Connect){var ld=new YAHOO.util.YUILoader();ld.insert({base:this.base,filter:this.filter,require:"connection",insertBefore:this.insertBefore,charset:this.charset,onSuccess:function(){this.sandbox(null,"js");},scope:this},"js");return ;}this._scriptText=[];this._loadCount=0;this._stopCount=this.sorted.length;this._xhr=[];this.calculate();var s=this.sorted,l=s.length,i,m,url;for(i=0;i<l;i=i+1){m=this.moduleInfo[s[i]];if(!m){this.onFailure.call(this.scope,{msg:"undefined module "+m,data:this.data});for(var j=0;j<this._xhr.length;j=j+1){this._xhr[j].abort();}return ;}if(m.type!=="js"){this._loadCount++;continue;}url=m.fullpath||this._url(m.path);var xhrData={success:function(o){var idx=o.argument[0],name=o.argument[2];this._scriptText[idx]=o.responseText;if(this.onProgress){this.onProgress.call(this.scope,{name:name,scriptTex!
 t:o.responseText,xhrResponse:o,data:this.data});}this._loadCou!
 nt++;if(
this._loadCount>=this._stopCount){var v=this.varName||"YAHOO";var t="(function() {\n";var b="\nreturn "+v+";\n})();";var ref=eval(t+this._scriptText.join("\n")+b);this._pushEvents(ref);if(ref){this.onSuccess.call(this.scope,{reference:ref,data:this.data});}else{this.onFailure.call(this.scope,{msg:this.varName+" reference failure",data:this.data});}}},failure:function(o){this.onFailure.call(this.scope,{msg:"XHR failure",xhrResponse:o,data:this.data});},scope:this,argument:[i,url,s[i]]};this._xhr.push(util.Connect.asyncRequest("GET",url,xhrData));}},loadNext:function(mname){if(!this._loading){return ;}if(mname){if(mname!==this._loading){return ;}this.inserted[mname]=true;if(this.onProgress){this.onProgress.call(this.scope,{name:mname,data:this.data});}}var s=this.sorted,len=s.length,i,m;for(i=0;i<len;i=i+1){if(s[i] in this.inserted){continue;}if(s[i]===this._loading){return ;}m=this.moduleInfo[s[i]];if(!m){this.onFailure.call(this.scope,{msg:"undefined module "+m,data:this.dat!
 a});return ;}if(!this.loadType||this.loadType===m.type){this._loading=s[i];var fn=(m.type==="css")?util.Get.css:util.Get.script,url=m.fullpath||this._url(m.path),self=this,c=function(o){self.loadNext(o.data);};if(env.ua.webkit&&env.ua.webkit<420&&m.type==="js"&&!m.varName){c=null;this._useYahooListener=true;}fn(url,{data:s[i],onSuccess:c,insertBefore:this.insertBefore,charset:this.charset,varName:m.varName,scope:self});return ;}}this._loading=null;if(this._internalCallback){var f=this._internalCallback;this._internalCallback=null;f.call(this);}else{if(this.onSuccess){this._pushEvents();this.onSuccess.call(this.scope,{data:this.data});}}},_pushEvents:function(ref){var r=ref||YAHOO;if(r.util&&r.util.Event){r.util.Event._load();}},_url:function(path){var u=this.base||"",f=this.filter;u=u+path;if(f){u=u.replace(new RegExp(f.searchExp),f.replaceStr);}return u;}};})();(function(){var B=YAHOO.util,K,I,J={},F={},M=window.document;YAHOO.env._id_counter=YAHOO.env._id_counter||0;var C!
 =YAHOO.env.ua.opera,L=YAHOO.env.ua.webkit,A=YAHOO.env.ua.gecko!
 ,G=YAHOO
.env.ua.ie;var E={HYPHEN:/(-[a-z])/i,ROOT_TAG:/^body|html$/i,OP_SCROLL:/^(?:inline|table-row)$/i};var N=function(P){if(!E.HYPHEN.test(P)){return P;}if(J[P]){return J[P];}var Q=P;while(E.HYPHEN.exec(Q)){Q=Q.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());}J[P]=Q;return Q;};var O=function(Q){var P=F[Q];if(!P){P=new RegExp("(?:^|\\s+)"+Q+"(?:\\s+|$)");F[Q]=P;}return P;};if(M.defaultView&&M.defaultView.getComputedStyle){K=function(P,S){var R=null;if(S=="float"){S="cssFloat";}var Q=P.ownerDocument.defaultView.getComputedStyle(P,"");if(Q){R=Q[N(S)];}return P.style[S]||R;};}else{if(M.documentElement.currentStyle&&G){K=function(P,R){switch(N(R)){case"opacity":var T=100;try{T=P.filters["DXImageTransform.Microsoft.Alpha"].opacity;}catch(S){try{T=P.filters("alpha").opacity;}catch(S){}}return T/100;case"float":R="styleFloat";default:var Q=P.currentStyle?P.currentStyle[R]:null;return(P.style[R]||Q);}};}else{K=function(P,Q){return P.style[Q];};}}if(G){I=function(P,Q,R){switch(Q){case!
 "opacity":if(YAHOO.lang.isString(P.style.filter)){P.style.filter="alpha(opacity="+R*100+")";if(!P.currentStyle||!P.currentStyle.hasLayout){P.style.zoom=1;}}break;case"float":Q="styleFloat";default:P.style[Q]=R;}};}else{I=function(P,Q,R){if(Q=="float"){Q="cssFloat";}P.style[Q]=R;};}var D=function(P,Q){return P&&P.nodeType==1&&(!Q||Q(P));};YAHOO.util.Dom={get:function(R){if(R&&(R.nodeType||R.item)){return R;}if(YAHOO.lang.isString(R)||!R){return M.getElementById(R);}if(R.length!==undefined){var S=[];for(var Q=0,P=R.length;Q<P;++Q){S[S.length]=B.Dom.get(R[Q]);}return S;}return R;},getStyle:function(P,R){R=N(R);var Q=function(S){return K(S,R);};return B.Dom.batch(P,Q,B.Dom,true);},setStyle:function(P,R,S){R=N(R);var Q=function(T){I(T,R,S);};B.Dom.batch(P,Q,B.Dom,true);},getXY:function(P){var Q=function(R){if((R.parentNode===null||R.offsetParent===null||this.getStyle(R,"display")=="none")&&R!=R.ownerDocument.body){return false;}return H(R);};return B.Dom.batch(P,Q,B.Dom,true);},!
 getX:function(P){var Q=function(R){return B.Dom.getXY(R)[0];};!
 return B
.Dom.batch(P,Q,B.Dom,true);},getY:function(P){var Q=function(R){return B.Dom.getXY(R)[1];};return B.Dom.batch(P,Q,B.Dom,true);},setXY:function(P,S,R){var Q=function(V){var U=this.getStyle(V,"position");if(U=="static"){this.setStyle(V,"position","relative");U="relative";}var X=this.getXY(V);if(X===false){return false;}var W=[parseInt(this.getStyle(V,"left"),10),parseInt(this.getStyle(V,"top"),10)];if(isNaN(W[0])){W[0]=(U=="relative")?0:V.offsetLeft;}if(isNaN(W[1])){W[1]=(U=="relative")?0:V.offsetTop;}if(S[0]!==null){V.style.left=S[0]-X[0]+W[0]+"px";}if(S[1]!==null){V.style.top=S[1]-X[1]+W[1]+"px";}if(!R){var T=this.getXY(V);if((S[0]!==null&&T[0]!=S[0])||(S[1]!==null&&T[1]!=S[1])){this.setXY(V,S,true);}}};B.Dom.batch(P,Q,B.Dom,true);},setX:function(Q,P){B.Dom.setXY(Q,[P,null]);},setY:function(P,Q){B.Dom.setXY(P,[null,Q]);},getRegion:function(P){var Q=function(R){if((R.parentNode===null||R.offsetParent===null||this.getStyle(R,"display")=="none")&&R!=R.ownerDocument.body){return!
  false;}var S=B.Region.getRegion(R);return S;};return B.Dom.batch(P,Q,B.Dom,true);},getClientWidth:function(){return B.Dom.getViewportWidth();},getClientHeight:function(){return B.Dom.getViewportHeight();},getElementsByClassName:function(T,X,U,V){X=X||"*";U=(U)?B.Dom.get(U):null||M;if(!U){return[];}var Q=[],P=U.getElementsByTagName(X),W=O(T);for(var R=0,S=P.length;R<S;++R){if(W.test(P[R].className)){Q[Q.length]=P[R];if(V){V.call(P[R],P[R]);}}}return Q;},hasClass:function(R,Q){var P=O(Q);var S=function(T){return P.test(T.className);};return B.Dom.batch(R,S,B.Dom,true);},addClass:function(Q,P){var R=function(S){if(this.hasClass(S,P)){return false;}S.className=YAHOO.lang.trim([S.className,P].join(" "));return true;};return B.Dom.batch(Q,R,B.Dom,true);},removeClass:function(R,Q){var P=O(Q);var S=function(T){if(!Q||!this.hasClass(T,Q)){return false;}var U=T.className;T.className=U.replace(P," ");if(this.hasClass(T,Q)){this.removeClass(T,Q);}T.className=YAHOO.lang.trim(T.classNam!
 e);return true;};return B.Dom.batch(R,S,B.Dom,true);},replaceC!
 lass:fun
ction(S,Q,P){if(!P||Q===P){return false;}var R=O(Q);var T=function(U){if(!this.hasClass(U,Q)){this.addClass(U,P);return true;}U.className=U.className.replace(R," "+P+" ");if(this.hasClass(U,Q)){this.replaceClass(U,Q,P);}U.className=YAHOO.lang.trim(U.className);return true;};return B.Dom.batch(S,T,B.Dom,true);},generateId:function(P,R){R=R||"yui-gen";var Q=function(S){if(S&&S.id){return S.id;}var T=R+YAHOO.env._id_counter++;if(S){S.id=T;}return T;};return B.Dom.batch(P,Q,B.Dom,true)||Q.apply(B.Dom,arguments);},isAncestor:function(P,Q){P=B.Dom.get(P);Q=B.Dom.get(Q);if(!P||!Q){return false;}if(P.contains&&Q.nodeType&&!L){return P.contains(Q);}else{if(P.compareDocumentPosition&&Q.nodeType){return !!(P.compareDocumentPosition(Q)&16);}else{if(Q.nodeType){return !!this.getAncestorBy(Q,function(R){return R==P;});}}}return false;},inDocument:function(P){return this.isAncestor(M.documentElement,P);},getElementsBy:function(W,Q,R,T){Q=Q||"*";R=(R)?B.Dom.get(R):null||M;if(!R){return[];}v!
 ar S=[],V=R.getElementsByTagName(Q);for(var U=0,P=V.length;U<P;++U){if(W(V[U])){S[S.length]=V[U];if(T){T(V[U]);}}}return S;},batch:function(T,W,V,R){T=(T&&(T.tagName||T.item))?T:B.Dom.get(T);if(!T||!W){return false;}var S=(R)?V:window;if(T.tagName||T.length===undefined){return W.call(S,T,V);}var U=[];for(var Q=0,P=T.length;Q<P;++Q){U[U.length]=W.call(S,T[Q],V);}return U;},getDocumentHeight:function(){var Q=(M.compatMode!="CSS1Compat")?M.body.scrollHeight:M.documentElement.scrollHeight;var P=Math.max(Q,B.Dom.getViewportHeight());return P;},getDocumentWidth:function(){var Q=(M.compatMode!="CSS1Compat")?M.body.scrollWidth:M.documentElement.scrollWidth;var P=Math.max(Q,B.Dom.getViewportWidth());return P;},getViewportHeight:function(){var P=self.innerHeight;
+var Q=M.compatMode;if((Q||G)&&!C){P=(Q=="CSS1Compat")?M.documentElement.clientHeight:M.body.clientHeight;}return P;},getViewportWidth:function(){var P=self.innerWidth;var Q=M.compatMode;if(Q||G){P=(Q=="CSS1Compat")?M.documentElement.clientWidth:M.body.clientWidth;}return P;},getAncestorBy:function(P,Q){while(P=P.parentNode){if(D(P,Q)){return P;}}return null;},getAncestorByClassName:function(Q,P){Q=B.Dom.get(Q);if(!Q){return null;}var R=function(S){return B.Dom.hasClass(S,P);};return B.Dom.getAncestorBy(Q,R);},getAncestorByTagName:function(Q,P){Q=B.Dom.get(Q);if(!Q){return null;}var R=function(S){return S.tagName&&S.tagName.toUpperCase()==P.toUpperCase();};return B.Dom.getAncestorBy(Q,R);},getPreviousSiblingBy:function(P,Q){while(P){P=P.previousSibling;if(D(P,Q)){return P;}}return null;},getPreviousSibling:function(P){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getPreviousSiblingBy(P);},getNextSiblingBy:function(P,Q){while(P){P=P.nextSibling;if(D(P,Q)){return P;}}return !
 null;},getNextSibling:function(P){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getNextSiblingBy(P);},getFirstChildBy:function(P,R){var Q=(D(P.firstChild,R))?P.firstChild:null;return Q||B.Dom.getNextSiblingBy(P.firstChild,R);},getFirstChild:function(P,Q){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getFirstChildBy(P);},getLastChildBy:function(P,R){if(!P){return null;}var Q=(D(P.lastChild,R))?P.lastChild:null;return Q||B.Dom.getPreviousSiblingBy(P.lastChild,R);},getLastChild:function(P){P=B.Dom.get(P);return B.Dom.getLastChildBy(P);},getChildrenBy:function(Q,S){var R=B.Dom.getFirstChildBy(Q,S);var P=R?[R]:[];B.Dom.getNextSiblingBy(R,function(T){if(!S||S(T)){P[P.length]=T;}return false;});return P;},getChildren:function(P){P=B.Dom.get(P);if(!P){}return B.Dom.getChildrenBy(P);},getDocumentScrollLeft:function(P){P=P||M;return Math.max(P.documentElement.scrollLeft,P.body.scrollLeft);},getDocumentScrollTop:function(P){P=P||M;return Math.max(P.documentElement.scrollTop,P.body!
 .scrollTop);},insertBefore:function(Q,P){Q=B.Dom.get(Q);P=B.Do!
 m.get(P)
;if(!Q||!P||!P.parentNode){return null;}return P.parentNode.insertBefore(Q,P);},insertAfter:function(Q,P){Q=B.Dom.get(Q);P=B.Dom.get(P);if(!Q||!P||!P.parentNode){return null;}if(P.nextSibling){return P.parentNode.insertBefore(Q,P.nextSibling);}else{return P.parentNode.appendChild(Q);}},getClientRegion:function(){var R=B.Dom.getDocumentScrollTop(),Q=B.Dom.getDocumentScrollLeft(),S=B.Dom.getViewportWidth()+Q,P=B.Dom.getViewportHeight()+R;return new B.Region(R,S,P,Q);}};var H=function(){if(M.documentElement.getBoundingClientRect){return function(Q){var R=Q.getBoundingClientRect();var P=Q.ownerDocument;return[R.left+B.Dom.getDocumentScrollLeft(P),R.top+B.Dom.getDocumentScrollTop(P)];};}else{return function(R){var S=[R.offsetLeft,R.offsetTop];var Q=R.offsetParent;var P=(L&&B.Dom.getStyle(R,"position")=="absolute"&&R.offsetParent==R.ownerDocument.body);if(Q!=R){while(Q){S[0]+=Q.offsetLeft;S[1]+=Q.offsetTop;if(!P&&L&&B.Dom.getStyle(Q,"position")=="absolute"){P=true;}Q=Q.offsetParen!
 t;}}if(P){S[0]-=R.ownerDocument.body.offsetLeft;S[1]-=R.ownerDocument.body.offsetTop;}Q=R.parentNode;while(Q.tagName&&!E.ROOT_TAG.test(Q.tagName)){if(Q.scrollTop||Q.scrollLeft){if(!E.OP_SCROLL.test(B.Dom.getStyle(Q,"display"))){if(!C||B.Dom.getStyle(Q,"overflow")!=="visible"){S[0]-=Q.scrollLeft;S[1]-=Q.scrollTop;}}}Q=Q.parentNode;}return S;};}}();})();YAHOO.util.Region=function(C,D,A,B){this.top=C;this[1]=C;this.right=D;this.bottom=A;this.left=B;this[0]=B;};YAHOO.util.Region.prototype.contains=function(A){return(A.left>=this.left&&A.right<=this.right&&A.top>=this.top&&A.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(E){var C=Math.max(this.top,E.top);var D=Math.min(this.right,E.right);var A=Math.min(this.bottom,E.bottom);var B=Math.max(this.left,E.left);if(A>=C&&D>=B){return new YAHOO.util.Region(C,D,A,B);}else{return null;}};YAHOO.util.Region.prototy!
 pe.union=function(E){var C=Math.min(this.top,E.top);var D=Math!
 .max(thi
s.right,E.right);var A=Math.max(this.bottom,E.bottom);var B=Math.min(this.left,E.left);return new YAHOO.util.Region(C,D,A,B);};YAHOO.util.Region.prototype.toString=function(){return("Region {"+"top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+"}");};YAHOO.util.Region.getRegion=function(D){var F=YAHOO.util.Dom.getXY(D);var C=F[1];var E=F[0]+D.offsetWidth;var A=F[1]+D.offsetHeight;var B=F[0];return new YAHOO.util.Region(C,E,A,B);};YAHOO.util.Point=function(A,B){if(YAHOO.lang.isArray(A)){B=A[1];A=A[0];}this.x=this.right=this.left=this[0]=A;this.y=this.top=this.bottom=this[1]=B;};YAHOO.util.Point.prototype=new YAHOO.util.Region();YAHOO.register("dom",YAHOO.util.Dom,{version:"2.5.1",build:"984"});YAHOO.util.CustomEvent=function(D,B,C,A){this.type=D;this.scope=B||window;this.silent=C;this.signature=A||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){}var E="_YUICEOnSubscribe";if(D!==E){this.subscribeEvent=new YAHOO.util.CustomEve!
 nt(E,this,true);}this.lastError=null;};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(B,C,A){if(!B){throw new Error("Invalid callback for subscriber to '"+this.type+"'");}if(this.subscribeEvent){this.subscribeEvent.fire(B,C,A);}this.subscribers.push(new YAHOO.util.Subscriber(B,C,A));},unsubscribe:function(D,F){if(!D){return this.unsubscribeAll();}var E=false;for(var B=0,A=this.subscribers.length;B<A;++B){var C=this.subscribers[B];if(C&&C.contains(D,F)){this._delete(B);E=true;}}return E;},fire:function(){var D=this.subscribers.length;if(!D&&this.silent){return true;}var H=[].slice.call(arguments,0),F=true,C,I=false;if(!this.silent){}var B=this.subscribers.slice();for(C=0;C<D;++C){var K=B[C];if(!K){I=true;}else{if(!this.silent){}var J=K.getScope(this.scope);if(this.signature==YAHOO.util.CustomEvent.FLAT){var A=null;if(H.length>0){A=H[0];}try{F=K.fn.call(J,A,K.obj);}catch(E){this.lastError=E;}}else{try{F=K.fn.ca!
 ll(J,this.type,H,K.obj);}catch(G){this.lastError=G;}}if(false=!
 ==F){if(
!this.silent){}return false;}}}return true;},unsubscribeAll:function(){for(var A=this.subscribers.length-1;A>-1;A--){this._delete(A);}this.subscribers=[];return A;},_delete:function(A){var B=this.subscribers[A];if(B){delete B.fn;delete B.obj;}this.subscribers.splice(A,1);},toString:function(){return"CustomEvent: "+"'"+this.type+"', "+"scope: "+this.scope;}};YAHOO.util.Subscriber=function(B,C,A){this.fn=B;this.obj=YAHOO.lang.isUndefined(C)?null:C;this.override=A;};YAHOO.util.Subscriber.prototype.getScope=function(A){if(this.override){if(this.override===true){return this.obj;}else{return this.override;}}return A;};YAHOO.util.Subscriber.prototype.contains=function(A,B){if(B){return(this.fn==A&&this.obj==B);}else{return(this.fn==A);}};YAHOO.util.Subscriber.prototype.toString=function(){return"Subscriber { obj: "+this.obj+", override: "+(this.override||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var H=false;var I=[];var J=[];var G=[];var E=[];var C=0;var F=[];v!
 ar B=[];var A=0;var D={63232:38,63233:40,63234:37,63235:39,63276:33,63277:34,25:9};return{POLL_RETRYS:2000,POLL_INTERVAL:20,EL:0,TYPE:1,FN:2,WFN:3,UNLOAD_OBJ:3,ADJ_SCOPE:4,OBJ:5,OVERRIDE:6,lastError:null,isSafari:YAHOO.env.ua.webkit,webkit:YAHOO.env.ua.webkit,isIE:YAHOO.env.ua.ie,_interval:null,_dri:null,DOMReady:false,startInterval:function(){if(!this._interval){var K=this;var L=function(){K._tryPreloadAttach();};this._interval=setInterval(L,this.POLL_INTERVAL);}},onAvailable:function(P,M,Q,O,N){var K=(YAHOO.lang.isString(P))?[P]:P;for(var L=0;L<K.length;L=L+1){F.push({id:K[L],fn:M,obj:Q,override:O,checkReady:N});}C=this.POLL_RETRYS;this.startInterval();},onContentReady:function(M,K,N,L){this.onAvailable(M,K,N,L,true);},onDOMReady:function(K,M,L){if(this.DOMReady){setTimeout(function(){var N=window;if(L){if(L===true){N=M;}else{N=L;}}K.call(N,"DOMReady",[],M);},0);}else{this.DOMReadyEvent.subscribe(K,M,L);}},addListener:function(M,K,V,Q,L){if(!V||!V.call){return false;}if(t!
 his._isValidCollection(M)){var W=true;for(var R=0,T=M.length;R!
 <T;++R){
W=this.on(M[R],K,V,Q,L)&&W;}return W;}else{if(YAHOO.lang.isString(M)){var P=this.getEl(M);if(P){M=P;}else{this.onAvailable(M,function(){YAHOO.util.Event.on(M,K,V,Q,L);});return true;}}}if(!M){return false;}if("unload"==K&&Q!==this){J[J.length]=[M,K,V,Q,L];return true;}var Y=M;if(L){if(L===true){Y=Q;}else{Y=L;}}var N=function(Z){return V.call(Y,YAHOO.util.Event.getEvent(Z,M),Q);};var X=[M,K,V,N,Y,Q,L];var S=I.length;I[S]=X;if(this.useLegacyEvent(M,K)){var O=this.getLegacyIndex(M,K);if(O==-1||M!=G[O][0]){O=G.length;B[M.id+K]=O;G[O]=[M,K,M["on"+K]];E[O]=[];M["on"+K]=function(Z){YAHOO.util.Event.fireLegacyEvent(YAHOO.util.Event.getEvent(Z),O);};}E[O].push(X);}else{try{this._simpleAdd(M,K,N,false);}catch(U){this.lastError=U;this.removeListener(M,K,V);return false;}}return true;},fireLegacyEvent:function(O,M){var Q=true,K,S,R,T,P;S=E[M].slice();for(var L=0,N=S.length;L<N;++L){R=S[L];if(R&&R[this.WFN]){T=R[this.ADJ_SCOPE];P=R[this.WFN].call(T,O);Q=(Q&&P);}}K=G[M];if(K&&K[2]){K[2](O!
 );}return Q;},getLegacyIndex:function(L,M){var K=this.generateId(L)+M;if(typeof B[K]=="undefined"){return -1;}else{return B[K];}},useLegacyEvent:function(L,M){if(this.webkit&&("click"==M||"dblclick"==M)){var K=parseInt(this.webkit,10);if(!isNaN(K)&&K<418){return true;}}return false;},removeListener:function(L,K,T){var O,R,V;if(typeof L=="string"){L=this.getEl(L);}else{if(this._isValidCollection(L)){var U=true;for(O=L.length-1;O>-1;O--){U=(this.removeListener(L[O],K,T)&&U);}return U;}}if(!T||!T.call){return this.purgeElement(L,false,K);}if("unload"==K){for(O=J.length-1;O>-1;O--){V=J[O];if(V&&V[0]==L&&V[1]==K&&V[2]==T){J.splice(O,1);return true;}}return false;}var P=null;var Q=arguments[3];if("undefined"===typeof Q){Q=this._getCacheIndex(L,K,T);}if(Q>=0){P=I[Q];}if(!L||!P){return false;}if(this.useLegacyEvent(L,K)){var N=this.getLegacyIndex(L,K);var M=E[N];if(M){for(O=0,R=M.length;O<R;++O){V=M[O];if(V&&V[this.EL]==L&&V[this.TYPE]==K&&V[this.FN]==T){M.splice(O,1);break;}}}}els!
 e{try{this._simpleRemove(L,K,P[this.WFN],false);}catch(S){this!
 .lastErr
or=S;return false;}}delete I[Q][this.WFN];delete I[Q][this.FN];I.splice(Q,1);return true;},getTarget:function(M,L){var K=M.target||M.srcElement;return this.resolveTextNode(K);},resolveTextNode:function(L){try{if(L&&3==L.nodeType){return L.parentNode;}}catch(K){}return L;},getPageX:function(L){var K=L.pageX;if(!K&&0!==K){K=L.clientX||0;if(this.isIE){K+=this._getScrollLeft();}}return K;},getPageY:function(K){var L=K.pageY;if(!L&&0!==L){L=K.clientY||0;if(this.isIE){L+=this._getScrollTop();}}return L;},getXY:function(K){return[this.getPageX(K),this.getPageY(K)];},getRelatedTarget:function(L){var K=L.relatedTarget;
+if(!K){if(L.type=="mouseout"){K=L.toElement;}else{if(L.type=="mouseover"){K=L.fromElement;}}}return this.resolveTextNode(K);},getTime:function(M){if(!M.time){var L=new Date().getTime();try{M.time=L;}catch(K){this.lastError=K;return L;}}return M.time;},stopEvent:function(K){this.stopPropagation(K);this.preventDefault(K);},stopPropagation:function(K){if(K.stopPropagation){K.stopPropagation();}else{K.cancelBubble=true;}},preventDefault:function(K){if(K.preventDefault){K.preventDefault();}else{K.returnValue=false;}},getEvent:function(M,K){var L=M||window.event;if(!L){var N=this.getEvent.caller;while(N){L=N.arguments[0];if(L&&Event==L.constructor){break;}N=N.caller;}}return L;},getCharCode:function(L){var K=L.keyCode||L.charCode||0;if(YAHOO.env.ua.webkit&&(K in D)){K=D[K];}return K;},_getCacheIndex:function(O,P,N){for(var M=0,L=I.length;M<L;M=M+1){var K=I[M];if(K&&K[this.FN]==N&&K[this.EL]==O&&K[this.TYPE]==P){return M;}}return -1;},generateId:function(K){var L=K.id;if(!L){L="yu!
 ievtautoid-"+A;++A;K.id=L;}return L;},_isValidCollection:function(L){try{return(L&&typeof L!=="string"&&L.length&&!L.tagName&&!L.alert&&typeof L[0]!=="undefined");}catch(K){return false;}},elCache:{},getEl:function(K){return(typeof K==="string")?document.getElementById(K):K;},clearCache:function(){},DOMReadyEvent:new YAHOO.util.CustomEvent("DOMReady",this),_load:function(L){if(!H){H=true;var K=YAHOO.util.Event;K._ready();K._tryPreloadAttach();}},_ready:function(L){var K=YAHOO.util.Event;if(!K.DOMReady){K.DOMReady=true;K.DOMReadyEvent.fire();K._simpleRemove(document,"DOMContentLoaded",K._ready);}},_tryPreloadAttach:function(){if(F.length===0){C=0;clearInterval(this._interval);this._interval=null;return ;}if(this.locked){return ;}if(this.isIE){if(!this.DOMReady){this.startInterval();return ;}}this.locked=true;var Q=!H;if(!Q){Q=(C>0&&F.length>0);}var P=[];var R=function(T,U){var S=T;if(U.override){if(U.override===true){S=U.obj;}else{S=U.override;}}U.fn.call(S,U.obj);};var L,K,!
 O,N,M=[];for(L=0,K=F.length;L<K;L=L+1){O=F[L];if(O){N=this.get!
 El(O.id)
;if(N){if(O.checkReady){if(H||N.nextSibling||!Q){M.push(O);F[L]=null;}}else{R(N,O);F[L]=null;}}else{P.push(O);}}}for(L=0,K=M.length;L<K;L=L+1){O=M[L];R(this.getEl(O.id),O);}C--;if(Q){for(L=F.length-1;L>-1;L--){O=F[L];if(!O||!O.id){F.splice(L,1);}}this.startInterval();}else{clearInterval(this._interval);this._interval=null;}this.locked=false;},purgeElement:function(O,P,R){var M=(YAHOO.lang.isString(O))?this.getEl(O):O;var Q=this.getListeners(M,R),N,K;if(Q){for(N=Q.length-1;N>-1;N--){var L=Q[N];this.removeListener(M,L.type,L.fn);}}if(P&&M&&M.childNodes){for(N=0,K=M.childNodes.length;N<K;++N){this.purgeElement(M.childNodes[N],P,R);}}},getListeners:function(M,K){var P=[],L;if(!K){L=[I,J];}else{if(K==="unload"){L=[J];}else{L=[I];}}var R=(YAHOO.lang.isString(M))?this.getEl(M):M;for(var O=0;O<L.length;O=O+1){var T=L[O];if(T){for(var Q=0,S=T.length;Q<S;++Q){var N=T[Q];if(N&&N[this.EL]===R&&(!K||K===N[this.TYPE])){P.push({type:N[this.TYPE],fn:N[this.FN],obj:N[this.OBJ],adjust:N[this.!
 OVERRIDE],scope:N[this.ADJ_SCOPE],index:Q});}}}}return(P.length)?P:null;},_unload:function(Q){var K=YAHOO.util.Event,N,M,L,P,O,R=J.slice();for(N=0,P=J.length;N<P;++N){L=R[N];if(L){var S=window;if(L[K.ADJ_SCOPE]){if(L[K.ADJ_SCOPE]===true){S=L[K.UNLOAD_OBJ];}else{S=L[K.ADJ_SCOPE];}}L[K.FN].call(S,K.getEvent(Q,L[K.EL]),L[K.UNLOAD_OBJ]);R[N]=null;L=null;S=null;}}J=null;if(I){for(M=I.length-1;M>-1;M--){L=I[M];if(L){K.removeListener(L[K.EL],L[K.TYPE],L[K.FN],M);}}L=null;}G=null;K._simpleRemove(window,"unload",K._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var K=document.documentElement,L=document.body;if(K&&(K.scrollTop||K.scrollLeft)){return[K.scrollTop,K.scrollLeft];}else{if(L){return[L.scrollTop,L.scrollLeft];}else{return[0,0];}}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(M,N,L,K){M.addEventListener(N,L,(K));};}else{if(window.attachEvent!
 ){return function(M,N,L,K){M.attachEvent("on"+N,L);};}else{ret!
 urn func
tion(){};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(M,N,L,K){M.removeEventListener(N,L,(K));};}else{if(window.detachEvent){return function(L,M,K){L.detachEvent("on"+M,K);};}else{return function(){};}}}()};}();(function(){var EU=YAHOO.util.Event;EU.on=EU.addListener;
+/* DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller */
+if(EU.isIE){YAHOO.util.Event.onDOMReady(YAHOO.util.Event._tryPreloadAttach,YAHOO.util.Event,true);var n=document.createElement("p");EU._dri=setInterval(function(){try{n.doScroll("left");clearInterval(EU._dri);EU._dri=null;EU._ready();n=null;}catch(ex){}},EU.POLL_INTERVAL);}else{if(EU.webkit&&EU.webkit<525){EU._dri=setInterval(function(){var rs=document.readyState;if("loaded"==rs||"complete"==rs){clearInterval(EU._dri);EU._dri=null;EU._ready();}},EU.POLL_INTERVAL);}else{EU._simpleAdd(document,"DOMContentLoaded",EU._ready);}}EU._simpleAdd(window,"load",EU._load);EU._simpleAdd(window,"unload",EU._unload);EU._tryPreloadAttach();})();}YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null,__yui_subscribers:null,subscribe:function(A,C,F,E){this.__yui_events=this.__yui_events||{};var D=this.__yui_events[A];if(D){D.subscribe(C,F,E);}else{this.__yui_subscribers=this.__yui_subscribers||{};var B=this.__yui_subscribers;if(!B[A]){B[A]=[];}B[A].push({!
 fn:C,obj:F,override:E});}},unsubscribe:function(C,E,G){this.__yui_events=this.__yui_events||{};var A=this.__yui_events;if(C){var F=A[C];if(F){return F.unsubscribe(E,G);}}else{var B=true;for(var D in A){if(YAHOO.lang.hasOwnProperty(A,D)){B=B&&A[D].unsubscribe(E,G);}}return B;}return false;},unsubscribeAll:function(A){return this.unsubscribe(A);},createEvent:function(G,D){this.__yui_events=this.__yui_events||{};var A=D||{};var I=this.__yui_events;if(I[G]){}else{var H=A.scope||this;var E=(A.silent);var B=new YAHOO.util.CustomEvent(G,H,E,YAHOO.util.CustomEvent.FLAT);
+I[G]=B;if(A.onSubscribeCallback){B.subscribeEvent.subscribe(A.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};var F=this.__yui_subscribers[G];if(F){for(var C=0;C<F.length;++C){B.subscribe(F[C].fn,F[C].obj,F[C].override);}}}return I[G];},fireEvent:function(E,D,A,C){this.__yui_events=this.__yui_events||{};var G=this.__yui_events[E];if(!G){return null;}var B=[];for(var F=1;F<arguments.length;++F){B.push(arguments[F]);}return G.fire.apply(G,B);},hasEvent:function(A){if(this.__yui_events){if(this.__yui_events[A]){return true;}}return false;}};YAHOO.util.KeyListener=function(A,F,B,C){if(!A){}else{if(!F){}else{if(!B){}}}if(!C){C=YAHOO.util.KeyListener.KEYDOWN;}var D=new YAHOO.util.CustomEvent("keyPressed");this.enabledEvent=new YAHOO.util.CustomEvent("enabled");this.disabledEvent=new YAHOO.util.CustomEvent("disabled");if(typeof A=="string"){A=document.getElementById(A);}if(typeof B=="function"){D.subscribe(B);}else{D.subscribe(B.fn,B.scope,B.correctScope);}!
 function E(J,I){if(!F.shift){F.shift=false;}if(!F.alt){F.alt=false;}if(!F.ctrl){F.ctrl=false;}if(J.shiftKey==F.shift&&J.altKey==F.alt&&J.ctrlKey==F.ctrl){var G;if(F.keys instanceof Array){for(var H=0;H<F.keys.length;H++){G=F.keys[H];if(G==J.charCode){D.fire(J.charCode,J);break;}else{if(G==J.keyCode){D.fire(J.keyCode,J);break;}}}}else{G=F.keys;if(G==J.charCode){D.fire(J.charCode,J);}else{if(G==J.keyCode){D.fire(J.keyCode,J);}}}}}this.enable=function(){if(!this.enabled){YAHOO.util.Event.addListener(A,C,E);this.enabledEvent.fire(F);}this.enabled=true;};this.disable=function(){if(this.enabled){YAHOO.util.Event.removeListener(A,C,E);this.disabledEvent.fire(F);}this.enabled=false;};this.toString=function(){return"KeyListener ["+F.keys+"] "+A.tagName+(A.id?"["+A.id+"]":"");};};YAHOO.util.KeyListener.KEYDOWN="keydown";YAHOO.util.KeyListener.KEYUP="keyup";YAHOO.util.KeyListener.KEY={ALT:18,BACK_SPACE:8,CAPS_LOCK:20,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:!
 37,META:224,NUM_LOCK:144,PAGE_DOWN:34,PAGE_UP:33,PAUSE:19,PRIN!
 TSCREEN:
44,RIGHT:39,SCROLL_LOCK:145,SHIFT:16,SPACE:32,TAB:9,UP:38};YAHOO.register("event",YAHOO.util.Event,{version:"2.5.1",build:"984"});YAHOO.register("yuiloader-dom-event", YAHOO, {version: "2.5.1", build: "984"});

Modified: trunk/root/static/yui/yuitest/README
===================================================================
--- trunk/root/static/yui/yuitest/README	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/README	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,17 +1,28 @@
 YUI Library - YUITest - Release Notes
 
-2.3.0
+2.5.1
 
-  * Beta release
+  * Fixed ObjectAssert.hasProperty() so that is correctly identifies declared properties with a value of undefined.
+  * Fixed DateAssert documentation errors.
+  * Added ability to include framework assertion message in addition to custom assertion message.
+  
+2.5.0
+ 
+  * Updated test results format to include ignored tests, result types, and names.
+  * Introduced test result formats in JSON and XML.
+  * Introduced TestReporter object.
+  * Removed beta tag.
+  
+2.4.0
 
+  * Changed test running from synchronous to asynchronous.
+  * Added wait() and resume() methods to TestRunner to allow testing of asynchronous features.
+  
 2.3.1
 
   * No changes
 
-2.4.0
+2.3.0
 
-  * Changed test running from synchronous to asynchronous.
-  * Added wait() and resume() methods to TestRunner to allow testing of asynchronous features.
+  * Beta release
 
-2.4.1
-No change

Modified: trunk/root/static/yui/yuitest/assets/skins/sam/yuitest-skin.css
===================================================================
--- trunk/root/static/yui/yuitest/assets/skins/sam/yuitest-skin.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/assets/skins/sam/yuitest-skin.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 

Modified: trunk/root/static/yui/yuitest/assets/skins/sam/yuitest.css
===================================================================
--- trunk/root/static/yui/yuitest/assets/skins/sam/yuitest.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/assets/skins/sam/yuitest.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 

Modified: trunk/root/static/yui/yuitest/assets/testlogger.css
===================================================================
--- trunk/root/static/yui/yuitest/assets/testlogger.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/assets/testlogger.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,8 +1,8 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 .yui-log {padding-top:3em;}
 /*

Modified: trunk/root/static/yui/yuitest/assets/yuitest-core.css
===================================================================
--- trunk/root/static/yui/yuitest/assets/yuitest-core.css	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/assets/yuitest-core.css	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,7 +1,7 @@
 /*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
 Code licensed under the BSD License:
 http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
+version: 2.5.1
 */
 

Deleted: trunk/root/static/yui/yuitest/yuitest-beta-debug.js
===================================================================
--- trunk/root/static/yui/yuitest/yuitest-beta-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/yuitest-beta-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,3007 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-YAHOO.namespace("tool");
-
-//-----------------------------------------------------------------------------
-// TestCase object
-//-----------------------------------------------------------------------------
-
-/**
- * Test case containing various tests to run.
- * @param template An object containing any number of test methods, other methods,
- *                 an optional name, and anything else the test case needs.
- * @class TestCase
- * @namespace YAHOO.tool
- * @constructor
- */
-YAHOO.tool.TestCase = function (template /*:Object*/) {
-    
-    /**
-     * Special rules for the test case. Possible subobjects
-     * are fail, for tests that should fail, and error, for
-     * tests that should throw an error.
-     */
-    this._should /*:Object*/ = {};
-    
-    //copy over all properties from the template to this object
-    for (var prop in template) {
-        this[prop] = template[prop];
-    }    
-    
-    //check for a valid name
-    if (!YAHOO.lang.isString(this.name)){
-        /**
-         * Name for the test case.
-         */
-        this.name /*:String*/ = YAHOO.util.Dom.generateId(null, "testCase");
-    }
-
-};
-
-
-YAHOO.tool.TestCase.prototype = {  
-
-    /**
-     * Resumes a paused test and runs the given function.
-     * @param {Function} segment (Optional) The function to run.
-     *      If omitted, the test automatically passes.
-     * @return {Void}
-     * @method resume
-     */
-    resume : function (segment /*:Function*/) /*:Void*/ {
-        YAHOO.tool.TestRunner.resume(segment);
-    },
-
-    /**
-     * Causes the test case to wait a specified amount of time and then
-     * continue executing the given code.
-     * @param {Function} segment (Optional) The function to run after the delay.
-     *      If omitted, the TestRunner will wait until resume() is called.
-     * @param {int} delay (Optional) The number of milliseconds to wait before running
-     *      the function. If omitted, defaults to zero.
-     * @return {Void}
-     * @method wait
-     */
-    wait : function (segment /*:Function*/, delay /*:int*/) /*:Void*/{
-        throw new YAHOO.tool.TestCase.Wait(segment, delay);
-    },
-
-    //-------------------------------------------------------------------------
-    // Stub Methods
-    //-------------------------------------------------------------------------
-
-    /**
-     * Function to run before each test is executed.
-     * @return {Void}
-     * @method setUp
-     */
-    setUp : function () /*:Void*/ {
-    },
-    
-    /**
-     * Function to run after each test is executed.
-     * @return {Void}
-     * @method tearDown
-     */
-    tearDown: function () /*:Void*/ {    
-    }
-};
-
-/**
- * Represents a stoppage in test execution to wait for an amount of time before
- * continuing.
- * @param {Function} segment A function to run when the wait is over.
- * @param {int} delay The number of milliseconds to wait before running the code.
- * @class Wait
- * @namespace YAHOO.tool.TestCase
- * @constructor
- *
- */
-YAHOO.tool.TestCase.Wait = function (segment /*:Function*/, delay /*:int*/) {
-    
-    /**
-     * The segment of code to run when the wait is over.
-     * @type Function
-     * @property segment
-     */
-    this.segment /*:Function*/ = (YAHOO.lang.isFunction(segment) ? segment : null);
-
-    /**
-     * The delay before running the segment of code.
-     * @type int
-     * @property delay
-     */
-    this.delay /*:int*/ = (YAHOO.lang.isNumber(delay) ? delay : 0);
-
-};
-
-YAHOO.namespace("tool");
-
-
-//-----------------------------------------------------------------------------
-// TestSuite object
-//-----------------------------------------------------------------------------
-
-/**
- * A test suite that can contain a collection of TestCase and TestSuite objects.
- * @param {String||Object} data The name of the test suite or an object containing
- *      a name property as well as setUp and tearDown methods.
- * @namespace YAHOO.tool
- * @class TestSuite
- * @constructor
- */
-YAHOO.tool.TestSuite = function (data /*:String||Object*/) {
-
-    /**
-     * The name of the test suite.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "";
-
-    /**
-     * Array of test suites and
-     * @private
-     */
-    this.items /*:Array*/ = [];
-
-    //initialize the properties
-    if (YAHOO.lang.isString(data)){
-        this.name = data;
-    } else if (YAHOO.lang.isObject(data)){
-        YAHOO.lang.augmentObject(this, data, true);
-    }
-
-    //double-check name
-    if (this.name === ""){
-        this.name = YAHOO.util.Dom.generateId(null, "testSuite");
-    }
-
-};
-
-YAHOO.tool.TestSuite.prototype = {
-    
-    /**
-     * Adds a test suite or test case to the test suite.
-     * @param {YAHOO.tool.TestSuite||YAHOO.tool.TestCase} testObject The test suite or test case to add.
-     * @return {Void}
-     * @method add
-     */
-    add : function (testObject /*:YAHOO.tool.TestSuite*/) /*:Void*/ {
-        if (testObject instanceof YAHOO.tool.TestSuite || testObject instanceof YAHOO.tool.TestCase) {
-            this.items.push(testObject);
-        }
-    },
-    
-    //-------------------------------------------------------------------------
-    // Stub Methods
-    //-------------------------------------------------------------------------
-
-    /**
-     * Function to run before each test is executed.
-     * @return {Void}
-     * @method setUp
-     */
-    setUp : function () /*:Void*/ {
-    },
-    
-    /**
-     * Function to run after each test is executed.
-     * @return {Void}
-     * @method tearDown
-     */
-    tearDown: function () /*:Void*/ {
-    }
-    
-};
-
-YAHOO.namespace("tool");
-
-/**
- * The YUI test tool
- * @module yuitest
- * @namespace YAHOO.tool
- * @requires yahoo,dom,event,logger
- */
-
-
-//-----------------------------------------------------------------------------
-// TestRunner object
-//-----------------------------------------------------------------------------
-
-/**
- * Runs test suites and test cases, providing events to allowing for the
- * interpretation of test results.
- * @namespace YAHOO.tool
- * @class TestRunner
- * @static
- */
-YAHOO.tool.TestRunner = (function(){
-
-    /**
-     * A node in the test tree structure. May represent a TestSuite, TestCase, or
-     * test function.
-     * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.
-     * @class TestNode
-     * @constructor
-     * @private
-     */
-    function TestNode(testObject /*:Variant*/){
-    
-        /**
-         * The TestSuite, TestCase, or test function represented by this node.
-         * @type Variant
-         * @property testObject
-         */
-        this.testObject = testObject;
-        
-        /**
-         * Pointer to this node's first child.
-         * @type TestNode
-         * @property firstChild
-         */        
-        this.firstChild /*:TestNode*/ = null;
-        
-        /**
-         * Pointer to this node's last child.
-         * @type TestNode
-         * @property lastChild
-         */        
-        this.lastChild = null;
-        
-        /**
-         * Pointer to this node's parent.
-         * @type TestNode
-         * @property parent
-         */        
-        this.parent = null; 
-   
-        /**
-         * Pointer to this node's next sibling.
-         * @type TestNode
-         * @property next
-         */        
-        this.next = null;
-        
-        /**
-         * Test results for this test object.
-         * @type object
-         * @property results
-         */                
-        this.results /*:Object*/ = {
-            passed : 0,
-            failed : 0,
-            total : 0
-        };
-       
-    }
-    
-    TestNode.prototype = {
-    
-        /**
-         * Appends a new test object (TestSuite, TestCase, or test function name) as a child
-         * of this node.
-         * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.
-         * @return {Void}
-         */
-        appendChild : function (testObject /*:Variant*/) /*:Void*/{
-            var node = new TestNode(testObject);
-            if (this.firstChild === null){
-                this.firstChild = this.lastChild = node;
-            } else {
-                this.lastChild.next = node;
-                this.lastChild = node;
-            }
-            node.parent = this;
-            return node;
-        }       
-    };
-
-    function TestRunner(){
-    
-        //inherit from EventProvider
-        TestRunner.superclass.constructor.apply(this,arguments);
-        
-        /**
-         * Suite on which to attach all TestSuites and TestCases to be run.
-         * @type YAHOO.tool.TestSuite
-         * @property masterSuite
-         * @private
-         */
-        this.masterSuite /*:YAHOO.tool.TestSuite*/ = new YAHOO.tool.TestSuite("MasterSuite");        
-
-        /**
-         * Pointer to the current node in the test tree.
-         * @type TestNode
-         * @private
-         * @property _cur
-         */
-        this._cur = null;
-        
-        /**
-         * Pointer to the root node in the test tree.
-         * @type TestNode
-         * @private
-         * @property _root
-         */
-        this._root = null;
-        
-        //create events
-        var events /*:Array*/ = [
-            this.TEST_CASE_BEGIN_EVENT,
-            this.TEST_CASE_COMPLETE_EVENT,
-            this.TEST_SUITE_BEGIN_EVENT,
-            this.TEST_SUITE_COMPLETE_EVENT,
-            this.TEST_PASS_EVENT,
-            this.TEST_FAIL_EVENT,
-            this.TEST_IGNORE_EVENT,
-            this.COMPLETE_EVENT,
-            this.BEGIN_EVENT
-        ];
-        for (var i=0; i < events.length; i++){
-            this.createEvent(events[i], { scope: this });
-        }       
-   
-    }
-    
-    YAHOO.lang.extend(TestRunner, YAHOO.util.EventProvider, {
-    
-        //-------------------------------------------------------------------------
-        // Constants
-        //-------------------------------------------------------------------------
-         
-        /**
-         * Fires when a test case is opened but before the first 
-         * test is executed.
-         * @event testcasebegin
-         */         
-        TEST_CASE_BEGIN_EVENT /*:String*/ : "testcasebegin",
-        
-        /**
-         * Fires when all tests in a test case have been executed.
-         * @event testcasecomplete
-         */        
-        TEST_CASE_COMPLETE_EVENT /*:String*/ : "testcasecomplete",
-        
-        /**
-         * Fires when a test suite is opened but before the first 
-         * test is executed.
-         * @event testsuitebegin
-         */        
-        TEST_SUITE_BEGIN_EVENT /*:String*/ : "testsuitebegin",
-        
-        /**
-         * Fires when all test cases in a test suite have been
-         * completed.
-         * @event testsuitecomplete
-         */        
-        TEST_SUITE_COMPLETE_EVENT /*:String*/ : "testsuitecomplete",
-        
-        /**
-         * Fires when a test has passed.
-         * @event pass
-         */        
-        TEST_PASS_EVENT /*:String*/ : "pass",
-        
-        /**
-         * Fires when a test has failed.
-         * @event fail
-         */        
-        TEST_FAIL_EVENT /*:String*/ : "fail",
-        
-        /**
-         * Fires when a test has been ignored.
-         * @event ignore
-         */        
-        TEST_IGNORE_EVENT /*:String*/ : "ignore",
-        
-        /**
-         * Fires when all test suites and test cases have been completed.
-         * @event complete
-         */        
-        COMPLETE_EVENT /*:String*/ : "complete",
-        
-        /**
-         * Fires when the run() method is called.
-         * @event begin
-         */        
-        BEGIN_EVENT /*:String*/ : "begin",    
-        
-        //-------------------------------------------------------------------------
-        // Test Tree-Related Methods
-        //-------------------------------------------------------------------------
-
-        /**
-         * Adds a test case to the test tree as a child of the specified node.
-         * @param {TestNode} parentNode The node to add the test case to as a child.
-         * @param {YAHOO.tool.TestCase} testCase The test case to add.
-         * @return {Void}
-         * @static
-         * @private
-         * @method _addTestCaseToTestTree
-         */
-       _addTestCaseToTestTree : function (parentNode /*:TestNode*/, testCase /*:YAHOO.tool.TestCase*/) /*:Void*/{
-            
-            //add the test suite
-            var node = parentNode.appendChild(testCase);
-            
-            //iterate over the items in the test case
-            for (var prop in testCase){
-                if (prop.indexOf("test") === 0 && YAHOO.lang.isFunction(testCase[prop])){
-                    node.appendChild(prop);
-                }
-            }
-         
-        },
-        
-        /**
-         * Adds a test suite to the test tree as a child of the specified node.
-         * @param {TestNode} parentNode The node to add the test suite to as a child.
-         * @param {YAHOO.tool.TestSuite} testSuite The test suite to add.
-         * @return {Void}
-         * @static
-         * @private
-         * @method _addTestSuiteToTestTree
-         */
-        _addTestSuiteToTestTree : function (parentNode /*:TestNode*/, testSuite /*:YAHOO.tool.TestSuite*/) /*:Void*/ {
-            
-            //add the test suite
-            var node = parentNode.appendChild(testSuite);
-            
-            //iterate over the items in the master suite
-            for (var i=0; i < testSuite.items.length; i++){
-                if (testSuite.items[i] instanceof YAHOO.tool.TestSuite) {
-                    this._addTestSuiteToTestTree(node, testSuite.items[i]);
-                } else if (testSuite.items[i] instanceof YAHOO.tool.TestCase) {
-                    this._addTestCaseToTestTree(node, testSuite.items[i]);
-                }                   
-            }            
-        },
-        
-        /**
-         * Builds the test tree based on items in the master suite. The tree is a hierarchical
-         * representation of the test suites, test cases, and test functions. The resulting tree
-         * is stored in _root and the pointer _cur is set to the root initially.
-         * @return {Void}
-         * @static
-         * @private
-         * @method _buildTestTree
-         */
-        _buildTestTree : function () /*:Void*/ {
-        
-            this._root = new TestNode(this.masterSuite);
-            this._cur = this._root;
-            
-            //iterate over the items in the master suite
-            for (var i=0; i < this.masterSuite.items.length; i++){
-                if (this.masterSuite.items[i] instanceof YAHOO.tool.TestSuite) {
-                    this._addTestSuiteToTestTree(this._root, this.masterSuite.items[i]);
-                } else if (this.masterSuite.items[i] instanceof YAHOO.tool.TestCase) {
-                    this._addTestCaseToTestTree(this._root, this.masterSuite.items[i]);
-                }                   
-            }            
-        
-        }, 
-    
-        //-------------------------------------------------------------------------
-        // Private Methods
-        //-------------------------------------------------------------------------
-        _handleTestObjectComplete : function (node /*:TestNode*/) /*:Void*/ {
-            if (YAHOO.lang.isObject(node.testObject)){
-                node.parent.results.passed += node.results.passed;
-                node.parent.results.failed += node.results.failed;
-                node.parent.results.total += node.results.total;                
-                node.parent.results[node.testObject.name] = node.results;
-            
-                if (node.testObject instanceof YAHOO.tool.TestSuite){
-                    node.testObject.tearDown();
-                    this.fireEvent(this.TEST_SUITE_COMPLETE_EVENT, { testSuite: node.testObject, results: node.results});
-                } else if (node.testObject instanceof YAHOO.tool.TestCase){
-                    this.fireEvent(this.TEST_CASE_COMPLETE_EVENT, { testCase: node.testObject, results: node.results});
-                }      
-            } 
-        },        
-        
-        
-        //-------------------------------------------------------------------------
-        // Navigation Methods
-        //-------------------------------------------------------------------------
-        
-        /**
-         * Retrieves the next node in the test tree.
-         * @return {TestNode} The next node in the test tree or null if the end is reached.
-         * @private
-         * @static
-         * @method _next
-         */
-        _next : function () /*:TestNode*/ {
-        
-            if (this._cur.firstChild) {
-                this._cur = this._cur.firstChild;
-            } else if (this._cur.next) {
-                this._cur = this._cur.next;            
-            } else {
-                while (this._cur && !this._cur.next && this._cur !== this._root){
-                    this._handleTestObjectComplete(this._cur);
-                    this._cur = this._cur.parent;
-                }
-                
-                if (this._cur == this._root){
-                    this.fireEvent(this.COMPLETE_EVENT, { results: this._cur.results});
-                    this._cur = null;
-                } else {
-                    this._handleTestObjectComplete(this._cur);               
-                    this._cur = this._cur.next;                
-                }
-            }
-        
-            return this._cur;
-        },
-        
-        /**
-         * Runs a test case or test suite, returning the results.
-         * @param {YAHOO.tool.TestCase|YAHOO.tool.TestSuite} testObject The test case or test suite to run.
-         * @return {Object} Results of the execution with properties passed, failed, and total.
-         * @private
-         * @method _run
-         * @static
-         */
-        _run : function () /*:Void*/ {
-        
-            //flag to indicate if the TestRunner should wait before continuing
-            var shouldWait /*:Boolean*/ = false;
-            
-            //get the next test node
-            var node = this._next();
-            
-            if (node !== null) {
-                var testObject = node.testObject;
-                
-                //figure out what to do
-                if (YAHOO.lang.isObject(testObject)){
-                    if (testObject instanceof YAHOO.tool.TestSuite){
-                        this.fireEvent(this.TEST_SUITE_BEGIN_EVENT, { testSuite: testObject });
-                        testObject.setUp();
-                    } else if (testObject instanceof YAHOO.tool.TestCase){
-                        this.fireEvent(this.TEST_CASE_BEGIN_EVENT, { testCase: testObject });
-                    }
-                    
-                    //some environments don't support setTimeout
-                    if (typeof setTimeout != "undefined"){                    
-                        setTimeout(function(){
-                            YAHOO.tool.TestRunner._run();
-                        }, 0);              
-                    } else {
-                        this._run();
-                    }
-                } else {
-                    this._runTest(node);
-                }
-
-            }
-        },
-        
-        _resumeTest : function (segment /*:Function*/) /*:Void*/ {
-        
-            //get relevant information
-            var node /*:TestNode*/ = this._cur;
-            var testName /*:String*/ = node.testObject;
-            var testCase /*:YAHOO.tool.TestCase*/ = node.parent.testObject;
-            
-            //get the "should" test cases
-            var shouldFail /*:Object*/ = (testCase._should.fail || {})[testName];
-            var shouldError /*:Object*/ = (testCase._should.error || {})[testName];
-            
-            //variable to hold whether or not the test failed
-            var failed /*:Boolean*/ = false;
-            var error /*:Error*/ = null;
-                
-            //try the test
-            try {
-            
-                //run the test
-                segment.apply(testCase);
-                
-                //if it should fail, and it got here, then it's a fail because it didn't
-                if (shouldFail){
-                    error = new YAHOO.util.ShouldFail();
-                    failed = true;
-                } else if (shouldError){
-                    error = new YAHOO.util.ShouldError();
-                    failed = true;
-                }
-                           
-            } catch (thrown /*:Error*/){
-                if (thrown instanceof YAHOO.util.AssertionError) {
-                    if (!shouldFail){
-                        error = thrown;
-                        failed = true;
-                    }
-                } else if (thrown instanceof YAHOO.tool.TestCase.Wait){
-                
-                    if (YAHOO.lang.isFunction(thrown.segment)){
-                        if (YAHOO.lang.isNumber(thrown.delay)){
-                        
-                            //some environments don't support setTimeout
-                            if (typeof setTimeout != "undefined"){
-                                setTimeout(function(){
-                                    YAHOO.tool.TestRunner._resumeTest(thrown.segment);
-                                }, thrown.delay);
-                            } else {
-                                throw new Error("Asynchronous tests not supported in this environment.");
-                            }
-                        }
-                    }
-                    
-                    return;
-                
-                } else {
-                    //first check to see if it should error
-                    if (!shouldError) {                        
-                        error = new YAHOO.util.UnexpectedError(thrown);
-                        failed = true;
-                    } else {
-                        //check to see what type of data we have
-                        if (YAHOO.lang.isString(shouldError)){
-                            
-                            //if it's a string, check the error message
-                            if (thrown.message != shouldError){
-                                error = new YAHOO.util.UnexpectedError(thrown);
-                                failed = true;                                    
-                            }
-                        } else if (YAHOO.lang.isObject(shouldError)){
-                        
-                            //if it's an object, check the instance and message
-                            if (!(thrown instanceof shouldError.constructor) || 
-                                    thrown.message != shouldError.message){
-                                error = new YAHOO.util.UnexpectedError(thrown);
-                                failed = true;                                    
-                            }
-                        
-                        }
-                    
-                    }
-                }
-                
-            }
-            
-            //fireEvent appropriate event
-            if (failed) {
-                this.fireEvent(this.TEST_FAIL_EVENT, { testCase: testCase, testName: testName, error: error });
-            } else {
-                this.fireEvent(this.TEST_PASS_EVENT, { testCase: testCase, testName: testName });
-            }
-            
-            //run the tear down
-            testCase.tearDown();
-            
-            //update results
-            node.parent.results[testName] = { 
-                result: failed ? "fail" : "pass",
-                message : error ? error.getMessage() : "Test passed"
-            };
-            
-            if (failed){
-                node.parent.results.failed++;
-            } else {
-                node.parent.results.passed++;
-            }
-            node.parent.results.total++;    
-
-            //set timeout not supported in all environments
-            if (typeof setTimeout != "undefined"){
-                setTimeout(function(){
-                    YAHOO.tool.TestRunner._run();
-                }, 0);
-            } else {
-                this._run();
-            }
-        
-        },
-                
-        /**
-         * Runs a single test based on the data provided in the node.
-         * @param {TestNode} node The TestNode representing the test to run.
-         * @return {Void}
-         * @static
-         * @private
-         * @name _runTest
-         */
-        _runTest : function (node /*:TestNode*/) /*:Void*/ {
-        
-            //get relevant information
-            var testName /*:String*/ = node.testObject;
-            var testCase /*:YAHOO.tool.TestCase*/ = node.parent.testObject;
-            var test /*:Function*/ = testCase[testName];
-            
-            //get the "should" test cases
-            var shouldIgnore /*:Object*/ = (testCase._should.ignore || {})[testName];
-            
-            //figure out if the test should be ignored or not
-            if (shouldIgnore){
-                this.fireEvent(this.TEST_IGNORE_EVENT, { testCase: testCase, testName: testName });
-                
-                //some environments don't support setTimeout
-                if (typeof setTimeout != "undefined"){                    
-                    setTimeout(function(){
-                        YAHOO.tool.TestRunner._run();
-                    }, 0);              
-                } else {
-                    this._run();
-                }
-
-            } else {
-            
-                //run the setup
-                testCase.setUp();
-                
-                //now call the body of the test
-                this._resumeTest(test);                
-            }
-
-        },        
-        
-        //-------------------------------------------------------------------------
-        // Protected Methods
-        //-------------------------------------------------------------------------   
-    
-        /*
-         * Fires events for the TestRunner. This overrides the default fireEvent()
-         * method from EventProvider to add the type property to the data that is
-         * passed through on each event call.
-         * @param {String} type The type of event to fire.
-         * @param {Object} data (Optional) Data for the event.
-         * @method fireEvent
-         * @static
-         * @protected
-         */
-        fireEvent : function (type /*:String*/, data /*:Object*/) /*:Void*/ {
-            data = data || {};
-            data.type = type;
-            TestRunner.superclass.fireEvent.call(this, type, data);
-        },
-        
-        //-------------------------------------------------------------------------
-        // Public Methods
-        //-------------------------------------------------------------------------   
-    
-        /**
-         * Adds a test suite or test case to the list of test objects to run.
-         * @param testObject Either a TestCase or a TestSuite that should be run.
-         * @return {Void}
-         * @method add
-         * @static
-         */
-        add : function (testObject /*:Object*/) /*:Void*/ {
-            this.masterSuite.add(testObject);
-        },
-        
-        /**
-         * Removes all test objects from the runner.
-         * @return {Void}
-         * @method clear
-         * @static
-         */
-        clear : function () /*:Void*/ {
-            this.masterSuite.items = [];
-        },
-        
-        /**
-         * Resumes the TestRunner after wait() was called.
-         * @param {Function} segment The function to run as the rest
-         *      of the haulted test.
-         * @return {Void}
-         * @method resume
-         * @static
-         */
-        resume : function (segment /*:Function*/) /*:Void*/ {
-            this._resumeTest(segment || function(){});
-        },
-    
-        /**
-         * Runs the test suite.
-         * @return {Void}
-         * @method run
-         * @static
-         */
-        run : function (testObject /*:Object*/) /*:Void*/ {
-            
-            //pointer to runner to avoid scope issues 
-            var runner = YAHOO.tool.TestRunner;
-
-            //build the test tree
-            runner._buildTestTree();
-            
-            //fire the begin event
-            runner.fireEvent(runner.BEGIN_EVENT);
-       
-            //begin the testing
-            runner._run();
-        }    
-    });
-    
-    return new TestRunner();
-    
-})();
-
-YAHOO.namespace("util");
-
-//-----------------------------------------------------------------------------
-// Assert object
-//-----------------------------------------------------------------------------
-
-/**
- * The Assert object provides functions to test JavaScript values against
- * known and expected results. Whenever a comparison (assertion) fails,
- * an error is thrown.
- *
- * @namespace YAHOO.util
- * @class Assert
- * @static
- */
-YAHOO.util.Assert = {
-
-    //-------------------------------------------------------------------------
-    // Generic Assertion Methods
-    //-------------------------------------------------------------------------
-    
-    /** 
-     * Forces an assertion error to occur.
-     * @param {String} message (Optional) The message to display with the failure.
-     * @method fail
-     * @static
-     */
-    fail : function (message /*:String*/) /*:Void*/ {
-        throw new YAHOO.util.AssertionError(message || "Test force-failed.");
-    },       
-    
-    //-------------------------------------------------------------------------
-    // Equality Assertion Methods
-    //-------------------------------------------------------------------------    
-    
-    /**
-     * Asserts that a value is equal to another. This uses the double equals sign
-     * so type cohersion may occur.
-     * @param {Object} expected The expected value.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method areEqual
-     * @static
-     */
-    areEqual : function (expected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (expected != actual) {
-            throw new YAHOO.util.ComparisonFailure(message || "Values should be equal.", expected, actual);
-        }
-    },
-    
-    /**
-     * Asserts that a value is not equal to another. This uses the double equals sign
-     * so type cohersion may occur.
-     * @param {Object} unexpected The unexpected value.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method areNotEqual
-     * @static
-     */
-    areNotEqual : function (unexpected /*:Object*/, actual /*:Object*/, 
-                         message /*:String*/) /*:Void*/ {
-        if (unexpected == actual) {
-            throw new YAHOO.util.UnexpectedValue(message || "Values should not be equal.", unexpected);
-        }
-    },
-    
-    /**
-     * Asserts that a value is not the same as another. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} unexpected The unexpected value.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method areNotSame
-     * @static
-     */
-    areNotSame : function (unexpected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (unexpected === actual) {
-            throw new YAHOO.util.UnexpectedValue(message || "Values should not be the same.", unexpected);
-        }
-    },
-
-    /**
-     * Asserts that a value is the same as another. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} expected The expected value.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method areSame
-     * @static
-     */
-    areSame : function (expected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (expected !== actual) {
-            throw new YAHOO.util.ComparisonFailure(message || "Values should be the same.", expected, actual);
-        }
-    },    
-    
-    //-------------------------------------------------------------------------
-    // Boolean Assertion Methods
-    //-------------------------------------------------------------------------    
-    
-    /**
-     * Asserts that a value is false. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isFalse
-     * @static
-     */
-    isFalse : function (actual /*:Boolean*/, message /*:String*/) {
-        if (false !== actual) {
-            throw new YAHOO.util.ComparisonFailure(message || "Value should be false.", false, actual);
-        }
-    },
-    
-    /**
-     * Asserts that a value is true. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isTrue
-     * @static
-     */
-    isTrue : function (actual /*:Boolean*/, message /*:String*/) /*:Void*/ {
-        if (true !== actual) {
-            throw new YAHOO.util.ComparisonFailure(message || "Value should be true.", true, actual);
-        }
-
-    },
-    
-    //-------------------------------------------------------------------------
-    // Special Value Assertion Methods
-    //-------------------------------------------------------------------------    
-    
-    /**
-     * Asserts that a value is not a number.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNaN
-     * @static
-     */
-    isNaN : function (actual /*:Object*/, message /*:String*/) /*:Void*/{
-        if (!isNaN(actual)){
-            throw new YAHOO.util.ComparisonFailure(message || "Value should be NaN.", NaN, actual);
-        }    
-    },
-    
-    /**
-     * Asserts that a value is not the special NaN value.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNotNaN
-     * @static
-     */
-    isNotNaN : function (actual /*:Object*/, message /*:String*/) /*:Void*/{
-        if (isNaN(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Values should not be NaN.", NaN);
-        }    
-    },
-    
-    /**
-     * Asserts that a value is not null. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNotNull
-     * @static
-     */
-    isNotNull : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (YAHOO.lang.isNull(actual)) {
-            throw new YAHOO.util.UnexpectedValue(message || "Values should not be null.", null);
-        }
-    },
-
-    /**
-     * Asserts that a value is not undefined. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNotUndefined
-     * @static
-     */
-    isNotUndefined : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (YAHOO.lang.isUndefined(actual)) {
-            throw new YAHOO.util.UnexpectedValue(message || "Value should not be undefined.", undefined);
-        }
-    },
-
-    /**
-     * Asserts that a value is null. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNull
-     * @static
-     */
-    isNull : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isNull(actual)) {
-            throw new YAHOO.util.ComparisonFailure(message || "Value should be null.", null, actual);
-        }
-    },
-        
-    /**
-     * Asserts that a value is undefined. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} expected The expected value.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isUndefined
-     * @static
-     */
-    isUndefined : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isUndefined(actual)) {
-            throw new YAHOO.util.ComparisonFailure(message || "Value should be undefined.", undefined, actual);
-        }
-    },    
-    
-    //--------------------------------------------------------------------------
-    // Instance Assertion Methods
-    //--------------------------------------------------------------------------    
-   
-    /**
-     * Asserts that a value is an array.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isArray
-     * @static
-     */
-    isArray : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isArray(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Value should be an array.", actual);
-        }    
-    },
-   
-    /**
-     * Asserts that a value is a Boolean.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isBoolean
-     * @static
-     */
-    isBoolean : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isBoolean(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Value should be a Boolean.", actual);
-        }    
-    },
-   
-    /**
-     * Asserts that a value is a function.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isFunction
-     * @static
-     */
-    isFunction : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isFunction(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Value should be a function.", actual);
-        }    
-    },
-   
-    /**
-     * Asserts that a value is an instance of a particular object. This may return
-     * incorrect results when comparing objects from one frame to constructors in
-     * another frame. For best results, don't use in a cross-frame manner.
-     * @param {Function} expected The function that the object should be an instance of.
-     * @param {Object} actual The object to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isInstanceOf
-     * @static
-     */
-    isInstanceOf : function (expected /*:Function*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!(actual instanceof expected)){
-            throw new YAHOO.util.ComparisonFailure(message || "Value isn't an instance of expected type.", expected, actual);
-        }
-    },
-    
-    /**
-     * Asserts that a value is a number.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNumber
-     * @static
-     */
-    isNumber : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isNumber(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Value should be a number.", actual);
-        }    
-    },    
-    
-    /**
-     * Asserts that a value is an object.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isObject
-     * @static
-     */
-    isObject : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isObject(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Value should be an object.", actual);
-        }
-    },
-    
-    /**
-     * Asserts that a value is a string.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isString
-     * @static
-     */
-    isString : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isString(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Value should be a string.", actual);
-        }
-    },
-    
-    /**
-     * Asserts that a value is of a particular type. 
-     * @param {String} expectedType The expected type of the variable.
-     * @param {Object} actualValue The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isTypeOf
-     * @static
-     */
-    isTypeOf : function (expectedType /*:String*/, actualValue /*:Object*/, message /*:String*/) /*:Void*/{
-        if (typeof actualValue != expectedType){
-            throw new YAHOO.util.ComparisonFailure(message || "Value should be of type " + expected + ".", expected, typeof actual);
-        }
-    }
-};
-
-//-----------------------------------------------------------------------------
-// Assertion errors
-//-----------------------------------------------------------------------------
-
-/**
- * AssertionError is thrown whenever an assertion fails. It provides methods
- * to more easily get at error information and also provides a base class
- * from which more specific assertion errors can be derived.
- *
- * @param {String} message The message to display when the error occurs.
- * @namespace YAHOO.util
- * @class AssertionError
- * @extends Error
- * @constructor
- */ 
-YAHOO.util.AssertionError = function (message /*:String*/){
-
-    //call superclass
-    arguments.callee.superclass.constructor.call(this, message);
-    
-    /*
-     * Error message. Must be duplicated to ensure browser receives it.
-     * @type String
-     * @property message
-     */
-    this.message /*:String*/ = message;
-    
-    /**
-     * The name of the error that occurred.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "AssertionError";
-};
-
-//inherit methods
-YAHOO.lang.extend(YAHOO.util.AssertionError, Error, {
-
-    /**
-     * Returns a fully formatted error for an assertion failure. This should
-     * be overridden by all subclasses to provide specific information.
-     * @method getMessage
-     * @return {String} A string describing the error.
-     */
-    getMessage : function () /*:String*/ {
-        return this.message;
-    },
-    
-    /**
-     * Returns a string representation of the error.
-     * @method toString
-     * @return {String} A string representation of the error.
-     */
-    toString : function () /*:String*/ {
-        return this.name + ": " + this.getMessage();
-    },
-    
-    /**
-     * Returns a primitive value version of the error. Same as toString().
-     * @method valueOf
-     * @return {String} A primitive value version of the error.
-     */
-    valueOf : function () /*:String*/ {
-        return this.toString();
-    }
-
-});
-
-/**
- * ComparisonFailure is subclass of AssertionError that is thrown whenever
- * a comparison between two values fails. It provides mechanisms to retrieve
- * both the expected and actual value.
- *
- * @param {String} message The message to display when the error occurs.
- * @param {Object} expected The expected value.
- * @param {Object} actual The actual value that caused the assertion to fail.
- * @namespace YAHOO.util
- * @extends YAHOO.util.AssertionError
- * @class ComparisonFailure
- * @constructor
- */ 
-YAHOO.util.ComparisonFailure = function (message /*:String*/, expected /*:Object*/, actual /*:Object*/){
-
-    //call superclass
-    arguments.callee.superclass.constructor.call(this, message);
-    
-    /**
-     * The expected value.
-     * @type Object
-     * @property expected
-     */
-    this.expected /*:Object*/ = expected;
-    
-    /**
-     * The actual value.
-     * @type Object
-     * @property actual
-     */
-    this.actual /*:Object*/ = actual;
-    
-    /**
-     * The name of the error that occurred.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "ComparisonFailure";
-    
-};
-
-//inherit methods
-YAHOO.lang.extend(YAHOO.util.ComparisonFailure, YAHOO.util.AssertionError, {
-
-    /**
-     * Returns a fully formatted error for an assertion failure. This message
-     * provides information about the expected and actual values.
-     * @method toString
-     * @return {String} A string describing the error.
-     */
-    getMessage : function () /*:String*/ {
-        return this.message + "\nExpected: " + this.expected + " (" + (typeof this.expected) + ")"  +
-            "\nActual:" + this.actual + " (" + (typeof this.actual) + ")";
-    }
-
-});
-
-/**
- * UnexpectedValue is subclass of AssertionError that is thrown whenever
- * a value was unexpected in its scope. This typically means that a test
- * was performed to determine that a value was *not* equal to a certain
- * value.
- *
- * @param {String} message The message to display when the error occurs.
- * @param {Object} unexpected The unexpected value.
- * @namespace YAHOO.util
- * @extends YAHOO.util.AssertionError
- * @class UnexpectedValue
- * @constructor
- */ 
-YAHOO.util.UnexpectedValue = function (message /*:String*/, unexpected /*:Object*/){
-
-    //call superclass
-    arguments.callee.superclass.constructor.call(this, message);
-    
-    /**
-     * The unexpected value.
-     * @type Object
-     * @property unexpected
-     */
-    this.unexpected /*:Object*/ = unexpected;
-    
-    /**
-     * The name of the error that occurred.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "UnexpectedValue";
-    
-};
-
-//inherit methods
-YAHOO.lang.extend(YAHOO.util.UnexpectedValue, YAHOO.util.AssertionError, {
-
-    /**
-     * Returns a fully formatted error for an assertion failure. The message
-     * contains information about the unexpected value that was encountered.
-     * @method getMessage
-     * @return {String} A string describing the error.
-     */
-    getMessage : function () /*:String*/ {
-        return this.message + "\nUnexpected: " + this.unexpected + " (" + (typeof this.unexpected) + ") ";
-    }
-
-});
-
-/**
- * ShouldFail is subclass of AssertionError that is thrown whenever
- * a test was expected to fail but did not.
- *
- * @param {String} message The message to display when the error occurs.
- * @namespace YAHOO.util
- * @extends YAHOO.util.AssertionError
- * @class ShouldFail
- * @constructor
- */  
-YAHOO.util.ShouldFail = function (message /*:String*/){
-
-    //call superclass
-    arguments.callee.superclass.constructor.call(this, message || "This test should fail but didn't.");
-    
-    /**
-     * The name of the error that occurred.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "ShouldFail";
-    
-};
-
-//inherit methods
-YAHOO.lang.extend(YAHOO.util.ShouldFail, YAHOO.util.AssertionError);
-
-/**
- * ShouldError is subclass of AssertionError that is thrown whenever
- * a test is expected to throw an error but doesn't.
- *
- * @param {String} message The message to display when the error occurs.
- * @namespace YAHOO.util
- * @extends YAHOO.util.AssertionError
- * @class ShouldError
- * @constructor
- */  
-YAHOO.util.ShouldError = function (message /*:String*/){
-
-    //call superclass
-    arguments.callee.superclass.constructor.call(this, message || "This test should have thrown an error but didn't.");
-    
-    /**
-     * The name of the error that occurred.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "ShouldError";
-    
-};
-
-//inherit methods
-YAHOO.lang.extend(YAHOO.util.ShouldError, YAHOO.util.AssertionError);
-
-/**
- * UnexpectedError is subclass of AssertionError that is thrown whenever
- * an error occurs within the course of a test and the test was not expected
- * to throw an error.
- *
- * @param {Error} cause The unexpected error that caused this error to be 
- *                      thrown.
- * @namespace YAHOO.util
- * @extends YAHOO.util.AssertionError
- * @class UnexpectedError
- * @constructor
- */  
-YAHOO.util.UnexpectedError = function (cause /*:Object*/){
-
-    //call superclass
-    arguments.callee.superclass.constructor.call(this, "Unexpected error: " + cause.message);
-    
-    /**
-     * The unexpected error that occurred.
-     * @type Error
-     * @property cause
-     */
-    this.cause /*:Error*/ = cause;
-    
-    /**
-     * The name of the error that occurred.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "UnexpectedError";
-    
-};
-
-//inherit methods
-YAHOO.lang.extend(YAHOO.util.UnexpectedError, YAHOO.util.AssertionError);
-
-//-----------------------------------------------------------------------------
-// ArrayAssert object
-//-----------------------------------------------------------------------------
-
-/**
- * The ArrayAssert object provides functions to test JavaScript array objects
- * for a variety of cases.
- *
- * @namespace YAHOO.util
- * @class ArrayAssert
- * @static
- */
- 
-YAHOO.util.ArrayAssert = {
-
-    /**
-     * Asserts that a value is present in an array. This uses the triple equals 
-     * sign so no type cohersion may occur.
-     * @param {Object} needle The value that is expected in the array.
-     * @param {Array} haystack An array of values.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method contains
-     * @static
-     */
-    contains : function (needle /*:Object*/, haystack /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-        
-        var found /*:Boolean*/ = false;
-        
-        //begin checking values
-        for (var i=0; i < haystack.length && !found; i++){
-            if (haystack[i] === needle) {
-                found = true;
-            }
-        }
-        
-        if (!found){
-            YAHOO.util.Assert.fail(message || "Value (" + needle + ") not found in array.");
-        }
-    },
-
-    /**
-     * Asserts that a set of values are present in an array. This uses the triple equals 
-     * sign so no type cohersion may occur. For this assertion to pass, all values must
-     * be found.
-     * @param {Object[]} needles An array of values that are expected in the array.
-     * @param {Array} haystack An array of values to check.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method containsItems
-     * @static
-     */
-    containsItems : function (needles /*:Object[]*/, haystack /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-
-        //begin checking values
-        for (var i=0; i < needles.length; i++){
-            this.contains(needles[i], haystack, message);
-        }
-        
-        if (!found){
-            YAHOO.util.Assert.fail(message || "Value not found in array.");
-        }
-    },
-
-    /**
-     * Asserts that a value matching some condition is present in an array. This uses
-     * a function to determine a match.
-     * @param {Function} matcher A function that returns true if the items matches or false if not.
-     * @param {Array} haystack An array of values.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method containsMatch
-     * @static
-     */
-    containsMatch : function (matcher /*:Function*/, haystack /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-        
-        //check for valid matcher
-        if (typeof matcher != "function"){
-            throw new TypeError("ArrayAssert.containsMatch(): First argument must be a function.");
-        }
-        
-        var found /*:Boolean*/ = false;
-        
-        //begin checking values
-        for (var i=0; i < haystack.length && !found; i++){
-            if (matcher(haystack[i])) {
-                found = true;
-            }
-        }
-        
-        if (!found){
-            YAHOO.util.Assert.fail(message || "No match found in array.");
-        }
-    },
-
-    /**
-     * Asserts that a value is not present in an array. This uses the triple equals 
-     * sign so no type cohersion may occur.
-     * @param {Object} needle The value that is expected in the array.
-     * @param {Array} haystack An array of values.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method doesNotContain
-     * @static
-     */
-    doesNotContain : function (needle /*:Object*/, haystack /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-        
-        var found /*:Boolean*/ = false;
-        
-        //begin checking values
-        for (var i=0; i < haystack.length && !found; i++){
-            if (haystack[i] === needle) {
-                found = true;
-            }
-        }
-        
-        if (found){
-            YAHOO.util.Assert.fail(message || "Value found in array.");
-        }
-    },
-
-    /**
-     * Asserts that a set of values are not present in an array. This uses the triple equals 
-     * sign so no type cohersion may occur. For this assertion to pass, all values must
-     * not be found.
-     * @param {Object[]} needles An array of values that are not expected in the array.
-     * @param {Array} haystack An array of values to check.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method doesNotContainItems
-     * @static
-     */
-    doesNotContainItems : function (needles /*:Object[]*/, haystack /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-
-        for (var i=0; i < needles.length; i++){
-            this.doesNotContain(needles[i], haystack, message);
-        }
-
-    },
-        
-    /**
-     * Asserts that no values matching a condition are present in an array. This uses
-     * a function to determine a match.
-     * @param {Function} matcher A function that returns true if the items matches or false if not.
-     * @param {Array} haystack An array of values.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method doesNotContainMatch
-     * @static
-     */
-    doesNotContainMatch : function (matcher /*:Function*/, haystack /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-        
-        //check for valid matcher
-        if (typeof matcher != "function"){
-            throw new TypeError("ArrayAssert.doesNotContainMatch(): First argument must be a function.");
-        }
-
-        var found /*:Boolean*/ = false;
-        
-        //begin checking values
-        for (var i=0; i < haystack.length && !found; i++){
-            if (matcher(haystack[i])) {
-                found = true;
-            }
-        }
-        
-        if (found){
-            YAHOO.util.Assert.fail(message || "Value found in array.");
-        }
-    },
-        
-    /**
-     * Asserts that the given value is contained in an array at the specified index.
-     * This uses the triple equals sign so no type cohersion will occur.
-     * @param {Object} needle The value to look for.
-     * @param {Array} haystack The array to search in.
-     * @param {int} index The index at which the value should exist.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method indexOf
-     * @static
-     */
-    indexOf : function (needle /*:Object*/, haystack /*:Array*/, index /*:int*/, message /*:String*/) /*:Void*/ {
-    
-        //try to find the value in the array
-        for (var i=0; i < haystack.length; i++){
-            if (haystack[i] === needle){
-                YAHOO.util.Assert.areEqual(index, i, message || "Value exists at index " + i + " but should be at index " + index + ".");
-                return;
-            }
-        }
-        
-        //if it makes it here, it wasn't found at all
-        YAHOO.util.Assert.fail(message || "Value doesn't exist in array.");        
-    },
-        
-    /**
-     * Asserts that the values in an array are equal, and in the same position,
-     * as values in another array. This uses the double equals sign
-     * so type cohersion may occur. Note that the array objects themselves
-     * need not be the same for this test to pass.
-     * @param {Array} expected An array of the expected values.
-     * @param {Array} actual Any array of the actual values.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method itemsAreEqual
-     * @static
-     */
-    itemsAreEqual : function (expected /*:Array*/, actual /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-        
-        //one may be longer than the other, so get the maximum length
-        var len /*:int*/ = Math.max(expected.length, actual.length);
-        
-        //begin checking values
-        for (var i=0; i < len; i++){
-            YAHOO.util.Assert.areEqual(expected[i], actual[i], message || 
-                    "Values in position " + i + " are not equal.");
-        }
-    },
-    
-    /**
-     * Asserts that the values in an array are equivalent, and in the same position,
-     * as values in another array. This uses a function to determine if the values
-     * are equivalent. Note that the array objects themselves
-     * need not be the same for this test to pass.
-     * @param {Array} expected An array of the expected values.
-     * @param {Array} actual Any array of the actual values.
-     * @param {Function} comparator A function that returns true if the values are equivalent
-     *      or false if not.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @return {Void}
-     * @method itemsAreEquivalent
-     * @static
-     */
-    itemsAreEquivalent : function (expected /*:Array*/, actual /*:Array*/, 
-                           comparator /*:Function*/, message /*:String*/) /*:Void*/ {
-        
-        //make sure the comparator is valid
-        if (typeof comparator != "function"){
-            throw new TypeError("ArrayAssert.itemsAreEquivalent(): Third argument must be a function.");
-        }
-        
-        //one may be longer than the other, so get the maximum length
-        var len /*:int*/ = Math.max(expected.length, actual.length);
-        
-        //begin checking values
-        for (var i=0; i < len; i++){
-            if (!comparator(expected[i], actual[i])){
-                throw new YAHOO.util.ComparisonFailure(message || "Values in position " + i + " are not equivalent.", expected[i], actual[i]);
-            }
-        }
-    },
-    
-    /**
-     * Asserts that an array is empty.
-     * @param {Array} actual The array to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isEmpty
-     * @static
-     */
-    isEmpty : function (actual /*:Array*/, message /*:String*/) /*:Void*/ {        
-        if (actual.length > 0){
-            YAHOO.util.Assert.fail(message || "Array should be empty.");
-        }
-    },    
-    
-    /**
-     * Asserts that an array is not empty.
-     * @param {Array} actual The array to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNotEmpty
-     * @static
-     */
-    isNotEmpty : function (actual /*:Array*/, message /*:String*/) /*:Void*/ {        
-        if (actual.length === 0){
-            YAHOO.util.Assert.fail(message || "Array should not be empty.");
-        }
-    },    
-    
-    /**
-     * Asserts that the values in an array are the same, and in the same position,
-     * as values in another array. This uses the triple equals sign
-     * so no type cohersion will occur. Note that the array objects themselves
-     * need not be the same for this test to pass.
-     * @param {Array} expected An array of the expected values.
-     * @param {Array} actual Any array of the actual values.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method itemsAreSame
-     * @static
-     */
-    itemsAreSame : function (expected /*:Array*/, actual /*:Array*/, 
-                          message /*:String*/) /*:Void*/ {
-        
-        //one may be longer than the other, so get the maximum length
-        var len /*:int*/ = Math.max(expected.length, actual.length);
-        
-        //begin checking values
-        for (var i=0; i < len; i++){
-            YAHOO.util.Assert.areSame(expected[i], actual[i], 
-                message || "Values in position " + i + " are not the same.");
-        }
-    },
-    
-    /**
-     * Asserts that the given value is contained in an array at the specified index,
-     * starting from the back of the array.
-     * This uses the triple equals sign so no type cohersion will occur.
-     * @param {Object} needle The value to look for.
-     * @param {Array} haystack The array to search in.
-     * @param {int} index The index at which the value should exist.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method lastIndexOf
-     * @static
-     */
-    lastIndexOf : function (needle /*:Object*/, haystack /*:Array*/, index /*:int*/, message /*:String*/) /*:Void*/ {
-    
-        //try to find the value in the array
-        for (var i=haystack.length; i >= 0; i--){
-            if (haystack[i] === needle){
-                YAHOO.util.Assert.areEqual(index, i, message || "Value exists at index " + i + " but should be at index " + index + ".");
-                return;
-            }
-        }
-        
-        //if it makes it here, it wasn't found at all
-        YAHOO.util.Assert.fail(message || "Value doesn't exist in array.");        
-    }
-    
-};
-
-YAHOO.namespace("util");
-
-
-//-----------------------------------------------------------------------------
-// ObjectAssert object
-//-----------------------------------------------------------------------------
-
-/**
- * The ObjectAssert object provides functions to test JavaScript objects
- * for a variety of cases.
- *
- * @namespace YAHOO.util
- * @class ObjectAssert
- * @static
- */
-YAHOO.util.ObjectAssert = {
-        
-    /**
-     * Asserts that all properties in the object exist in another object.
-     * @param {Object} expected An object with the expected properties.
-     * @param {Object} actual An object with the actual properties.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method propertiesAreEqual
-     * @static
-     */
-    propertiesAreEqual : function (expected /*:Object*/, actual /*:Object*/, 
-                           message /*:String*/) /*:Void*/ {
-        
-        //get all properties in the object
-        var properties /*:Array*/ = [];        
-        for (var property in expected){
-            properties.push(property);
-        }
-        
-        //see if the properties are in the expected object
-        for (var i=0; i < properties.length; i++){
-            YAHOO.util.Assert.isNotUndefined(actual[properties[i]], message || 
-                    "Property'" + properties[i] + "' expected.");
-        }
-
-    },
-    
-    /**
-     * Asserts that an object has a property with the given name.
-     * @param {String} propertyName The name of the property to test.
-     * @param {Object} object The object to search.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method hasProperty
-     * @static
-     */    
-    hasProperty : function (propertyName /*:String*/, object /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (YAHOO.lang.isUndefined(object[propertyName])){
-            YAHOO.util.Assert.fail(message || 
-                    "Property " + propertyName + " not found on object.");
-        }    
-    },
-    
-    /**
-     * Asserts that a property with the given name exists on an object instance (not on its prototype).
-     * @param {String} propertyName The name of the property to test.
-     * @param {Object} object The object to search.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method hasProperty
-     * @static
-     */    
-    hasOwnProperty : function (propertyName /*:String*/, object /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.hasOwnProperty(object, propertyName)){
-            YAHOO.util.Assert.fail(message || 
-                    "Property " + propertyName + " not found on object instance.");
-        }     
-    }
-};
-
-//-----------------------------------------------------------------------------
-// DateAssert object
-//-----------------------------------------------------------------------------
-
-/**
- * The DateAssert object provides functions to test JavaScript Date objects
- * for a variety of cases.
- *
- * @namespace YAHOO.util
- * @class DateAssert
- * @static
- */
- 
-YAHOO.util.DateAssert = {
-
-    /**
-     * Asserts that a date's month, day, and year are equal to another date's.
-     * @param {Date} expected The expected date.
-     * @param {Date} actual The actual date to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method areEqual
-     * @static
-     */
-    datesAreEqual : function (expected /*:Date*/, actual /*:Date*/, message /*:String*/){
-        if (expected instanceof Date && actual instanceof Date){
-            YAHOO.util.Assert.areEqual(expected.getFullYear(), actual.getFullYear(), message || "Years should be equal.");
-            YAHOO.util.Assert.areEqual(expected.getMonth(), actual.getMonth(), message || "Months should be equal.");
-            YAHOO.util.Assert.areEqual(expected.getDate(), actual.getDate(), message || "Day of month should be equal.");
-        } else {
-            throw new TypeError("DateAssert.datesAreEqual(): Expected and actual values must be Date objects.");
-        }
-    },
-
-    /**
-     * Asserts that a date's hour, minutes, and seconds are equal to another date's.
-     * @param {Date} expected The expected date.
-     * @param {Date} actual The actual date to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method areEqual
-     * @static
-     */
-    timesAreEqual : function (expected /*:Date*/, actual /*:Date*/, message /*:String*/){
-        if (expected instanceof Date && actual instanceof Date){
-            YAHOO.util.Assert.areEqual(expected.getHours(), actual.getHours(), message || "Hours should be equal.");
-            YAHOO.util.Assert.areEqual(expected.getMinutes(), actual.getMinutes(), message || "Minutes should be equal.");
-            YAHOO.util.Assert.areEqual(expected.getSeconds(), actual.getSeconds(), message || "Seconds should be equal.");
-        } else {
-            throw new TypeError("DateAssert.timesAreEqual(): Expected and actual values must be Date objects.");
-        }
-    }
-    
-};
-
-YAHOO.namespace("util");
-
-/**
- * The UserAction object provides functions that simulate events occurring in
- * the browser. Since these are simulated events, they do not behave exactly
- * as regular, user-initiated events do, but can be used to test simple
- * user interactions safely.
- *
- * @namespace YAHOO.util
- * @class UserAction
- * @static
- */
-YAHOO.util.UserAction = {
-
-    //--------------------------------------------------------------------------
-    // Generic event methods
-    //--------------------------------------------------------------------------
-
-    /**
-     * Simulates a key event using the given event information to populate
-     * the generated event object. This method does browser-equalizing
-     * calculations to account for differences in the DOM and IE event models
-     * as well as different browser quirks. Note: keydown causes Safari 2.x to
-     * crash.
-     * @method simulateKeyEvent
-     * @private
-     * @static
-     * @param {HTMLElement} target The target of the given event.
-     * @param {String} type The type of event to fire. This can be any one of
-     *      the following: keyup, keydown, and keypress.
-     * @param {Boolean} bubbles (Optional) Indicates if the event can be
-     *      bubbled up. DOM Level 3 specifies that all key events bubble by
-     *      default. The default is true.
-     * @param {Boolean} cancelable (Optional) Indicates if the event can be
-     *      canceled using preventDefault(). DOM Level 3 specifies that all
-     *      key events can be cancelled. The default 
-     *      is true.
-     * @param {Window} view (Optional) The view containing the target. This is
-     *      typically the window object. The default is window.
-     * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {int} keyCode (Optional) The code for the key that is in use. 
-     *      The default is 0.
-     * @param {int} charCode (Optional) The Unicode code for the character
-     *      associated with the key being used. The default is 0.
-     */
-    simulateKeyEvent : function (target /*:HTMLElement*/, type /*:String*/, 
-                                 bubbles /*:Boolean*/,  cancelable /*:Boolean*/,    
-                                 view /*:Window*/,
-                                 ctrlKey /*:Boolean*/,    altKey /*:Boolean*/, 
-                                 shiftKey /*:Boolean*/,   metaKey /*:Boolean*/, 
-                                 keyCode /*:int*/,        charCode /*:int*/) /*:Void*/                             
-    {
-        //check target
-        target = YAHOO.util.Dom.get(target);        
-        if (!target){
-            throw new Error("simulateKeyEvent(): Invalid target.");
-        }
-        
-        //check event type
-        if (YAHOO.lang.isString(type)){
-            type = type.toLowerCase();
-            switch(type){
-                case "keyup":
-                case "keydown":
-                case "keypress":
-                    break;
-                case "textevent": //DOM Level 3
-                    type = "keypress";
-                    break;
-                    // @TODO was the fallthrough intentional, if so throw error
-                default:
-                    throw new Error("simulateKeyEvent(): Event type '" + type + "' not supported.");
-            }
-        } else {
-            throw new Error("simulateKeyEvent(): Event type must be a string.");
-        }
-        
-        //setup default values
-        if (!YAHOO.lang.isBoolean(bubbles)){
-            bubbles = true; //all key events bubble
-        }
-        if (!YAHOO.lang.isBoolean(cancelable)){
-            cancelable = true; //all key events can be cancelled
-        }
-        if (!YAHOO.lang.isObject(view)){
-            view = window; //view is typically window
-        }
-        if (!YAHOO.lang.isBoolean(ctrlKey)){
-            ctrlKey = false;
-        }
-        if (!YAHOO.lang.isBoolean(altKey)){
-            altKey = false;
-        }
-        if (!YAHOO.lang.isBoolean(shiftKey)){
-            shiftKey = false;
-        }
-        if (!YAHOO.lang.isBoolean(metaKey)){
-            metaKey = false;
-        }
-        if (!YAHOO.lang.isNumber(keyCode)){
-            keyCode = 0;
-        }
-        if (!YAHOO.lang.isNumber(charCode)){
-            charCode = 0; 
-        }
-
-        //try to create a mouse event
-        var customEvent /*:MouseEvent*/ = null;
-            
-        //check for DOM-compliant browsers first
-        if (YAHOO.lang.isFunction(document.createEvent)){
-        
-            try {
-                
-                //try to create key event
-                customEvent = document.createEvent("KeyEvents");
-                
-                /*
-                 * Interesting problem: Firefox implemented a non-standard
-                 * version of initKeyEvent() based on DOM Level 2 specs.
-                 * Key event was removed from DOM Level 2 and re-introduced
-                 * in DOM Level 3 with a different interface. Firefox is the
-                 * only browser with any implementation of Key Events, so for
-                 * now, assume it's Firefox if the above line doesn't error.
-                 */
-                //TODO: Decipher between Firefox's implementation and a correct one.
-                customEvent.initKeyEvent(type, bubbles, cancelable, view, ctrlKey,
-                    altKey, shiftKey, metaKey, keyCode, charCode);       
-                
-            } catch (ex /*:Error*/){
-
-                /*
-                 * If it got here, that means key events aren't officially supported. 
-                 * Safari/WebKit is a real problem now. WebKit 522 won't let you
-                 * set keyCode, charCode, or other properties if you use a
-                 * UIEvent, so we first must try to create a generic event. The
-                 * fun part is that this will throw an error on Safari 2.x. The
-                 * end result is that we need another try...catch statement just to
-                 * deal with this mess.
-                 */
-                try {
-
-                    //try to create generic event - will fail in Safari 2.x
-                    customEvent = document.createEvent("Events");
-
-                } catch (uierror /*:Error*/){
-
-                    //the above failed, so create a UIEvent for Safari 2.x
-                    customEvent = document.createEvent("UIEvents");
-
-                } finally {
-
-                    customEvent.initEvent(type, bubbles, cancelable);
-    
-                    //initialize
-                    customEvent.view = view;
-                    customEvent.altKey = altKey;
-                    customEvent.ctrlKey = ctrlKey;
-                    customEvent.shiftKey = shiftKey;
-                    customEvent.metaKey = metaKey;
-                    customEvent.keyCode = keyCode;
-                    customEvent.charCode = charCode;
-          
-                }          
-             
-            }
-            
-            //fire the event
-            target.dispatchEvent(customEvent);
-
-        } else if (YAHOO.lang.isObject(document.createEventObject)){ //IE
-        
-            //create an IE event object
-            customEvent = document.createEventObject();
-            
-            //assign available properties
-            customEvent.bubbles = bubbles;
-            customEvent.cancelable = cancelable;
-            customEvent.view = view;
-            customEvent.ctrlKey = ctrlKey;
-            customEvent.altKey = altKey;
-            customEvent.shiftKey = shiftKey;
-            customEvent.metaKey = metaKey;
-            
-            /*
-             * IE doesn't support charCode explicitly. CharCode should
-             * take precedence over any keyCode value for accurate
-             * representation.
-             */
-            customEvent.keyCode = (charCode > 0) ? charCode : keyCode;
-            
-            //fire the event
-            target.fireEvent("on" + type, customEvent);  
-                    
-        } else {
-            throw new Error("simulateKeyEvent(): No event simulation framework present.");
-        }
-    },
-
-    /**
-     * Simulates a mouse event using the given event information to populate
-     * the generated event object. This method does browser-equalizing
-     * calculations to account for differences in the DOM and IE event models
-     * as well as different browser quirks.
-     * @method simulateMouseEvent
-     * @private
-     * @static
-     * @param {HTMLElement} target The target of the given event.
-     * @param {String} type The type of event to fire. This can be any one of
-     *      the following: click, dblclick, mousedown, mouseup, mouseout,
-     *      mouseover, and mousemove.
-     * @param {Boolean} bubbles (Optional) Indicates if the event can be
-     *      bubbled up. DOM Level 2 specifies that all mouse events bubble by
-     *      default. The default is true.
-     * @param {Boolean} cancelable (Optional) Indicates if the event can be
-     *      canceled using preventDefault(). DOM Level 2 specifies that all
-     *      mouse events except mousemove can be cancelled. The default 
-     *      is true for all events except mousemove, for which the default 
-     *      is false.
-     * @param {Window} view (Optional) The view containing the target. This is
-     *      typically the window object. The default is window.
-     * @param {int} detail (Optional) The number of times the mouse button has
-     *      been used. The default value is 1.
-     * @param {int} screenX (Optional) The x-coordinate on the screen at which
-     *      point the event occured. The default is 0.
-     * @param {int} screenY (Optional) The y-coordinate on the screen at which
-     *      point the event occured. The default is 0.
-     * @param {int} clientX (Optional) The x-coordinate on the client at which
-     *      point the event occured. The default is 0.
-     * @param {int} clientY (Optional) The y-coordinate on the client at which
-     *      point the event occured. The default is 0.
-     * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {int} button (Optional) The button being pressed while the event
-     *      is executing. The value should be 0 for the primary mouse button
-     *      (typically the left button), 1 for the terciary mouse button
-     *      (typically the middle button), and 2 for the secondary mouse button
-     *      (typically the right button). The default is 0.
-     * @param {HTMLElement} relatedTarget (Optional) For mouseout events,
-     *      this is the element that the mouse has moved to. For mouseover
-     *      events, this is the element that the mouse has moved from. This
-     *      argument is ignored for all other events. The default is null.
-     */
-    simulateMouseEvent : function (target /*:HTMLElement*/, type /*:String*/, 
-                                   bubbles /*:Boolean*/,  cancelable /*:Boolean*/,    
-                                   view /*:Window*/,        detail /*:int*/, 
-                                   screenX /*:int*/,        screenY /*:int*/, 
-                                   clientX /*:int*/,        clientY /*:int*/,       
-                                   ctrlKey /*:Boolean*/,    altKey /*:Boolean*/, 
-                                   shiftKey /*:Boolean*/,   metaKey /*:Boolean*/, 
-                                   button /*:int*/,         relatedTarget /*:HTMLElement*/) /*:Void*/
-    {
-        
-        //check target
-        target = YAHOO.util.Dom.get(target);        
-        if (!target){
-            throw new Error("simulateMouseEvent(): Invalid target.");
-        }
-        
-        //check event type
-        if (YAHOO.lang.isString(type)){
-            type = type.toLowerCase();
-            switch(type){
-                case "mouseover":
-                case "mouseout":
-                case "mousedown":
-                case "mouseup":
-                case "click":
-                case "dblclick":
-                case "mousemove":
-                    break;
-                default:
-                    throw new Error("simulateMouseEvent(): Event type '" + type + "' not supported.");
-            }
-        } else {
-            throw new Error("simulateMouseEvent(): Event type must be a string.");
-        }
-        
-        //setup default values
-        if (!YAHOO.lang.isBoolean(bubbles)){
-            bubbles = true; //all mouse events bubble
-        }
-        if (!YAHOO.lang.isBoolean(cancelable)){
-            cancelable = (type != "mousemove"); //mousemove is the only one that can't be cancelled
-        }
-        if (!YAHOO.lang.isObject(view)){
-            view = window; //view is typically window
-        }
-        if (!YAHOO.lang.isNumber(detail)){
-            detail = 1;  //number of mouse clicks must be at least one
-        }
-        if (!YAHOO.lang.isNumber(screenX)){
-            screenX = 0; 
-        }
-        if (!YAHOO.lang.isNumber(screenY)){
-            screenY = 0; 
-        }
-        if (!YAHOO.lang.isNumber(clientX)){
-            clientX = 0; 
-        }
-        if (!YAHOO.lang.isNumber(clientY)){
-            clientY = 0; 
-        }
-        if (!YAHOO.lang.isBoolean(ctrlKey)){
-            ctrlKey = false;
-        }
-        if (!YAHOO.lang.isBoolean(altKey)){
-            altKey = false;
-        }
-        if (!YAHOO.lang.isBoolean(shiftKey)){
-            shiftKey = false;
-        }
-        if (!YAHOO.lang.isBoolean(metaKey)){
-            metaKey = false;
-        }
-        if (!YAHOO.lang.isNumber(button)){
-            button = 0; 
-        }
-
-        //try to create a mouse event
-        var customEvent /*:MouseEvent*/ = null;
-            
-        //check for DOM-compliant browsers first
-        if (YAHOO.lang.isFunction(document.createEvent)){
-        
-            customEvent = document.createEvent("MouseEvents");
-        
-            //Safari 2.x (WebKit 418) still doesn't implement initMouseEvent()
-            if (customEvent.initMouseEvent){
-                customEvent.initMouseEvent(type, bubbles, cancelable, view, detail,
-                                     screenX, screenY, clientX, clientY, 
-                                     ctrlKey, altKey, shiftKey, metaKey, 
-                                     button, relatedTarget);
-            } else { //Safari
-            
-                //the closest thing available in Safari 2.x is UIEvents
-                customEvent = document.createEvent("UIEvents");
-                customEvent.initEvent(type, bubbles, cancelable);
-                customEvent.view = view;
-                customEvent.detail = detail;
-                customEvent.screenX = screenX;
-                customEvent.screenY = screenY;
-                customEvent.clientX = clientX;
-                customEvent.clientY = clientY;
-                customEvent.ctrlKey = ctrlKey;
-                customEvent.altKey = altKey;
-                customEvent.metaKey = metaKey;
-                customEvent.shiftKey = shiftKey;
-                customEvent.button = button;
-                customEvent.relatedTarget = relatedTarget;
-            }
-            
-            /*
-             * Check to see if relatedTarget has been assigned. Firefox
-             * versions less than 2.0 don't allow it to be assigned via
-             * initMouseEvent() and the property is readonly after event
-             * creation, so in order to keep YAHOO.util.getRelatedTarget()
-             * working, assign to the IE proprietary toElement property
-             * for mouseout event and fromElement property for mouseover
-             * event.
-             */
-            if (relatedTarget && !customEvent.relatedTarget){
-                if (type == "mouseout"){
-                    customEvent.toElement = relatedTarget;
-                } else if (type == "mouseover"){
-                    customEvent.fromElement = relatedTarget;
-                }
-            }
-            
-            //fire the event
-            target.dispatchEvent(customEvent);
-
-        } else if (YAHOO.lang.isObject(document.createEventObject)){ //IE
-        
-            //create an IE event object
-            customEvent = document.createEventObject();
-            
-            //assign available properties
-            customEvent.bubbles = bubbles;
-            customEvent.cancelable = cancelable;
-            customEvent.view = view;
-            customEvent.detail = detail;
-            customEvent.screenX = screenX;
-            customEvent.screenY = screenY;
-            customEvent.clientX = clientX;
-            customEvent.clientY = clientY;
-            customEvent.ctrlKey = ctrlKey;
-            customEvent.altKey = altKey;
-            customEvent.metaKey = metaKey;
-            customEvent.shiftKey = shiftKey;
-
-            //fix button property for IE's wacky implementation
-            switch(button){
-                case 0:
-                    customEvent.button = 1;
-                    break;
-                case 1:
-                    customEvent.button = 4;
-                    break;
-                case 2:
-                    //leave as is
-                    break;
-                default:
-                    customEvent.button = 0;                    
-            }    
-
-            /*
-             * Have to use relatedTarget because IE won't allow assignment
-             * to toElement or fromElement on generic events. This keeps
-             * YAHOO.util.customEvent.getRelatedTarget() functional.
-             */
-            customEvent.relatedTarget = relatedTarget;
-            
-            //fire the event
-            target.fireEvent("on" + type, customEvent);
-                    
-        } else {
-            throw new Error("simulateMouseEvent(): No event simulation framework present.");
-        }
-    },
-   
-    //--------------------------------------------------------------------------
-    // Mouse events
-    //--------------------------------------------------------------------------
-
-    /**
-     * Simulates a mouse event on a particular element.
-     * @param {HTMLElement} target The element to click on.
-     * @param {String} type The type of event to fire. This can be any one of
-     *      the following: click, dblclick, mousedown, mouseup, mouseout,
-     *      mouseover, and mousemove.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method mouseEvent
-     * @static
-     */
-    fireMouseEvent : function (target /*:HTMLElement*/, type /*:String*/, 
-                           options /*:Object*/) /*:Void*/
-    {
-        options = options || {};
-        this.simulateMouseEvent(target, type, options.bubbles,
-            options.cancelable, options.view, options.detail, options.screenX,        
-            options.screenY, options.clientX, options.clientY, options.ctrlKey,
-            options.altKey, options.shiftKey, options.metaKey, options.button,         
-            options.relatedTarget);        
-    },
-
-    /**
-     * Simulates a click on a particular element.
-     * @param {HTMLElement} target The element to click on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method click
-     * @static     
-     */
-    click : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
-        this.fireMouseEvent(target, "click", options);
-    },
-    
-    /**
-     * Simulates a double click on a particular element.
-     * @param {HTMLElement} target The element to double click on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method dblclick
-     * @static
-     */
-    dblclick : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
-        this.fireMouseEvent( target, "dblclick", options);
-    },
-    
-    /**
-     * Simulates a mousedown on a particular element.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method mousedown
-     * @static
-     */
-    mousedown : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
-        this.fireMouseEvent(target, "mousedown", options);
-    },
-    
-    /**
-     * Simulates a mousemove on a particular element.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method mousemove
-     * @static
-     */
-    mousemove : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
-        this.fireMouseEvent(target, "mousemove", options);
-    },
-    
-    /**
-     * Simulates a mouseout event on a particular element. Use "relatedTarget"
-     * on the options object to specify where the mouse moved to.
-     * Quirks: Firefox less than 2.0 doesn't set relatedTarget properly, so
-     * toElement is assigned in its place. IE doesn't allow toElement to be
-     * be assigned, so relatedTarget is assigned in its place. Both of these
-     * concessions allow YAHOO.util.Event.getRelatedTarget() to work correctly
-     * in both browsers.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method mouseout
-     * @static
-     */
-    mouseout : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
-        this.fireMouseEvent(target, "mouseout", options);
-    },
-    
-    /**
-     * Simulates a mouseover event on a particular element. Use "relatedTarget"
-     * on the options object to specify where the mouse moved from.
-     * Quirks: Firefox less than 2.0 doesn't set relatedTarget properly, so
-     * fromElement is assigned in its place. IE doesn't allow fromElement to be
-     * be assigned, so relatedTarget is assigned in its place. Both of these
-     * concessions allow YAHOO.util.Event.getRelatedTarget() to work correctly
-     * in both browsers.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method mouseover
-     * @static
-     */
-    mouseover : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
-        this.fireMouseEvent(target, "mouseover", options);
-    },
-    
-    /**
-     * Simulates a mouseup on a particular element.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method mouseup
-     * @static
-     */
-    mouseup : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
-        this.fireMouseEvent(target, "mouseup", options);
-    },
-    
-    //--------------------------------------------------------------------------
-    // Key events
-    //--------------------------------------------------------------------------
-
-    /**
-     * Fires an event that normally would be fired by the keyboard (keyup,
-     * keydown, keypress). Make sure to specify either keyCode or charCode as
-     * an option.
-     * @private
-     * @param {String} type The type of event ("keyup", "keydown" or "keypress").
-     * @param {HTMLElement} target The target of the event.
-     * @param {Object} options Options for the event. Either keyCode or charCode
-     *                         are required.
-     * @method fireKeyEvent
-     * @static
-     */     
-    fireKeyEvent : function (type /*:String*/, target /*:HTMLElement*/,
-                             options /*:Object*/) /*:Void*/ 
-    {
-        options = options || {};
-        this.simulateKeyEvent(target, type, options.bubbles,
-            options.cancelable, options.view, options.ctrlKey,
-            options.altKey, options.shiftKey, options.metaKey, 
-            options.keyCode, options.charCode);    
-    },
-    
-    /**
-     * Simulates a keydown event on a particular element.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method keydown
-     * @static
-     */
-    keydown : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
-        this.fireKeyEvent("keydown", target, options);
-    },
-    
-    /**
-     * Simulates a keypress on a particular element.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method keypress
-     * @static
-     */
-    keypress : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
-        this.fireKeyEvent("keypress", target, options);
-    },
-    
-    /**
-     * Simulates a keyup event on a particular element.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method keyup
-     * @static
-     */
-    keyup : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
-        this.fireKeyEvent("keyup", target, options);
-    }
-    
-
-};
-
-YAHOO.namespace("tool");
-
-//-----------------------------------------------------------------------------
-// TestManager object
-//-----------------------------------------------------------------------------
-
-/**
- * Runs pages containing test suite definitions.
- * @namespace YAHOO.tool
- * @class TestManager
- * @static
- */
-YAHOO.tool.TestManager = {
-
-    /**
-     * Constant for the testpagebegin custom event
-     * @property TEST_PAGE_BEGIN_EVENT
-     * @static
-     * @type string
-     * @final
-     */
-    TEST_PAGE_BEGIN_EVENT /*:String*/ : "testpagebegin",
-
-    /**
-     * Constant for the testpagecomplete custom event
-     * @property TEST_PAGE_COMPLETE_EVENT
-     * @static
-     * @type string
-     * @final
-     */
-    TEST_PAGE_COMPLETE_EVENT /*:String*/ : "testpagecomplete",
-
-    /**
-     * Constant for the testmanagerbegin custom event
-     * @property TEST_MANAGER_BEGIN_EVENT
-     * @static
-     * @type string
-     * @final
-     */
-    TEST_MANAGER_BEGIN_EVENT /*:String*/ : "testmanagerbegin",
-
-    /**
-     * Constant for the testmanagercomplete custom event
-     * @property TEST_MANAGER_COMPLETE_EVENT
-     * @static
-     * @type string
-     * @final
-     */
-    TEST_MANAGER_COMPLETE_EVENT /*:String*/ : "testmanagercomplete",
-
-    //-------------------------------------------------------------------------
-    // Private Properties
-    //-------------------------------------------------------------------------
-    
-    
-    /**
-     * The URL of the page currently being executed.
-     * @type String
-     * @private
-     * @property _curPage
-     * @static
-     */
-    _curPage /*:String*/ : null,
-    
-    /**
-     * The frame used to load and run tests.
-     * @type Window
-     * @private
-     * @property _frame
-     * @static
-     */
-    _frame /*:Window*/ : null,
-    
-    /**
-     * The logger used to output results from the various tests.
-     * @type YAHOO.tool.TestLogger
-     * @private
-     * @property _logger
-     * @static
-     */
-    _logger : null,
-    
-    /**
-     * The timeout ID for the next iteration through the tests.
-     * @type int
-     * @private
-     * @property _timeoutId
-     * @static
-     */
-    _timeoutId /*:int*/ : 0,
-    
-    /**
-     * Array of pages to load.
-     * @type String[]
-     * @private
-     * @property _pages
-     * @static
-     */
-    _pages /*:String[]*/ : [],
-    
-    /**
-     * Aggregated results
-     * @type Object
-     * @private
-     * @property _results
-     * @static
-     */
-    _results: null,
-    
-    //-------------------------------------------------------------------------
-    // Private Methods
-    //-------------------------------------------------------------------------
-    
-    /**
-     * Handles TestRunner.COMPLETE_EVENT, storing the results and beginning
-     * the loop again.
-     * @param {Object} data Data about the event.
-     * @return {Void}
-     * @private
-     * @static
-     */
-    _handleTestRunnerComplete : function (data /*:Object*/) /*:Void*/ {
-
-        this.fireEvent(this.TEST_PAGE_COMPLETE_EVENT, {
-                page: this._curPage,
-                results: data.results
-            });
-    
-        //save results
-        //this._results[this.curPage] = data.results;
-        
-        //process 'em
-        this._processResults(this._curPage, data.results);
-        
-        this._logger.clearTestRunner();
-    
-        //if there's more to do, set a timeout to begin again
-        if (this._pages.length){
-            this._timeoutId = setTimeout(function(){
-                YAHOO.tool.TestManager._run();
-            }, 1000);
-        }
-    },
-    
-    /**
-     * Processes the results of a test page run, outputting log messages
-     * for failed tests.
-     * @return {Void}
-     * @private
-     * @static
-     */
-    _processResults : function (page /*:String*/, results /*:Object*/) /*:Void*/ {
-
-        var r = this._results;
-
-        r.page_results[page] = results;
-
-        if (results.passed) {
-            r.pages_passed++;
-            r.tests_passed += results.passed;
-        }
-
-        if (results.failed) {
-            r.pages_failed++;
-            r.tests_failed += results.failed;
-            r.failed.push(page);
-        } else {
-            r.passed.push(page);
-        }
-
-        if (!this._pages.length) {
-            this.fireEvent(this.TEST_MANAGER_COMPLETE_EVENT, this._results);
-        }
-
-    },
-    
-    /**
-     * Loads the next test page into the iframe.
-     * @return {Void}
-     * @static
-     * @private
-     */
-    _run : function () /*:Void*/ {
-    
-        //set the current page
-        this._curPage = this._pages.shift();
-
-        this.fireEvent(this.TEST_PAGE_BEGIN_EVENT, this._curPage);
-        
-        //load the frame - destroy history in case there are other iframes that
-        //need testing
-        this._frame.location.replace(this._curPage);
-    
-    },
-        
-    //-------------------------------------------------------------------------
-    // Public Methods
-    //-------------------------------------------------------------------------
-    
-    /**
-     * Signals that a test page has been loaded. This should be called from
-     * within the test page itself to notify the TestManager that it is ready.
-     * @return {Void}
-     * @static
-     */
-    load : function () /*:Void*/ {
-        if (parent.YAHOO.tool.TestManager !== this){
-            parent.YAHOO.tool.TestManager.load();
-        } else {
-            
-            if (this._frame) {
-                //assign event handling
-                var TestRunner = this._frame.YAHOO.tool.TestRunner;
-
-                this._logger.setTestRunner(TestRunner);
-                TestRunner.subscribe(TestRunner.COMPLETE_EVENT, this._handleTestRunnerComplete, this, true);
-                
-                //run it
-                TestRunner.run();
-            }
-        }
-    },
-    
-    /**
-     * Sets the pages to be loaded.
-     * @param {String[]} pages An array of URLs to load.
-     * @return {Void}
-     * @static
-     */
-    setPages : function (pages /*:String[]*/) /*:Void*/ {
-        this._pages = pages;
-    },
-    
-    /**
-     * Begins the process of running the tests.
-     * @return {Void}
-     * @static
-     */
-    start : function () /*:Void*/ {
-
-        if (!this._initialized) {
-
-            /**
-             * Fires when loading a test page
-             * @event testpagebegin
-             * @param curPage {string} the page being loaded
-             * @static
-             */
-            this.createEvent(this.TEST_PAGE_BEGIN_EVENT);
-
-            /**
-             * Fires when a test page is complete
-             * @event testpagecomplete
-             * @param obj {page: string, results: object} the name of the
-             * page that was loaded, and the test suite results
-             * @static
-             */
-            this.createEvent(this.TEST_PAGE_COMPLETE_EVENT);
-
-            /**
-             * Fires when the test manager starts running all test pages
-             * @event testmanagerbegin
-             * @static
-             */
-            this.createEvent(this.TEST_MANAGER_BEGIN_EVENT);
-
-            /**
-             * Fires when the test manager finishes running all test pages.  External
-             * test runners should subscribe to this event in order to get the
-             * aggregated test results.
-             * @event testmanagercomplete
-             * @param obj { pages_passed: int, pages_failed: int, tests_passed: int
-             *              tests_failed: int, passed: string[], failed: string[],
-             *              page_results: {} }
-             * @static
-             */
-            this.createEvent(this.TEST_MANAGER_COMPLETE_EVENT);
-
-            //create iframe if not already available
-            if (!this._frame){
-                var frame /*:HTMLElement*/ = document.createElement("iframe");
-                frame.style.visibility = "hidden";
-                frame.style.position = "absolute";
-                document.body.appendChild(frame);
-                this._frame = frame.contentWindow || frame.contentDocument.ownerWindow;
-            }
-            
-            //create test logger if not already available
-            if (!this._logger){
-                this._logger = new YAHOO.tool.TestLogger();
-            }
-
-            this._initialized = true;
-        }
-
-
-        // reset the results cache
-        this._results = {
-            // number of pages that pass
-            pages_passed: 0,
-            // number of pages that fail
-            pages_failed: 0,
-            // total number of tests passed
-            tests_passed: 0,
-            // total number of tests failed
-            tests_failed: 0,
-            // array of pages that passed
-            passed: [],
-            // array of pages that failed
-            failed: [],
-            // map of full results for each page
-            page_results: {}
-        };
-
-        this.fireEvent(this.TEST_MANAGER_BEGIN_EVENT, null);
-        this._run();
-    
-    },
-
-    /**
-     * Stops the execution of tests.
-     * @return {Void}
-     * @static
-     */
-    stop : function () /*:Void*/ {
-        clearTimeout(this._timeoutId);
-    }
-
-};
-
-YAHOO.lang.augmentObject(YAHOO.tool.TestManager, YAHOO.util.EventProvider.prototype);
-
-
-YAHOO.namespace("tool");
-
-//-----------------------------------------------------------------------------
-// TestLogger object
-//-----------------------------------------------------------------------------
-
-/**
- * Displays test execution progress and results, providing filters based on
- * different key events.
- * @namespace YAHOO.tool
- * @class TestLogger
- * @constructor
- * @param {HTMLElement} element (Optional) The element to create the logger in.
- * @param {Object} config (Optional) Configuration options for the logger.
- */
-YAHOO.tool.TestLogger = function (element, config) {
-    YAHOO.tool.TestLogger.superclass.constructor.call(this, element, config);
-    this.init();
-};
-
-YAHOO.lang.extend(YAHOO.tool.TestLogger, YAHOO.widget.LogReader, {
-
-    footerEnabled : true,
-    newestOnTop : false,
-
-    /**
-     * Formats message string to HTML for output to console.
-     * @private
-     * @method formatMsg
-     * @param oLogMsg {Object} Log message object.
-     * @return {String} HTML-formatted message for output to console.
-     */
-    formatMsg : function(message /*:Object*/) {
-    
-        var category /*:String*/ = message.category;        
-        var text /*:String*/ = this.html2Text(message.msg);
-        
-        return "<pre><p><span class=\"" + category + "\">" + category.toUpperCase() + "</span> " + text + "</p></pre>";
-    
-    },
-    
-    //-------------------------------------------------------------------------
-    // Private Methods
-    //-------------------------------------------------------------------------
-    
-    /*
-     * Initializes the logger.
-     * @private
-     */
-    init : function () {
-    
-        //attach to any available TestRunner
-        if (YAHOO.tool.TestRunner){
-            this.setTestRunner(YAHOO.tool.TestRunner);
-        }
-        
-        //hide useless sources
-        this.hideSource("global");
-        this.hideSource("LogReader");
-        
-        //hide useless message categories
-        this.hideCategory("warn");
-        this.hideCategory("window");
-        this.hideCategory("time");
-        
-        //reset the logger
-        this.clearConsole();
-    },
-    
-    /**
-     * Clears the reference to the TestRunner from previous operations. This 
-     * unsubscribes all events and removes the object reference.
-     * @return {Void}
-     * @static
-     */
-    clearTestRunner : function () /*:Void*/ {
-        if (this._runner){
-            this._runner.unsubscribeAll();
-            this._runner = null;
-        }
-    },
-    
-    /**
-     * Sets the source test runner that the logger should monitor.
-     * @param {YAHOO.tool.TestRunner} testRunner The TestRunner to observe.
-     * @return {Void}
-     * @static
-     */
-    setTestRunner : function (testRunner /*:YAHOO.tool.TestRunner*/) /*:Void*/ {
-    
-        if (this._runner){
-            this.clearTestRunner();
-        }
-        
-        this._runner = testRunner;
-        
-        //setup event _handlers
-        testRunner.subscribe(testRunner.TEST_PASS_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.TEST_FAIL_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.TEST_IGNORE_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.BEGIN_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.COMPLETE_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.TEST_SUITE_BEGIN_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.TEST_SUITE_COMPLETE_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.TEST_CASE_BEGIN_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.TEST_CASE_COMPLETE_EVENT, this._handleTestRunnerEvent, this, true);    
-    },
-    
-    //-------------------------------------------------------------------------
-    // Event Handlers
-    //-------------------------------------------------------------------------
-    
-    /**
-     * Handles all TestRunner events, outputting appropriate data into the console.
-     * @param {Object} data The event data object.
-     * @return {Void}
-     * @private
-     */
-    _handleTestRunnerEvent : function (data /*:Object*/) /*:Void*/ {
-    
-        //shortcut variables
-        var TestRunner /*:Object*/ = YAHOO.tool.TestRunner;
-    
-        //data variables
-        var message /*:String*/ = "";
-        var messageType /*:String*/ = "";
-        
-        switch(data.type){
-            case TestRunner.BEGIN_EVENT:
-                message = "Testing began at " + (new Date()).toString() + ".";
-                messageType = "info";
-                break;
-                
-            case TestRunner.COMPLETE_EVENT:
-                message = "Testing completed at " + (new Date()).toString() + ".\nPassed:" + 
-                    data.results.passed + " Failed:" + data.results.failed + " Total:" + data.results.total;
-                messageType = "info";
-                break;
-                
-            case TestRunner.TEST_FAIL_EVENT:
-                message = data.testName + ": " + data.error.getMessage();
-                messageType = "fail";
-                break;
-                
-            case TestRunner.TEST_IGNORE_EVENT:
-                message = data.testName + ": ignored.";
-                messageType = "ignore";
-                break;
-                
-            case TestRunner.TEST_PASS_EVENT:
-                message = data.testName + ": passed.";
-                messageType = "pass";
-                break;
-                
-            case TestRunner.TEST_SUITE_BEGIN_EVENT:
-                message = "Test suite \"" + data.testSuite.name + "\" started.";
-                messageType = "info";
-                break;
-                
-            case TestRunner.TEST_SUITE_COMPLETE_EVENT:
-                message = "Test suite \"" + data.testSuite.name + "\" completed.\nPassed:" + 
-                    data.results.passed + " Failed:" + data.results.failed + " Total:" + data.results.total;
-                messageType = "info";
-                break;
-                
-            case TestRunner.TEST_CASE_BEGIN_EVENT:
-                message = "Test case \"" + data.testCase.name + "\" started.";
-                messageType = "info";
-                break;
-                
-            case TestRunner.TEST_CASE_COMPLETE_EVENT:
-                message = "Test case \"" + data.testCase.name + "\" completed.\nPassed:" + 
-                    data.results.passed + " Failed:" + data.results.failed + " Total:" + data.results.total;
-                messageType = "info";
-                break;
-            default:
-                message = "Unexpected event " + data.type;
-                message = "info";
-        }
-    
-        YAHOO.log(message, messageType, "TestRunner");    
-    }
-    
-});
-
-YAHOO.register("yuitest", YAHOO.tool.TestRunner, {version: "2.4.1", build: "742"});

Deleted: trunk/root/static/yui/yuitest/yuitest-beta-min.js
===================================================================
--- trunk/root/static/yui/yuitest/yuitest-beta-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/yuitest-beta-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,10 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-YAHOO.namespace("tool");YAHOO.tool.TestCase=function(A){this._should={};for(var B in A){this[B]=A[B];}if(!YAHOO.lang.isString(this.name)){this.name=YAHOO.util.Dom.generateId(null,"testCase");}};YAHOO.tool.TestCase.prototype={resume:function(A){YAHOO.tool.TestRunner.resume(A);},wait:function(B,A){throw new YAHOO.tool.TestCase.Wait(B,A);},setUp:function(){},tearDown:function(){}};YAHOO.tool.TestCase.Wait=function(B,A){this.segment=(YAHOO.lang.isFunction(B)?B:null);this.delay=(YAHOO.lang.isNumber(A)?A:0);};YAHOO.namespace("tool");YAHOO.tool.TestSuite=function(A){this.name="";this.items=[];if(YAHOO.lang.isString(A)){this.name=A;}else{if(YAHOO.lang.isObject(A)){YAHOO.lang.augmentObject(this,A,true);}}if(this.name===""){this.name=YAHOO.util.Dom.generateId(null,"testSuite");}};YAHOO.tool.TestSuite.prototype={add:function(A){if(A instanceof YAHOO.tool.TestSuite||A instanceof YAHOO.tool.TestCase){this.items.push(A);}},setUp:function(){},tearDown:function(){}};YAHOO.namespace("tool")!
 ;YAHOO.tool.TestRunner=(function(){function B(C){this.testObject=C;this.firstChild=null;this.lastChild=null;this.parent=null;this.next=null;this.results={passed:0,failed:0,total:0};}B.prototype={appendChild:function(C){var D=new B(C);if(this.firstChild===null){this.firstChild=this.lastChild=D;}else{this.lastChild.next=D;this.lastChild=D;}D.parent=this;return D;}};function A(){A.superclass.constructor.apply(this,arguments);this.masterSuite=new YAHOO.tool.TestSuite("MasterSuite");this._cur=null;this._root=null;var D=[this.TEST_CASE_BEGIN_EVENT,this.TEST_CASE_COMPLETE_EVENT,this.TEST_SUITE_BEGIN_EVENT,this.TEST_SUITE_COMPLETE_EVENT,this.TEST_PASS_EVENT,this.TEST_FAIL_EVENT,this.TEST_IGNORE_EVENT,this.COMPLETE_EVENT,this.BEGIN_EVENT];for(var C=0;C<D.length;C++){this.createEvent(D[C],{scope:this});}}YAHOO.lang.extend(A,YAHOO.util.EventProvider,{TEST_CASE_BEGIN_EVENT:"testcasebegin",TEST_CASE_COMPLETE_EVENT:"testcasecomplete",TEST_SUITE_BEGIN_EVENT:"testsuitebegin",TEST_SUITE_COM!
 PLETE_EVENT:"testsuitecomplete",TEST_PASS_EVENT:"pass",TEST_FA!
 IL_EVENT
:"fail",TEST_IGNORE_EVENT:"ignore",COMPLETE_EVENT:"complete",BEGIN_EVENT:"begin",_addTestCaseToTestTree:function(C,D){var E=C.appendChild(D);for(var F in D){if(F.indexOf("test")===0&&YAHOO.lang.isFunction(D[F])){E.appendChild(F);}}},_addTestSuiteToTestTree:function(C,F){var E=C.appendChild(F);for(var D=0;D<F.items.length;D++){if(F.items[D] instanceof YAHOO.tool.TestSuite){this._addTestSuiteToTestTree(E,F.items[D]);}else{if(F.items[D] instanceof YAHOO.tool.TestCase){this._addTestCaseToTestTree(E,F.items[D]);}}}},_buildTestTree:function(){this._root=new B(this.masterSuite);this._cur=this._root;for(var C=0;C<this.masterSuite.items.length;C++){if(this.masterSuite.items[C] instanceof YAHOO.tool.TestSuite){this._addTestSuiteToTestTree(this._root,this.masterSuite.items[C]);}else{if(this.masterSuite.items[C] instanceof YAHOO.tool.TestCase){this._addTestCaseToTestTree(this._root,this.masterSuite.items[C]);}}}},_handleTestObjectComplete:function(C){if(YAHOO.lang.isObject(C.testObject)!
 ){C.parent.results.passed+=C.results.passed;C.parent.results.failed+=C.results.failed;C.parent.results.total+=C.results.total;C.parent.results[C.testObject.name]=C.results;if(C.testObject instanceof YAHOO.tool.TestSuite){C.testObject.tearDown();this.fireEvent(this.TEST_SUITE_COMPLETE_EVENT,{testSuite:C.testObject,results:C.results});}else{if(C.testObject instanceof YAHOO.tool.TestCase){this.fireEvent(this.TEST_CASE_COMPLETE_EVENT,{testCase:C.testObject,results:C.results});}}}},_next:function(){if(this._cur.firstChild){this._cur=this._cur.firstChild;}else{if(this._cur.next){this._cur=this._cur.next;}else{while(this._cur&&!this._cur.next&&this._cur!==this._root){this._handleTestObjectComplete(this._cur);this._cur=this._cur.parent;}if(this._cur==this._root){this.fireEvent(this.COMPLETE_EVENT,{results:this._cur.results});this._cur=null;}else{this._handleTestObjectComplete(this._cur);this._cur=this._cur.next;}}}return this._cur;},_run:function(){var E=false;var D=this._next();if!
 (D!==null){var C=D.testObject;if(YAHOO.lang.isObject(C)){if(C !
 instance
of YAHOO.tool.TestSuite){this.fireEvent(this.TEST_SUITE_BEGIN_EVENT,{testSuite:C});C.setUp();}else{if(C instanceof YAHOO.tool.TestCase){this.fireEvent(this.TEST_CASE_BEGIN_EVENT,{testCase:C});}}if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._run();},0);}else{this._run();}}else{this._runTest(D);}}},_resumeTest:function(G){var C=this._cur;var H=C.testObject;var E=C.parent.testObject;var K=(E._should.fail||{})[H];var D=(E._should.error||{})[H];var F=false;var I=null;try{G.apply(E);if(K){I=new YAHOO.util.ShouldFail();F=true;}else{if(D){I=new YAHOO.util.ShouldError();F=true;}}}catch(J){if(J instanceof YAHOO.util.AssertionError){if(!K){I=J;F=true;}}else{if(J instanceof YAHOO.tool.TestCase.Wait){if(YAHOO.lang.isFunction(J.segment)){if(YAHOO.lang.isNumber(J.delay)){if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._resumeTest(J.segment);},J.delay);}else{throw new Error("Asynchronous tests not supported in this environment.!
 ");}}}return ;}else{if(!D){I=new YAHOO.util.UnexpectedError(J);F=true;}else{if(YAHOO.lang.isString(D)){if(J.message!=D){I=new YAHOO.util.UnexpectedError(J);F=true;}}else{if(YAHOO.lang.isObject(D)){if(!(J instanceof D.constructor)||J.message!=D.message){I=new YAHOO.util.UnexpectedError(J);F=true;}}}}}}}if(F){this.fireEvent(this.TEST_FAIL_EVENT,{testCase:E,testName:H,error:I});}else{this.fireEvent(this.TEST_PASS_EVENT,{testCase:E,testName:H});}E.tearDown();C.parent.results[H]={result:F?"fail":"pass",message:I?I.getMessage():"Test passed"};if(F){C.parent.results.failed++;}else{C.parent.results.passed++;}C.parent.results.total++;if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._run();},0);}else{this._run();}},_runTest:function(F){var C=F.testObject;var D=F.parent.testObject;var G=D[C];var E=(D._should.ignore||{})[C];if(E){this.fireEvent(this.TEST_IGNORE_EVENT,{testCase:D,testName:C});
-if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._run();},0);}else{this._run();}}else{D.setUp();this._resumeTest(G);}},fireEvent:function(C,D){D=D||{};D.type=C;A.superclass.fireEvent.call(this,C,D);},add:function(C){this.masterSuite.add(C);},clear:function(){this.masterSuite.items=[];},resume:function(C){this._resumeTest(C||function(){});},run:function(C){var D=YAHOO.tool.TestRunner;D._buildTestTree();D.fireEvent(D.BEGIN_EVENT);D._run();}});return new A();})();YAHOO.namespace("util");YAHOO.util.Assert={fail:function(A){throw new YAHOO.util.AssertionError(A||"Test force-failed.");},areEqual:function(B,C,A){if(B!=C){throw new YAHOO.util.ComparisonFailure(A||"Values should be equal.",B,C);}},areNotEqual:function(A,C,B){if(A==C){throw new YAHOO.util.UnexpectedValue(B||"Values should not be equal.",A);}},areNotSame:function(A,C,B){if(A===C){throw new YAHOO.util.UnexpectedValue(B||"Values should not be the same.",A);}},areSame:function(B,C,A){if(B!==!
 C){throw new YAHOO.util.ComparisonFailure(A||"Values should be the same.",B,C);}},isFalse:function(B,A){if(false!==B){throw new YAHOO.util.ComparisonFailure(A||"Value should be false.",false,B);}},isTrue:function(B,A){if(true!==B){throw new YAHOO.util.ComparisonFailure(A||"Value should be true.",true,B);}},isNaN:function(B,A){if(!isNaN(B)){throw new YAHOO.util.ComparisonFailure(A||"Value should be NaN.",NaN,B);}},isNotNaN:function(B,A){if(isNaN(B)){throw new YAHOO.util.UnexpectedValue(A||"Values should not be NaN.",NaN);}},isNotNull:function(B,A){if(YAHOO.lang.isNull(B)){throw new YAHOO.util.UnexpectedValue(A||"Values should not be null.",null);}},isNotUndefined:function(B,A){if(YAHOO.lang.isUndefined(B)){throw new YAHOO.util.UnexpectedValue(A||"Value should not be undefined.",undefined);}},isNull:function(B,A){if(!YAHOO.lang.isNull(B)){throw new YAHOO.util.ComparisonFailure(A||"Value should be null.",null,B);}},isUndefined:function(B,A){if(!YAHOO.lang.isUndefined(B)){throw!
  new YAHOO.util.ComparisonFailure(A||"Value should be undefine!
 d.",unde
fined,B);}},isArray:function(B,A){if(!YAHOO.lang.isArray(B)){throw new YAHOO.util.UnexpectedValue(A||"Value should be an array.",B);}},isBoolean:function(B,A){if(!YAHOO.lang.isBoolean(B)){throw new YAHOO.util.UnexpectedValue(A||"Value should be a Boolean.",B);}},isFunction:function(B,A){if(!YAHOO.lang.isFunction(B)){throw new YAHOO.util.UnexpectedValue(A||"Value should be a function.",B);}},isInstanceOf:function(B,C,A){if(!(C instanceof B)){throw new YAHOO.util.ComparisonFailure(A||"Value isn't an instance of expected type.",B,C);}},isNumber:function(B,A){if(!YAHOO.lang.isNumber(B)){throw new YAHOO.util.UnexpectedValue(A||"Value should be a number.",B);}},isObject:function(B,A){if(!YAHOO.lang.isObject(B)){throw new YAHOO.util.UnexpectedValue(A||"Value should be an object.",B);}},isString:function(B,A){if(!YAHOO.lang.isString(B)){throw new YAHOO.util.UnexpectedValue(A||"Value should be a string.",B);}},isTypeOf:function(A,C,B){if(typeof C!=A){throw new YAHOO.util.ComparisonFa!
 ilure(B||"Value should be of type "+expected+".",expected,typeof actual);}}};YAHOO.util.AssertionError=function(A){arguments.callee.superclass.constructor.call(this,A);this.message=A;this.name="AssertionError";};YAHOO.lang.extend(YAHOO.util.AssertionError,Error,{getMessage:function(){return this.message;},toString:function(){return this.name+": "+this.getMessage();},valueOf:function(){return this.toString();}});YAHOO.util.ComparisonFailure=function(B,A,C){arguments.callee.superclass.constructor.call(this,B);this.expected=A;this.actual=C;this.name="ComparisonFailure";};YAHOO.lang.extend(YAHOO.util.ComparisonFailure,YAHOO.util.AssertionError,{getMessage:function(){return this.message+"\nExpected: "+this.expected+" ("+(typeof this.expected)+")\nActual:"+this.actual+" ("+(typeof this.actual)+")";}});YAHOO.util.UnexpectedValue=function(B,A){arguments.callee.superclass.constructor.call(this,B);this.unexpected=A;this.name="UnexpectedValue";};YAHOO.lang.extend(YAHOO.util.Unexpected!
 Value,YAHOO.util.AssertionError,{getMessage:function(){return !
 this.mes
sage+"\nUnexpected: "+this.unexpected+" ("+(typeof this.unexpected)+") ";}});YAHOO.util.ShouldFail=function(A){arguments.callee.superclass.constructor.call(this,A||"This test should fail but didn't.");this.name="ShouldFail";};YAHOO.lang.extend(YAHOO.util.ShouldFail,YAHOO.util.AssertionError);YAHOO.util.ShouldError=function(A){arguments.callee.superclass.constructor.call(this,A||"This test should have thrown an error but didn't.");this.name="ShouldError";};YAHOO.lang.extend(YAHOO.util.ShouldError,YAHOO.util.AssertionError);YAHOO.util.UnexpectedError=function(A){arguments.callee.superclass.constructor.call(this,"Unexpected error: "+A.message);this.cause=A;this.name="UnexpectedError";};YAHOO.lang.extend(YAHOO.util.UnexpectedError,YAHOO.util.AssertionError);YAHOO.util.ArrayAssert={contains:function(E,D,B){var C=false;for(var A=0;A<D.length&&!C;A++){if(D[A]===E){C=true;}}if(!C){YAHOO.util.Assert.fail(B||"Value ("+E+") not found in array.");}},containsItems:function(C,D,B){for(var!
  A=0;A<C.length;A++){this.contains(C[A],D,B);}if(!found){YAHOO.util.Assert.fail(B||"Value not found in array.");}},containsMatch:function(E,D,B){if(typeof E!="function"){throw new TypeError("ArrayAssert.containsMatch(): First argument must be a function.");}var C=false;for(var A=0;A<D.length&&!C;A++){if(E(D[A])){C=true;}}if(!C){YAHOO.util.Assert.fail(B||"No match found in array.");}},doesNotContain:function(E,D,B){var C=false;for(var A=0;A<D.length&&!C;A++){if(D[A]===E){C=true;}}if(C){YAHOO.util.Assert.fail(B||"Value found in array.");}},doesNotContainItems:function(C,D,B){for(var A=0;A<C.length;A++){this.doesNotContain(C[A],D,B);}},doesNotContainMatch:function(E,D,B){if(typeof E!="function"){throw new TypeError("ArrayAssert.doesNotContainMatch(): First argument must be a function.");}var C=false;for(var A=0;A<D.length&&!C;A++){if(E(D[A])){C=true;}}if(C){YAHOO.util.Assert.fail(B||"Value found in array.");}},indexOf:function(E,D,A,C){for(var B=0;
-B<D.length;B++){if(D[B]===E){YAHOO.util.Assert.areEqual(A,B,C||"Value exists at index "+B+" but should be at index "+A+".");return ;}}YAHOO.util.Assert.fail(C||"Value doesn't exist in array.");},itemsAreEqual:function(D,E,C){var A=Math.max(D.length,E.length);for(var B=0;B<A;B++){YAHOO.util.Assert.areEqual(D[B],E[B],C||"Values in position "+B+" are not equal.");}},itemsAreEquivalent:function(E,F,B,D){if(typeof B!="function"){throw new TypeError("ArrayAssert.itemsAreEquivalent(): Third argument must be a function.");}var A=Math.max(E.length,F.length);for(var C=0;C<A;C++){if(!B(E[C],F[C])){throw new YAHOO.util.ComparisonFailure(D||"Values in position "+C+" are not equivalent.",E[C],F[C]);}}},isEmpty:function(B,A){if(B.length>0){YAHOO.util.Assert.fail(A||"Array should be empty.");}},isNotEmpty:function(B,A){if(B.length===0){YAHOO.util.Assert.fail(A||"Array should not be empty.");}},itemsAreSame:function(D,E,C){var A=Math.max(D.length,E.length);for(var B=0;B<A;B++){YAHOO.util.As!
 sert.areSame(D[B],E[B],C||"Values in position "+B+" are not the same.");}},lastIndexOf:function(E,D,A,C){for(var B=D.length;B>=0;B--){if(D[B]===E){YAHOO.util.Assert.areEqual(A,B,C||"Value exists at index "+B+" but should be at index "+A+".");return ;}}YAHOO.util.Assert.fail(C||"Value doesn't exist in array.");}};YAHOO.namespace("util");YAHOO.util.ObjectAssert={propertiesAreEqual:function(D,F,C){var B=[];for(var E in D){B.push(E);}for(var A=0;A<B.length;A++){YAHOO.util.Assert.isNotUndefined(F[B[A]],C||"Property'"+B[A]+"' expected.");}},hasProperty:function(A,B,C){if(YAHOO.lang.isUndefined(B[A])){YAHOO.util.Assert.fail(C||"Property "+A+" not found on object.");}},hasOwnProperty:function(A,B,C){if(!YAHOO.lang.hasOwnProperty(B,A)){YAHOO.util.Assert.fail(C||"Property "+A+" not found on object instance.");}}};YAHOO.util.DateAssert={datesAreEqual:function(B,C,A){if(B instanceof Date&&C instanceof Date){YAHOO.util.Assert.areEqual(B.getFullYear(),C.getFullYear(),A||"Years should be !
 equal.");YAHOO.util.Assert.areEqual(B.getMonth(),C.getMonth(),!
 A||"Mont
hs should be equal.");YAHOO.util.Assert.areEqual(B.getDate(),C.getDate(),A||"Day of month should be equal.");}else{throw new TypeError("DateAssert.datesAreEqual(): Expected and actual values must be Date objects.");}},timesAreEqual:function(B,C,A){if(B instanceof Date&&C instanceof Date){YAHOO.util.Assert.areEqual(B.getHours(),C.getHours(),A||"Hours should be equal.");YAHOO.util.Assert.areEqual(B.getMinutes(),C.getMinutes(),A||"Minutes should be equal.");YAHOO.util.Assert.areEqual(B.getSeconds(),C.getSeconds(),A||"Seconds should be equal.");}else{throw new TypeError("DateAssert.timesAreEqual(): Expected and actual values must be Date objects.");}}};YAHOO.namespace("util");YAHOO.util.UserAction={simulateKeyEvent:function(F,J,E,C,L,B,A,K,H,N,M){F=YAHOO.util.Dom.get(F);if(!F){throw new Error("simulateKeyEvent(): Invalid target.");}if(YAHOO.lang.isString(J)){J=J.toLowerCase();switch(J){case"keyup":case"keydown":case"keypress":break;case"textevent":J="keypress";break;default:thro!
 w new Error("simulateKeyEvent(): Event type '"+J+"' not supported.");}}else{throw new Error("simulateKeyEvent(): Event type must be a string.");}if(!YAHOO.lang.isBoolean(E)){E=true;}if(!YAHOO.lang.isBoolean(C)){C=true;}if(!YAHOO.lang.isObject(L)){L=window;}if(!YAHOO.lang.isBoolean(B)){B=false;}if(!YAHOO.lang.isBoolean(A)){A=false;}if(!YAHOO.lang.isBoolean(K)){K=false;}if(!YAHOO.lang.isBoolean(H)){H=false;}if(!YAHOO.lang.isNumber(N)){N=0;}if(!YAHOO.lang.isNumber(M)){M=0;}var I=null;if(YAHOO.lang.isFunction(document.createEvent)){try{I=document.createEvent("KeyEvents");I.initKeyEvent(J,E,C,L,B,A,K,H,N,M);}catch(G){try{I=document.createEvent("Events");}catch(D){I=document.createEvent("UIEvents");}finally{I.initEvent(J,E,C);I.view=L;I.altKey=A;I.ctrlKey=B;I.shiftKey=K;I.metaKey=H;I.keyCode=N;I.charCode=M;}}F.dispatchEvent(I);}else{if(YAHOO.lang.isObject(document.createEventObject)){I=document.createEventObject();I.bubbles=E;I.cancelable=C;I.view=L;I.ctrlKey=B;I.altKey=A;I.shift!
 Key=K;I.metaKey=H;I.keyCode=(M>0)?M:N;F.fireEvent("on"+J,I);}e!
 lse{thro
w new Error("simulateKeyEvent(): No event simulation framework present.");}}},simulateMouseEvent:function(K,P,H,E,Q,J,G,F,D,B,C,A,O,M,I,L){K=YAHOO.util.Dom.get(K);if(!K){throw new Error("simulateMouseEvent(): Invalid target.");}if(YAHOO.lang.isString(P)){P=P.toLowerCase();switch(P){case"mouseover":case"mouseout":case"mousedown":case"mouseup":case"click":case"dblclick":case"mousemove":break;default:throw new Error("simulateMouseEvent(): Event type '"+P+"' not supported.");}}else{throw new Error("simulateMouseEvent(): Event type must be a string.");}if(!YAHOO.lang.isBoolean(H)){H=true;}if(!YAHOO.lang.isBoolean(E)){E=(P!="mousemove");}if(!YAHOO.lang.isObject(Q)){Q=window;}if(!YAHOO.lang.isNumber(J)){J=1;}if(!YAHOO.lang.isNumber(G)){G=0;}if(!YAHOO.lang.isNumber(F)){F=0;}if(!YAHOO.lang.isNumber(D)){D=0;}if(!YAHOO.lang.isNumber(B)){B=0;}if(!YAHOO.lang.isBoolean(C)){C=false;}if(!YAHOO.lang.isBoolean(A)){A=false;}if(!YAHOO.lang.isBoolean(O)){O=false;}if(!YAHOO.lang.isBoolean(M)){M=f!
 alse;}if(!YAHOO.lang.isNumber(I)){I=0;}var N=null;if(YAHOO.lang.isFunction(document.createEvent)){N=document.createEvent("MouseEvents");if(N.initMouseEvent){N.initMouseEvent(P,H,E,Q,J,G,F,D,B,C,A,O,M,I,L);}else{N=document.createEvent("UIEvents");N.initEvent(P,H,E);N.view=Q;N.detail=J;N.screenX=G;N.screenY=F;N.clientX=D;N.clientY=B;N.ctrlKey=C;N.altKey=A;N.metaKey=M;N.shiftKey=O;N.button=I;N.relatedTarget=L;}if(L&&!N.relatedTarget){if(P=="mouseout"){N.toElement=L;}else{if(P=="mouseover"){N.fromElement=L;}}}K.dispatchEvent(N);}else{if(YAHOO.lang.isObject(document.createEventObject)){N=document.createEventObject();N.bubbles=H;N.cancelable=E;N.view=Q;N.detail=J;N.screenX=G;N.screenY=F;N.clientX=D;N.clientY=B;N.ctrlKey=C;N.altKey=A;N.metaKey=M;N.shiftKey=O;switch(I){case 0:N.button=1;break;case 1:N.button=4;break;case 2:break;default:N.button=0;}N.relatedTarget=L;K.fireEvent("on"+P,N);}else{throw new Error("simulateMouseEvent(): No event simulation framework present.");
-}}},fireMouseEvent:function(C,B,A){A=A||{};this.simulateMouseEvent(C,B,A.bubbles,A.cancelable,A.view,A.detail,A.screenX,A.screenY,A.clientX,A.clientY,A.ctrlKey,A.altKey,A.shiftKey,A.metaKey,A.button,A.relatedTarget);},click:function(B,A){this.fireMouseEvent(B,"click",A);},dblclick:function(B,A){this.fireMouseEvent(B,"dblclick",A);},mousedown:function(B,A){this.fireMouseEvent(B,"mousedown",A);},mousemove:function(B,A){this.fireMouseEvent(B,"mousemove",A);},mouseout:function(B,A){this.fireMouseEvent(B,"mouseout",A);},mouseover:function(B,A){this.fireMouseEvent(B,"mouseover",A);},mouseup:function(B,A){this.fireMouseEvent(B,"mouseup",A);},fireKeyEvent:function(B,C,A){A=A||{};this.simulateKeyEvent(C,B,A.bubbles,A.cancelable,A.view,A.ctrlKey,A.altKey,A.shiftKey,A.metaKey,A.keyCode,A.charCode);},keydown:function(B,A){this.fireKeyEvent("keydown",B,A);},keypress:function(B,A){this.fireKeyEvent("keypress",B,A);},keyup:function(B,A){this.fireKeyEvent("keyup",B,A);}};YAHOO.namespace("t!
 ool");YAHOO.tool.TestManager={TEST_PAGE_BEGIN_EVENT:"testpagebegin",TEST_PAGE_COMPLETE_EVENT:"testpagecomplete",TEST_MANAGER_BEGIN_EVENT:"testmanagerbegin",TEST_MANAGER_COMPLETE_EVENT:"testmanagercomplete",_curPage:null,_frame:null,_logger:null,_timeoutId:0,_pages:[],_results:null,_handleTestRunnerComplete:function(A){this.fireEvent(this.TEST_PAGE_COMPLETE_EVENT,{page:this._curPage,results:A.results});this._processResults(this._curPage,A.results);this._logger.clearTestRunner();if(this._pages.length){this._timeoutId=setTimeout(function(){YAHOO.tool.TestManager._run();},1000);}},_processResults:function(C,A){var B=this._results;B.page_results[C]=A;if(A.passed){B.pages_passed++;B.tests_passed+=A.passed;}if(A.failed){B.pages_failed++;B.tests_failed+=A.failed;B.failed.push(C);}else{B.passed.push(C);}if(!this._pages.length){this.fireEvent(this.TEST_MANAGER_COMPLETE_EVENT,this._results);}},_run:function(){this._curPage=this._pages.shift();this.fireEvent(this.TEST_PAGE_BEGIN_EVENT,!
 this._curPage);this._frame.location.replace(this._curPage);},l!
 oad:func
tion(){if(parent.YAHOO.tool.TestManager!==this){parent.YAHOO.tool.TestManager.load();}else{if(this._frame){var A=this._frame.YAHOO.tool.TestRunner;this._logger.setTestRunner(A);A.subscribe(A.COMPLETE_EVENT,this._handleTestRunnerComplete,this,true);A.run();}}},setPages:function(A){this._pages=A;},start:function(){if(!this._initialized){this.createEvent(this.TEST_PAGE_BEGIN_EVENT);this.createEvent(this.TEST_PAGE_COMPLETE_EVENT);this.createEvent(this.TEST_MANAGER_BEGIN_EVENT);this.createEvent(this.TEST_MANAGER_COMPLETE_EVENT);if(!this._frame){var A=document.createElement("iframe");A.style.visibility="hidden";A.style.position="absolute";document.body.appendChild(A);this._frame=A.contentWindow||A.contentDocument.ownerWindow;}if(!this._logger){this._logger=new YAHOO.tool.TestLogger();}this._initialized=true;}this._results={pages_passed:0,pages_failed:0,tests_passed:0,tests_failed:0,passed:[],failed:[],page_results:{}};this.fireEvent(this.TEST_MANAGER_BEGIN_EVENT,null);this._run();!
 },stop:function(){clearTimeout(this._timeoutId);}};YAHOO.lang.augmentObject(YAHOO.tool.TestManager,YAHOO.util.EventProvider.prototype);YAHOO.namespace("tool");YAHOO.tool.TestLogger=function(B,A){YAHOO.tool.TestLogger.superclass.constructor.call(this,B,A);this.init();};YAHOO.lang.extend(YAHOO.tool.TestLogger,YAHOO.widget.LogReader,{footerEnabled:true,newestOnTop:false,formatMsg:function(B){var A=B.category;var C=this.html2Text(B.msg);return"<pre><p><span class=\""+A+"\">"+A.toUpperCase()+"</span> "+C+"</p></pre>";},init:function(){if(YAHOO.tool.TestRunner){this.setTestRunner(YAHOO.tool.TestRunner);}this.hideSource("global");this.hideSource("LogReader");this.hideCategory("warn");this.hideCategory("window");this.hideCategory("time");this.clearConsole();},clearTestRunner:function(){if(this._runner){this._runner.unsubscribeAll();this._runner=null;}},setTestRunner:function(A){if(this._runner){this.clearTestRunner();}this._runner=A;A.subscribe(A.TEST_PASS_EVENT,this._handleTestRun!
 nerEvent,this,true);A.subscribe(A.TEST_FAIL_EVENT,this._handle!
 TestRunn
erEvent,this,true);A.subscribe(A.TEST_IGNORE_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.BEGIN_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.COMPLETE_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_SUITE_BEGIN_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_SUITE_COMPLETE_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_CASE_BEGIN_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_CASE_COMPLETE_EVENT,this._handleTestRunnerEvent,this,true);},_handleTestRunnerEvent:function(D){var A=YAHOO.tool.TestRunner;var C="";var B="";switch(D.type){case A.BEGIN_EVENT:C="Testing began at "+(new Date()).toString()+".";B="info";break;case A.COMPLETE_EVENT:C="Testing completed at "+(new Date()).toString()+".\nPassed:"+D.results.passed+" Failed:"+D.results.failed+" Total:"+D.results.total;B="info";break;case A.TEST_FAIL_EVENT:C=D.testName+": "+D.error.getMessage();B="fail";break;case A.TEST_IGNORE_EVENT:C=D!
 .testName+": ignored.";B="ignore";break;case A.TEST_PASS_EVENT:C=D.testName+": passed.";B="pass";break;case A.TEST_SUITE_BEGIN_EVENT:C="Test suite \""+D.testSuite.name+"\" started.";B="info";break;case A.TEST_SUITE_COMPLETE_EVENT:C="Test suite \""+D.testSuite.name+"\" completed.\nPassed:"+D.results.passed+" Failed:"+D.results.failed+" Total:"+D.results.total;B="info";break;case A.TEST_CASE_BEGIN_EVENT:C="Test case \""+D.testCase.name+"\" started.";B="info";break;case A.TEST_CASE_COMPLETE_EVENT:C="Test case \""+D.testCase.name+"\" completed.\nPassed:"+D.results.passed+" Failed:"+D.results.failed+" Total:"+D.results.total;B="info";break;default:C="Unexpected event "+D.type;C="info";}YAHOO.log(C,B,"TestRunner");}});YAHOO.register("yuitest",YAHOO.tool.TestRunner,{version:"2.4.1",build:"742"});
\ No newline at end of file

Deleted: trunk/root/static/yui/yuitest/yuitest-beta.js
===================================================================
--- trunk/root/static/yui/yuitest/yuitest-beta.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/yuitest-beta.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -1,3007 +0,0 @@
-/*
-Copyright (c) 2007, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.4.1
-*/
-YAHOO.namespace("tool");
-
-//-----------------------------------------------------------------------------
-// TestCase object
-//-----------------------------------------------------------------------------
-
-/**
- * Test case containing various tests to run.
- * @param template An object containing any number of test methods, other methods,
- *                 an optional name, and anything else the test case needs.
- * @class TestCase
- * @namespace YAHOO.tool
- * @constructor
- */
-YAHOO.tool.TestCase = function (template /*:Object*/) {
-    
-    /**
-     * Special rules for the test case. Possible subobjects
-     * are fail, for tests that should fail, and error, for
-     * tests that should throw an error.
-     */
-    this._should /*:Object*/ = {};
-    
-    //copy over all properties from the template to this object
-    for (var prop in template) {
-        this[prop] = template[prop];
-    }    
-    
-    //check for a valid name
-    if (!YAHOO.lang.isString(this.name)){
-        /**
-         * Name for the test case.
-         */
-        this.name /*:String*/ = YAHOO.util.Dom.generateId(null, "testCase");
-    }
-
-};
-
-
-YAHOO.tool.TestCase.prototype = {  
-
-    /**
-     * Resumes a paused test and runs the given function.
-     * @param {Function} segment (Optional) The function to run.
-     *      If omitted, the test automatically passes.
-     * @return {Void}
-     * @method resume
-     */
-    resume : function (segment /*:Function*/) /*:Void*/ {
-        YAHOO.tool.TestRunner.resume(segment);
-    },
-
-    /**
-     * Causes the test case to wait a specified amount of time and then
-     * continue executing the given code.
-     * @param {Function} segment (Optional) The function to run after the delay.
-     *      If omitted, the TestRunner will wait until resume() is called.
-     * @param {int} delay (Optional) The number of milliseconds to wait before running
-     *      the function. If omitted, defaults to zero.
-     * @return {Void}
-     * @method wait
-     */
-    wait : function (segment /*:Function*/, delay /*:int*/) /*:Void*/{
-        throw new YAHOO.tool.TestCase.Wait(segment, delay);
-    },
-
-    //-------------------------------------------------------------------------
-    // Stub Methods
-    //-------------------------------------------------------------------------
-
-    /**
-     * Function to run before each test is executed.
-     * @return {Void}
-     * @method setUp
-     */
-    setUp : function () /*:Void*/ {
-    },
-    
-    /**
-     * Function to run after each test is executed.
-     * @return {Void}
-     * @method tearDown
-     */
-    tearDown: function () /*:Void*/ {    
-    }
-};
-
-/**
- * Represents a stoppage in test execution to wait for an amount of time before
- * continuing.
- * @param {Function} segment A function to run when the wait is over.
- * @param {int} delay The number of milliseconds to wait before running the code.
- * @class Wait
- * @namespace YAHOO.tool.TestCase
- * @constructor
- *
- */
-YAHOO.tool.TestCase.Wait = function (segment /*:Function*/, delay /*:int*/) {
-    
-    /**
-     * The segment of code to run when the wait is over.
-     * @type Function
-     * @property segment
-     */
-    this.segment /*:Function*/ = (YAHOO.lang.isFunction(segment) ? segment : null);
-
-    /**
-     * The delay before running the segment of code.
-     * @type int
-     * @property delay
-     */
-    this.delay /*:int*/ = (YAHOO.lang.isNumber(delay) ? delay : 0);
-
-};
-
-YAHOO.namespace("tool");
-
-
-//-----------------------------------------------------------------------------
-// TestSuite object
-//-----------------------------------------------------------------------------
-
-/**
- * A test suite that can contain a collection of TestCase and TestSuite objects.
- * @param {String||Object} data The name of the test suite or an object containing
- *      a name property as well as setUp and tearDown methods.
- * @namespace YAHOO.tool
- * @class TestSuite
- * @constructor
- */
-YAHOO.tool.TestSuite = function (data /*:String||Object*/) {
-
-    /**
-     * The name of the test suite.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "";
-
-    /**
-     * Array of test suites and
-     * @private
-     */
-    this.items /*:Array*/ = [];
-
-    //initialize the properties
-    if (YAHOO.lang.isString(data)){
-        this.name = data;
-    } else if (YAHOO.lang.isObject(data)){
-        YAHOO.lang.augmentObject(this, data, true);
-    }
-
-    //double-check name
-    if (this.name === ""){
-        this.name = YAHOO.util.Dom.generateId(null, "testSuite");
-    }
-
-};
-
-YAHOO.tool.TestSuite.prototype = {
-    
-    /**
-     * Adds a test suite or test case to the test suite.
-     * @param {YAHOO.tool.TestSuite||YAHOO.tool.TestCase} testObject The test suite or test case to add.
-     * @return {Void}
-     * @method add
-     */
-    add : function (testObject /*:YAHOO.tool.TestSuite*/) /*:Void*/ {
-        if (testObject instanceof YAHOO.tool.TestSuite || testObject instanceof YAHOO.tool.TestCase) {
-            this.items.push(testObject);
-        }
-    },
-    
-    //-------------------------------------------------------------------------
-    // Stub Methods
-    //-------------------------------------------------------------------------
-
-    /**
-     * Function to run before each test is executed.
-     * @return {Void}
-     * @method setUp
-     */
-    setUp : function () /*:Void*/ {
-    },
-    
-    /**
-     * Function to run after each test is executed.
-     * @return {Void}
-     * @method tearDown
-     */
-    tearDown: function () /*:Void*/ {
-    }
-    
-};
-
-YAHOO.namespace("tool");
-
-/**
- * The YUI test tool
- * @module yuitest
- * @namespace YAHOO.tool
- * @requires yahoo,dom,event,logger
- */
-
-
-//-----------------------------------------------------------------------------
-// TestRunner object
-//-----------------------------------------------------------------------------
-
-/**
- * Runs test suites and test cases, providing events to allowing for the
- * interpretation of test results.
- * @namespace YAHOO.tool
- * @class TestRunner
- * @static
- */
-YAHOO.tool.TestRunner = (function(){
-
-    /**
-     * A node in the test tree structure. May represent a TestSuite, TestCase, or
-     * test function.
-     * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.
-     * @class TestNode
-     * @constructor
-     * @private
-     */
-    function TestNode(testObject /*:Variant*/){
-    
-        /**
-         * The TestSuite, TestCase, or test function represented by this node.
-         * @type Variant
-         * @property testObject
-         */
-        this.testObject = testObject;
-        
-        /**
-         * Pointer to this node's first child.
-         * @type TestNode
-         * @property firstChild
-         */        
-        this.firstChild /*:TestNode*/ = null;
-        
-        /**
-         * Pointer to this node's last child.
-         * @type TestNode
-         * @property lastChild
-         */        
-        this.lastChild = null;
-        
-        /**
-         * Pointer to this node's parent.
-         * @type TestNode
-         * @property parent
-         */        
-        this.parent = null; 
-   
-        /**
-         * Pointer to this node's next sibling.
-         * @type TestNode
-         * @property next
-         */        
-        this.next = null;
-        
-        /**
-         * Test results for this test object.
-         * @type object
-         * @property results
-         */                
-        this.results /*:Object*/ = {
-            passed : 0,
-            failed : 0,
-            total : 0
-        };
-       
-    }
-    
-    TestNode.prototype = {
-    
-        /**
-         * Appends a new test object (TestSuite, TestCase, or test function name) as a child
-         * of this node.
-         * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.
-         * @return {Void}
-         */
-        appendChild : function (testObject /*:Variant*/) /*:Void*/{
-            var node = new TestNode(testObject);
-            if (this.firstChild === null){
-                this.firstChild = this.lastChild = node;
-            } else {
-                this.lastChild.next = node;
-                this.lastChild = node;
-            }
-            node.parent = this;
-            return node;
-        }       
-    };
-
-    function TestRunner(){
-    
-        //inherit from EventProvider
-        TestRunner.superclass.constructor.apply(this,arguments);
-        
-        /**
-         * Suite on which to attach all TestSuites and TestCases to be run.
-         * @type YAHOO.tool.TestSuite
-         * @property masterSuite
-         * @private
-         */
-        this.masterSuite /*:YAHOO.tool.TestSuite*/ = new YAHOO.tool.TestSuite("MasterSuite");        
-
-        /**
-         * Pointer to the current node in the test tree.
-         * @type TestNode
-         * @private
-         * @property _cur
-         */
-        this._cur = null;
-        
-        /**
-         * Pointer to the root node in the test tree.
-         * @type TestNode
-         * @private
-         * @property _root
-         */
-        this._root = null;
-        
-        //create events
-        var events /*:Array*/ = [
-            this.TEST_CASE_BEGIN_EVENT,
-            this.TEST_CASE_COMPLETE_EVENT,
-            this.TEST_SUITE_BEGIN_EVENT,
-            this.TEST_SUITE_COMPLETE_EVENT,
-            this.TEST_PASS_EVENT,
-            this.TEST_FAIL_EVENT,
-            this.TEST_IGNORE_EVENT,
-            this.COMPLETE_EVENT,
-            this.BEGIN_EVENT
-        ];
-        for (var i=0; i < events.length; i++){
-            this.createEvent(events[i], { scope: this });
-        }       
-   
-    }
-    
-    YAHOO.lang.extend(TestRunner, YAHOO.util.EventProvider, {
-    
-        //-------------------------------------------------------------------------
-        // Constants
-        //-------------------------------------------------------------------------
-         
-        /**
-         * Fires when a test case is opened but before the first 
-         * test is executed.
-         * @event testcasebegin
-         */         
-        TEST_CASE_BEGIN_EVENT /*:String*/ : "testcasebegin",
-        
-        /**
-         * Fires when all tests in a test case have been executed.
-         * @event testcasecomplete
-         */        
-        TEST_CASE_COMPLETE_EVENT /*:String*/ : "testcasecomplete",
-        
-        /**
-         * Fires when a test suite is opened but before the first 
-         * test is executed.
-         * @event testsuitebegin
-         */        
-        TEST_SUITE_BEGIN_EVENT /*:String*/ : "testsuitebegin",
-        
-        /**
-         * Fires when all test cases in a test suite have been
-         * completed.
-         * @event testsuitecomplete
-         */        
-        TEST_SUITE_COMPLETE_EVENT /*:String*/ : "testsuitecomplete",
-        
-        /**
-         * Fires when a test has passed.
-         * @event pass
-         */        
-        TEST_PASS_EVENT /*:String*/ : "pass",
-        
-        /**
-         * Fires when a test has failed.
-         * @event fail
-         */        
-        TEST_FAIL_EVENT /*:String*/ : "fail",
-        
-        /**
-         * Fires when a test has been ignored.
-         * @event ignore
-         */        
-        TEST_IGNORE_EVENT /*:String*/ : "ignore",
-        
-        /**
-         * Fires when all test suites and test cases have been completed.
-         * @event complete
-         */        
-        COMPLETE_EVENT /*:String*/ : "complete",
-        
-        /**
-         * Fires when the run() method is called.
-         * @event begin
-         */        
-        BEGIN_EVENT /*:String*/ : "begin",    
-        
-        //-------------------------------------------------------------------------
-        // Test Tree-Related Methods
-        //-------------------------------------------------------------------------
-
-        /**
-         * Adds a test case to the test tree as a child of the specified node.
-         * @param {TestNode} parentNode The node to add the test case to as a child.
-         * @param {YAHOO.tool.TestCase} testCase The test case to add.
-         * @return {Void}
-         * @static
-         * @private
-         * @method _addTestCaseToTestTree
-         */
-       _addTestCaseToTestTree : function (parentNode /*:TestNode*/, testCase /*:YAHOO.tool.TestCase*/) /*:Void*/{
-            
-            //add the test suite
-            var node = parentNode.appendChild(testCase);
-            
-            //iterate over the items in the test case
-            for (var prop in testCase){
-                if (prop.indexOf("test") === 0 && YAHOO.lang.isFunction(testCase[prop])){
-                    node.appendChild(prop);
-                }
-            }
-         
-        },
-        
-        /**
-         * Adds a test suite to the test tree as a child of the specified node.
-         * @param {TestNode} parentNode The node to add the test suite to as a child.
-         * @param {YAHOO.tool.TestSuite} testSuite The test suite to add.
-         * @return {Void}
-         * @static
-         * @private
-         * @method _addTestSuiteToTestTree
-         */
-        _addTestSuiteToTestTree : function (parentNode /*:TestNode*/, testSuite /*:YAHOO.tool.TestSuite*/) /*:Void*/ {
-            
-            //add the test suite
-            var node = parentNode.appendChild(testSuite);
-            
-            //iterate over the items in the master suite
-            for (var i=0; i < testSuite.items.length; i++){
-                if (testSuite.items[i] instanceof YAHOO.tool.TestSuite) {
-                    this._addTestSuiteToTestTree(node, testSuite.items[i]);
-                } else if (testSuite.items[i] instanceof YAHOO.tool.TestCase) {
-                    this._addTestCaseToTestTree(node, testSuite.items[i]);
-                }                   
-            }            
-        },
-        
-        /**
-         * Builds the test tree based on items in the master suite. The tree is a hierarchical
-         * representation of the test suites, test cases, and test functions. The resulting tree
-         * is stored in _root and the pointer _cur is set to the root initially.
-         * @return {Void}
-         * @static
-         * @private
-         * @method _buildTestTree
-         */
-        _buildTestTree : function () /*:Void*/ {
-        
-            this._root = new TestNode(this.masterSuite);
-            this._cur = this._root;
-            
-            //iterate over the items in the master suite
-            for (var i=0; i < this.masterSuite.items.length; i++){
-                if (this.masterSuite.items[i] instanceof YAHOO.tool.TestSuite) {
-                    this._addTestSuiteToTestTree(this._root, this.masterSuite.items[i]);
-                } else if (this.masterSuite.items[i] instanceof YAHOO.tool.TestCase) {
-                    this._addTestCaseToTestTree(this._root, this.masterSuite.items[i]);
-                }                   
-            }            
-        
-        }, 
-    
-        //-------------------------------------------------------------------------
-        // Private Methods
-        //-------------------------------------------------------------------------
-        _handleTestObjectComplete : function (node /*:TestNode*/) /*:Void*/ {
-            if (YAHOO.lang.isObject(node.testObject)){
-                node.parent.results.passed += node.results.passed;
-                node.parent.results.failed += node.results.failed;
-                node.parent.results.total += node.results.total;                
-                node.parent.results[node.testObject.name] = node.results;
-            
-                if (node.testObject instanceof YAHOO.tool.TestSuite){
-                    node.testObject.tearDown();
-                    this.fireEvent(this.TEST_SUITE_COMPLETE_EVENT, { testSuite: node.testObject, results: node.results});
-                } else if (node.testObject instanceof YAHOO.tool.TestCase){
-                    this.fireEvent(this.TEST_CASE_COMPLETE_EVENT, { testCase: node.testObject, results: node.results});
-                }      
-            } 
-        },        
-        
-        
-        //-------------------------------------------------------------------------
-        // Navigation Methods
-        //-------------------------------------------------------------------------
-        
-        /**
-         * Retrieves the next node in the test tree.
-         * @return {TestNode} The next node in the test tree or null if the end is reached.
-         * @private
-         * @static
-         * @method _next
-         */
-        _next : function () /*:TestNode*/ {
-        
-            if (this._cur.firstChild) {
-                this._cur = this._cur.firstChild;
-            } else if (this._cur.next) {
-                this._cur = this._cur.next;            
-            } else {
-                while (this._cur && !this._cur.next && this._cur !== this._root){
-                    this._handleTestObjectComplete(this._cur);
-                    this._cur = this._cur.parent;
-                }
-                
-                if (this._cur == this._root){
-                    this.fireEvent(this.COMPLETE_EVENT, { results: this._cur.results});
-                    this._cur = null;
-                } else {
-                    this._handleTestObjectComplete(this._cur);               
-                    this._cur = this._cur.next;                
-                }
-            }
-        
-            return this._cur;
-        },
-        
-        /**
-         * Runs a test case or test suite, returning the results.
-         * @param {YAHOO.tool.TestCase|YAHOO.tool.TestSuite} testObject The test case or test suite to run.
-         * @return {Object} Results of the execution with properties passed, failed, and total.
-         * @private
-         * @method _run
-         * @static
-         */
-        _run : function () /*:Void*/ {
-        
-            //flag to indicate if the TestRunner should wait before continuing
-            var shouldWait /*:Boolean*/ = false;
-            
-            //get the next test node
-            var node = this._next();
-            
-            if (node !== null) {
-                var testObject = node.testObject;
-                
-                //figure out what to do
-                if (YAHOO.lang.isObject(testObject)){
-                    if (testObject instanceof YAHOO.tool.TestSuite){
-                        this.fireEvent(this.TEST_SUITE_BEGIN_EVENT, { testSuite: testObject });
-                        testObject.setUp();
-                    } else if (testObject instanceof YAHOO.tool.TestCase){
-                        this.fireEvent(this.TEST_CASE_BEGIN_EVENT, { testCase: testObject });
-                    }
-                    
-                    //some environments don't support setTimeout
-                    if (typeof setTimeout != "undefined"){                    
-                        setTimeout(function(){
-                            YAHOO.tool.TestRunner._run();
-                        }, 0);              
-                    } else {
-                        this._run();
-                    }
-                } else {
-                    this._runTest(node);
-                }
-
-            }
-        },
-        
-        _resumeTest : function (segment /*:Function*/) /*:Void*/ {
-        
-            //get relevant information
-            var node /*:TestNode*/ = this._cur;
-            var testName /*:String*/ = node.testObject;
-            var testCase /*:YAHOO.tool.TestCase*/ = node.parent.testObject;
-            
-            //get the "should" test cases
-            var shouldFail /*:Object*/ = (testCase._should.fail || {})[testName];
-            var shouldError /*:Object*/ = (testCase._should.error || {})[testName];
-            
-            //variable to hold whether or not the test failed
-            var failed /*:Boolean*/ = false;
-            var error /*:Error*/ = null;
-                
-            //try the test
-            try {
-            
-                //run the test
-                segment.apply(testCase);
-                
-                //if it should fail, and it got here, then it's a fail because it didn't
-                if (shouldFail){
-                    error = new YAHOO.util.ShouldFail();
-                    failed = true;
-                } else if (shouldError){
-                    error = new YAHOO.util.ShouldError();
-                    failed = true;
-                }
-                           
-            } catch (thrown /*:Error*/){
-                if (thrown instanceof YAHOO.util.AssertionError) {
-                    if (!shouldFail){
-                        error = thrown;
-                        failed = true;
-                    }
-                } else if (thrown instanceof YAHOO.tool.TestCase.Wait){
-                
-                    if (YAHOO.lang.isFunction(thrown.segment)){
-                        if (YAHOO.lang.isNumber(thrown.delay)){
-                        
-                            //some environments don't support setTimeout
-                            if (typeof setTimeout != "undefined"){
-                                setTimeout(function(){
-                                    YAHOO.tool.TestRunner._resumeTest(thrown.segment);
-                                }, thrown.delay);
-                            } else {
-                                throw new Error("Asynchronous tests not supported in this environment.");
-                            }
-                        }
-                    }
-                    
-                    return;
-                
-                } else {
-                    //first check to see if it should error
-                    if (!shouldError) {                        
-                        error = new YAHOO.util.UnexpectedError(thrown);
-                        failed = true;
-                    } else {
-                        //check to see what type of data we have
-                        if (YAHOO.lang.isString(shouldError)){
-                            
-                            //if it's a string, check the error message
-                            if (thrown.message != shouldError){
-                                error = new YAHOO.util.UnexpectedError(thrown);
-                                failed = true;                                    
-                            }
-                        } else if (YAHOO.lang.isObject(shouldError)){
-                        
-                            //if it's an object, check the instance and message
-                            if (!(thrown instanceof shouldError.constructor) || 
-                                    thrown.message != shouldError.message){
-                                error = new YAHOO.util.UnexpectedError(thrown);
-                                failed = true;                                    
-                            }
-                        
-                        }
-                    
-                    }
-                }
-                
-            }
-            
-            //fireEvent appropriate event
-            if (failed) {
-                this.fireEvent(this.TEST_FAIL_EVENT, { testCase: testCase, testName: testName, error: error });
-            } else {
-                this.fireEvent(this.TEST_PASS_EVENT, { testCase: testCase, testName: testName });
-            }
-            
-            //run the tear down
-            testCase.tearDown();
-            
-            //update results
-            node.parent.results[testName] = { 
-                result: failed ? "fail" : "pass",
-                message : error ? error.getMessage() : "Test passed"
-            };
-            
-            if (failed){
-                node.parent.results.failed++;
-            } else {
-                node.parent.results.passed++;
-            }
-            node.parent.results.total++;    
-
-            //set timeout not supported in all environments
-            if (typeof setTimeout != "undefined"){
-                setTimeout(function(){
-                    YAHOO.tool.TestRunner._run();
-                }, 0);
-            } else {
-                this._run();
-            }
-        
-        },
-                
-        /**
-         * Runs a single test based on the data provided in the node.
-         * @param {TestNode} node The TestNode representing the test to run.
-         * @return {Void}
-         * @static
-         * @private
-         * @name _runTest
-         */
-        _runTest : function (node /*:TestNode*/) /*:Void*/ {
-        
-            //get relevant information
-            var testName /*:String*/ = node.testObject;
-            var testCase /*:YAHOO.tool.TestCase*/ = node.parent.testObject;
-            var test /*:Function*/ = testCase[testName];
-            
-            //get the "should" test cases
-            var shouldIgnore /*:Object*/ = (testCase._should.ignore || {})[testName];
-            
-            //figure out if the test should be ignored or not
-            if (shouldIgnore){
-                this.fireEvent(this.TEST_IGNORE_EVENT, { testCase: testCase, testName: testName });
-                
-                //some environments don't support setTimeout
-                if (typeof setTimeout != "undefined"){                    
-                    setTimeout(function(){
-                        YAHOO.tool.TestRunner._run();
-                    }, 0);              
-                } else {
-                    this._run();
-                }
-
-            } else {
-            
-                //run the setup
-                testCase.setUp();
-                
-                //now call the body of the test
-                this._resumeTest(test);                
-            }
-
-        },        
-        
-        //-------------------------------------------------------------------------
-        // Protected Methods
-        //-------------------------------------------------------------------------   
-    
-        /*
-         * Fires events for the TestRunner. This overrides the default fireEvent()
-         * method from EventProvider to add the type property to the data that is
-         * passed through on each event call.
-         * @param {String} type The type of event to fire.
-         * @param {Object} data (Optional) Data for the event.
-         * @method fireEvent
-         * @static
-         * @protected
-         */
-        fireEvent : function (type /*:String*/, data /*:Object*/) /*:Void*/ {
-            data = data || {};
-            data.type = type;
-            TestRunner.superclass.fireEvent.call(this, type, data);
-        },
-        
-        //-------------------------------------------------------------------------
-        // Public Methods
-        //-------------------------------------------------------------------------   
-    
-        /**
-         * Adds a test suite or test case to the list of test objects to run.
-         * @param testObject Either a TestCase or a TestSuite that should be run.
-         * @return {Void}
-         * @method add
-         * @static
-         */
-        add : function (testObject /*:Object*/) /*:Void*/ {
-            this.masterSuite.add(testObject);
-        },
-        
-        /**
-         * Removes all test objects from the runner.
-         * @return {Void}
-         * @method clear
-         * @static
-         */
-        clear : function () /*:Void*/ {
-            this.masterSuite.items = [];
-        },
-        
-        /**
-         * Resumes the TestRunner after wait() was called.
-         * @param {Function} segment The function to run as the rest
-         *      of the haulted test.
-         * @return {Void}
-         * @method resume
-         * @static
-         */
-        resume : function (segment /*:Function*/) /*:Void*/ {
-            this._resumeTest(segment || function(){});
-        },
-    
-        /**
-         * Runs the test suite.
-         * @return {Void}
-         * @method run
-         * @static
-         */
-        run : function (testObject /*:Object*/) /*:Void*/ {
-            
-            //pointer to runner to avoid scope issues 
-            var runner = YAHOO.tool.TestRunner;
-
-            //build the test tree
-            runner._buildTestTree();
-            
-            //fire the begin event
-            runner.fireEvent(runner.BEGIN_EVENT);
-       
-            //begin the testing
-            runner._run();
-        }    
-    });
-    
-    return new TestRunner();
-    
-})();
-
-YAHOO.namespace("util");
-
-//-----------------------------------------------------------------------------
-// Assert object
-//-----------------------------------------------------------------------------
-
-/**
- * The Assert object provides functions to test JavaScript values against
- * known and expected results. Whenever a comparison (assertion) fails,
- * an error is thrown.
- *
- * @namespace YAHOO.util
- * @class Assert
- * @static
- */
-YAHOO.util.Assert = {
-
-    //-------------------------------------------------------------------------
-    // Generic Assertion Methods
-    //-------------------------------------------------------------------------
-    
-    /** 
-     * Forces an assertion error to occur.
-     * @param {String} message (Optional) The message to display with the failure.
-     * @method fail
-     * @static
-     */
-    fail : function (message /*:String*/) /*:Void*/ {
-        throw new YAHOO.util.AssertionError(message || "Test force-failed.");
-    },       
-    
-    //-------------------------------------------------------------------------
-    // Equality Assertion Methods
-    //-------------------------------------------------------------------------    
-    
-    /**
-     * Asserts that a value is equal to another. This uses the double equals sign
-     * so type cohersion may occur.
-     * @param {Object} expected The expected value.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method areEqual
-     * @static
-     */
-    areEqual : function (expected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (expected != actual) {
-            throw new YAHOO.util.ComparisonFailure(message || "Values should be equal.", expected, actual);
-        }
-    },
-    
-    /**
-     * Asserts that a value is not equal to another. This uses the double equals sign
-     * so type cohersion may occur.
-     * @param {Object} unexpected The unexpected value.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method areNotEqual
-     * @static
-     */
-    areNotEqual : function (unexpected /*:Object*/, actual /*:Object*/, 
-                         message /*:String*/) /*:Void*/ {
-        if (unexpected == actual) {
-            throw new YAHOO.util.UnexpectedValue(message || "Values should not be equal.", unexpected);
-        }
-    },
-    
-    /**
-     * Asserts that a value is not the same as another. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} unexpected The unexpected value.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method areNotSame
-     * @static
-     */
-    areNotSame : function (unexpected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (unexpected === actual) {
-            throw new YAHOO.util.UnexpectedValue(message || "Values should not be the same.", unexpected);
-        }
-    },
-
-    /**
-     * Asserts that a value is the same as another. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} expected The expected value.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method areSame
-     * @static
-     */
-    areSame : function (expected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (expected !== actual) {
-            throw new YAHOO.util.ComparisonFailure(message || "Values should be the same.", expected, actual);
-        }
-    },    
-    
-    //-------------------------------------------------------------------------
-    // Boolean Assertion Methods
-    //-------------------------------------------------------------------------    
-    
-    /**
-     * Asserts that a value is false. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isFalse
-     * @static
-     */
-    isFalse : function (actual /*:Boolean*/, message /*:String*/) {
-        if (false !== actual) {
-            throw new YAHOO.util.ComparisonFailure(message || "Value should be false.", false, actual);
-        }
-    },
-    
-    /**
-     * Asserts that a value is true. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isTrue
-     * @static
-     */
-    isTrue : function (actual /*:Boolean*/, message /*:String*/) /*:Void*/ {
-        if (true !== actual) {
-            throw new YAHOO.util.ComparisonFailure(message || "Value should be true.", true, actual);
-        }
-
-    },
-    
-    //-------------------------------------------------------------------------
-    // Special Value Assertion Methods
-    //-------------------------------------------------------------------------    
-    
-    /**
-     * Asserts that a value is not a number.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNaN
-     * @static
-     */
-    isNaN : function (actual /*:Object*/, message /*:String*/) /*:Void*/{
-        if (!isNaN(actual)){
-            throw new YAHOO.util.ComparisonFailure(message || "Value should be NaN.", NaN, actual);
-        }    
-    },
-    
-    /**
-     * Asserts that a value is not the special NaN value.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNotNaN
-     * @static
-     */
-    isNotNaN : function (actual /*:Object*/, message /*:String*/) /*:Void*/{
-        if (isNaN(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Values should not be NaN.", NaN);
-        }    
-    },
-    
-    /**
-     * Asserts that a value is not null. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNotNull
-     * @static
-     */
-    isNotNull : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (YAHOO.lang.isNull(actual)) {
-            throw new YAHOO.util.UnexpectedValue(message || "Values should not be null.", null);
-        }
-    },
-
-    /**
-     * Asserts that a value is not undefined. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNotUndefined
-     * @static
-     */
-    isNotUndefined : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (YAHOO.lang.isUndefined(actual)) {
-            throw new YAHOO.util.UnexpectedValue(message || "Value should not be undefined.", undefined);
-        }
-    },
-
-    /**
-     * Asserts that a value is null. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNull
-     * @static
-     */
-    isNull : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isNull(actual)) {
-            throw new YAHOO.util.ComparisonFailure(message || "Value should be null.", null, actual);
-        }
-    },
-        
-    /**
-     * Asserts that a value is undefined. This uses the triple equals sign
-     * so no type cohersion may occur.
-     * @param {Object} expected The expected value.
-     * @param {Object} actual The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isUndefined
-     * @static
-     */
-    isUndefined : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isUndefined(actual)) {
-            throw new YAHOO.util.ComparisonFailure(message || "Value should be undefined.", undefined, actual);
-        }
-    },    
-    
-    //--------------------------------------------------------------------------
-    // Instance Assertion Methods
-    //--------------------------------------------------------------------------    
-   
-    /**
-     * Asserts that a value is an array.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isArray
-     * @static
-     */
-    isArray : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isArray(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Value should be an array.", actual);
-        }    
-    },
-   
-    /**
-     * Asserts that a value is a Boolean.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isBoolean
-     * @static
-     */
-    isBoolean : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isBoolean(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Value should be a Boolean.", actual);
-        }    
-    },
-   
-    /**
-     * Asserts that a value is a function.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isFunction
-     * @static
-     */
-    isFunction : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isFunction(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Value should be a function.", actual);
-        }    
-    },
-   
-    /**
-     * Asserts that a value is an instance of a particular object. This may return
-     * incorrect results when comparing objects from one frame to constructors in
-     * another frame. For best results, don't use in a cross-frame manner.
-     * @param {Function} expected The function that the object should be an instance of.
-     * @param {Object} actual The object to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isInstanceOf
-     * @static
-     */
-    isInstanceOf : function (expected /*:Function*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!(actual instanceof expected)){
-            throw new YAHOO.util.ComparisonFailure(message || "Value isn't an instance of expected type.", expected, actual);
-        }
-    },
-    
-    /**
-     * Asserts that a value is a number.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNumber
-     * @static
-     */
-    isNumber : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isNumber(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Value should be a number.", actual);
-        }    
-    },    
-    
-    /**
-     * Asserts that a value is an object.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isObject
-     * @static
-     */
-    isObject : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isObject(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Value should be an object.", actual);
-        }
-    },
-    
-    /**
-     * Asserts that a value is a string.
-     * @param {Object} actual The value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isString
-     * @static
-     */
-    isString : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.isString(actual)){
-            throw new YAHOO.util.UnexpectedValue(message || "Value should be a string.", actual);
-        }
-    },
-    
-    /**
-     * Asserts that a value is of a particular type. 
-     * @param {String} expectedType The expected type of the variable.
-     * @param {Object} actualValue The actual value to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isTypeOf
-     * @static
-     */
-    isTypeOf : function (expectedType /*:String*/, actualValue /*:Object*/, message /*:String*/) /*:Void*/{
-        if (typeof actualValue != expectedType){
-            throw new YAHOO.util.ComparisonFailure(message || "Value should be of type " + expected + ".", expected, typeof actual);
-        }
-    }
-};
-
-//-----------------------------------------------------------------------------
-// Assertion errors
-//-----------------------------------------------------------------------------
-
-/**
- * AssertionError is thrown whenever an assertion fails. It provides methods
- * to more easily get at error information and also provides a base class
- * from which more specific assertion errors can be derived.
- *
- * @param {String} message The message to display when the error occurs.
- * @namespace YAHOO.util
- * @class AssertionError
- * @extends Error
- * @constructor
- */ 
-YAHOO.util.AssertionError = function (message /*:String*/){
-
-    //call superclass
-    arguments.callee.superclass.constructor.call(this, message);
-    
-    /*
-     * Error message. Must be duplicated to ensure browser receives it.
-     * @type String
-     * @property message
-     */
-    this.message /*:String*/ = message;
-    
-    /**
-     * The name of the error that occurred.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "AssertionError";
-};
-
-//inherit methods
-YAHOO.lang.extend(YAHOO.util.AssertionError, Error, {
-
-    /**
-     * Returns a fully formatted error for an assertion failure. This should
-     * be overridden by all subclasses to provide specific information.
-     * @method getMessage
-     * @return {String} A string describing the error.
-     */
-    getMessage : function () /*:String*/ {
-        return this.message;
-    },
-    
-    /**
-     * Returns a string representation of the error.
-     * @method toString
-     * @return {String} A string representation of the error.
-     */
-    toString : function () /*:String*/ {
-        return this.name + ": " + this.getMessage();
-    },
-    
-    /**
-     * Returns a primitive value version of the error. Same as toString().
-     * @method valueOf
-     * @return {String} A primitive value version of the error.
-     */
-    valueOf : function () /*:String*/ {
-        return this.toString();
-    }
-
-});
-
-/**
- * ComparisonFailure is subclass of AssertionError that is thrown whenever
- * a comparison between two values fails. It provides mechanisms to retrieve
- * both the expected and actual value.
- *
- * @param {String} message The message to display when the error occurs.
- * @param {Object} expected The expected value.
- * @param {Object} actual The actual value that caused the assertion to fail.
- * @namespace YAHOO.util
- * @extends YAHOO.util.AssertionError
- * @class ComparisonFailure
- * @constructor
- */ 
-YAHOO.util.ComparisonFailure = function (message /*:String*/, expected /*:Object*/, actual /*:Object*/){
-
-    //call superclass
-    arguments.callee.superclass.constructor.call(this, message);
-    
-    /**
-     * The expected value.
-     * @type Object
-     * @property expected
-     */
-    this.expected /*:Object*/ = expected;
-    
-    /**
-     * The actual value.
-     * @type Object
-     * @property actual
-     */
-    this.actual /*:Object*/ = actual;
-    
-    /**
-     * The name of the error that occurred.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "ComparisonFailure";
-    
-};
-
-//inherit methods
-YAHOO.lang.extend(YAHOO.util.ComparisonFailure, YAHOO.util.AssertionError, {
-
-    /**
-     * Returns a fully formatted error for an assertion failure. This message
-     * provides information about the expected and actual values.
-     * @method toString
-     * @return {String} A string describing the error.
-     */
-    getMessage : function () /*:String*/ {
-        return this.message + "\nExpected: " + this.expected + " (" + (typeof this.expected) + ")"  +
-            "\nActual:" + this.actual + " (" + (typeof this.actual) + ")";
-    }
-
-});
-
-/**
- * UnexpectedValue is subclass of AssertionError that is thrown whenever
- * a value was unexpected in its scope. This typically means that a test
- * was performed to determine that a value was *not* equal to a certain
- * value.
- *
- * @param {String} message The message to display when the error occurs.
- * @param {Object} unexpected The unexpected value.
- * @namespace YAHOO.util
- * @extends YAHOO.util.AssertionError
- * @class UnexpectedValue
- * @constructor
- */ 
-YAHOO.util.UnexpectedValue = function (message /*:String*/, unexpected /*:Object*/){
-
-    //call superclass
-    arguments.callee.superclass.constructor.call(this, message);
-    
-    /**
-     * The unexpected value.
-     * @type Object
-     * @property unexpected
-     */
-    this.unexpected /*:Object*/ = unexpected;
-    
-    /**
-     * The name of the error that occurred.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "UnexpectedValue";
-    
-};
-
-//inherit methods
-YAHOO.lang.extend(YAHOO.util.UnexpectedValue, YAHOO.util.AssertionError, {
-
-    /**
-     * Returns a fully formatted error for an assertion failure. The message
-     * contains information about the unexpected value that was encountered.
-     * @method getMessage
-     * @return {String} A string describing the error.
-     */
-    getMessage : function () /*:String*/ {
-        return this.message + "\nUnexpected: " + this.unexpected + " (" + (typeof this.unexpected) + ") ";
-    }
-
-});
-
-/**
- * ShouldFail is subclass of AssertionError that is thrown whenever
- * a test was expected to fail but did not.
- *
- * @param {String} message The message to display when the error occurs.
- * @namespace YAHOO.util
- * @extends YAHOO.util.AssertionError
- * @class ShouldFail
- * @constructor
- */  
-YAHOO.util.ShouldFail = function (message /*:String*/){
-
-    //call superclass
-    arguments.callee.superclass.constructor.call(this, message || "This test should fail but didn't.");
-    
-    /**
-     * The name of the error that occurred.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "ShouldFail";
-    
-};
-
-//inherit methods
-YAHOO.lang.extend(YAHOO.util.ShouldFail, YAHOO.util.AssertionError);
-
-/**
- * ShouldError is subclass of AssertionError that is thrown whenever
- * a test is expected to throw an error but doesn't.
- *
- * @param {String} message The message to display when the error occurs.
- * @namespace YAHOO.util
- * @extends YAHOO.util.AssertionError
- * @class ShouldError
- * @constructor
- */  
-YAHOO.util.ShouldError = function (message /*:String*/){
-
-    //call superclass
-    arguments.callee.superclass.constructor.call(this, message || "This test should have thrown an error but didn't.");
-    
-    /**
-     * The name of the error that occurred.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "ShouldError";
-    
-};
-
-//inherit methods
-YAHOO.lang.extend(YAHOO.util.ShouldError, YAHOO.util.AssertionError);
-
-/**
- * UnexpectedError is subclass of AssertionError that is thrown whenever
- * an error occurs within the course of a test and the test was not expected
- * to throw an error.
- *
- * @param {Error} cause The unexpected error that caused this error to be 
- *                      thrown.
- * @namespace YAHOO.util
- * @extends YAHOO.util.AssertionError
- * @class UnexpectedError
- * @constructor
- */  
-YAHOO.util.UnexpectedError = function (cause /*:Object*/){
-
-    //call superclass
-    arguments.callee.superclass.constructor.call(this, "Unexpected error: " + cause.message);
-    
-    /**
-     * The unexpected error that occurred.
-     * @type Error
-     * @property cause
-     */
-    this.cause /*:Error*/ = cause;
-    
-    /**
-     * The name of the error that occurred.
-     * @type String
-     * @property name
-     */
-    this.name /*:String*/ = "UnexpectedError";
-    
-};
-
-//inherit methods
-YAHOO.lang.extend(YAHOO.util.UnexpectedError, YAHOO.util.AssertionError);
-
-//-----------------------------------------------------------------------------
-// ArrayAssert object
-//-----------------------------------------------------------------------------
-
-/**
- * The ArrayAssert object provides functions to test JavaScript array objects
- * for a variety of cases.
- *
- * @namespace YAHOO.util
- * @class ArrayAssert
- * @static
- */
- 
-YAHOO.util.ArrayAssert = {
-
-    /**
-     * Asserts that a value is present in an array. This uses the triple equals 
-     * sign so no type cohersion may occur.
-     * @param {Object} needle The value that is expected in the array.
-     * @param {Array} haystack An array of values.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method contains
-     * @static
-     */
-    contains : function (needle /*:Object*/, haystack /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-        
-        var found /*:Boolean*/ = false;
-        
-        //begin checking values
-        for (var i=0; i < haystack.length && !found; i++){
-            if (haystack[i] === needle) {
-                found = true;
-            }
-        }
-        
-        if (!found){
-            YAHOO.util.Assert.fail(message || "Value (" + needle + ") not found in array.");
-        }
-    },
-
-    /**
-     * Asserts that a set of values are present in an array. This uses the triple equals 
-     * sign so no type cohersion may occur. For this assertion to pass, all values must
-     * be found.
-     * @param {Object[]} needles An array of values that are expected in the array.
-     * @param {Array} haystack An array of values to check.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method containsItems
-     * @static
-     */
-    containsItems : function (needles /*:Object[]*/, haystack /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-
-        //begin checking values
-        for (var i=0; i < needles.length; i++){
-            this.contains(needles[i], haystack, message);
-        }
-        
-        if (!found){
-            YAHOO.util.Assert.fail(message || "Value not found in array.");
-        }
-    },
-
-    /**
-     * Asserts that a value matching some condition is present in an array. This uses
-     * a function to determine a match.
-     * @param {Function} matcher A function that returns true if the items matches or false if not.
-     * @param {Array} haystack An array of values.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method containsMatch
-     * @static
-     */
-    containsMatch : function (matcher /*:Function*/, haystack /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-        
-        //check for valid matcher
-        if (typeof matcher != "function"){
-            throw new TypeError("ArrayAssert.containsMatch(): First argument must be a function.");
-        }
-        
-        var found /*:Boolean*/ = false;
-        
-        //begin checking values
-        for (var i=0; i < haystack.length && !found; i++){
-            if (matcher(haystack[i])) {
-                found = true;
-            }
-        }
-        
-        if (!found){
-            YAHOO.util.Assert.fail(message || "No match found in array.");
-        }
-    },
-
-    /**
-     * Asserts that a value is not present in an array. This uses the triple equals 
-     * sign so no type cohersion may occur.
-     * @param {Object} needle The value that is expected in the array.
-     * @param {Array} haystack An array of values.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method doesNotContain
-     * @static
-     */
-    doesNotContain : function (needle /*:Object*/, haystack /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-        
-        var found /*:Boolean*/ = false;
-        
-        //begin checking values
-        for (var i=0; i < haystack.length && !found; i++){
-            if (haystack[i] === needle) {
-                found = true;
-            }
-        }
-        
-        if (found){
-            YAHOO.util.Assert.fail(message || "Value found in array.");
-        }
-    },
-
-    /**
-     * Asserts that a set of values are not present in an array. This uses the triple equals 
-     * sign so no type cohersion may occur. For this assertion to pass, all values must
-     * not be found.
-     * @param {Object[]} needles An array of values that are not expected in the array.
-     * @param {Array} haystack An array of values to check.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method doesNotContainItems
-     * @static
-     */
-    doesNotContainItems : function (needles /*:Object[]*/, haystack /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-
-        for (var i=0; i < needles.length; i++){
-            this.doesNotContain(needles[i], haystack, message);
-        }
-
-    },
-        
-    /**
-     * Asserts that no values matching a condition are present in an array. This uses
-     * a function to determine a match.
-     * @param {Function} matcher A function that returns true if the items matches or false if not.
-     * @param {Array} haystack An array of values.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method doesNotContainMatch
-     * @static
-     */
-    doesNotContainMatch : function (matcher /*:Function*/, haystack /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-        
-        //check for valid matcher
-        if (typeof matcher != "function"){
-            throw new TypeError("ArrayAssert.doesNotContainMatch(): First argument must be a function.");
-        }
-
-        var found /*:Boolean*/ = false;
-        
-        //begin checking values
-        for (var i=0; i < haystack.length && !found; i++){
-            if (matcher(haystack[i])) {
-                found = true;
-            }
-        }
-        
-        if (found){
-            YAHOO.util.Assert.fail(message || "Value found in array.");
-        }
-    },
-        
-    /**
-     * Asserts that the given value is contained in an array at the specified index.
-     * This uses the triple equals sign so no type cohersion will occur.
-     * @param {Object} needle The value to look for.
-     * @param {Array} haystack The array to search in.
-     * @param {int} index The index at which the value should exist.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method indexOf
-     * @static
-     */
-    indexOf : function (needle /*:Object*/, haystack /*:Array*/, index /*:int*/, message /*:String*/) /*:Void*/ {
-    
-        //try to find the value in the array
-        for (var i=0; i < haystack.length; i++){
-            if (haystack[i] === needle){
-                YAHOO.util.Assert.areEqual(index, i, message || "Value exists at index " + i + " but should be at index " + index + ".");
-                return;
-            }
-        }
-        
-        //if it makes it here, it wasn't found at all
-        YAHOO.util.Assert.fail(message || "Value doesn't exist in array.");        
-    },
-        
-    /**
-     * Asserts that the values in an array are equal, and in the same position,
-     * as values in another array. This uses the double equals sign
-     * so type cohersion may occur. Note that the array objects themselves
-     * need not be the same for this test to pass.
-     * @param {Array} expected An array of the expected values.
-     * @param {Array} actual Any array of the actual values.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method itemsAreEqual
-     * @static
-     */
-    itemsAreEqual : function (expected /*:Array*/, actual /*:Array*/, 
-                           message /*:String*/) /*:Void*/ {
-        
-        //one may be longer than the other, so get the maximum length
-        var len /*:int*/ = Math.max(expected.length, actual.length);
-        
-        //begin checking values
-        for (var i=0; i < len; i++){
-            YAHOO.util.Assert.areEqual(expected[i], actual[i], message || 
-                    "Values in position " + i + " are not equal.");
-        }
-    },
-    
-    /**
-     * Asserts that the values in an array are equivalent, and in the same position,
-     * as values in another array. This uses a function to determine if the values
-     * are equivalent. Note that the array objects themselves
-     * need not be the same for this test to pass.
-     * @param {Array} expected An array of the expected values.
-     * @param {Array} actual Any array of the actual values.
-     * @param {Function} comparator A function that returns true if the values are equivalent
-     *      or false if not.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @return {Void}
-     * @method itemsAreEquivalent
-     * @static
-     */
-    itemsAreEquivalent : function (expected /*:Array*/, actual /*:Array*/, 
-                           comparator /*:Function*/, message /*:String*/) /*:Void*/ {
-        
-        //make sure the comparator is valid
-        if (typeof comparator != "function"){
-            throw new TypeError("ArrayAssert.itemsAreEquivalent(): Third argument must be a function.");
-        }
-        
-        //one may be longer than the other, so get the maximum length
-        var len /*:int*/ = Math.max(expected.length, actual.length);
-        
-        //begin checking values
-        for (var i=0; i < len; i++){
-            if (!comparator(expected[i], actual[i])){
-                throw new YAHOO.util.ComparisonFailure(message || "Values in position " + i + " are not equivalent.", expected[i], actual[i]);
-            }
-        }
-    },
-    
-    /**
-     * Asserts that an array is empty.
-     * @param {Array} actual The array to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isEmpty
-     * @static
-     */
-    isEmpty : function (actual /*:Array*/, message /*:String*/) /*:Void*/ {        
-        if (actual.length > 0){
-            YAHOO.util.Assert.fail(message || "Array should be empty.");
-        }
-    },    
-    
-    /**
-     * Asserts that an array is not empty.
-     * @param {Array} actual The array to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method isNotEmpty
-     * @static
-     */
-    isNotEmpty : function (actual /*:Array*/, message /*:String*/) /*:Void*/ {        
-        if (actual.length === 0){
-            YAHOO.util.Assert.fail(message || "Array should not be empty.");
-        }
-    },    
-    
-    /**
-     * Asserts that the values in an array are the same, and in the same position,
-     * as values in another array. This uses the triple equals sign
-     * so no type cohersion will occur. Note that the array objects themselves
-     * need not be the same for this test to pass.
-     * @param {Array} expected An array of the expected values.
-     * @param {Array} actual Any array of the actual values.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method itemsAreSame
-     * @static
-     */
-    itemsAreSame : function (expected /*:Array*/, actual /*:Array*/, 
-                          message /*:String*/) /*:Void*/ {
-        
-        //one may be longer than the other, so get the maximum length
-        var len /*:int*/ = Math.max(expected.length, actual.length);
-        
-        //begin checking values
-        for (var i=0; i < len; i++){
-            YAHOO.util.Assert.areSame(expected[i], actual[i], 
-                message || "Values in position " + i + " are not the same.");
-        }
-    },
-    
-    /**
-     * Asserts that the given value is contained in an array at the specified index,
-     * starting from the back of the array.
-     * This uses the triple equals sign so no type cohersion will occur.
-     * @param {Object} needle The value to look for.
-     * @param {Array} haystack The array to search in.
-     * @param {int} index The index at which the value should exist.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method lastIndexOf
-     * @static
-     */
-    lastIndexOf : function (needle /*:Object*/, haystack /*:Array*/, index /*:int*/, message /*:String*/) /*:Void*/ {
-    
-        //try to find the value in the array
-        for (var i=haystack.length; i >= 0; i--){
-            if (haystack[i] === needle){
-                YAHOO.util.Assert.areEqual(index, i, message || "Value exists at index " + i + " but should be at index " + index + ".");
-                return;
-            }
-        }
-        
-        //if it makes it here, it wasn't found at all
-        YAHOO.util.Assert.fail(message || "Value doesn't exist in array.");        
-    }
-    
-};
-
-YAHOO.namespace("util");
-
-
-//-----------------------------------------------------------------------------
-// ObjectAssert object
-//-----------------------------------------------------------------------------
-
-/**
- * The ObjectAssert object provides functions to test JavaScript objects
- * for a variety of cases.
- *
- * @namespace YAHOO.util
- * @class ObjectAssert
- * @static
- */
-YAHOO.util.ObjectAssert = {
-        
-    /**
-     * Asserts that all properties in the object exist in another object.
-     * @param {Object} expected An object with the expected properties.
-     * @param {Object} actual An object with the actual properties.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method propertiesAreEqual
-     * @static
-     */
-    propertiesAreEqual : function (expected /*:Object*/, actual /*:Object*/, 
-                           message /*:String*/) /*:Void*/ {
-        
-        //get all properties in the object
-        var properties /*:Array*/ = [];        
-        for (var property in expected){
-            properties.push(property);
-        }
-        
-        //see if the properties are in the expected object
-        for (var i=0; i < properties.length; i++){
-            YAHOO.util.Assert.isNotUndefined(actual[properties[i]], message || 
-                    "Property'" + properties[i] + "' expected.");
-        }
-
-    },
-    
-    /**
-     * Asserts that an object has a property with the given name.
-     * @param {String} propertyName The name of the property to test.
-     * @param {Object} object The object to search.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method hasProperty
-     * @static
-     */    
-    hasProperty : function (propertyName /*:String*/, object /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (YAHOO.lang.isUndefined(object[propertyName])){
-            YAHOO.util.Assert.fail(message || 
-                    "Property " + propertyName + " not found on object.");
-        }    
-    },
-    
-    /**
-     * Asserts that a property with the given name exists on an object instance (not on its prototype).
-     * @param {String} propertyName The name of the property to test.
-     * @param {Object} object The object to search.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method hasProperty
-     * @static
-     */    
-    hasOwnProperty : function (propertyName /*:String*/, object /*:Object*/, message /*:String*/) /*:Void*/ {
-        if (!YAHOO.lang.hasOwnProperty(object, propertyName)){
-            YAHOO.util.Assert.fail(message || 
-                    "Property " + propertyName + " not found on object instance.");
-        }     
-    }
-};
-
-//-----------------------------------------------------------------------------
-// DateAssert object
-//-----------------------------------------------------------------------------
-
-/**
- * The DateAssert object provides functions to test JavaScript Date objects
- * for a variety of cases.
- *
- * @namespace YAHOO.util
- * @class DateAssert
- * @static
- */
- 
-YAHOO.util.DateAssert = {
-
-    /**
-     * Asserts that a date's month, day, and year are equal to another date's.
-     * @param {Date} expected The expected date.
-     * @param {Date} actual The actual date to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method areEqual
-     * @static
-     */
-    datesAreEqual : function (expected /*:Date*/, actual /*:Date*/, message /*:String*/){
-        if (expected instanceof Date && actual instanceof Date){
-            YAHOO.util.Assert.areEqual(expected.getFullYear(), actual.getFullYear(), message || "Years should be equal.");
-            YAHOO.util.Assert.areEqual(expected.getMonth(), actual.getMonth(), message || "Months should be equal.");
-            YAHOO.util.Assert.areEqual(expected.getDate(), actual.getDate(), message || "Day of month should be equal.");
-        } else {
-            throw new TypeError("DateAssert.datesAreEqual(): Expected and actual values must be Date objects.");
-        }
-    },
-
-    /**
-     * Asserts that a date's hour, minutes, and seconds are equal to another date's.
-     * @param {Date} expected The expected date.
-     * @param {Date} actual The actual date to test.
-     * @param {String} message (Optional) The message to display if the assertion fails.
-     * @method areEqual
-     * @static
-     */
-    timesAreEqual : function (expected /*:Date*/, actual /*:Date*/, message /*:String*/){
-        if (expected instanceof Date && actual instanceof Date){
-            YAHOO.util.Assert.areEqual(expected.getHours(), actual.getHours(), message || "Hours should be equal.");
-            YAHOO.util.Assert.areEqual(expected.getMinutes(), actual.getMinutes(), message || "Minutes should be equal.");
-            YAHOO.util.Assert.areEqual(expected.getSeconds(), actual.getSeconds(), message || "Seconds should be equal.");
-        } else {
-            throw new TypeError("DateAssert.timesAreEqual(): Expected and actual values must be Date objects.");
-        }
-    }
-    
-};
-
-YAHOO.namespace("util");
-
-/**
- * The UserAction object provides functions that simulate events occurring in
- * the browser. Since these are simulated events, they do not behave exactly
- * as regular, user-initiated events do, but can be used to test simple
- * user interactions safely.
- *
- * @namespace YAHOO.util
- * @class UserAction
- * @static
- */
-YAHOO.util.UserAction = {
-
-    //--------------------------------------------------------------------------
-    // Generic event methods
-    //--------------------------------------------------------------------------
-
-    /**
-     * Simulates a key event using the given event information to populate
-     * the generated event object. This method does browser-equalizing
-     * calculations to account for differences in the DOM and IE event models
-     * as well as different browser quirks. Note: keydown causes Safari 2.x to
-     * crash.
-     * @method simulateKeyEvent
-     * @private
-     * @static
-     * @param {HTMLElement} target The target of the given event.
-     * @param {String} type The type of event to fire. This can be any one of
-     *      the following: keyup, keydown, and keypress.
-     * @param {Boolean} bubbles (Optional) Indicates if the event can be
-     *      bubbled up. DOM Level 3 specifies that all key events bubble by
-     *      default. The default is true.
-     * @param {Boolean} cancelable (Optional) Indicates if the event can be
-     *      canceled using preventDefault(). DOM Level 3 specifies that all
-     *      key events can be cancelled. The default 
-     *      is true.
-     * @param {Window} view (Optional) The view containing the target. This is
-     *      typically the window object. The default is window.
-     * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {int} keyCode (Optional) The code for the key that is in use. 
-     *      The default is 0.
-     * @param {int} charCode (Optional) The Unicode code for the character
-     *      associated with the key being used. The default is 0.
-     */
-    simulateKeyEvent : function (target /*:HTMLElement*/, type /*:String*/, 
-                                 bubbles /*:Boolean*/,  cancelable /*:Boolean*/,    
-                                 view /*:Window*/,
-                                 ctrlKey /*:Boolean*/,    altKey /*:Boolean*/, 
-                                 shiftKey /*:Boolean*/,   metaKey /*:Boolean*/, 
-                                 keyCode /*:int*/,        charCode /*:int*/) /*:Void*/                             
-    {
-        //check target
-        target = YAHOO.util.Dom.get(target);        
-        if (!target){
-            throw new Error("simulateKeyEvent(): Invalid target.");
-        }
-        
-        //check event type
-        if (YAHOO.lang.isString(type)){
-            type = type.toLowerCase();
-            switch(type){
-                case "keyup":
-                case "keydown":
-                case "keypress":
-                    break;
-                case "textevent": //DOM Level 3
-                    type = "keypress";
-                    break;
-                    // @TODO was the fallthrough intentional, if so throw error
-                default:
-                    throw new Error("simulateKeyEvent(): Event type '" + type + "' not supported.");
-            }
-        } else {
-            throw new Error("simulateKeyEvent(): Event type must be a string.");
-        }
-        
-        //setup default values
-        if (!YAHOO.lang.isBoolean(bubbles)){
-            bubbles = true; //all key events bubble
-        }
-        if (!YAHOO.lang.isBoolean(cancelable)){
-            cancelable = true; //all key events can be cancelled
-        }
-        if (!YAHOO.lang.isObject(view)){
-            view = window; //view is typically window
-        }
-        if (!YAHOO.lang.isBoolean(ctrlKey)){
-            ctrlKey = false;
-        }
-        if (!YAHOO.lang.isBoolean(altKey)){
-            altKey = false;
-        }
-        if (!YAHOO.lang.isBoolean(shiftKey)){
-            shiftKey = false;
-        }
-        if (!YAHOO.lang.isBoolean(metaKey)){
-            metaKey = false;
-        }
-        if (!YAHOO.lang.isNumber(keyCode)){
-            keyCode = 0;
-        }
-        if (!YAHOO.lang.isNumber(charCode)){
-            charCode = 0; 
-        }
-
-        //try to create a mouse event
-        var customEvent /*:MouseEvent*/ = null;
-            
-        //check for DOM-compliant browsers first
-        if (YAHOO.lang.isFunction(document.createEvent)){
-        
-            try {
-                
-                //try to create key event
-                customEvent = document.createEvent("KeyEvents");
-                
-                /*
-                 * Interesting problem: Firefox implemented a non-standard
-                 * version of initKeyEvent() based on DOM Level 2 specs.
-                 * Key event was removed from DOM Level 2 and re-introduced
-                 * in DOM Level 3 with a different interface. Firefox is the
-                 * only browser with any implementation of Key Events, so for
-                 * now, assume it's Firefox if the above line doesn't error.
-                 */
-                //TODO: Decipher between Firefox's implementation and a correct one.
-                customEvent.initKeyEvent(type, bubbles, cancelable, view, ctrlKey,
-                    altKey, shiftKey, metaKey, keyCode, charCode);       
-                
-            } catch (ex /*:Error*/){
-
-                /*
-                 * If it got here, that means key events aren't officially supported. 
-                 * Safari/WebKit is a real problem now. WebKit 522 won't let you
-                 * set keyCode, charCode, or other properties if you use a
-                 * UIEvent, so we first must try to create a generic event. The
-                 * fun part is that this will throw an error on Safari 2.x. The
-                 * end result is that we need another try...catch statement just to
-                 * deal with this mess.
-                 */
-                try {
-
-                    //try to create generic event - will fail in Safari 2.x
-                    customEvent = document.createEvent("Events");
-
-                } catch (uierror /*:Error*/){
-
-                    //the above failed, so create a UIEvent for Safari 2.x
-                    customEvent = document.createEvent("UIEvents");
-
-                } finally {
-
-                    customEvent.initEvent(type, bubbles, cancelable);
-    
-                    //initialize
-                    customEvent.view = view;
-                    customEvent.altKey = altKey;
-                    customEvent.ctrlKey = ctrlKey;
-                    customEvent.shiftKey = shiftKey;
-                    customEvent.metaKey = metaKey;
-                    customEvent.keyCode = keyCode;
-                    customEvent.charCode = charCode;
-          
-                }          
-             
-            }
-            
-            //fire the event
-            target.dispatchEvent(customEvent);
-
-        } else if (YAHOO.lang.isObject(document.createEventObject)){ //IE
-        
-            //create an IE event object
-            customEvent = document.createEventObject();
-            
-            //assign available properties
-            customEvent.bubbles = bubbles;
-            customEvent.cancelable = cancelable;
-            customEvent.view = view;
-            customEvent.ctrlKey = ctrlKey;
-            customEvent.altKey = altKey;
-            customEvent.shiftKey = shiftKey;
-            customEvent.metaKey = metaKey;
-            
-            /*
-             * IE doesn't support charCode explicitly. CharCode should
-             * take precedence over any keyCode value for accurate
-             * representation.
-             */
-            customEvent.keyCode = (charCode > 0) ? charCode : keyCode;
-            
-            //fire the event
-            target.fireEvent("on" + type, customEvent);  
-                    
-        } else {
-            throw new Error("simulateKeyEvent(): No event simulation framework present.");
-        }
-    },
-
-    /**
-     * Simulates a mouse event using the given event information to populate
-     * the generated event object. This method does browser-equalizing
-     * calculations to account for differences in the DOM and IE event models
-     * as well as different browser quirks.
-     * @method simulateMouseEvent
-     * @private
-     * @static
-     * @param {HTMLElement} target The target of the given event.
-     * @param {String} type The type of event to fire. This can be any one of
-     *      the following: click, dblclick, mousedown, mouseup, mouseout,
-     *      mouseover, and mousemove.
-     * @param {Boolean} bubbles (Optional) Indicates if the event can be
-     *      bubbled up. DOM Level 2 specifies that all mouse events bubble by
-     *      default. The default is true.
-     * @param {Boolean} cancelable (Optional) Indicates if the event can be
-     *      canceled using preventDefault(). DOM Level 2 specifies that all
-     *      mouse events except mousemove can be cancelled. The default 
-     *      is true for all events except mousemove, for which the default 
-     *      is false.
-     * @param {Window} view (Optional) The view containing the target. This is
-     *      typically the window object. The default is window.
-     * @param {int} detail (Optional) The number of times the mouse button has
-     *      been used. The default value is 1.
-     * @param {int} screenX (Optional) The x-coordinate on the screen at which
-     *      point the event occured. The default is 0.
-     * @param {int} screenY (Optional) The y-coordinate on the screen at which
-     *      point the event occured. The default is 0.
-     * @param {int} clientX (Optional) The x-coordinate on the client at which
-     *      point the event occured. The default is 0.
-     * @param {int} clientY (Optional) The y-coordinate on the client at which
-     *      point the event occured. The default is 0.
-     * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
-     *      is pressed while the event is firing. The default is false.
-     * @param {int} button (Optional) The button being pressed while the event
-     *      is executing. The value should be 0 for the primary mouse button
-     *      (typically the left button), 1 for the terciary mouse button
-     *      (typically the middle button), and 2 for the secondary mouse button
-     *      (typically the right button). The default is 0.
-     * @param {HTMLElement} relatedTarget (Optional) For mouseout events,
-     *      this is the element that the mouse has moved to. For mouseover
-     *      events, this is the element that the mouse has moved from. This
-     *      argument is ignored for all other events. The default is null.
-     */
-    simulateMouseEvent : function (target /*:HTMLElement*/, type /*:String*/, 
-                                   bubbles /*:Boolean*/,  cancelable /*:Boolean*/,    
-                                   view /*:Window*/,        detail /*:int*/, 
-                                   screenX /*:int*/,        screenY /*:int*/, 
-                                   clientX /*:int*/,        clientY /*:int*/,       
-                                   ctrlKey /*:Boolean*/,    altKey /*:Boolean*/, 
-                                   shiftKey /*:Boolean*/,   metaKey /*:Boolean*/, 
-                                   button /*:int*/,         relatedTarget /*:HTMLElement*/) /*:Void*/
-    {
-        
-        //check target
-        target = YAHOO.util.Dom.get(target);        
-        if (!target){
-            throw new Error("simulateMouseEvent(): Invalid target.");
-        }
-        
-        //check event type
-        if (YAHOO.lang.isString(type)){
-            type = type.toLowerCase();
-            switch(type){
-                case "mouseover":
-                case "mouseout":
-                case "mousedown":
-                case "mouseup":
-                case "click":
-                case "dblclick":
-                case "mousemove":
-                    break;
-                default:
-                    throw new Error("simulateMouseEvent(): Event type '" + type + "' not supported.");
-            }
-        } else {
-            throw new Error("simulateMouseEvent(): Event type must be a string.");
-        }
-        
-        //setup default values
-        if (!YAHOO.lang.isBoolean(bubbles)){
-            bubbles = true; //all mouse events bubble
-        }
-        if (!YAHOO.lang.isBoolean(cancelable)){
-            cancelable = (type != "mousemove"); //mousemove is the only one that can't be cancelled
-        }
-        if (!YAHOO.lang.isObject(view)){
-            view = window; //view is typically window
-        }
-        if (!YAHOO.lang.isNumber(detail)){
-            detail = 1;  //number of mouse clicks must be at least one
-        }
-        if (!YAHOO.lang.isNumber(screenX)){
-            screenX = 0; 
-        }
-        if (!YAHOO.lang.isNumber(screenY)){
-            screenY = 0; 
-        }
-        if (!YAHOO.lang.isNumber(clientX)){
-            clientX = 0; 
-        }
-        if (!YAHOO.lang.isNumber(clientY)){
-            clientY = 0; 
-        }
-        if (!YAHOO.lang.isBoolean(ctrlKey)){
-            ctrlKey = false;
-        }
-        if (!YAHOO.lang.isBoolean(altKey)){
-            altKey = false;
-        }
-        if (!YAHOO.lang.isBoolean(shiftKey)){
-            shiftKey = false;
-        }
-        if (!YAHOO.lang.isBoolean(metaKey)){
-            metaKey = false;
-        }
-        if (!YAHOO.lang.isNumber(button)){
-            button = 0; 
-        }
-
-        //try to create a mouse event
-        var customEvent /*:MouseEvent*/ = null;
-            
-        //check for DOM-compliant browsers first
-        if (YAHOO.lang.isFunction(document.createEvent)){
-        
-            customEvent = document.createEvent("MouseEvents");
-        
-            //Safari 2.x (WebKit 418) still doesn't implement initMouseEvent()
-            if (customEvent.initMouseEvent){
-                customEvent.initMouseEvent(type, bubbles, cancelable, view, detail,
-                                     screenX, screenY, clientX, clientY, 
-                                     ctrlKey, altKey, shiftKey, metaKey, 
-                                     button, relatedTarget);
-            } else { //Safari
-            
-                //the closest thing available in Safari 2.x is UIEvents
-                customEvent = document.createEvent("UIEvents");
-                customEvent.initEvent(type, bubbles, cancelable);
-                customEvent.view = view;
-                customEvent.detail = detail;
-                customEvent.screenX = screenX;
-                customEvent.screenY = screenY;
-                customEvent.clientX = clientX;
-                customEvent.clientY = clientY;
-                customEvent.ctrlKey = ctrlKey;
-                customEvent.altKey = altKey;
-                customEvent.metaKey = metaKey;
-                customEvent.shiftKey = shiftKey;
-                customEvent.button = button;
-                customEvent.relatedTarget = relatedTarget;
-            }
-            
-            /*
-             * Check to see if relatedTarget has been assigned. Firefox
-             * versions less than 2.0 don't allow it to be assigned via
-             * initMouseEvent() and the property is readonly after event
-             * creation, so in order to keep YAHOO.util.getRelatedTarget()
-             * working, assign to the IE proprietary toElement property
-             * for mouseout event and fromElement property for mouseover
-             * event.
-             */
-            if (relatedTarget && !customEvent.relatedTarget){
-                if (type == "mouseout"){
-                    customEvent.toElement = relatedTarget;
-                } else if (type == "mouseover"){
-                    customEvent.fromElement = relatedTarget;
-                }
-            }
-            
-            //fire the event
-            target.dispatchEvent(customEvent);
-
-        } else if (YAHOO.lang.isObject(document.createEventObject)){ //IE
-        
-            //create an IE event object
-            customEvent = document.createEventObject();
-            
-            //assign available properties
-            customEvent.bubbles = bubbles;
-            customEvent.cancelable = cancelable;
-            customEvent.view = view;
-            customEvent.detail = detail;
-            customEvent.screenX = screenX;
-            customEvent.screenY = screenY;
-            customEvent.clientX = clientX;
-            customEvent.clientY = clientY;
-            customEvent.ctrlKey = ctrlKey;
-            customEvent.altKey = altKey;
-            customEvent.metaKey = metaKey;
-            customEvent.shiftKey = shiftKey;
-
-            //fix button property for IE's wacky implementation
-            switch(button){
-                case 0:
-                    customEvent.button = 1;
-                    break;
-                case 1:
-                    customEvent.button = 4;
-                    break;
-                case 2:
-                    //leave as is
-                    break;
-                default:
-                    customEvent.button = 0;                    
-            }    
-
-            /*
-             * Have to use relatedTarget because IE won't allow assignment
-             * to toElement or fromElement on generic events. This keeps
-             * YAHOO.util.customEvent.getRelatedTarget() functional.
-             */
-            customEvent.relatedTarget = relatedTarget;
-            
-            //fire the event
-            target.fireEvent("on" + type, customEvent);
-                    
-        } else {
-            throw new Error("simulateMouseEvent(): No event simulation framework present.");
-        }
-    },
-   
-    //--------------------------------------------------------------------------
-    // Mouse events
-    //--------------------------------------------------------------------------
-
-    /**
-     * Simulates a mouse event on a particular element.
-     * @param {HTMLElement} target The element to click on.
-     * @param {String} type The type of event to fire. This can be any one of
-     *      the following: click, dblclick, mousedown, mouseup, mouseout,
-     *      mouseover, and mousemove.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method mouseEvent
-     * @static
-     */
-    fireMouseEvent : function (target /*:HTMLElement*/, type /*:String*/, 
-                           options /*:Object*/) /*:Void*/
-    {
-        options = options || {};
-        this.simulateMouseEvent(target, type, options.bubbles,
-            options.cancelable, options.view, options.detail, options.screenX,        
-            options.screenY, options.clientX, options.clientY, options.ctrlKey,
-            options.altKey, options.shiftKey, options.metaKey, options.button,         
-            options.relatedTarget);        
-    },
-
-    /**
-     * Simulates a click on a particular element.
-     * @param {HTMLElement} target The element to click on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method click
-     * @static     
-     */
-    click : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
-        this.fireMouseEvent(target, "click", options);
-    },
-    
-    /**
-     * Simulates a double click on a particular element.
-     * @param {HTMLElement} target The element to double click on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method dblclick
-     * @static
-     */
-    dblclick : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
-        this.fireMouseEvent( target, "dblclick", options);
-    },
-    
-    /**
-     * Simulates a mousedown on a particular element.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method mousedown
-     * @static
-     */
-    mousedown : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
-        this.fireMouseEvent(target, "mousedown", options);
-    },
-    
-    /**
-     * Simulates a mousemove on a particular element.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method mousemove
-     * @static
-     */
-    mousemove : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
-        this.fireMouseEvent(target, "mousemove", options);
-    },
-    
-    /**
-     * Simulates a mouseout event on a particular element. Use "relatedTarget"
-     * on the options object to specify where the mouse moved to.
-     * Quirks: Firefox less than 2.0 doesn't set relatedTarget properly, so
-     * toElement is assigned in its place. IE doesn't allow toElement to be
-     * be assigned, so relatedTarget is assigned in its place. Both of these
-     * concessions allow YAHOO.util.Event.getRelatedTarget() to work correctly
-     * in both browsers.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method mouseout
-     * @static
-     */
-    mouseout : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
-        this.fireMouseEvent(target, "mouseout", options);
-    },
-    
-    /**
-     * Simulates a mouseover event on a particular element. Use "relatedTarget"
-     * on the options object to specify where the mouse moved from.
-     * Quirks: Firefox less than 2.0 doesn't set relatedTarget properly, so
-     * fromElement is assigned in its place. IE doesn't allow fromElement to be
-     * be assigned, so relatedTarget is assigned in its place. Both of these
-     * concessions allow YAHOO.util.Event.getRelatedTarget() to work correctly
-     * in both browsers.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method mouseover
-     * @static
-     */
-    mouseover : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
-        this.fireMouseEvent(target, "mouseover", options);
-    },
-    
-    /**
-     * Simulates a mouseup on a particular element.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method mouseup
-     * @static
-     */
-    mouseup : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
-        this.fireMouseEvent(target, "mouseup", options);
-    },
-    
-    //--------------------------------------------------------------------------
-    // Key events
-    //--------------------------------------------------------------------------
-
-    /**
-     * Fires an event that normally would be fired by the keyboard (keyup,
-     * keydown, keypress). Make sure to specify either keyCode or charCode as
-     * an option.
-     * @private
-     * @param {String} type The type of event ("keyup", "keydown" or "keypress").
-     * @param {HTMLElement} target The target of the event.
-     * @param {Object} options Options for the event. Either keyCode or charCode
-     *                         are required.
-     * @method fireKeyEvent
-     * @static
-     */     
-    fireKeyEvent : function (type /*:String*/, target /*:HTMLElement*/,
-                             options /*:Object*/) /*:Void*/ 
-    {
-        options = options || {};
-        this.simulateKeyEvent(target, type, options.bubbles,
-            options.cancelable, options.view, options.ctrlKey,
-            options.altKey, options.shiftKey, options.metaKey, 
-            options.keyCode, options.charCode);    
-    },
-    
-    /**
-     * Simulates a keydown event on a particular element.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method keydown
-     * @static
-     */
-    keydown : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
-        this.fireKeyEvent("keydown", target, options);
-    },
-    
-    /**
-     * Simulates a keypress on a particular element.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method keypress
-     * @static
-     */
-    keypress : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
-        this.fireKeyEvent("keypress", target, options);
-    },
-    
-    /**
-     * Simulates a keyup event on a particular element.
-     * @param {HTMLElement} target The element to act on.
-     * @param {Object} options Additional event options (use DOM standard names).
-     * @method keyup
-     * @static
-     */
-    keyup : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
-        this.fireKeyEvent("keyup", target, options);
-    }
-    
-
-};
-
-YAHOO.namespace("tool");
-
-//-----------------------------------------------------------------------------
-// TestManager object
-//-----------------------------------------------------------------------------
-
-/**
- * Runs pages containing test suite definitions.
- * @namespace YAHOO.tool
- * @class TestManager
- * @static
- */
-YAHOO.tool.TestManager = {
-
-    /**
-     * Constant for the testpagebegin custom event
-     * @property TEST_PAGE_BEGIN_EVENT
-     * @static
-     * @type string
-     * @final
-     */
-    TEST_PAGE_BEGIN_EVENT /*:String*/ : "testpagebegin",
-
-    /**
-     * Constant for the testpagecomplete custom event
-     * @property TEST_PAGE_COMPLETE_EVENT
-     * @static
-     * @type string
-     * @final
-     */
-    TEST_PAGE_COMPLETE_EVENT /*:String*/ : "testpagecomplete",
-
-    /**
-     * Constant for the testmanagerbegin custom event
-     * @property TEST_MANAGER_BEGIN_EVENT
-     * @static
-     * @type string
-     * @final
-     */
-    TEST_MANAGER_BEGIN_EVENT /*:String*/ : "testmanagerbegin",
-
-    /**
-     * Constant for the testmanagercomplete custom event
-     * @property TEST_MANAGER_COMPLETE_EVENT
-     * @static
-     * @type string
-     * @final
-     */
-    TEST_MANAGER_COMPLETE_EVENT /*:String*/ : "testmanagercomplete",
-
-    //-------------------------------------------------------------------------
-    // Private Properties
-    //-------------------------------------------------------------------------
-    
-    
-    /**
-     * The URL of the page currently being executed.
-     * @type String
-     * @private
-     * @property _curPage
-     * @static
-     */
-    _curPage /*:String*/ : null,
-    
-    /**
-     * The frame used to load and run tests.
-     * @type Window
-     * @private
-     * @property _frame
-     * @static
-     */
-    _frame /*:Window*/ : null,
-    
-    /**
-     * The logger used to output results from the various tests.
-     * @type YAHOO.tool.TestLogger
-     * @private
-     * @property _logger
-     * @static
-     */
-    _logger : null,
-    
-    /**
-     * The timeout ID for the next iteration through the tests.
-     * @type int
-     * @private
-     * @property _timeoutId
-     * @static
-     */
-    _timeoutId /*:int*/ : 0,
-    
-    /**
-     * Array of pages to load.
-     * @type String[]
-     * @private
-     * @property _pages
-     * @static
-     */
-    _pages /*:String[]*/ : [],
-    
-    /**
-     * Aggregated results
-     * @type Object
-     * @private
-     * @property _results
-     * @static
-     */
-    _results: null,
-    
-    //-------------------------------------------------------------------------
-    // Private Methods
-    //-------------------------------------------------------------------------
-    
-    /**
-     * Handles TestRunner.COMPLETE_EVENT, storing the results and beginning
-     * the loop again.
-     * @param {Object} data Data about the event.
-     * @return {Void}
-     * @private
-     * @static
-     */
-    _handleTestRunnerComplete : function (data /*:Object*/) /*:Void*/ {
-
-        this.fireEvent(this.TEST_PAGE_COMPLETE_EVENT, {
-                page: this._curPage,
-                results: data.results
-            });
-    
-        //save results
-        //this._results[this.curPage] = data.results;
-        
-        //process 'em
-        this._processResults(this._curPage, data.results);
-        
-        this._logger.clearTestRunner();
-    
-        //if there's more to do, set a timeout to begin again
-        if (this._pages.length){
-            this._timeoutId = setTimeout(function(){
-                YAHOO.tool.TestManager._run();
-            }, 1000);
-        }
-    },
-    
-    /**
-     * Processes the results of a test page run, outputting log messages
-     * for failed tests.
-     * @return {Void}
-     * @private
-     * @static
-     */
-    _processResults : function (page /*:String*/, results /*:Object*/) /*:Void*/ {
-
-        var r = this._results;
-
-        r.page_results[page] = results;
-
-        if (results.passed) {
-            r.pages_passed++;
-            r.tests_passed += results.passed;
-        }
-
-        if (results.failed) {
-            r.pages_failed++;
-            r.tests_failed += results.failed;
-            r.failed.push(page);
-        } else {
-            r.passed.push(page);
-        }
-
-        if (!this._pages.length) {
-            this.fireEvent(this.TEST_MANAGER_COMPLETE_EVENT, this._results);
-        }
-
-    },
-    
-    /**
-     * Loads the next test page into the iframe.
-     * @return {Void}
-     * @static
-     * @private
-     */
-    _run : function () /*:Void*/ {
-    
-        //set the current page
-        this._curPage = this._pages.shift();
-
-        this.fireEvent(this.TEST_PAGE_BEGIN_EVENT, this._curPage);
-        
-        //load the frame - destroy history in case there are other iframes that
-        //need testing
-        this._frame.location.replace(this._curPage);
-    
-    },
-        
-    //-------------------------------------------------------------------------
-    // Public Methods
-    //-------------------------------------------------------------------------
-    
-    /**
-     * Signals that a test page has been loaded. This should be called from
-     * within the test page itself to notify the TestManager that it is ready.
-     * @return {Void}
-     * @static
-     */
-    load : function () /*:Void*/ {
-        if (parent.YAHOO.tool.TestManager !== this){
-            parent.YAHOO.tool.TestManager.load();
-        } else {
-            
-            if (this._frame) {
-                //assign event handling
-                var TestRunner = this._frame.YAHOO.tool.TestRunner;
-
-                this._logger.setTestRunner(TestRunner);
-                TestRunner.subscribe(TestRunner.COMPLETE_EVENT, this._handleTestRunnerComplete, this, true);
-                
-                //run it
-                TestRunner.run();
-            }
-        }
-    },
-    
-    /**
-     * Sets the pages to be loaded.
-     * @param {String[]} pages An array of URLs to load.
-     * @return {Void}
-     * @static
-     */
-    setPages : function (pages /*:String[]*/) /*:Void*/ {
-        this._pages = pages;
-    },
-    
-    /**
-     * Begins the process of running the tests.
-     * @return {Void}
-     * @static
-     */
-    start : function () /*:Void*/ {
-
-        if (!this._initialized) {
-
-            /**
-             * Fires when loading a test page
-             * @event testpagebegin
-             * @param curPage {string} the page being loaded
-             * @static
-             */
-            this.createEvent(this.TEST_PAGE_BEGIN_EVENT);
-
-            /**
-             * Fires when a test page is complete
-             * @event testpagecomplete
-             * @param obj {page: string, results: object} the name of the
-             * page that was loaded, and the test suite results
-             * @static
-             */
-            this.createEvent(this.TEST_PAGE_COMPLETE_EVENT);
-
-            /**
-             * Fires when the test manager starts running all test pages
-             * @event testmanagerbegin
-             * @static
-             */
-            this.createEvent(this.TEST_MANAGER_BEGIN_EVENT);
-
-            /**
-             * Fires when the test manager finishes running all test pages.  External
-             * test runners should subscribe to this event in order to get the
-             * aggregated test results.
-             * @event testmanagercomplete
-             * @param obj { pages_passed: int, pages_failed: int, tests_passed: int
-             *              tests_failed: int, passed: string[], failed: string[],
-             *              page_results: {} }
-             * @static
-             */
-            this.createEvent(this.TEST_MANAGER_COMPLETE_EVENT);
-
-            //create iframe if not already available
-            if (!this._frame){
-                var frame /*:HTMLElement*/ = document.createElement("iframe");
-                frame.style.visibility = "hidden";
-                frame.style.position = "absolute";
-                document.body.appendChild(frame);
-                this._frame = frame.contentWindow || frame.contentDocument.ownerWindow;
-            }
-            
-            //create test logger if not already available
-            if (!this._logger){
-                this._logger = new YAHOO.tool.TestLogger();
-            }
-
-            this._initialized = true;
-        }
-
-
-        // reset the results cache
-        this._results = {
-            // number of pages that pass
-            pages_passed: 0,
-            // number of pages that fail
-            pages_failed: 0,
-            // total number of tests passed
-            tests_passed: 0,
-            // total number of tests failed
-            tests_failed: 0,
-            // array of pages that passed
-            passed: [],
-            // array of pages that failed
-            failed: [],
-            // map of full results for each page
-            page_results: {}
-        };
-
-        this.fireEvent(this.TEST_MANAGER_BEGIN_EVENT, null);
-        this._run();
-    
-    },
-
-    /**
-     * Stops the execution of tests.
-     * @return {Void}
-     * @static
-     */
-    stop : function () /*:Void*/ {
-        clearTimeout(this._timeoutId);
-    }
-
-};
-
-YAHOO.lang.augmentObject(YAHOO.tool.TestManager, YAHOO.util.EventProvider.prototype);
-
-
-YAHOO.namespace("tool");
-
-//-----------------------------------------------------------------------------
-// TestLogger object
-//-----------------------------------------------------------------------------
-
-/**
- * Displays test execution progress and results, providing filters based on
- * different key events.
- * @namespace YAHOO.tool
- * @class TestLogger
- * @constructor
- * @param {HTMLElement} element (Optional) The element to create the logger in.
- * @param {Object} config (Optional) Configuration options for the logger.
- */
-YAHOO.tool.TestLogger = function (element, config) {
-    YAHOO.tool.TestLogger.superclass.constructor.call(this, element, config);
-    this.init();
-};
-
-YAHOO.lang.extend(YAHOO.tool.TestLogger, YAHOO.widget.LogReader, {
-
-    footerEnabled : true,
-    newestOnTop : false,
-
-    /**
-     * Formats message string to HTML for output to console.
-     * @private
-     * @method formatMsg
-     * @param oLogMsg {Object} Log message object.
-     * @return {String} HTML-formatted message for output to console.
-     */
-    formatMsg : function(message /*:Object*/) {
-    
-        var category /*:String*/ = message.category;        
-        var text /*:String*/ = this.html2Text(message.msg);
-        
-        return "<pre><p><span class=\"" + category + "\">" + category.toUpperCase() + "</span> " + text + "</p></pre>";
-    
-    },
-    
-    //-------------------------------------------------------------------------
-    // Private Methods
-    //-------------------------------------------------------------------------
-    
-    /*
-     * Initializes the logger.
-     * @private
-     */
-    init : function () {
-    
-        //attach to any available TestRunner
-        if (YAHOO.tool.TestRunner){
-            this.setTestRunner(YAHOO.tool.TestRunner);
-        }
-        
-        //hide useless sources
-        this.hideSource("global");
-        this.hideSource("LogReader");
-        
-        //hide useless message categories
-        this.hideCategory("warn");
-        this.hideCategory("window");
-        this.hideCategory("time");
-        
-        //reset the logger
-        this.clearConsole();
-    },
-    
-    /**
-     * Clears the reference to the TestRunner from previous operations. This 
-     * unsubscribes all events and removes the object reference.
-     * @return {Void}
-     * @static
-     */
-    clearTestRunner : function () /*:Void*/ {
-        if (this._runner){
-            this._runner.unsubscribeAll();
-            this._runner = null;
-        }
-    },
-    
-    /**
-     * Sets the source test runner that the logger should monitor.
-     * @param {YAHOO.tool.TestRunner} testRunner The TestRunner to observe.
-     * @return {Void}
-     * @static
-     */
-    setTestRunner : function (testRunner /*:YAHOO.tool.TestRunner*/) /*:Void*/ {
-    
-        if (this._runner){
-            this.clearTestRunner();
-        }
-        
-        this._runner = testRunner;
-        
-        //setup event _handlers
-        testRunner.subscribe(testRunner.TEST_PASS_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.TEST_FAIL_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.TEST_IGNORE_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.BEGIN_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.COMPLETE_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.TEST_SUITE_BEGIN_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.TEST_SUITE_COMPLETE_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.TEST_CASE_BEGIN_EVENT, this._handleTestRunnerEvent, this, true);
-        testRunner.subscribe(testRunner.TEST_CASE_COMPLETE_EVENT, this._handleTestRunnerEvent, this, true);    
-    },
-    
-    //-------------------------------------------------------------------------
-    // Event Handlers
-    //-------------------------------------------------------------------------
-    
-    /**
-     * Handles all TestRunner events, outputting appropriate data into the console.
-     * @param {Object} data The event data object.
-     * @return {Void}
-     * @private
-     */
-    _handleTestRunnerEvent : function (data /*:Object*/) /*:Void*/ {
-    
-        //shortcut variables
-        var TestRunner /*:Object*/ = YAHOO.tool.TestRunner;
-    
-        //data variables
-        var message /*:String*/ = "";
-        var messageType /*:String*/ = "";
-        
-        switch(data.type){
-            case TestRunner.BEGIN_EVENT:
-                message = "Testing began at " + (new Date()).toString() + ".";
-                messageType = "info";
-                break;
-                
-            case TestRunner.COMPLETE_EVENT:
-                message = "Testing completed at " + (new Date()).toString() + ".\nPassed:" + 
-                    data.results.passed + " Failed:" + data.results.failed + " Total:" + data.results.total;
-                messageType = "info";
-                break;
-                
-            case TestRunner.TEST_FAIL_EVENT:
-                message = data.testName + ": " + data.error.getMessage();
-                messageType = "fail";
-                break;
-                
-            case TestRunner.TEST_IGNORE_EVENT:
-                message = data.testName + ": ignored.";
-                messageType = "ignore";
-                break;
-                
-            case TestRunner.TEST_PASS_EVENT:
-                message = data.testName + ": passed.";
-                messageType = "pass";
-                break;
-                
-            case TestRunner.TEST_SUITE_BEGIN_EVENT:
-                message = "Test suite \"" + data.testSuite.name + "\" started.";
-                messageType = "info";
-                break;
-                
-            case TestRunner.TEST_SUITE_COMPLETE_EVENT:
-                message = "Test suite \"" + data.testSuite.name + "\" completed.\nPassed:" + 
-                    data.results.passed + " Failed:" + data.results.failed + " Total:" + data.results.total;
-                messageType = "info";
-                break;
-                
-            case TestRunner.TEST_CASE_BEGIN_EVENT:
-                message = "Test case \"" + data.testCase.name + "\" started.";
-                messageType = "info";
-                break;
-                
-            case TestRunner.TEST_CASE_COMPLETE_EVENT:
-                message = "Test case \"" + data.testCase.name + "\" completed.\nPassed:" + 
-                    data.results.passed + " Failed:" + data.results.failed + " Total:" + data.results.total;
-                messageType = "info";
-                break;
-            default:
-                message = "Unexpected event " + data.type;
-                message = "info";
-        }
-    
-        YAHOO.log(message, messageType, "TestRunner");    
-    }
-    
-});
-
-YAHOO.register("yuitest", YAHOO.tool.TestRunner, {version: "2.4.1", build: "742"});

Added: trunk/root/static/yui/yuitest/yuitest-debug.js
===================================================================
--- trunk/root/static/yui/yuitest/yuitest-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/yuitest-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,3313 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+YAHOO.namespace("tool");
+
+//-----------------------------------------------------------------------------
+// TestCase object
+//-----------------------------------------------------------------------------
+
+/**
+ * Test case containing various tests to run.
+ * @param template An object containing any number of test methods, other methods,
+ *                 an optional name, and anything else the test case needs.
+ * @class TestCase
+ * @namespace YAHOO.tool
+ * @constructor
+ */
+YAHOO.tool.TestCase = function (template /*:Object*/) {
+    
+    /**
+     * Special rules for the test case. Possible subobjects
+     * are fail, for tests that should fail, and error, for
+     * tests that should throw an error.
+     */
+    this._should /*:Object*/ = {};
+    
+    //copy over all properties from the template to this object
+    for (var prop in template) {
+        this[prop] = template[prop];
+    }    
+    
+    //check for a valid name
+    if (!YAHOO.lang.isString(this.name)){
+        /**
+         * Name for the test case.
+         */
+        this.name /*:String*/ = YAHOO.util.Dom.generateId(null, "testCase");
+    }
+
+};
+
+
+YAHOO.tool.TestCase.prototype = {  
+
+    /**
+     * Resumes a paused test and runs the given function.
+     * @param {Function} segment (Optional) The function to run.
+     *      If omitted, the test automatically passes.
+     * @return {Void}
+     * @method resume
+     */
+    resume : function (segment /*:Function*/) /*:Void*/ {
+        YAHOO.tool.TestRunner.resume(segment);
+    },
+
+    /**
+     * Causes the test case to wait a specified amount of time and then
+     * continue executing the given code.
+     * @param {Function} segment (Optional) The function to run after the delay.
+     *      If omitted, the TestRunner will wait until resume() is called.
+     * @param {int} delay (Optional) The number of milliseconds to wait before running
+     *      the function. If omitted, defaults to zero.
+     * @return {Void}
+     * @method wait
+     */
+    wait : function (segment /*:Function*/, delay /*:int*/) /*:Void*/{
+        throw new YAHOO.tool.TestCase.Wait(segment, delay);
+    },
+
+    //-------------------------------------------------------------------------
+    // Stub Methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Function to run before each test is executed.
+     * @return {Void}
+     * @method setUp
+     */
+    setUp : function () /*:Void*/ {
+    },
+    
+    /**
+     * Function to run after each test is executed.
+     * @return {Void}
+     * @method tearDown
+     */
+    tearDown: function () /*:Void*/ {    
+    }
+};
+
+/**
+ * Represents a stoppage in test execution to wait for an amount of time before
+ * continuing.
+ * @param {Function} segment A function to run when the wait is over.
+ * @param {int} delay The number of milliseconds to wait before running the code.
+ * @class Wait
+ * @namespace YAHOO.tool.TestCase
+ * @constructor
+ *
+ */
+YAHOO.tool.TestCase.Wait = function (segment /*:Function*/, delay /*:int*/) {
+    
+    /**
+     * The segment of code to run when the wait is over.
+     * @type Function
+     * @property segment
+     */
+    this.segment /*:Function*/ = (YAHOO.lang.isFunction(segment) ? segment : null);
+
+    /**
+     * The delay before running the segment of code.
+     * @type int
+     * @property delay
+     */
+    this.delay /*:int*/ = (YAHOO.lang.isNumber(delay) ? delay : 0);
+
+};
+
+YAHOO.namespace("tool");
+
+
+//-----------------------------------------------------------------------------
+// TestSuite object
+//-----------------------------------------------------------------------------
+
+/**
+ * A test suite that can contain a collection of TestCase and TestSuite objects.
+ * @param {String||Object} data The name of the test suite or an object containing
+ *      a name property as well as setUp and tearDown methods.
+ * @namespace YAHOO.tool
+ * @class TestSuite
+ * @constructor
+ */
+YAHOO.tool.TestSuite = function (data /*:String||Object*/) {
+
+    /**
+     * The name of the test suite.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "";
+
+    /**
+     * Array of test suites and
+     * @private
+     */
+    this.items /*:Array*/ = [];
+
+    //initialize the properties
+    if (YAHOO.lang.isString(data)){
+        this.name = data;
+    } else if (YAHOO.lang.isObject(data)){
+        YAHOO.lang.augmentObject(this, data, true);
+    }
+
+    //double-check name
+    if (this.name === ""){
+        this.name = YAHOO.util.Dom.generateId(null, "testSuite");
+    }
+
+};
+
+YAHOO.tool.TestSuite.prototype = {
+    
+    /**
+     * Adds a test suite or test case to the test suite.
+     * @param {YAHOO.tool.TestSuite||YAHOO.tool.TestCase} testObject The test suite or test case to add.
+     * @return {Void}
+     * @method add
+     */
+    add : function (testObject /*:YAHOO.tool.TestSuite*/) /*:Void*/ {
+        if (testObject instanceof YAHOO.tool.TestSuite || testObject instanceof YAHOO.tool.TestCase) {
+            this.items.push(testObject);
+        }
+    },
+    
+    //-------------------------------------------------------------------------
+    // Stub Methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Function to run before each test is executed.
+     * @return {Void}
+     * @method setUp
+     */
+    setUp : function () /*:Void*/ {
+    },
+    
+    /**
+     * Function to run after each test is executed.
+     * @return {Void}
+     * @method tearDown
+     */
+    tearDown: function () /*:Void*/ {
+    }
+    
+};
+
+YAHOO.namespace("tool");
+
+/**
+ * The YUI test tool
+ * @module yuitest
+ * @namespace YAHOO.tool
+ * @requires yahoo,dom,event,logger
+ */
+
+
+//-----------------------------------------------------------------------------
+// TestRunner object
+//-----------------------------------------------------------------------------
+
+/**
+ * Runs test suites and test cases, providing events to allowing for the
+ * interpretation of test results.
+ * @namespace YAHOO.tool
+ * @class TestRunner
+ * @static
+ */
+YAHOO.tool.TestRunner = (function(){
+
+    /**
+     * A node in the test tree structure. May represent a TestSuite, TestCase, or
+     * test function.
+     * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.
+     * @class TestNode
+     * @constructor
+     * @private
+     */
+    function TestNode(testObject /*:Variant*/){
+    
+        /**
+         * The TestSuite, TestCase, or test function represented by this node.
+         * @type Variant
+         * @property testObject
+         */
+        this.testObject = testObject;
+        
+        /**
+         * Pointer to this node's first child.
+         * @type TestNode
+         * @property firstChild
+         */        
+        this.firstChild /*:TestNode*/ = null;
+        
+        /**
+         * Pointer to this node's last child.
+         * @type TestNode
+         * @property lastChild
+         */        
+        this.lastChild = null;
+        
+        /**
+         * Pointer to this node's parent.
+         * @type TestNode
+         * @property parent
+         */        
+        this.parent = null; 
+   
+        /**
+         * Pointer to this node's next sibling.
+         * @type TestNode
+         * @property next
+         */        
+        this.next = null;
+        
+        /**
+         * Test results for this test object.
+         * @type object
+         * @property results
+         */                
+        this.results /*:Object*/ = {
+            passed : 0,
+            failed : 0,
+            total : 0,
+            ignored : 0
+        };
+        
+        //initialize results
+        if (testObject instanceof YAHOO.tool.TestSuite){
+            this.results.type = "testsuite";
+            this.results.name = testObject.name;
+        } else if (testObject instanceof YAHOO.tool.TestCase){
+            this.results.type = "testcase";
+            this.results.name = testObject.name;
+        }
+       
+    }
+    
+    TestNode.prototype = {
+    
+        /**
+         * Appends a new test object (TestSuite, TestCase, or test function name) as a child
+         * of this node.
+         * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.
+         * @return {Void}
+         */
+        appendChild : function (testObject /*:Variant*/) /*:Void*/{
+            var node = new TestNode(testObject);
+            if (this.firstChild === null){
+                this.firstChild = this.lastChild = node;
+            } else {
+                this.lastChild.next = node;
+                this.lastChild = node;
+            }
+            node.parent = this;
+            return node;
+        }       
+    };
+
+    function TestRunner(){
+    
+        //inherit from EventProvider
+        TestRunner.superclass.constructor.apply(this,arguments);
+        
+        /**
+         * Suite on which to attach all TestSuites and TestCases to be run.
+         * @type YAHOO.tool.TestSuite
+         * @property masterSuite
+         * @private
+         */
+        this.masterSuite /*:YAHOO.tool.TestSuite*/ = new YAHOO.tool.TestSuite("YUI Test Results");        
+
+        /**
+         * Pointer to the current node in the test tree.
+         * @type TestNode
+         * @private
+         * @property _cur
+         */
+        this._cur = null;
+        
+        /**
+         * Pointer to the root node in the test tree.
+         * @type TestNode
+         * @private
+         * @property _root
+         */
+        this._root = null;
+        
+        //create events
+        var events /*:Array*/ = [
+            this.TEST_CASE_BEGIN_EVENT,
+            this.TEST_CASE_COMPLETE_EVENT,
+            this.TEST_SUITE_BEGIN_EVENT,
+            this.TEST_SUITE_COMPLETE_EVENT,
+            this.TEST_PASS_EVENT,
+            this.TEST_FAIL_EVENT,
+            this.TEST_IGNORE_EVENT,
+            this.COMPLETE_EVENT,
+            this.BEGIN_EVENT
+        ];
+        for (var i=0; i < events.length; i++){
+            this.createEvent(events[i], { scope: this });
+        }       
+   
+    }
+    
+    YAHOO.lang.extend(TestRunner, YAHOO.util.EventProvider, {
+    
+        //-------------------------------------------------------------------------
+        // Constants
+        //-------------------------------------------------------------------------
+         
+        /**
+         * Fires when a test case is opened but before the first 
+         * test is executed.
+         * @event testcasebegin
+         */         
+        TEST_CASE_BEGIN_EVENT /*:String*/ : "testcasebegin",
+        
+        /**
+         * Fires when all tests in a test case have been executed.
+         * @event testcasecomplete
+         */        
+        TEST_CASE_COMPLETE_EVENT /*:String*/ : "testcasecomplete",
+        
+        /**
+         * Fires when a test suite is opened but before the first 
+         * test is executed.
+         * @event testsuitebegin
+         */        
+        TEST_SUITE_BEGIN_EVENT /*:String*/ : "testsuitebegin",
+        
+        /**
+         * Fires when all test cases in a test suite have been
+         * completed.
+         * @event testsuitecomplete
+         */        
+        TEST_SUITE_COMPLETE_EVENT /*:String*/ : "testsuitecomplete",
+        
+        /**
+         * Fires when a test has passed.
+         * @event pass
+         */        
+        TEST_PASS_EVENT /*:String*/ : "pass",
+        
+        /**
+         * Fires when a test has failed.
+         * @event fail
+         */        
+        TEST_FAIL_EVENT /*:String*/ : "fail",
+        
+        /**
+         * Fires when a test has been ignored.
+         * @event ignore
+         */        
+        TEST_IGNORE_EVENT /*:String*/ : "ignore",
+        
+        /**
+         * Fires when all test suites and test cases have been completed.
+         * @event complete
+         */        
+        COMPLETE_EVENT /*:String*/ : "complete",
+        
+        /**
+         * Fires when the run() method is called.
+         * @event begin
+         */        
+        BEGIN_EVENT /*:String*/ : "begin",    
+        
+        //-------------------------------------------------------------------------
+        // Test Tree-Related Methods
+        //-------------------------------------------------------------------------
+
+        /**
+         * Adds a test case to the test tree as a child of the specified node.
+         * @param {TestNode} parentNode The node to add the test case to as a child.
+         * @param {YAHOO.tool.TestCase} testCase The test case to add.
+         * @return {Void}
+         * @static
+         * @private
+         * @method _addTestCaseToTestTree
+         */
+       _addTestCaseToTestTree : function (parentNode /*:TestNode*/, testCase /*:YAHOO.tool.TestCase*/) /*:Void*/{
+            
+            //add the test suite
+            var node = parentNode.appendChild(testCase);
+            
+            //iterate over the items in the test case
+            for (var prop in testCase){
+                if (prop.indexOf("test") === 0 && YAHOO.lang.isFunction(testCase[prop])){
+                    node.appendChild(prop);
+                }
+            }
+         
+        },
+        
+        /**
+         * Adds a test suite to the test tree as a child of the specified node.
+         * @param {TestNode} parentNode The node to add the test suite to as a child.
+         * @param {YAHOO.tool.TestSuite} testSuite The test suite to add.
+         * @return {Void}
+         * @static
+         * @private
+         * @method _addTestSuiteToTestTree
+         */
+        _addTestSuiteToTestTree : function (parentNode /*:TestNode*/, testSuite /*:YAHOO.tool.TestSuite*/) /*:Void*/ {
+            
+            //add the test suite
+            var node = parentNode.appendChild(testSuite);
+            
+            //iterate over the items in the master suite
+            for (var i=0; i < testSuite.items.length; i++){
+                if (testSuite.items[i] instanceof YAHOO.tool.TestSuite) {
+                    this._addTestSuiteToTestTree(node, testSuite.items[i]);
+                } else if (testSuite.items[i] instanceof YAHOO.tool.TestCase) {
+                    this._addTestCaseToTestTree(node, testSuite.items[i]);
+                }                   
+            }            
+        },
+        
+        /**
+         * Builds the test tree based on items in the master suite. The tree is a hierarchical
+         * representation of the test suites, test cases, and test functions. The resulting tree
+         * is stored in _root and the pointer _cur is set to the root initially.
+         * @return {Void}
+         * @static
+         * @private
+         * @method _buildTestTree
+         */
+        _buildTestTree : function () /*:Void*/ {
+        
+            this._root = new TestNode(this.masterSuite);
+            this._cur = this._root;
+            
+            //iterate over the items in the master suite
+            for (var i=0; i < this.masterSuite.items.length; i++){
+                if (this.masterSuite.items[i] instanceof YAHOO.tool.TestSuite) {
+                    this._addTestSuiteToTestTree(this._root, this.masterSuite.items[i]);
+                } else if (this.masterSuite.items[i] instanceof YAHOO.tool.TestCase) {
+                    this._addTestCaseToTestTree(this._root, this.masterSuite.items[i]);
+                }                   
+            }            
+        
+        }, 
+    
+        //-------------------------------------------------------------------------
+        // Private Methods
+        //-------------------------------------------------------------------------
+        
+        /**
+         * Handles the completion of a test object's tests. Tallies test results 
+         * from one level up to the next.
+         * @param {TestNode} node The TestNode representing the test object.
+         * @return {Void}
+         * @method _handleTestObjectComplete
+         * @private
+         */
+        _handleTestObjectComplete : function (node /*:TestNode*/) /*:Void*/ {
+            if (YAHOO.lang.isObject(node.testObject)){
+                node.parent.results.passed += node.results.passed;
+                node.parent.results.failed += node.results.failed;
+                node.parent.results.total += node.results.total;                
+                node.parent.results.ignored += node.results.ignored;                
+                node.parent.results[node.testObject.name] = node.results;
+            
+                if (node.testObject instanceof YAHOO.tool.TestSuite){
+                    node.testObject.tearDown();
+                    this.fireEvent(this.TEST_SUITE_COMPLETE_EVENT, { testSuite: node.testObject, results: node.results});
+                } else if (node.testObject instanceof YAHOO.tool.TestCase){
+                    this.fireEvent(this.TEST_CASE_COMPLETE_EVENT, { testCase: node.testObject, results: node.results});
+                }      
+            } 
+        },                
+        
+        //-------------------------------------------------------------------------
+        // Navigation Methods
+        //-------------------------------------------------------------------------
+        
+        /**
+         * Retrieves the next node in the test tree.
+         * @return {TestNode} The next node in the test tree or null if the end is reached.
+         * @private
+         * @static
+         * @method _next
+         */
+        _next : function () /*:TestNode*/ {
+        
+            if (this._cur.firstChild) {
+                this._cur = this._cur.firstChild;
+            } else if (this._cur.next) {
+                this._cur = this._cur.next;            
+            } else {
+                while (this._cur && !this._cur.next && this._cur !== this._root){
+                    this._handleTestObjectComplete(this._cur);
+                    this._cur = this._cur.parent;
+                }
+                
+                if (this._cur == this._root){
+                    this._cur.results.type = "report";
+                    this._cur.results.timestamp = (new Date()).toLocaleString();
+                    this.fireEvent(this.COMPLETE_EVENT, { results: this._cur.results});
+                    this._cur = null;
+                } else {
+                    this._handleTestObjectComplete(this._cur);               
+                    this._cur = this._cur.next;                
+                }
+            }
+        
+            return this._cur;
+        },
+        
+        /**
+         * Runs a test case or test suite, returning the results.
+         * @param {YAHOO.tool.TestCase|YAHOO.tool.TestSuite} testObject The test case or test suite to run.
+         * @return {Object} Results of the execution with properties passed, failed, and total.
+         * @private
+         * @method _run
+         * @static
+         */
+        _run : function () /*:Void*/ {
+        
+            //flag to indicate if the TestRunner should wait before continuing
+            var shouldWait /*:Boolean*/ = false;
+            
+            //get the next test node
+            var node = this._next();
+            
+            if (node !== null) {
+                var testObject = node.testObject;
+                
+                //figure out what to do
+                if (YAHOO.lang.isObject(testObject)){
+                    if (testObject instanceof YAHOO.tool.TestSuite){
+                        this.fireEvent(this.TEST_SUITE_BEGIN_EVENT, { testSuite: testObject });
+                        testObject.setUp();
+                    } else if (testObject instanceof YAHOO.tool.TestCase){
+                        this.fireEvent(this.TEST_CASE_BEGIN_EVENT, { testCase: testObject });
+                    }
+                    
+                    //some environments don't support setTimeout
+                    if (typeof setTimeout != "undefined"){                    
+                        setTimeout(function(){
+                            YAHOO.tool.TestRunner._run();
+                        }, 0);
+                    } else {
+                        this._run();
+                    }
+                } else {
+                    this._runTest(node);
+                }
+
+            }
+        },
+        
+        _resumeTest : function (segment /*:Function*/) /*:Void*/ {
+        
+            //get relevant information
+            var node /*:TestNode*/ = this._cur;
+            var testName /*:String*/ = node.testObject;
+            var testCase /*:YAHOO.tool.TestCase*/ = node.parent.testObject;
+            
+            //get the "should" test cases
+            var shouldFail /*:Object*/ = (testCase._should.fail || {})[testName];
+            var shouldError /*:Object*/ = (testCase._should.error || {})[testName];
+            
+            //variable to hold whether or not the test failed
+            var failed /*:Boolean*/ = false;
+            var error /*:Error*/ = null;
+                
+            //try the test
+            try {
+            
+                //run the test
+                segment.apply(testCase);
+                
+                //if it should fail, and it got here, then it's a fail because it didn't
+                if (shouldFail){
+                    error = new YAHOO.util.ShouldFail();
+                    failed = true;
+                } else if (shouldError){
+                    error = new YAHOO.util.ShouldError();
+                    failed = true;
+                }
+                           
+            } catch (thrown /*:Error*/){
+                if (thrown instanceof YAHOO.util.AssertionError) {
+                    if (!shouldFail){
+                        error = thrown;
+                        failed = true;
+                    }
+                } else if (thrown instanceof YAHOO.tool.TestCase.Wait){
+                
+                    if (YAHOO.lang.isFunction(thrown.segment)){
+                        if (YAHOO.lang.isNumber(thrown.delay)){
+                        
+                            //some environments don't support setTimeout
+                            if (typeof setTimeout != "undefined"){
+                                setTimeout(function(){
+                                    YAHOO.tool.TestRunner._resumeTest(thrown.segment);
+                                }, thrown.delay);
+                            } else {
+                                throw new Error("Asynchronous tests not supported in this environment.");
+                            }
+                        }
+                    }
+                    
+                    return;
+                
+                } else {
+                    //first check to see if it should error
+                    if (!shouldError) {                        
+                        error = new YAHOO.util.UnexpectedError(thrown);
+                        failed = true;
+                    } else {
+                        //check to see what type of data we have
+                        if (YAHOO.lang.isString(shouldError)){
+                            
+                            //if it's a string, check the error message
+                            if (thrown.message != shouldError){
+                                error = new YAHOO.util.UnexpectedError(thrown);
+                                failed = true;                                    
+                            }
+                        } else if (YAHOO.lang.isFunction(shouldError)){
+                        
+                            //if it's a function, see if the error is an instance of it
+                            if (!(thrown instanceof shouldError)){
+                                error = new YAHOO.util.UnexpectedError(thrown);
+                                failed = true;
+                            }
+                        
+                        } else if (YAHOO.lang.isObject(shouldError)){
+                        
+                            //if it's an object, check the instance and message
+                            if (!(thrown instanceof shouldError.constructor) || 
+                                    thrown.message != shouldError.message){
+                                error = new YAHOO.util.UnexpectedError(thrown);
+                                failed = true;                                    
+                            }
+                        
+                        }
+                    
+                    }
+                }
+                
+            }
+            
+            //fireEvent appropriate event
+            if (failed) {
+                this.fireEvent(this.TEST_FAIL_EVENT, { testCase: testCase, testName: testName, error: error });
+            } else {
+                this.fireEvent(this.TEST_PASS_EVENT, { testCase: testCase, testName: testName });
+            }
+            
+            //run the tear down
+            testCase.tearDown();
+            
+            //update results
+            node.parent.results[testName] = { 
+                result: failed ? "fail" : "pass",
+                message: error ? error.getMessage() : "Test passed",
+                type: "test",
+                name: testName
+            };
+            
+            if (failed){
+                node.parent.results.failed++;
+            } else {
+                node.parent.results.passed++;
+            }
+            node.parent.results.total++;
+
+            //set timeout not supported in all environments
+            if (typeof setTimeout != "undefined"){
+                setTimeout(function(){
+                    YAHOO.tool.TestRunner._run();
+                }, 0);
+            } else {
+                this._run();
+            }
+        
+        },
+                
+        /**
+         * Runs a single test based on the data provided in the node.
+         * @param {TestNode} node The TestNode representing the test to run.
+         * @return {Void}
+         * @static
+         * @private
+         * @name _runTest
+         */
+        _runTest : function (node /*:TestNode*/) /*:Void*/ {
+        
+            //get relevant information
+            var testName /*:String*/ = node.testObject;
+            var testCase /*:YAHOO.tool.TestCase*/ = node.parent.testObject;
+            var test /*:Function*/ = testCase[testName];
+            
+            //get the "should" test cases
+            var shouldIgnore /*:Object*/ = (testCase._should.ignore || {})[testName];
+            
+            //figure out if the test should be ignored or not
+            if (shouldIgnore){
+            
+                //update results
+                node.parent.results[testName] = { 
+                    result: "ignore",
+                    message: "Test ignored",
+                    type: "test",
+                    name: testName
+                };
+                
+                node.parent.results.ignored++;
+                node.parent.results.total++;
+            
+                this.fireEvent(this.TEST_IGNORE_EVENT, { testCase: testCase, testName: testName });
+                
+                //some environments don't support setTimeout
+                if (typeof setTimeout != "undefined"){                    
+                    setTimeout(function(){
+                        YAHOO.tool.TestRunner._run();
+                    }, 0);              
+                } else {
+                    this._run();
+                }
+
+            } else {
+            
+                //run the setup
+                testCase.setUp();
+                
+                //now call the body of the test
+                this._resumeTest(test);                
+            }
+
+        },        
+        
+        //-------------------------------------------------------------------------
+        // Protected Methods
+        //-------------------------------------------------------------------------   
+    
+        /*
+         * Fires events for the TestRunner. This overrides the default fireEvent()
+         * method from EventProvider to add the type property to the data that is
+         * passed through on each event call.
+         * @param {String} type The type of event to fire.
+         * @param {Object} data (Optional) Data for the event.
+         * @method fireEvent
+         * @static
+         * @protected
+         */
+        fireEvent : function (type /*:String*/, data /*:Object*/) /*:Void*/ {
+            data = data || {};
+            data.type = type;
+            TestRunner.superclass.fireEvent.call(this, type, data);
+        },
+        
+        //-------------------------------------------------------------------------
+        // Public Methods
+        //-------------------------------------------------------------------------   
+    
+        /**
+         * Adds a test suite or test case to the list of test objects to run.
+         * @param testObject Either a TestCase or a TestSuite that should be run.
+         * @return {Void}
+         * @method add
+         * @static
+         */
+        add : function (testObject /*:Object*/) /*:Void*/ {
+            this.masterSuite.add(testObject);
+        },
+        
+        /**
+         * Removes all test objects from the runner.
+         * @return {Void}
+         * @method clear
+         * @static
+         */
+        clear : function () /*:Void*/ {
+            this.masterSuite.items = [];
+        },
+        
+        /**
+         * Resumes the TestRunner after wait() was called.
+         * @param {Function} segment The function to run as the rest
+         *      of the haulted test.
+         * @return {Void}
+         * @method resume
+         * @static
+         */
+        resume : function (segment /*:Function*/) /*:Void*/ {
+            this._resumeTest(segment || function(){});
+        },
+    
+        /**
+         * Runs the test suite.
+         * @return {Void}
+         * @method run
+         * @static
+         */
+        run : function (testObject /*:Object*/) /*:Void*/ {
+            
+            //pointer to runner to avoid scope issues 
+            var runner = YAHOO.tool.TestRunner;
+
+            //build the test tree
+            runner._buildTestTree();
+            
+            //fire the begin event
+            runner.fireEvent(runner.BEGIN_EVENT);
+       
+            //begin the testing
+            runner._run();
+        }    
+    });
+    
+    return new TestRunner();
+    
+})();
+
+YAHOO.namespace("util");
+
+//-----------------------------------------------------------------------------
+// Assert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The Assert object provides functions to test JavaScript values against
+ * known and expected results. Whenever a comparison (assertion) fails,
+ * an error is thrown.
+ *
+ * @namespace YAHOO.util
+ * @class Assert
+ * @static
+ */
+YAHOO.util.Assert = {
+
+    //-------------------------------------------------------------------------
+    // Helper Methods
+    //-------------------------------------------------------------------------
+    
+    /**
+     * Formats a message so that it can contain the original assertion message
+     * in addition to the custom message.
+     * @param {String} customMessage The message passed in by the developer.
+     * @param {String} defaultMessage The message created by the error by default.
+     * @return {String} The final error message, containing either or both.
+     * @protected
+     * @static
+     * @method _formatMessage
+     */
+    _formatMessage : function (customMessage /*:String*/, defaultMessage /*:String*/) /*:String*/ {
+        var message = customMessage;
+        if (YAHOO.lang.isString(customMessage) && customMessage.length > 0){
+            return YAHOO.lang.substitute(customMessage, { message: defaultMessage });
+        } else {
+            return defaultMessage;
+        }        
+    },
+    
+    //-------------------------------------------------------------------------
+    // Generic Assertion Methods
+    //-------------------------------------------------------------------------
+    
+    /** 
+     * Forces an assertion error to occur.
+     * @param {String} message (Optional) The message to display with the failure.
+     * @method fail
+     * @static
+     */
+    fail : function (message /*:String*/) /*:Void*/ {
+        throw new YAHOO.util.AssertionError(this._formatMessage(message, "Test force-failed."));
+    },       
+    
+    //-------------------------------------------------------------------------
+    // Equality Assertion Methods
+    //-------------------------------------------------------------------------    
+    
+    /**
+     * Asserts that a value is equal to another. This uses the double equals sign
+     * so type cohersion may occur.
+     * @param {Object} expected The expected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areEqual
+     * @static
+     */
+    areEqual : function (expected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (expected != actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Values should be equal."), expected, actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is not equal to another. This uses the double equals sign
+     * so type cohersion may occur.
+     * @param {Object} unexpected The unexpected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areNotEqual
+     * @static
+     */
+    areNotEqual : function (unexpected /*:Object*/, actual /*:Object*/, 
+                         message /*:String*/) /*:Void*/ {
+        if (unexpected == actual) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be equal."), unexpected);
+        }
+    },
+    
+    /**
+     * Asserts that a value is not the same as another. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} unexpected The unexpected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areNotSame
+     * @static
+     */
+    areNotSame : function (unexpected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (unexpected === actual) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be the same."), unexpected);
+        }
+    },
+
+    /**
+     * Asserts that a value is the same as another. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} expected The expected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areSame
+     * @static
+     */
+    areSame : function (expected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (expected !== actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Values should be the same."), expected, actual);
+        }
+    },    
+    
+    //-------------------------------------------------------------------------
+    // Boolean Assertion Methods
+    //-------------------------------------------------------------------------    
+    
+    /**
+     * Asserts that a value is false. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isFalse
+     * @static
+     */
+    isFalse : function (actual /*:Boolean*/, message /*:String*/) {
+        if (false !== actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be false."), false, actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is true. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isTrue
+     * @static
+     */
+    isTrue : function (actual /*:Boolean*/, message /*:String*/) /*:Void*/ {
+        if (true !== actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be true."), true, actual);
+        }
+
+    },
+    
+    //-------------------------------------------------------------------------
+    // Special Value Assertion Methods
+    //-------------------------------------------------------------------------    
+    
+    /**
+     * Asserts that a value is not a number.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNaN
+     * @static
+     */
+    isNaN : function (actual /*:Object*/, message /*:String*/) /*:Void*/{
+        if (!isNaN(actual)){
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be NaN."), NaN, actual);
+        }    
+    },
+    
+    /**
+     * Asserts that a value is not the special NaN value.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotNaN
+     * @static
+     */
+    isNotNaN : function (actual /*:Object*/, message /*:String*/) /*:Void*/{
+        if (isNaN(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be NaN."), NaN);
+        }    
+    },
+    
+    /**
+     * Asserts that a value is not null. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotNull
+     * @static
+     */
+    isNotNull : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (YAHOO.lang.isNull(actual)) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be null."), null);
+        }
+    },
+
+    /**
+     * Asserts that a value is not undefined. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotUndefined
+     * @static
+     */
+    isNotUndefined : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (YAHOO.lang.isUndefined(actual)) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should not be undefined."), undefined);
+        }
+    },
+
+    /**
+     * Asserts that a value is null. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNull
+     * @static
+     */
+    isNull : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isNull(actual)) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be null."), null, actual);
+        }
+    },
+        
+    /**
+     * Asserts that a value is undefined. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isUndefined
+     * @static
+     */
+    isUndefined : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isUndefined(actual)) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be undefined."), undefined, actual);
+        }
+    },    
+    
+    //--------------------------------------------------------------------------
+    // Instance Assertion Methods
+    //--------------------------------------------------------------------------    
+   
+    /**
+     * Asserts that a value is an array.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isArray
+     * @static
+     */
+    isArray : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isArray(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be an array."), actual);
+        }    
+    },
+   
+    /**
+     * Asserts that a value is a Boolean.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isBoolean
+     * @static
+     */
+    isBoolean : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isBoolean(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a Boolean."), actual);
+        }    
+    },
+   
+    /**
+     * Asserts that a value is a function.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isFunction
+     * @static
+     */
+    isFunction : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isFunction(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a function."), actual);
+        }    
+    },
+   
+    /**
+     * Asserts that a value is an instance of a particular object. This may return
+     * incorrect results when comparing objects from one frame to constructors in
+     * another frame. For best results, don't use in a cross-frame manner.
+     * @param {Function} expected The function that the object should be an instance of.
+     * @param {Object} actual The object to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isInstanceOf
+     * @static
+     */
+    isInstanceOf : function (expected /*:Function*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!(actual instanceof expected)){
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value isn't an instance of expected type."), expected, actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is a number.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNumber
+     * @static
+     */
+    isNumber : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isNumber(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a number."), actual);
+        }    
+    },    
+    
+    /**
+     * Asserts that a value is an object.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isObject
+     * @static
+     */
+    isObject : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isObject(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be an object."), actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is a string.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isString
+     * @static
+     */
+    isString : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isString(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a string."), actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is of a particular type. 
+     * @param {String} expectedType The expected type of the variable.
+     * @param {Object} actualValue The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isTypeOf
+     * @static
+     */
+    isTypeOf : function (expectedType /*:String*/, actualValue /*:Object*/, message /*:String*/) /*:Void*/{
+        if (typeof actualValue != expectedType){
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be of type " + expected + "."), expected, typeof actual);
+        }
+    }
+};
+
+//-----------------------------------------------------------------------------
+// Assertion errors
+//-----------------------------------------------------------------------------
+
+/**
+ * AssertionError is thrown whenever an assertion fails. It provides methods
+ * to more easily get at error information and also provides a base class
+ * from which more specific assertion errors can be derived.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @namespace YAHOO.util
+ * @class AssertionError
+ * @extends Error
+ * @constructor
+ */ 
+YAHOO.util.AssertionError = function (message /*:String*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message);
+    
+    /*
+     * Error message. Must be duplicated to ensure browser receives it.
+     * @type String
+     * @property message
+     */
+    this.message /*:String*/ = message;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "AssertionError";
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.AssertionError, Error, {
+
+    /**
+     * Returns a fully formatted error for an assertion failure. This should
+     * be overridden by all subclasses to provide specific information.
+     * @method getMessage
+     * @return {String} A string describing the error.
+     */
+    getMessage : function () /*:String*/ {
+        return this.message;
+    },
+    
+    /**
+     * Returns a string representation of the error.
+     * @method toString
+     * @return {String} A string representation of the error.
+     */
+    toString : function () /*:String*/ {
+        return this.name + ": " + this.getMessage();
+    },
+    
+    /**
+     * Returns a primitive value version of the error. Same as toString().
+     * @method valueOf
+     * @return {String} A primitive value version of the error.
+     */
+    valueOf : function () /*:String*/ {
+        return this.toString();
+    }
+
+});
+
+/**
+ * ComparisonFailure is subclass of AssertionError that is thrown whenever
+ * a comparison between two values fails. It provides mechanisms to retrieve
+ * both the expected and actual value.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @param {Object} expected The expected value.
+ * @param {Object} actual The actual value that caused the assertion to fail.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class ComparisonFailure
+ * @constructor
+ */ 
+YAHOO.util.ComparisonFailure = function (message /*:String*/, expected /*:Object*/, actual /*:Object*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message);
+    
+    /**
+     * The expected value.
+     * @type Object
+     * @property expected
+     */
+    this.expected /*:Object*/ = expected;
+    
+    /**
+     * The actual value.
+     * @type Object
+     * @property actual
+     */
+    this.actual /*:Object*/ = actual;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "ComparisonFailure";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.ComparisonFailure, YAHOO.util.AssertionError, {
+
+    /**
+     * Returns a fully formatted error for an assertion failure. This message
+     * provides information about the expected and actual values.
+     * @method toString
+     * @return {String} A string describing the error.
+     */
+    getMessage : function () /*:String*/ {
+        return this.message + "\nExpected: " + this.expected + " (" + (typeof this.expected) + ")"  +
+            "\nActual:" + this.actual + " (" + (typeof this.actual) + ")";
+    }
+
+});
+
+/**
+ * UnexpectedValue is subclass of AssertionError that is thrown whenever
+ * a value was unexpected in its scope. This typically means that a test
+ * was performed to determine that a value was *not* equal to a certain
+ * value.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @param {Object} unexpected The unexpected value.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class UnexpectedValue
+ * @constructor
+ */ 
+YAHOO.util.UnexpectedValue = function (message /*:String*/, unexpected /*:Object*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message);
+    
+    /**
+     * The unexpected value.
+     * @type Object
+     * @property unexpected
+     */
+    this.unexpected /*:Object*/ = unexpected;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "UnexpectedValue";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.UnexpectedValue, YAHOO.util.AssertionError, {
+
+    /**
+     * Returns a fully formatted error for an assertion failure. The message
+     * contains information about the unexpected value that was encountered.
+     * @method getMessage
+     * @return {String} A string describing the error.
+     */
+    getMessage : function () /*:String*/ {
+        return this.message + "\nUnexpected: " + this.unexpected + " (" + (typeof this.unexpected) + ") ";
+    }
+
+});
+
+/**
+ * ShouldFail is subclass of AssertionError that is thrown whenever
+ * a test was expected to fail but did not.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class ShouldFail
+ * @constructor
+ */  
+YAHOO.util.ShouldFail = function (message /*:String*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message || "This test should fail but didn't.");
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "ShouldFail";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.ShouldFail, YAHOO.util.AssertionError);
+
+/**
+ * ShouldError is subclass of AssertionError that is thrown whenever
+ * a test is expected to throw an error but doesn't.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class ShouldError
+ * @constructor
+ */  
+YAHOO.util.ShouldError = function (message /*:String*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message || "This test should have thrown an error but didn't.");
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "ShouldError";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.ShouldError, YAHOO.util.AssertionError);
+
+/**
+ * UnexpectedError is subclass of AssertionError that is thrown whenever
+ * an error occurs within the course of a test and the test was not expected
+ * to throw an error.
+ *
+ * @param {Error} cause The unexpected error that caused this error to be 
+ *                      thrown.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class UnexpectedError
+ * @constructor
+ */  
+YAHOO.util.UnexpectedError = function (cause /*:Object*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, "Unexpected error: " + cause.message);
+    
+    /**
+     * The unexpected error that occurred.
+     * @type Error
+     * @property cause
+     */
+    this.cause /*:Error*/ = cause;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "UnexpectedError";
+    
+    /**
+     * Stack information for the error (if provided).
+     * @type String
+     * @property stack
+     */
+    this.stack /*:String*/ = cause.stack;
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.UnexpectedError, YAHOO.util.AssertionError);
+
+//-----------------------------------------------------------------------------
+// ArrayAssert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The ArrayAssert object provides functions to test JavaScript array objects
+ * for a variety of cases.
+ *
+ * @namespace YAHOO.util
+ * @class ArrayAssert
+ * @static
+ */
+ 
+YAHOO.util.ArrayAssert = {
+
+    /**
+     * Asserts that a value is present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur.
+     * @param {Object} needle The value that is expected in the array.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method contains
+     * @static
+     */
+    contains : function (needle /*:Object*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (haystack[i] === needle) {
+                found = true;
+            }
+        }
+        
+        if (!found){
+            Assert.fail(Assert._formatMessage(message, "Value " + needle + " (" + (typeof needle) + ") not found in array [" + haystack + "]."));
+        }
+    },
+
+    /**
+     * Asserts that a set of values are present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur. For this assertion to pass, all values must
+     * be found.
+     * @param {Object[]} needles An array of values that are expected in the array.
+     * @param {Array} haystack An array of values to check.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method containsItems
+     * @static
+     */
+    containsItems : function (needles /*:Object[]*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+
+        //begin checking values
+        for (var i=0; i < needles.length; i++){
+            this.contains(needles[i], haystack, message);
+        }
+    },
+
+    /**
+     * Asserts that a value matching some condition is present in an array. This uses
+     * a function to determine a match.
+     * @param {Function} matcher A function that returns true if the items matches or false if not.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method containsMatch
+     * @static
+     */
+    containsMatch : function (matcher /*:Function*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        //check for valid matcher
+        if (typeof matcher != "function"){
+            throw new TypeError("ArrayAssert.containsMatch(): First argument must be a function.");
+        }
+        
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (matcher(haystack[i])) {
+                found = true;
+            }
+        }
+        
+        if (!found){
+            Assert.fail(Assert._formatMessage(message, "No match found in array [" + haystack + "]."));
+        }
+    },
+
+    /**
+     * Asserts that a value is not present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur.
+     * @param {Object} needle The value that is expected in the array.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method doesNotContain
+     * @static
+     */
+    doesNotContain : function (needle /*:Object*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (haystack[i] === needle) {
+                found = true;
+            }
+        }
+        
+        if (found){
+            Assert.fail(Assert._formatMessage(message, "Value found in array [" + haystack + "]."));
+        }
+    },
+
+    /**
+     * Asserts that a set of values are not present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur. For this assertion to pass, all values must
+     * not be found.
+     * @param {Object[]} needles An array of values that are not expected in the array.
+     * @param {Array} haystack An array of values to check.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method doesNotContainItems
+     * @static
+     */
+    doesNotContainItems : function (needles /*:Object[]*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+
+        for (var i=0; i < needles.length; i++){
+            this.doesNotContain(needles[i], haystack, message);
+        }
+
+    },
+        
+    /**
+     * Asserts that no values matching a condition are present in an array. This uses
+     * a function to determine a match.
+     * @param {Function} matcher A function that returns true if the items matches or false if not.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method doesNotContainMatch
+     * @static
+     */
+    doesNotContainMatch : function (matcher /*:Function*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        //check for valid matcher
+        if (typeof matcher != "function"){
+            throw new TypeError("ArrayAssert.doesNotContainMatch(): First argument must be a function.");
+        }
+
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (matcher(haystack[i])) {
+                found = true;
+            }
+        }
+        
+        if (found){
+            Assert.fail(Assert._formatMessage(message, "Value found in array [" + haystack + "]."));
+        }
+    },
+        
+    /**
+     * Asserts that the given value is contained in an array at the specified index.
+     * This uses the triple equals sign so no type cohersion will occur.
+     * @param {Object} needle The value to look for.
+     * @param {Array} haystack The array to search in.
+     * @param {int} index The index at which the value should exist.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method indexOf
+     * @static
+     */
+    indexOf : function (needle /*:Object*/, haystack /*:Array*/, index /*:int*/, message /*:String*/) /*:Void*/ {
+    
+        //try to find the value in the array
+        for (var i=0; i < haystack.length; i++){
+            if (haystack[i] === needle){
+                YAHOO.util.Assert.areEqual(index, i, message || "Value exists at index " + i + " but should be at index " + index + ".");
+                return;
+            }
+        }
+        
+        var Assert = YAHOO.util.Assert;
+        
+        //if it makes it here, it wasn't found at all
+        Assert.fail(Assert._formatMessage(message, "Value doesn't exist in array [" + haystack + "]."));
+    },
+        
+    /**
+     * Asserts that the values in an array are equal, and in the same position,
+     * as values in another array. This uses the double equals sign
+     * so type cohersion may occur. Note that the array objects themselves
+     * need not be the same for this test to pass.
+     * @param {Array} expected An array of the expected values.
+     * @param {Array} actual Any array of the actual values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method itemsAreEqual
+     * @static
+     */
+    itemsAreEqual : function (expected /*:Array*/, actual /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        //one may be longer than the other, so get the maximum length
+        var len /*:int*/ = Math.max(expected.length, actual.length);
+        var Assert = YAHOO.util.Assert;
+       
+        //begin checking values
+        for (var i=0; i < len; i++){
+            Assert.areEqual(expected[i], actual[i], 
+                Assert._formatMessage(message, "Values in position " + i + " are not equal."));
+        }
+    },
+    
+    /**
+     * Asserts that the values in an array are equivalent, and in the same position,
+     * as values in another array. This uses a function to determine if the values
+     * are equivalent. Note that the array objects themselves
+     * need not be the same for this test to pass.
+     * @param {Array} expected An array of the expected values.
+     * @param {Array} actual Any array of the actual values.
+     * @param {Function} comparator A function that returns true if the values are equivalent
+     *      or false if not.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @return {Void}
+     * @method itemsAreEquivalent
+     * @static
+     */
+    itemsAreEquivalent : function (expected /*:Array*/, actual /*:Array*/, 
+                           comparator /*:Function*/, message /*:String*/) /*:Void*/ {
+        
+        //make sure the comparator is valid
+        if (typeof comparator != "function"){
+            throw new TypeError("ArrayAssert.itemsAreEquivalent(): Third argument must be a function.");
+        }
+        
+        //one may be longer than the other, so get the maximum length
+        var len /*:int*/ = Math.max(expected.length, actual.length);
+        
+        //begin checking values
+        for (var i=0; i < len; i++){
+            if (!comparator(expected[i], actual[i])){
+                throw new YAHOO.util.ComparisonFailure(YAHOO.util.Assert._formatMessage(message, "Values in position " + i + " are not equivalent."), expected[i], actual[i]);
+            }
+        }
+    },
+    
+    /**
+     * Asserts that an array is empty.
+     * @param {Array} actual The array to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isEmpty
+     * @static
+     */
+    isEmpty : function (actual /*:Array*/, message /*:String*/) /*:Void*/ {        
+        if (actual.length > 0){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Array should be empty."));
+        }
+    },    
+    
+    /**
+     * Asserts that an array is not empty.
+     * @param {Array} actual The array to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotEmpty
+     * @static
+     */
+    isNotEmpty : function (actual /*:Array*/, message /*:String*/) /*:Void*/ {        
+        if (actual.length === 0){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Array should not be empty."));
+        }
+    },    
+    
+    /**
+     * Asserts that the values in an array are the same, and in the same position,
+     * as values in another array. This uses the triple equals sign
+     * so no type cohersion will occur. Note that the array objects themselves
+     * need not be the same for this test to pass.
+     * @param {Array} expected An array of the expected values.
+     * @param {Array} actual Any array of the actual values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method itemsAreSame
+     * @static
+     */
+    itemsAreSame : function (expected /*:Array*/, actual /*:Array*/, 
+                          message /*:String*/) /*:Void*/ {
+        
+        //one may be longer than the other, so get the maximum length
+        var len /*:int*/ = Math.max(expected.length, actual.length);
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < len; i++){
+            Assert.areSame(expected[i], actual[i], 
+                Assert._formatMessage(message, "Values in position " + i + " are not the same."));
+        }
+    },
+    
+    /**
+     * Asserts that the given value is contained in an array at the specified index,
+     * starting from the back of the array.
+     * This uses the triple equals sign so no type cohersion will occur.
+     * @param {Object} needle The value to look for.
+     * @param {Array} haystack The array to search in.
+     * @param {int} index The index at which the value should exist.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method lastIndexOf
+     * @static
+     */
+    lastIndexOf : function (needle /*:Object*/, haystack /*:Array*/, index /*:int*/, message /*:String*/) /*:Void*/ {
+    
+        var Assert = YAHOO.util.Assert;
+    
+        //try to find the value in the array
+        for (var i=haystack.length; i >= 0; i--){
+            if (haystack[i] === needle){
+                Assert.areEqual(index, i, Assert._formatMessage(message, "Value exists at index " + i + " but should be at index " + index + "."));
+                return;
+            }
+        }
+        
+        //if it makes it here, it wasn't found at all
+        Assert.fail(Assert._formatMessage(message, "Value doesn't exist in array."));        
+    }
+    
+};
+
+YAHOO.namespace("util");
+
+
+//-----------------------------------------------------------------------------
+// ObjectAssert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The ObjectAssert object provides functions to test JavaScript objects
+ * for a variety of cases.
+ *
+ * @namespace YAHOO.util
+ * @class ObjectAssert
+ * @static
+ */
+YAHOO.util.ObjectAssert = {
+        
+    /**
+     * Asserts that all properties in the object exist in another object.
+     * @param {Object} expected An object with the expected properties.
+     * @param {Object} actual An object with the actual properties.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method propertiesAreEqual
+     * @static
+     */
+    propertiesAreEqual : function (expected /*:Object*/, actual /*:Object*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        var Assert = YAHOO.util.Assert;
+        
+        //get all properties in the object
+        var properties /*:Array*/ = [];        
+        for (var property in expected){
+            properties.push(property);
+        }
+        
+        //see if the properties are in the expected object
+        for (var i=0; i < properties.length; i++){
+            Assert.isNotUndefined(actual[properties[i]], 
+                Assert._formatMessage(message, "Property '" + properties[i] + "' expected."));
+        }
+
+    },
+    
+    /**
+     * Asserts that an object has a property with the given name.
+     * @param {String} propertyName The name of the property to test.
+     * @param {Object} object The object to search.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method hasProperty
+     * @static
+     */    
+    hasProperty : function (propertyName /*:String*/, object /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!(propertyName in object)){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Property '" + propertyName + "' not found on object."));
+        }    
+    },
+    
+    /**
+     * Asserts that a property with the given name exists on an object instance (not on its prototype).
+     * @param {String} propertyName The name of the property to test.
+     * @param {Object} object The object to search.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method hasProperty
+     * @static
+     */    
+    hasOwnProperty : function (propertyName /*:String*/, object /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.hasOwnProperty(object, propertyName)){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Property '" + propertyName + "' not found on object instance."));
+        }     
+    }
+};
+
+//-----------------------------------------------------------------------------
+// DateAssert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The DateAssert object provides functions to test JavaScript Date objects
+ * for a variety of cases.
+ *
+ * @namespace YAHOO.util
+ * @class DateAssert
+ * @static
+ */
+ 
+YAHOO.util.DateAssert = {
+
+    /**
+     * Asserts that a date's month, day, and year are equal to another date's.
+     * @param {Date} expected The expected date.
+     * @param {Date} actual The actual date to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method datesAreEqual
+     * @static
+     */
+    datesAreEqual : function (expected /*:Date*/, actual /*:Date*/, message /*:String*/){
+        if (expected instanceof Date && actual instanceof Date){
+            var Assert = YAHOO.util.Assert;
+            Assert.areEqual(expected.getFullYear(), actual.getFullYear(), Assert._formatMessage(message, "Years should be equal."));
+            Assert.areEqual(expected.getMonth(), actual.getMonth(), Assert._formatMessage(message, "Months should be equal."));
+            Assert.areEqual(expected.getDate(), actual.getDate(), Assert._formatMessage(message, "Day of month should be equal."));
+        } else {
+            throw new TypeError("DateAssert.datesAreEqual(): Expected and actual values must be Date objects.");
+        }
+    },
+
+    /**
+     * Asserts that a date's hour, minutes, and seconds are equal to another date's.
+     * @param {Date} expected The expected date.
+     * @param {Date} actual The actual date to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method timesAreEqual
+     * @static
+     */
+    timesAreEqual : function (expected /*:Date*/, actual /*:Date*/, message /*:String*/){
+        if (expected instanceof Date && actual instanceof Date){
+            var Assert = YAHOO.util.Assert;
+            Assert.areEqual(expected.getHours(), actual.getHours(), Assert._formatMessage(message, "Hours should be equal."));
+            Assert.areEqual(expected.getMinutes(), actual.getMinutes(), Assert._formatMessage(message, "Minutes should be equal."));
+            Assert.areEqual(expected.getSeconds(), actual.getSeconds(), Assert._formatMessage(message, "Seconds should be equal."));
+        } else {
+            throw new TypeError("DateAssert.timesAreEqual(): Expected and actual values must be Date objects.");
+        }
+    }
+    
+};
+
+YAHOO.namespace("util");
+
+/**
+ * The UserAction object provides functions that simulate events occurring in
+ * the browser. Since these are simulated events, they do not behave exactly
+ * as regular, user-initiated events do, but can be used to test simple
+ * user interactions safely.
+ *
+ * @namespace YAHOO.util
+ * @class UserAction
+ * @static
+ */
+YAHOO.util.UserAction = {
+
+    //--------------------------------------------------------------------------
+    // Generic event methods
+    //--------------------------------------------------------------------------
+
+    /**
+     * Simulates a key event using the given event information to populate
+     * the generated event object. This method does browser-equalizing
+     * calculations to account for differences in the DOM and IE event models
+     * as well as different browser quirks. Note: keydown causes Safari 2.x to
+     * crash.
+     * @method simulateKeyEvent
+     * @private
+     * @static
+     * @param {HTMLElement} target The target of the given event.
+     * @param {String} type The type of event to fire. This can be any one of
+     *      the following: keyup, keydown, and keypress.
+     * @param {Boolean} bubbles (Optional) Indicates if the event can be
+     *      bubbled up. DOM Level 3 specifies that all key events bubble by
+     *      default. The default is true.
+     * @param {Boolean} cancelable (Optional) Indicates if the event can be
+     *      canceled using preventDefault(). DOM Level 3 specifies that all
+     *      key events can be cancelled. The default 
+     *      is true.
+     * @param {Window} view (Optional) The view containing the target. This is
+     *      typically the window object. The default is window.
+     * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {int} keyCode (Optional) The code for the key that is in use. 
+     *      The default is 0.
+     * @param {int} charCode (Optional) The Unicode code for the character
+     *      associated with the key being used. The default is 0.
+     */
+    simulateKeyEvent : function (target /*:HTMLElement*/, type /*:String*/, 
+                                 bubbles /*:Boolean*/,  cancelable /*:Boolean*/,    
+                                 view /*:Window*/,
+                                 ctrlKey /*:Boolean*/,    altKey /*:Boolean*/, 
+                                 shiftKey /*:Boolean*/,   metaKey /*:Boolean*/, 
+                                 keyCode /*:int*/,        charCode /*:int*/) /*:Void*/                             
+    {
+        //check target
+        target = YAHOO.util.Dom.get(target);        
+        if (!target){
+            throw new Error("simulateKeyEvent(): Invalid target.");
+        }
+        
+        //check event type
+        if (YAHOO.lang.isString(type)){
+            type = type.toLowerCase();
+            switch(type){
+                case "keyup":
+                case "keydown":
+                case "keypress":
+                    break;
+                case "textevent": //DOM Level 3
+                    type = "keypress";
+                    break;
+                    // @TODO was the fallthrough intentional, if so throw error
+                default:
+                    throw new Error("simulateKeyEvent(): Event type '" + type + "' not supported.");
+            }
+        } else {
+            throw new Error("simulateKeyEvent(): Event type must be a string.");
+        }
+        
+        //setup default values
+        if (!YAHOO.lang.isBoolean(bubbles)){
+            bubbles = true; //all key events bubble
+        }
+        if (!YAHOO.lang.isBoolean(cancelable)){
+            cancelable = true; //all key events can be cancelled
+        }
+        if (!YAHOO.lang.isObject(view)){
+            view = window; //view is typically window
+        }
+        if (!YAHOO.lang.isBoolean(ctrlKey)){
+            ctrlKey = false;
+        }
+        if (!YAHOO.lang.isBoolean(altKey)){
+            altKey = false;
+        }
+        if (!YAHOO.lang.isBoolean(shiftKey)){
+            shiftKey = false;
+        }
+        if (!YAHOO.lang.isBoolean(metaKey)){
+            metaKey = false;
+        }
+        if (!YAHOO.lang.isNumber(keyCode)){
+            keyCode = 0;
+        }
+        if (!YAHOO.lang.isNumber(charCode)){
+            charCode = 0; 
+        }
+
+        //try to create a mouse event
+        var customEvent /*:MouseEvent*/ = null;
+            
+        //check for DOM-compliant browsers first
+        if (YAHOO.lang.isFunction(document.createEvent)){
+        
+            try {
+                
+                //try to create key event
+                customEvent = document.createEvent("KeyEvents");
+                
+                /*
+                 * Interesting problem: Firefox implemented a non-standard
+                 * version of initKeyEvent() based on DOM Level 2 specs.
+                 * Key event was removed from DOM Level 2 and re-introduced
+                 * in DOM Level 3 with a different interface. Firefox is the
+                 * only browser with any implementation of Key Events, so for
+                 * now, assume it's Firefox if the above line doesn't error.
+                 */
+                //TODO: Decipher between Firefox's implementation and a correct one.
+                customEvent.initKeyEvent(type, bubbles, cancelable, view, ctrlKey,
+                    altKey, shiftKey, metaKey, keyCode, charCode);       
+                
+            } catch (ex /*:Error*/){
+
+                /*
+                 * If it got here, that means key events aren't officially supported. 
+                 * Safari/WebKit is a real problem now. WebKit 522 won't let you
+                 * set keyCode, charCode, or other properties if you use a
+                 * UIEvent, so we first must try to create a generic event. The
+                 * fun part is that this will throw an error on Safari 2.x. The
+                 * end result is that we need another try...catch statement just to
+                 * deal with this mess.
+                 */
+                try {
+
+                    //try to create generic event - will fail in Safari 2.x
+                    customEvent = document.createEvent("Events");
+
+                } catch (uierror /*:Error*/){
+
+                    //the above failed, so create a UIEvent for Safari 2.x
+                    customEvent = document.createEvent("UIEvents");
+
+                } finally {
+
+                    customEvent.initEvent(type, bubbles, cancelable);
+    
+                    //initialize
+                    customEvent.view = view;
+                    customEvent.altKey = altKey;
+                    customEvent.ctrlKey = ctrlKey;
+                    customEvent.shiftKey = shiftKey;
+                    customEvent.metaKey = metaKey;
+                    customEvent.keyCode = keyCode;
+                    customEvent.charCode = charCode;
+          
+                }          
+             
+            }
+            
+            //fire the event
+            target.dispatchEvent(customEvent);
+
+        } else if (YAHOO.lang.isObject(document.createEventObject)){ //IE
+        
+            //create an IE event object
+            customEvent = document.createEventObject();
+            
+            //assign available properties
+            customEvent.bubbles = bubbles;
+            customEvent.cancelable = cancelable;
+            customEvent.view = view;
+            customEvent.ctrlKey = ctrlKey;
+            customEvent.altKey = altKey;
+            customEvent.shiftKey = shiftKey;
+            customEvent.metaKey = metaKey;
+            
+            /*
+             * IE doesn't support charCode explicitly. CharCode should
+             * take precedence over any keyCode value for accurate
+             * representation.
+             */
+            customEvent.keyCode = (charCode > 0) ? charCode : keyCode;
+            
+            //fire the event
+            target.fireEvent("on" + type, customEvent);  
+                    
+        } else {
+            throw new Error("simulateKeyEvent(): No event simulation framework present.");
+        }
+    },
+
+    /**
+     * Simulates a mouse event using the given event information to populate
+     * the generated event object. This method does browser-equalizing
+     * calculations to account for differences in the DOM and IE event models
+     * as well as different browser quirks.
+     * @method simulateMouseEvent
+     * @private
+     * @static
+     * @param {HTMLElement} target The target of the given event.
+     * @param {String} type The type of event to fire. This can be any one of
+     *      the following: click, dblclick, mousedown, mouseup, mouseout,
+     *      mouseover, and mousemove.
+     * @param {Boolean} bubbles (Optional) Indicates if the event can be
+     *      bubbled up. DOM Level 2 specifies that all mouse events bubble by
+     *      default. The default is true.
+     * @param {Boolean} cancelable (Optional) Indicates if the event can be
+     *      canceled using preventDefault(). DOM Level 2 specifies that all
+     *      mouse events except mousemove can be cancelled. The default 
+     *      is true for all events except mousemove, for which the default 
+     *      is false.
+     * @param {Window} view (Optional) The view containing the target. This is
+     *      typically the window object. The default is window.
+     * @param {int} detail (Optional) The number of times the mouse button has
+     *      been used. The default value is 1.
+     * @param {int} screenX (Optional) The x-coordinate on the screen at which
+     *      point the event occured. The default is 0.
+     * @param {int} screenY (Optional) The y-coordinate on the screen at which
+     *      point the event occured. The default is 0.
+     * @param {int} clientX (Optional) The x-coordinate on the client at which
+     *      point the event occured. The default is 0.
+     * @param {int} clientY (Optional) The y-coordinate on the client at which
+     *      point the event occured. The default is 0.
+     * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {int} button (Optional) The button being pressed while the event
+     *      is executing. The value should be 0 for the primary mouse button
+     *      (typically the left button), 1 for the terciary mouse button
+     *      (typically the middle button), and 2 for the secondary mouse button
+     *      (typically the right button). The default is 0.
+     * @param {HTMLElement} relatedTarget (Optional) For mouseout events,
+     *      this is the element that the mouse has moved to. For mouseover
+     *      events, this is the element that the mouse has moved from. This
+     *      argument is ignored for all other events. The default is null.
+     */
+    simulateMouseEvent : function (target /*:HTMLElement*/, type /*:String*/, 
+                                   bubbles /*:Boolean*/,  cancelable /*:Boolean*/,    
+                                   view /*:Window*/,        detail /*:int*/, 
+                                   screenX /*:int*/,        screenY /*:int*/, 
+                                   clientX /*:int*/,        clientY /*:int*/,       
+                                   ctrlKey /*:Boolean*/,    altKey /*:Boolean*/, 
+                                   shiftKey /*:Boolean*/,   metaKey /*:Boolean*/, 
+                                   button /*:int*/,         relatedTarget /*:HTMLElement*/) /*:Void*/
+    {
+        
+        //check target
+        target = YAHOO.util.Dom.get(target);        
+        if (!target){
+            throw new Error("simulateMouseEvent(): Invalid target.");
+        }
+        
+        //check event type
+        if (YAHOO.lang.isString(type)){
+            type = type.toLowerCase();
+            switch(type){
+                case "mouseover":
+                case "mouseout":
+                case "mousedown":
+                case "mouseup":
+                case "click":
+                case "dblclick":
+                case "mousemove":
+                    break;
+                default:
+                    throw new Error("simulateMouseEvent(): Event type '" + type + "' not supported.");
+            }
+        } else {
+            throw new Error("simulateMouseEvent(): Event type must be a string.");
+        }
+        
+        //setup default values
+        if (!YAHOO.lang.isBoolean(bubbles)){
+            bubbles = true; //all mouse events bubble
+        }
+        if (!YAHOO.lang.isBoolean(cancelable)){
+            cancelable = (type != "mousemove"); //mousemove is the only one that can't be cancelled
+        }
+        if (!YAHOO.lang.isObject(view)){
+            view = window; //view is typically window
+        }
+        if (!YAHOO.lang.isNumber(detail)){
+            detail = 1;  //number of mouse clicks must be at least one
+        }
+        if (!YAHOO.lang.isNumber(screenX)){
+            screenX = 0; 
+        }
+        if (!YAHOO.lang.isNumber(screenY)){
+            screenY = 0; 
+        }
+        if (!YAHOO.lang.isNumber(clientX)){
+            clientX = 0; 
+        }
+        if (!YAHOO.lang.isNumber(clientY)){
+            clientY = 0; 
+        }
+        if (!YAHOO.lang.isBoolean(ctrlKey)){
+            ctrlKey = false;
+        }
+        if (!YAHOO.lang.isBoolean(altKey)){
+            altKey = false;
+        }
+        if (!YAHOO.lang.isBoolean(shiftKey)){
+            shiftKey = false;
+        }
+        if (!YAHOO.lang.isBoolean(metaKey)){
+            metaKey = false;
+        }
+        if (!YAHOO.lang.isNumber(button)){
+            button = 0; 
+        }
+
+        //try to create a mouse event
+        var customEvent /*:MouseEvent*/ = null;
+            
+        //check for DOM-compliant browsers first
+        if (YAHOO.lang.isFunction(document.createEvent)){
+        
+            customEvent = document.createEvent("MouseEvents");
+        
+            //Safari 2.x (WebKit 418) still doesn't implement initMouseEvent()
+            if (customEvent.initMouseEvent){
+                customEvent.initMouseEvent(type, bubbles, cancelable, view, detail,
+                                     screenX, screenY, clientX, clientY, 
+                                     ctrlKey, altKey, shiftKey, metaKey, 
+                                     button, relatedTarget);
+            } else { //Safari
+            
+                //the closest thing available in Safari 2.x is UIEvents
+                customEvent = document.createEvent("UIEvents");
+                customEvent.initEvent(type, bubbles, cancelable);
+                customEvent.view = view;
+                customEvent.detail = detail;
+                customEvent.screenX = screenX;
+                customEvent.screenY = screenY;
+                customEvent.clientX = clientX;
+                customEvent.clientY = clientY;
+                customEvent.ctrlKey = ctrlKey;
+                customEvent.altKey = altKey;
+                customEvent.metaKey = metaKey;
+                customEvent.shiftKey = shiftKey;
+                customEvent.button = button;
+                customEvent.relatedTarget = relatedTarget;
+            }
+            
+            /*
+             * Check to see if relatedTarget has been assigned. Firefox
+             * versions less than 2.0 don't allow it to be assigned via
+             * initMouseEvent() and the property is readonly after event
+             * creation, so in order to keep YAHOO.util.getRelatedTarget()
+             * working, assign to the IE proprietary toElement property
+             * for mouseout event and fromElement property for mouseover
+             * event.
+             */
+            if (relatedTarget && !customEvent.relatedTarget){
+                if (type == "mouseout"){
+                    customEvent.toElement = relatedTarget;
+                } else if (type == "mouseover"){
+                    customEvent.fromElement = relatedTarget;
+                }
+            }
+            
+            //fire the event
+            target.dispatchEvent(customEvent);
+
+        } else if (YAHOO.lang.isObject(document.createEventObject)){ //IE
+        
+            //create an IE event object
+            customEvent = document.createEventObject();
+            
+            //assign available properties
+            customEvent.bubbles = bubbles;
+            customEvent.cancelable = cancelable;
+            customEvent.view = view;
+            customEvent.detail = detail;
+            customEvent.screenX = screenX;
+            customEvent.screenY = screenY;
+            customEvent.clientX = clientX;
+            customEvent.clientY = clientY;
+            customEvent.ctrlKey = ctrlKey;
+            customEvent.altKey = altKey;
+            customEvent.metaKey = metaKey;
+            customEvent.shiftKey = shiftKey;
+
+            //fix button property for IE's wacky implementation
+            switch(button){
+                case 0:
+                    customEvent.button = 1;
+                    break;
+                case 1:
+                    customEvent.button = 4;
+                    break;
+                case 2:
+                    //leave as is
+                    break;
+                default:
+                    customEvent.button = 0;                    
+            }    
+
+            /*
+             * Have to use relatedTarget because IE won't allow assignment
+             * to toElement or fromElement on generic events. This keeps
+             * YAHOO.util.customEvent.getRelatedTarget() functional.
+             */
+            customEvent.relatedTarget = relatedTarget;
+            
+            //fire the event
+            target.fireEvent("on" + type, customEvent);
+                    
+        } else {
+            throw new Error("simulateMouseEvent(): No event simulation framework present.");
+        }
+    },
+   
+    //--------------------------------------------------------------------------
+    // Mouse events
+    //--------------------------------------------------------------------------
+
+    /**
+     * Simulates a mouse event on a particular element.
+     * @param {HTMLElement} target The element to click on.
+     * @param {String} type The type of event to fire. This can be any one of
+     *      the following: click, dblclick, mousedown, mouseup, mouseout,
+     *      mouseover, and mousemove.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method mouseEvent
+     * @static
+     */
+    fireMouseEvent : function (target /*:HTMLElement*/, type /*:String*/, 
+                           options /*:Object*/) /*:Void*/
+    {
+        options = options || {};
+        this.simulateMouseEvent(target, type, options.bubbles,
+            options.cancelable, options.view, options.detail, options.screenX,        
+            options.screenY, options.clientX, options.clientY, options.ctrlKey,
+            options.altKey, options.shiftKey, options.metaKey, options.button,         
+            options.relatedTarget);        
+    },
+
+    /**
+     * Simulates a click on a particular element.
+     * @param {HTMLElement} target The element to click on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method click
+     * @static     
+     */
+    click : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
+        this.fireMouseEvent(target, "click", options);
+    },
+    
+    /**
+     * Simulates a double click on a particular element.
+     * @param {HTMLElement} target The element to double click on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method dblclick
+     * @static
+     */
+    dblclick : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
+        this.fireMouseEvent( target, "dblclick", options);
+    },
+    
+    /**
+     * Simulates a mousedown on a particular element.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method mousedown
+     * @static
+     */
+    mousedown : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
+        this.fireMouseEvent(target, "mousedown", options);
+    },
+    
+    /**
+     * Simulates a mousemove on a particular element.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method mousemove
+     * @static
+     */
+    mousemove : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
+        this.fireMouseEvent(target, "mousemove", options);
+    },
+    
+    /**
+     * Simulates a mouseout event on a particular element. Use "relatedTarget"
+     * on the options object to specify where the mouse moved to.
+     * Quirks: Firefox less than 2.0 doesn't set relatedTarget properly, so
+     * toElement is assigned in its place. IE doesn't allow toElement to be
+     * be assigned, so relatedTarget is assigned in its place. Both of these
+     * concessions allow YAHOO.util.Event.getRelatedTarget() to work correctly
+     * in both browsers.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method mouseout
+     * @static
+     */
+    mouseout : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
+        this.fireMouseEvent(target, "mouseout", options);
+    },
+    
+    /**
+     * Simulates a mouseover event on a particular element. Use "relatedTarget"
+     * on the options object to specify where the mouse moved from.
+     * Quirks: Firefox less than 2.0 doesn't set relatedTarget properly, so
+     * fromElement is assigned in its place. IE doesn't allow fromElement to be
+     * be assigned, so relatedTarget is assigned in its place. Both of these
+     * concessions allow YAHOO.util.Event.getRelatedTarget() to work correctly
+     * in both browsers.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method mouseover
+     * @static
+     */
+    mouseover : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
+        this.fireMouseEvent(target, "mouseover", options);
+    },
+    
+    /**
+     * Simulates a mouseup on a particular element.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method mouseup
+     * @static
+     */
+    mouseup : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
+        this.fireMouseEvent(target, "mouseup", options);
+    },
+    
+    //--------------------------------------------------------------------------
+    // Key events
+    //--------------------------------------------------------------------------
+
+    /**
+     * Fires an event that normally would be fired by the keyboard (keyup,
+     * keydown, keypress). Make sure to specify either keyCode or charCode as
+     * an option.
+     * @private
+     * @param {String} type The type of event ("keyup", "keydown" or "keypress").
+     * @param {HTMLElement} target The target of the event.
+     * @param {Object} options Options for the event. Either keyCode or charCode
+     *                         are required.
+     * @method fireKeyEvent
+     * @static
+     */     
+    fireKeyEvent : function (type /*:String*/, target /*:HTMLElement*/,
+                             options /*:Object*/) /*:Void*/ 
+    {
+        options = options || {};
+        this.simulateKeyEvent(target, type, options.bubbles,
+            options.cancelable, options.view, options.ctrlKey,
+            options.altKey, options.shiftKey, options.metaKey, 
+            options.keyCode, options.charCode);    
+    },
+    
+    /**
+     * Simulates a keydown event on a particular element.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method keydown
+     * @static
+     */
+    keydown : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
+        this.fireKeyEvent("keydown", target, options);
+    },
+    
+    /**
+     * Simulates a keypress on a particular element.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method keypress
+     * @static
+     */
+    keypress : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
+        this.fireKeyEvent("keypress", target, options);
+    },
+    
+    /**
+     * Simulates a keyup event on a particular element.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method keyup
+     * @static
+     */
+    keyup : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
+        this.fireKeyEvent("keyup", target, options);
+    }
+    
+
+};
+
+YAHOO.namespace("tool");
+
+//-----------------------------------------------------------------------------
+// TestManager object
+//-----------------------------------------------------------------------------
+
+/**
+ * Runs pages containing test suite definitions.
+ * @namespace YAHOO.tool
+ * @class TestManager
+ * @static
+ */
+YAHOO.tool.TestManager = {
+
+    /**
+     * Constant for the testpagebegin custom event
+     * @property TEST_PAGE_BEGIN_EVENT
+     * @static
+     * @type string
+     * @final
+     */
+    TEST_PAGE_BEGIN_EVENT /*:String*/ : "testpagebegin",
+
+    /**
+     * Constant for the testpagecomplete custom event
+     * @property TEST_PAGE_COMPLETE_EVENT
+     * @static
+     * @type string
+     * @final
+     */
+    TEST_PAGE_COMPLETE_EVENT /*:String*/ : "testpagecomplete",
+
+    /**
+     * Constant for the testmanagerbegin custom event
+     * @property TEST_MANAGER_BEGIN_EVENT
+     * @static
+     * @type string
+     * @final
+     */
+    TEST_MANAGER_BEGIN_EVENT /*:String*/ : "testmanagerbegin",
+
+    /**
+     * Constant for the testmanagercomplete custom event
+     * @property TEST_MANAGER_COMPLETE_EVENT
+     * @static
+     * @type string
+     * @final
+     */
+    TEST_MANAGER_COMPLETE_EVENT /*:String*/ : "testmanagercomplete",
+
+    //-------------------------------------------------------------------------
+    // Private Properties
+    //-------------------------------------------------------------------------
+    
+    
+    /**
+     * The URL of the page currently being executed.
+     * @type String
+     * @private
+     * @property _curPage
+     * @static
+     */
+    _curPage /*:String*/ : null,
+    
+    /**
+     * The frame used to load and run tests.
+     * @type Window
+     * @private
+     * @property _frame
+     * @static
+     */
+    _frame /*:Window*/ : null,
+    
+    /**
+     * The logger used to output results from the various tests.
+     * @type YAHOO.tool.TestLogger
+     * @private
+     * @property _logger
+     * @static
+     */
+    _logger : null,
+    
+    /**
+     * The timeout ID for the next iteration through the tests.
+     * @type int
+     * @private
+     * @property _timeoutId
+     * @static
+     */
+    _timeoutId /*:int*/ : 0,
+    
+    /**
+     * Array of pages to load.
+     * @type String[]
+     * @private
+     * @property _pages
+     * @static
+     */
+    _pages /*:String[]*/ : [],
+    
+    /**
+     * Aggregated results
+     * @type Object
+     * @private
+     * @property _results
+     * @static
+     */
+    _results: null,
+    
+    //-------------------------------------------------------------------------
+    // Private Methods
+    //-------------------------------------------------------------------------
+    
+    /**
+     * Handles TestRunner.COMPLETE_EVENT, storing the results and beginning
+     * the loop again.
+     * @param {Object} data Data about the event.
+     * @return {Void}
+     * @private
+     * @static
+     */
+    _handleTestRunnerComplete : function (data /*:Object*/) /*:Void*/ {
+
+        this.fireEvent(this.TEST_PAGE_COMPLETE_EVENT, {
+                page: this._curPage,
+                results: data.results
+            });
+    
+        //save results
+        //this._results[this.curPage] = data.results;
+        
+        //process 'em
+        this._processResults(this._curPage, data.results);
+        
+        this._logger.clearTestRunner();
+    
+        //if there's more to do, set a timeout to begin again
+        if (this._pages.length){
+            this._timeoutId = setTimeout(function(){
+                YAHOO.tool.TestManager._run();
+            }, 1000);
+        } else {
+            this.fireEvent(this.TEST_MANAGER_COMPLETE_EVENT, this._results);
+        }
+    },
+    
+    /**
+     * Processes the results of a test page run, outputting log messages
+     * for failed tests.
+     * @return {Void}
+     * @private
+     * @static
+     */
+    _processResults : function (page /*:String*/, results /*:Object*/) /*:Void*/ {
+
+        var r = this._results;
+        
+        r.passed += results.passed;
+        r.failed += results.failed;
+        r.ignored += results.ignored;
+        r.total += results.total;
+        
+        if (results.failed){
+            r.failedPages.push(page);
+        } else {
+            r.passedPages.push(page);
+        }
+        
+        results.name = page;
+        results.type = "page";
+        
+        r[page] = results;
+    },
+    
+    /**
+     * Loads the next test page into the iframe.
+     * @return {Void}
+     * @static
+     * @private
+     */
+    _run : function () /*:Void*/ {
+    
+        //set the current page
+        this._curPage = this._pages.shift();
+
+        this.fireEvent(this.TEST_PAGE_BEGIN_EVENT, this._curPage);
+        
+        //load the frame - destroy history in case there are other iframes that
+        //need testing
+        this._frame.location.replace(this._curPage);
+    
+    },
+        
+    //-------------------------------------------------------------------------
+    // Public Methods
+    //-------------------------------------------------------------------------
+    
+    /**
+     * Signals that a test page has been loaded. This should be called from
+     * within the test page itself to notify the TestManager that it is ready.
+     * @return {Void}
+     * @static
+     */
+    load : function () /*:Void*/ {
+        if (parent.YAHOO.tool.TestManager !== this){
+            parent.YAHOO.tool.TestManager.load();
+        } else {
+            
+            if (this._frame) {
+                //assign event handling
+                var TestRunner = this._frame.YAHOO.tool.TestRunner;
+
+                this._logger.setTestRunner(TestRunner);
+                TestRunner.subscribe(TestRunner.COMPLETE_EVENT, this._handleTestRunnerComplete, this, true);
+                
+                //run it
+                TestRunner.run();
+            }
+        }
+    },
+    
+    /**
+     * Sets the pages to be loaded.
+     * @param {String[]} pages An array of URLs to load.
+     * @return {Void}
+     * @static
+     */
+    setPages : function (pages /*:String[]*/) /*:Void*/ {
+        this._pages = pages;
+    },
+    
+    /**
+     * Begins the process of running the tests.
+     * @return {Void}
+     * @static
+     */
+    start : function () /*:Void*/ {
+
+        if (!this._initialized) {
+
+            /**
+             * Fires when loading a test page
+             * @event testpagebegin
+             * @param curPage {string} the page being loaded
+             * @static
+             */
+            this.createEvent(this.TEST_PAGE_BEGIN_EVENT);
+
+            /**
+             * Fires when a test page is complete
+             * @event testpagecomplete
+             * @param obj {page: string, results: object} the name of the
+             * page that was loaded, and the test suite results
+             * @static
+             */
+            this.createEvent(this.TEST_PAGE_COMPLETE_EVENT);
+
+            /**
+             * Fires when the test manager starts running all test pages
+             * @event testmanagerbegin
+             * @static
+             */
+            this.createEvent(this.TEST_MANAGER_BEGIN_EVENT);
+
+            /**
+             * Fires when the test manager finishes running all test pages.  External
+             * test runners should subscribe to this event in order to get the
+             * aggregated test results.
+             * @event testmanagercomplete
+             * @param obj { pages_passed: int, pages_failed: int, tests_passed: int
+             *              tests_failed: int, passed: string[], failed: string[],
+             *              page_results: {} }
+             * @static
+             */
+            this.createEvent(this.TEST_MANAGER_COMPLETE_EVENT);
+
+            //create iframe if not already available
+            if (!this._frame){
+                var frame /*:HTMLElement*/ = document.createElement("iframe");
+                frame.style.visibility = "hidden";
+                frame.style.position = "absolute";
+                document.body.appendChild(frame);
+                this._frame = frame.contentWindow || frame.contentDocument.ownerWindow;
+            }
+            
+            //create test logger if not already available
+            if (!this._logger){
+                this._logger = new YAHOO.tool.TestLogger();
+            }
+
+            this._initialized = true;
+        }
+
+
+        // reset the results cache
+        this._results = {
+        
+            passed: 0,
+            failed: 0,
+            ignored: 0,
+            total: 0,
+            type: "report",
+            name: "YUI Test Results",
+            failedPages:[],
+            passedPages:[]
+            /*
+            // number of pages that pass
+            pages_passed: 0,
+            // number of pages that fail
+            pages_failed: 0,
+            // total number of tests passed
+            tests_passed: 0,
+            // total number of tests failed
+            tests_failed: 0,
+            // array of pages that passed
+            passed: [],
+            // array of pages that failed
+            failed: [],
+            // map of full results for each page
+            page_results: {}*/
+        };
+
+        this.fireEvent(this.TEST_MANAGER_BEGIN_EVENT, null);
+        this._run();
+    
+    },
+
+    /**
+     * Stops the execution of tests.
+     * @return {Void}
+     * @static
+     */
+    stop : function () /*:Void*/ {
+        clearTimeout(this._timeoutId);
+    }
+
+};
+
+YAHOO.lang.augmentObject(YAHOO.tool.TestManager, YAHOO.util.EventProvider.prototype);
+
+
+YAHOO.namespace("tool");
+
+//-----------------------------------------------------------------------------
+// TestLogger object
+//-----------------------------------------------------------------------------
+
+/**
+ * Displays test execution progress and results, providing filters based on
+ * different key events.
+ * @namespace YAHOO.tool
+ * @class TestLogger
+ * @constructor
+ * @param {HTMLElement} element (Optional) The element to create the logger in.
+ * @param {Object} config (Optional) Configuration options for the logger.
+ */
+YAHOO.tool.TestLogger = function (element, config) {
+    YAHOO.tool.TestLogger.superclass.constructor.call(this, element, config);
+    this.init();
+};
+
+YAHOO.lang.extend(YAHOO.tool.TestLogger, YAHOO.widget.LogReader, {
+
+    footerEnabled : true,
+    newestOnTop : false,
+
+    /**
+     * Formats message string to HTML for output to console.
+     * @private
+     * @method formatMsg
+     * @param oLogMsg {Object} Log message object.
+     * @return {String} HTML-formatted message for output to console.
+     */
+    formatMsg : function(message /*:Object*/) {
+    
+        var category /*:String*/ = message.category;        
+        var text /*:String*/ = this.html2Text(message.msg);
+        
+        return "<pre><p><span class=\"" + category + "\">" + category.toUpperCase() + "</span> " + text + "</p></pre>";
+    
+    },
+    
+    //-------------------------------------------------------------------------
+    // Private Methods
+    //-------------------------------------------------------------------------
+    
+    /*
+     * Initializes the logger.
+     * @private
+     */
+    init : function () {
+    
+        //attach to any available TestRunner
+        if (YAHOO.tool.TestRunner){
+            this.setTestRunner(YAHOO.tool.TestRunner);
+        }
+        
+        //hide useless sources
+        this.hideSource("global");
+        this.hideSource("LogReader");
+        
+        //hide useless message categories
+        this.hideCategory("warn");
+        this.hideCategory("window");
+        this.hideCategory("time");
+        
+        //reset the logger
+        this.clearConsole();
+    },
+    
+    /**
+     * Clears the reference to the TestRunner from previous operations. This 
+     * unsubscribes all events and removes the object reference.
+     * @return {Void}
+     * @static
+     */
+    clearTestRunner : function () /*:Void*/ {
+        if (this._runner){
+            this._runner.unsubscribeAll();
+            this._runner = null;
+        }
+    },
+    
+    /**
+     * Sets the source test runner that the logger should monitor.
+     * @param {YAHOO.tool.TestRunner} testRunner The TestRunner to observe.
+     * @return {Void}
+     * @static
+     */
+    setTestRunner : function (testRunner /*:YAHOO.tool.TestRunner*/) /*:Void*/ {
+    
+        if (this._runner){
+            this.clearTestRunner();
+        }
+        
+        this._runner = testRunner;
+        
+        //setup event _handlers
+        testRunner.subscribe(testRunner.TEST_PASS_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.TEST_FAIL_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.TEST_IGNORE_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.BEGIN_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.COMPLETE_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.TEST_SUITE_BEGIN_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.TEST_SUITE_COMPLETE_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.TEST_CASE_BEGIN_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.TEST_CASE_COMPLETE_EVENT, this._handleTestRunnerEvent, this, true);    
+    },
+    
+    //-------------------------------------------------------------------------
+    // Event Handlers
+    //-------------------------------------------------------------------------
+    
+    /**
+     * Handles all TestRunner events, outputting appropriate data into the console.
+     * @param {Object} data The event data object.
+     * @return {Void}
+     * @private
+     */
+    _handleTestRunnerEvent : function (data /*:Object*/) /*:Void*/ {
+    
+        //shortcut variables
+        var TestRunner /*:Object*/ = YAHOO.tool.TestRunner;
+    
+        //data variables
+        var message /*:String*/ = "";
+        var messageType /*:String*/ = "";
+        
+        switch(data.type){
+            case TestRunner.BEGIN_EVENT:
+                message = "Testing began at " + (new Date()).toString() + ".";
+                messageType = "info";
+                break;
+                
+            case TestRunner.COMPLETE_EVENT:
+                message = "Testing completed at " + (new Date()).toString() + ".\nPassed:" + 
+                    data.results.passed + " Failed:" + data.results.failed + " Total:" + data.results.total;
+                messageType = "info";
+                break;
+                
+            case TestRunner.TEST_FAIL_EVENT:
+                message = data.testName + ": " + data.error.getMessage();
+                messageType = "fail";
+                break;
+                
+            case TestRunner.TEST_IGNORE_EVENT:
+                message = data.testName + ": ignored.";
+                messageType = "ignore";
+                break;
+                
+            case TestRunner.TEST_PASS_EVENT:
+                message = data.testName + ": passed.";
+                messageType = "pass";
+                break;
+                
+            case TestRunner.TEST_SUITE_BEGIN_EVENT:
+                message = "Test suite \"" + data.testSuite.name + "\" started.";
+                messageType = "info";
+                break;
+                
+            case TestRunner.TEST_SUITE_COMPLETE_EVENT:
+                message = "Test suite \"" + data.testSuite.name + "\" completed.\nPassed:" + 
+                    data.results.passed + " Failed:" + data.results.failed + " Total:" + data.results.total;
+                messageType = "info";
+                break;
+                
+            case TestRunner.TEST_CASE_BEGIN_EVENT:
+                message = "Test case \"" + data.testCase.name + "\" started.";
+                messageType = "info";
+                break;
+                
+            case TestRunner.TEST_CASE_COMPLETE_EVENT:
+                message = "Test case \"" + data.testCase.name + "\" completed.\nPassed:" + 
+                    data.results.passed + " Failed:" + data.results.failed + " Total:" + data.results.total;
+                messageType = "info";
+                break;
+            default:
+                message = "Unexpected event " + data.type;
+                message = "info";
+        }
+    
+        YAHOO.log(message, messageType, "TestRunner");    
+    }
+    
+});
+
+YAHOO.namespace("tool.TestFormat");
+
+/**
+ * Returns test results formatted as a JSON string. Requires JSON utility.
+ * @param {Object} result The results object created by TestRunner.
+ * @return {String} An XML-formatted string of results.
+ * @namespace YAHOO.tool.TestFormat
+ * @method JSON
+ * @static
+ */
+YAHOO.tool.TestFormat.JSON = function(results /*:Object*/) /*:String*/ {
+    return YAHOO.lang.JSON.stringify(results);
+};
+
+/**
+ * Returns test results formatted as an XML string.
+ * @param {Object} result The results object created by TestRunner.
+ * @return {String} An XML-formatted string of results.
+ * @namespace YAHOO.tool.TestFormat
+ * @method XML
+ * @static
+ */
+YAHOO.tool.TestFormat.XML = function(results /*:Object*/) /*:String*/ {
+
+    var l = YAHOO.lang;
+    var xml /*:String*/ = "<" + results.type + " name=\"" + results.name.replace(/"/g, """).replace(/'/g, "'") + "\"";
+    
+    if (results.type == "test"){
+        xml += " result=\"" + results.result + "\" message=\"" + results.message + "\">";
+    } else {
+        xml += " passed=\"" + results.passed + "\" failed=\"" + results.failed + "\" ignored=\"" + results.ignored + "\" total=\"" + results.total + "\">";
+        for (var prop in results) {
+            if (l.hasOwnProperty(results, prop) && l.isObject(results[prop]) && !l.isArray(results[prop])){
+                xml += arguments.callee(results[prop]);
+            }
+        }        
+    }
+
+    xml += "</" + results.type + ">";
+    
+    return xml;
+
+};
+
+YAHOO.namespace("tool");
+
+/**
+ * An object capable of sending test results to a server.
+ * @param {String} url The URL to submit the results to.
+ * @param {Function} format (Optiona) A function that outputs the results in a specific format.
+ *      Default is YAHOO.tool.TestFormat.XML.
+ * @constructor
+ * @namespace YAHOO.tool
+ * @class TestReporter
+ */
+YAHOO.tool.TestReporter = function(url /*:String*/, format /*:Function*/) {
+
+    /**
+     * The URL to submit the data to.
+     * @type String
+     * @property url
+     */
+    this.url /*:String*/ = url;
+
+    /**
+     * The formatting function to call when submitting the data.
+     * @type Function
+     * @property format
+     */
+    this.format /*:Function*/ = format || YAHOO.tool.TestFormat.XML;
+
+    /**
+     * Extra fields to submit with the request.
+     * @type Object
+     * @property _fields
+     * @private
+     */
+    this._fields /*:Object*/ = new Object();
+    
+    /**
+     * The form element used to submit the results.
+     * @type HTMLFormElement
+     * @property _form
+     * @private
+     */
+    this._form /*:HTMLElement*/ = null;
+
+    /**
+     * Iframe used as a target for form submission.
+     * @type HTMLIFrameElement
+     * @property _iframe
+     * @private
+     */
+    this._iframe /*:HTMLElement*/ = null;
+};
+
+YAHOO.tool.TestReporter.prototype = {
+
+    //restore missing constructor
+    constructor: YAHOO.tool.TestReporter,
+
+    /**
+     * Adds a field to the form that submits the results.
+     * @param {String} name The name of the field.
+     * @param {Variant} value The value of the field.
+     * @return {Void}
+     * @method addField
+     */
+    addField : function (name /*:String*/, value /*:Variant*/) /*:Void*/{
+        this._fields[name] = value;    
+    },
+    
+    /**
+     * Removes all previous defined fields.
+     * @return {Void}
+     * @method addField
+     */
+    clearFields : function() /*:Void*/{
+        this._fields = new Object();
+    },
+
+    /**
+     * Cleans up the memory associated with the TestReporter, removing DOM elements
+     * that were created.
+     * @return {Void}
+     * @method destroy
+     */
+    destroy : function() /*:Void*/ {
+        if (this._form){
+            this._form.parentNode.removeChild(this._form);
+            this._form = null;
+        }        
+        if (this._iframe){
+            this._iframe.parentNode.removeChild(this._iframe);
+            this._iframe = null;
+        }
+        this._fields = null;
+    },
+
+    /**
+     * Sends the report to the server.
+     * @param {Object} results The results object created by TestRunner.
+     * @return {Void}
+     * @method report
+     */
+    report : function(results /*:Object*/) /*:Void*/{
+    
+        //if the form hasn't been created yet, create it
+        if (!this._form){
+            this._form = document.createElement("form");
+            this._form.method = "post";
+            this._form.style.visibility = "hidden";
+            this._form.style.position = "absolute";
+            this._form.style.top = 0;
+            document.body.appendChild(this._form);
+        
+            //IE won't let you assign a name using the DOM, must do it the hacky way
+            if (YAHOO.env.ua.ie){
+                this._iframe = document.createElement("<iframe name=\"yuiTestTarget\" />");
+            } else {
+                this._iframe = document.createElement("iframe");
+                this._iframe.name = "yuiTestTarget";
+            }
+
+            this._iframe.src = "javascript:false";
+            this._iframe.style.visibility = "hidden";
+            this._iframe.style.position = "absolute";
+            this._iframe.style.top = 0;
+            document.body.appendChild(this._iframe);
+
+            this._form.target = "yuiTestTarget";
+        }
+
+        //set the form's action
+        this._form.action = this.url;
+    
+        //remove any existing fields
+        while(this._form.hasChildNodes()){
+            this._form.removeChild(this._form.lastChild);
+        }
+        
+        //create default fields
+        this._fields.results = this.format(results);
+        this._fields.useragent = navigator.userAgent;
+        this._fields.timestamp = (new Date()).toLocaleString();
+
+        //add fields to the form
+        for (var prop in this._fields){
+            if (YAHOO.lang.hasOwnProperty(this._fields, prop) && typeof this._fields[prop] != "function"){
+                if (YAHOO.env.ua.ie){
+                    input = document.createElement("<input name=\"" + prop + "\" >");
+                } else {
+                    input = document.createElement("input");
+                    input.name = prop;
+                }
+                input.type = "hidden";
+                input.value = this._fields[prop];
+                this._form.appendChild(input);
+            }
+        }
+
+        //remove default fields
+        delete this._fields.results;
+        delete this._fields.useragent;
+        delete this._fields.timestamp;
+        
+        if (arguments[1] !== false){
+            this._form.submit();
+        }
+    
+    }
+
+};
+
+YAHOO.register("yuitest", YAHOO.tool.TestRunner, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/yuitest/yuitest-min.js
===================================================================
--- trunk/root/static/yui/yuitest/yuitest-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/yuitest-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,11 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+YAHOO.namespace("tool");YAHOO.tool.TestCase=function(A){this._should={};for(var B in A){this[B]=A[B];}if(!YAHOO.lang.isString(this.name)){this.name=YAHOO.util.Dom.generateId(null,"testCase");}};YAHOO.tool.TestCase.prototype={resume:function(A){YAHOO.tool.TestRunner.resume(A);},wait:function(B,A){throw new YAHOO.tool.TestCase.Wait(B,A);},setUp:function(){},tearDown:function(){}};YAHOO.tool.TestCase.Wait=function(B,A){this.segment=(YAHOO.lang.isFunction(B)?B:null);this.delay=(YAHOO.lang.isNumber(A)?A:0);};YAHOO.namespace("tool");YAHOO.tool.TestSuite=function(A){this.name="";this.items=[];if(YAHOO.lang.isString(A)){this.name=A;}else{if(YAHOO.lang.isObject(A)){YAHOO.lang.augmentObject(this,A,true);}}if(this.name===""){this.name=YAHOO.util.Dom.generateId(null,"testSuite");}};YAHOO.tool.TestSuite.prototype={add:function(A){if(A instanceof YAHOO.tool.TestSuite||A instanceof YAHOO.tool.TestCase){this.items.push(A);}},setUp:function(){},tearDown:function(){}};YAHOO.namespace("tool")!
 ;YAHOO.tool.TestRunner=(function(){function B(C){this.testObject=C;this.firstChild=null;this.lastChild=null;this.parent=null;this.next=null;this.results={passed:0,failed:0,total:0,ignored:0};if(C instanceof YAHOO.tool.TestSuite){this.results.type="testsuite";this.results.name=C.name;}else{if(C instanceof YAHOO.tool.TestCase){this.results.type="testcase";this.results.name=C.name;}}}B.prototype={appendChild:function(C){var D=new B(C);if(this.firstChild===null){this.firstChild=this.lastChild=D;}else{this.lastChild.next=D;this.lastChild=D;}D.parent=this;return D;}};function A(){A.superclass.constructor.apply(this,arguments);this.masterSuite=new YAHOO.tool.TestSuite("YUI Test Results");this._cur=null;this._root=null;var D=[this.TEST_CASE_BEGIN_EVENT,this.TEST_CASE_COMPLETE_EVENT,this.TEST_SUITE_BEGIN_EVENT,this.TEST_SUITE_COMPLETE_EVENT,this.TEST_PASS_EVENT,this.TEST_FAIL_EVENT,this.TEST_IGNORE_EVENT,this.COMPLETE_EVENT,this.BEGIN_EVENT];for(var C=0;C<D.length;C++){this.createEv!
 ent(D[C],{scope:this});}}YAHOO.lang.extend(A,YAHOO.util.EventP!
 rovider,
{TEST_CASE_BEGIN_EVENT:"testcasebegin",TEST_CASE_COMPLETE_EVENT:"testcasecomplete",TEST_SUITE_BEGIN_EVENT:"testsuitebegin",TEST_SUITE_COMPLETE_EVENT:"testsuitecomplete",TEST_PASS_EVENT:"pass",TEST_FAIL_EVENT:"fail",TEST_IGNORE_EVENT:"ignore",COMPLETE_EVENT:"complete",BEGIN_EVENT:"begin",_addTestCaseToTestTree:function(C,D){var E=C.appendChild(D);for(var F in D){if(F.indexOf("test")===0&&YAHOO.lang.isFunction(D[F])){E.appendChild(F);}}},_addTestSuiteToTestTree:function(C,F){var E=C.appendChild(F);for(var D=0;D<F.items.length;D++){if(F.items[D] instanceof YAHOO.tool.TestSuite){this._addTestSuiteToTestTree(E,F.items[D]);}else{if(F.items[D] instanceof YAHOO.tool.TestCase){this._addTestCaseToTestTree(E,F.items[D]);}}}},_buildTestTree:function(){this._root=new B(this.masterSuite);this._cur=this._root;for(var C=0;C<this.masterSuite.items.length;C++){if(this.masterSuite.items[C] instanceof YAHOO.tool.TestSuite){this._addTestSuiteToTestTree(this._root,this.masterSuite.items[C]);}else!
 {if(this.masterSuite.items[C] instanceof YAHOO.tool.TestCase){this._addTestCaseToTestTree(this._root,this.masterSuite.items[C]);}}}},_handleTestObjectComplete:function(C){if(YAHOO.lang.isObject(C.testObject)){C.parent.results.passed+=C.results.passed;C.parent.results.failed+=C.results.failed;C.parent.results.total+=C.results.total;C.parent.results.ignored+=C.results.ignored;C.parent.results[C.testObject.name]=C.results;if(C.testObject instanceof YAHOO.tool.TestSuite){C.testObject.tearDown();this.fireEvent(this.TEST_SUITE_COMPLETE_EVENT,{testSuite:C.testObject,results:C.results});}else{if(C.testObject instanceof YAHOO.tool.TestCase){this.fireEvent(this.TEST_CASE_COMPLETE_EVENT,{testCase:C.testObject,results:C.results});}}}},_next:function(){if(this._cur.firstChild){this._cur=this._cur.firstChild;}else{if(this._cur.next){this._cur=this._cur.next;}else{while(this._cur&&!this._cur.next&&this._cur!==this._root){this._handleTestObjectComplete(this._cur);this._cur=this._cur.parent!
 ;}if(this._cur==this._root){this._cur.results.type="report";th!
 is._cur.
results.timestamp=(new Date()).toLocaleString();this.fireEvent(this.COMPLETE_EVENT,{results:this._cur.results});this._cur=null;}else{this._handleTestObjectComplete(this._cur);this._cur=this._cur.next;}}}return this._cur;},_run:function(){var E=false;var D=this._next();if(D!==null){var C=D.testObject;if(YAHOO.lang.isObject(C)){if(C instanceof YAHOO.tool.TestSuite){this.fireEvent(this.TEST_SUITE_BEGIN_EVENT,{testSuite:C});C.setUp();}else{if(C instanceof YAHOO.tool.TestCase){this.fireEvent(this.TEST_CASE_BEGIN_EVENT,{testCase:C});}}if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._run();},0);}else{this._run();}}else{this._runTest(D);}}},_resumeTest:function(G){var C=this._cur;var H=C.testObject;var E=C.parent.testObject;var K=(E._should.fail||{})[H];var D=(E._should.error||{})[H];var F=false;var I=null;try{G.apply(E);if(K){I=new YAHOO.util.ShouldFail();F=true;}else{if(D){I=new YAHOO.util.ShouldError();F=true;}}}catch(J){if(J instanceof YAHOO.util.A!
 ssertionError){if(!K){I=J;F=true;}}else{if(J instanceof YAHOO.tool.TestCase.Wait){if(YAHOO.lang.isFunction(J.segment)){if(YAHOO.lang.isNumber(J.delay)){if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._resumeTest(J.segment);},J.delay);}else{throw new Error("Asynchronous tests not supported in this environment.");}}}return ;}else{if(!D){I=new YAHOO.util.UnexpectedError(J);F=true;}else{if(YAHOO.lang.isString(D)){if(J.message!=D){I=new YAHOO.util.UnexpectedError(J);F=true;}}else{if(YAHOO.lang.isFunction(D)){if(!(J instanceof D)){I=new YAHOO.util.UnexpectedError(J);F=true;}}else{if(YAHOO.lang.isObject(D)){if(!(J instanceof D.constructor)||J.message!=D.message){I=new YAHOO.util.UnexpectedError(J);F=true;}}}}}}}}if(F){this.fireEvent(this.TEST_FAIL_EVENT,{testCase:E,testName:H,error:I});}else{this.fireEvent(this.TEST_PASS_EVENT,{testCase:E,testName:H});}E.tearDown();C.parent.results[H]={result:F?"fail":"pass",message:I?I.getMessage():"Test passed",typ!
 e:"test",name:H};
+if(F){C.parent.results.failed++;}else{C.parent.results.passed++;}C.parent.results.total++;if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._run();},0);}else{this._run();}},_runTest:function(F){var C=F.testObject;var D=F.parent.testObject;var G=D[C];var E=(D._should.ignore||{})[C];if(E){F.parent.results[C]={result:"ignore",message:"Test ignored",type:"test",name:C};F.parent.results.ignored++;F.parent.results.total++;this.fireEvent(this.TEST_IGNORE_EVENT,{testCase:D,testName:C});if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._run();},0);}else{this._run();}}else{D.setUp();this._resumeTest(G);}},fireEvent:function(C,D){D=D||{};D.type=C;A.superclass.fireEvent.call(this,C,D);},add:function(C){this.masterSuite.add(C);},clear:function(){this.masterSuite.items=[];},resume:function(C){this._resumeTest(C||function(){});},run:function(C){var D=YAHOO.tool.TestRunner;D._buildTestTree();D.fireEvent(D.BEGIN_EVENT);D._run();}});r!
 eturn new A();})();YAHOO.namespace("util");YAHOO.util.Assert={_formatMessage:function(B,A){var C=B;if(YAHOO.lang.isString(B)&&B.length>0){return YAHOO.lang.substitute(B,{message:A});}else{return A;}},fail:function(A){throw new YAHOO.util.AssertionError(this._formatMessage(A,"Test force-failed."));},areEqual:function(B,C,A){if(B!=C){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Values should be equal."),B,C);}},areNotEqual:function(A,C,B){if(A==C){throw new YAHOO.util.UnexpectedValue(this._formatMessage(B,"Values should not be equal."),A);}},areNotSame:function(A,C,B){if(A===C){throw new YAHOO.util.UnexpectedValue(this._formatMessage(B,"Values should not be the same."),A);}},areSame:function(B,C,A){if(B!==C){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Values should be the same."),B,C);}},isFalse:function(B,A){if(false!==B){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value should be false."),false,B);}},isTrue:function(B,A){!
 if(true!==B){throw new YAHOO.util.ComparisonFailure(this._form!
 atMessag
e(A,"Value should be true."),true,B);}},isNaN:function(B,A){if(!isNaN(B)){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value should be NaN."),NaN,B);}},isNotNaN:function(B,A){if(isNaN(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Values should not be NaN."),NaN);}},isNotNull:function(B,A){if(YAHOO.lang.isNull(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Values should not be null."),null);}},isNotUndefined:function(B,A){if(YAHOO.lang.isUndefined(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should not be undefined."),undefined);}},isNull:function(B,A){if(!YAHOO.lang.isNull(B)){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value should be null."),null,B);}},isUndefined:function(B,A){if(!YAHOO.lang.isUndefined(B)){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value should be undefined."),undefined,B);}},isArray:function(B,A){if(!YAHOO.lang.isArray(B)){throw new YAHOO.ut!
 il.UnexpectedValue(this._formatMessage(A,"Value should be an array."),B);}},isBoolean:function(B,A){if(!YAHOO.lang.isBoolean(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be a Boolean."),B);}},isFunction:function(B,A){if(!YAHOO.lang.isFunction(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be a function."),B);}},isInstanceOf:function(B,C,A){if(!(C instanceof B)){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value isn't an instance of expected type."),B,C);}},isNumber:function(B,A){if(!YAHOO.lang.isNumber(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be a number."),B);}},isObject:function(B,A){if(!YAHOO.lang.isObject(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be an object."),B);}},isString:function(B,A){if(!YAHOO.lang.isString(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be a string."),B);}},isTypeOf:fun!
 ction(A,C,B){if(typeof C!=A){throw new YAHOO.util.ComparisonFa!
 ilure(th
is._formatMessage(B,"Value should be of type "+expected+"."),expected,typeof actual);}}};YAHOO.util.AssertionError=function(A){arguments.callee.superclass.constructor.call(this,A);this.message=A;this.name="AssertionError";};YAHOO.lang.extend(YAHOO.util.AssertionError,Error,{getMessage:function(){return this.message;},toString:function(){return this.name+": "+this.getMessage();},valueOf:function(){return this.toString();}});YAHOO.util.ComparisonFailure=function(B,A,C){arguments.callee.superclass.constructor.call(this,B);this.expected=A;this.actual=C;this.name="ComparisonFailure";};YAHOO.lang.extend(YAHOO.util.ComparisonFailure,YAHOO.util.AssertionError,{getMessage:function(){return this.message+"\nExpected: "+this.expected+" ("+(typeof this.expected)+")\nActual:"+this.actual+" ("+(typeof this.actual)+")";}});YAHOO.util.UnexpectedValue=function(B,A){arguments.callee.superclass.constructor.call(this,B);this.unexpected=A;this.name="UnexpectedValue";};YAHOO.lang.extend(YAHOO.util!
 .UnexpectedValue,YAHOO.util.AssertionError,{getMessage:function(){return this.message+"\nUnexpected: "+this.unexpected+" ("+(typeof this.unexpected)+") ";}});YAHOO.util.ShouldFail=function(A){arguments.callee.superclass.constructor.call(this,A||"This test should fail but didn't.");this.name="ShouldFail";};YAHOO.lang.extend(YAHOO.util.ShouldFail,YAHOO.util.AssertionError);YAHOO.util.ShouldError=function(A){arguments.callee.superclass.constructor.call(this,A||"This test should have thrown an error but didn't.");this.name="ShouldError";};YAHOO.lang.extend(YAHOO.util.ShouldError,YAHOO.util.AssertionError);YAHOO.util.UnexpectedError=function(A){arguments.callee.superclass.constructor.call(this,"Unexpected error: "+A.message);this.cause=A;this.name="UnexpectedError";this.stack=A.stack;};YAHOO.lang.extend(YAHOO.util.UnexpectedError,YAHOO.util.AssertionError);YAHOO.util.ArrayAssert={contains:function(E,D,B){var C=false;
+var F=YAHOO.util.Assert;for(var A=0;A<D.length&&!C;A++){if(D[A]===E){C=true;}}if(!C){F.fail(F._formatMessage(B,"Value "+E+" ("+(typeof E)+") not found in array ["+D+"]."));}},containsItems:function(C,D,B){for(var A=0;A<C.length;A++){this.contains(C[A],D,B);}},containsMatch:function(E,D,B){if(typeof E!="function"){throw new TypeError("ArrayAssert.containsMatch(): First argument must be a function.");}var C=false;var F=YAHOO.util.Assert;for(var A=0;A<D.length&&!C;A++){if(E(D[A])){C=true;}}if(!C){F.fail(F._formatMessage(B,"No match found in array ["+D+"]."));}},doesNotContain:function(E,D,B){var C=false;var F=YAHOO.util.Assert;for(var A=0;A<D.length&&!C;A++){if(D[A]===E){C=true;}}if(C){F.fail(F._formatMessage(B,"Value found in array ["+D+"]."));}},doesNotContainItems:function(C,D,B){for(var A=0;A<C.length;A++){this.doesNotContain(C[A],D,B);}},doesNotContainMatch:function(E,D,B){if(typeof E!="function"){throw new TypeError("ArrayAssert.doesNotContainMatch(): First argument must!
  be a function.");}var C=false;var F=YAHOO.util.Assert;for(var A=0;A<D.length&&!C;A++){if(E(D[A])){C=true;}}if(C){F.fail(F._formatMessage(B,"Value found in array ["+D+"]."));}},indexOf:function(E,D,A,C){for(var B=0;B<D.length;B++){if(D[B]===E){YAHOO.util.Assert.areEqual(A,B,C||"Value exists at index "+B+" but should be at index "+A+".");return ;}}var F=YAHOO.util.Assert;F.fail(F._formatMessage(C,"Value doesn't exist in array ["+D+"]."));},itemsAreEqual:function(D,F,C){var A=Math.max(D.length,F.length);var E=YAHOO.util.Assert;for(var B=0;B<A;B++){E.areEqual(D[B],F[B],E._formatMessage(C,"Values in position "+B+" are not equal."));}},itemsAreEquivalent:function(E,F,B,D){if(typeof B!="function"){throw new TypeError("ArrayAssert.itemsAreEquivalent(): Third argument must be a function.");}var A=Math.max(E.length,F.length);for(var C=0;C<A;C++){if(!B(E[C],F[C])){throw new YAHOO.util.ComparisonFailure(YAHOO.util.Assert._formatMessage(D,"Values in position "+C+" are not equivalent.")!
 ,E[C],F[C]);}}},isEmpty:function(C,A){if(C.length>0){var B=YAH!
 OO.util.
Assert;B.fail(B._formatMessage(A,"Array should be empty."));}},isNotEmpty:function(C,A){if(C.length===0){var B=YAHOO.util.Assert;B.fail(B._formatMessage(A,"Array should not be empty."));}},itemsAreSame:function(D,F,C){var A=Math.max(D.length,F.length);var E=YAHOO.util.Assert;for(var B=0;B<A;B++){E.areSame(D[B],F[B],E._formatMessage(C,"Values in position "+B+" are not the same."));}},lastIndexOf:function(E,D,A,C){var F=YAHOO.util.Assert;for(var B=D.length;B>=0;B--){if(D[B]===E){F.areEqual(A,B,F._formatMessage(C,"Value exists at index "+B+" but should be at index "+A+"."));return ;}}F.fail(F._formatMessage(C,"Value doesn't exist in array."));}};YAHOO.namespace("util");YAHOO.util.ObjectAssert={propertiesAreEqual:function(D,G,C){var F=YAHOO.util.Assert;var B=[];for(var E in D){B.push(E);}for(var A=0;A<B.length;A++){F.isNotUndefined(G[B[A]],F._formatMessage(C,"Property '"+B[A]+"' expected."));}},hasProperty:function(A,B,C){if(!(A in B)){var D=YAHOO.util.Assert;D.fail(D._formatMes!
 sage(C,"Property '"+A+"' not found on object."));}},hasOwnProperty:function(A,B,C){if(!YAHOO.lang.hasOwnProperty(B,A)){var D=YAHOO.util.Assert;D.fail(D._formatMessage(C,"Property '"+A+"' not found on object instance."));}}};YAHOO.util.DateAssert={datesAreEqual:function(B,D,A){if(B instanceof Date&&D instanceof Date){var C=YAHOO.util.Assert;C.areEqual(B.getFullYear(),D.getFullYear(),C._formatMessage(A,"Years should be equal."));C.areEqual(B.getMonth(),D.getMonth(),C._formatMessage(A,"Months should be equal."));C.areEqual(B.getDate(),D.getDate(),C._formatMessage(A,"Day of month should be equal."));}else{throw new TypeError("DateAssert.datesAreEqual(): Expected and actual values must be Date objects.");}},timesAreEqual:function(B,D,A){if(B instanceof Date&&D instanceof Date){var C=YAHOO.util.Assert;C.areEqual(B.getHours(),D.getHours(),C._formatMessage(A,"Hours should be equal."));C.areEqual(B.getMinutes(),D.getMinutes(),C._formatMessage(A,"Minutes should be equal."));C.areEqua!
 l(B.getSeconds(),D.getSeconds(),C._formatMessage(A,"Seconds sh!
 ould be 
equal."));}else{throw new TypeError("DateAssert.timesAreEqual(): Expected and actual values must be Date objects.");}}};YAHOO.namespace("util");YAHOO.util.UserAction={simulateKeyEvent:function(F,J,E,C,L,B,A,K,H,N,M){F=YAHOO.util.Dom.get(F);if(!F){throw new Error("simulateKeyEvent(): Invalid target.");}if(YAHOO.lang.isString(J)){J=J.toLowerCase();switch(J){case"keyup":case"keydown":case"keypress":break;case"textevent":J="keypress";break;default:throw new Error("simulateKeyEvent(): Event type '"+J+"' not supported.");}}else{throw new Error("simulateKeyEvent(): Event type must be a string.");}if(!YAHOO.lang.isBoolean(E)){E=true;}if(!YAHOO.lang.isBoolean(C)){C=true;}if(!YAHOO.lang.isObject(L)){L=window;}if(!YAHOO.lang.isBoolean(B)){B=false;}if(!YAHOO.lang.isBoolean(A)){A=false;}if(!YAHOO.lang.isBoolean(K)){K=false;}if(!YAHOO.lang.isBoolean(H)){H=false;}if(!YAHOO.lang.isNumber(N)){N=0;}if(!YAHOO.lang.isNumber(M)){M=0;}var I=null;if(YAHOO.lang.isFunction(document.createEvent)){try!
 {I=document.createEvent("KeyEvents");I.initKeyEvent(J,E,C,L,B,A,K,H,N,M);}catch(G){try{I=document.createEvent("Events");}catch(D){I=document.createEvent("UIEvents");}finally{I.initEvent(J,E,C);I.view=L;I.altKey=A;I.ctrlKey=B;I.shiftKey=K;I.metaKey=H;I.keyCode=N;I.charCode=M;}}F.dispatchEvent(I);}else{if(YAHOO.lang.isObject(document.createEventObject)){I=document.createEventObject();I.bubbles=E;I.cancelable=C;I.view=L;I.ctrlKey=B;I.altKey=A;I.shiftKey=K;I.metaKey=H;I.keyCode=(M>0)?M:N;F.fireEvent("on"+J,I);}else{throw new Error("simulateKeyEvent(): No event simulation framework present.");}}},simulateMouseEvent:function(K,P,H,E,Q,J,G,F,D,B,C,A,O,M,I,L){K=YAHOO.util.Dom.get(K);if(!K){throw new Error("simulateMouseEvent(): Invalid target.");}if(YAHOO.lang.isString(P)){P=P.toLowerCase();switch(P){case"mouseover":case"mouseout":case"mousedown":case"mouseup":case"click":case"dblclick":case"mousemove":break;default:throw new Error("simulateMouseEvent(): Event type '"+P+"' not supp!
 orted.");
+}}else{throw new Error("simulateMouseEvent(): Event type must be a string.");}if(!YAHOO.lang.isBoolean(H)){H=true;}if(!YAHOO.lang.isBoolean(E)){E=(P!="mousemove");}if(!YAHOO.lang.isObject(Q)){Q=window;}if(!YAHOO.lang.isNumber(J)){J=1;}if(!YAHOO.lang.isNumber(G)){G=0;}if(!YAHOO.lang.isNumber(F)){F=0;}if(!YAHOO.lang.isNumber(D)){D=0;}if(!YAHOO.lang.isNumber(B)){B=0;}if(!YAHOO.lang.isBoolean(C)){C=false;}if(!YAHOO.lang.isBoolean(A)){A=false;}if(!YAHOO.lang.isBoolean(O)){O=false;}if(!YAHOO.lang.isBoolean(M)){M=false;}if(!YAHOO.lang.isNumber(I)){I=0;}var N=null;if(YAHOO.lang.isFunction(document.createEvent)){N=document.createEvent("MouseEvents");if(N.initMouseEvent){N.initMouseEvent(P,H,E,Q,J,G,F,D,B,C,A,O,M,I,L);}else{N=document.createEvent("UIEvents");N.initEvent(P,H,E);N.view=Q;N.detail=J;N.screenX=G;N.screenY=F;N.clientX=D;N.clientY=B;N.ctrlKey=C;N.altKey=A;N.metaKey=M;N.shiftKey=O;N.button=I;N.relatedTarget=L;}if(L&&!N.relatedTarget){if(P=="mouseout"){N.toElement=L;}else{if!
 (P=="mouseover"){N.fromElement=L;}}}K.dispatchEvent(N);}else{if(YAHOO.lang.isObject(document.createEventObject)){N=document.createEventObject();N.bubbles=H;N.cancelable=E;N.view=Q;N.detail=J;N.screenX=G;N.screenY=F;N.clientX=D;N.clientY=B;N.ctrlKey=C;N.altKey=A;N.metaKey=M;N.shiftKey=O;switch(I){case 0:N.button=1;break;case 1:N.button=4;break;case 2:break;default:N.button=0;}N.relatedTarget=L;K.fireEvent("on"+P,N);}else{throw new Error("simulateMouseEvent(): No event simulation framework present.");}}},fireMouseEvent:function(C,B,A){A=A||{};this.simulateMouseEvent(C,B,A.bubbles,A.cancelable,A.view,A.detail,A.screenX,A.screenY,A.clientX,A.clientY,A.ctrlKey,A.altKey,A.shiftKey,A.metaKey,A.button,A.relatedTarget);},click:function(B,A){this.fireMouseEvent(B,"click",A);},dblclick:function(B,A){this.fireMouseEvent(B,"dblclick",A);},mousedown:function(B,A){this.fireMouseEvent(B,"mousedown",A);},mousemove:function(B,A){this.fireMouseEvent(B,"mousemove",A);},mouseout:function(B,A){t!
 his.fireMouseEvent(B,"mouseout",A);},mouseover:function(B,A){t!
 his.fire
MouseEvent(B,"mouseover",A);},mouseup:function(B,A){this.fireMouseEvent(B,"mouseup",A);},fireKeyEvent:function(B,C,A){A=A||{};this.simulateKeyEvent(C,B,A.bubbles,A.cancelable,A.view,A.ctrlKey,A.altKey,A.shiftKey,A.metaKey,A.keyCode,A.charCode);},keydown:function(B,A){this.fireKeyEvent("keydown",B,A);},keypress:function(B,A){this.fireKeyEvent("keypress",B,A);},keyup:function(B,A){this.fireKeyEvent("keyup",B,A);}};YAHOO.namespace("tool");YAHOO.tool.TestManager={TEST_PAGE_BEGIN_EVENT:"testpagebegin",TEST_PAGE_COMPLETE_EVENT:"testpagecomplete",TEST_MANAGER_BEGIN_EVENT:"testmanagerbegin",TEST_MANAGER_COMPLETE_EVENT:"testmanagercomplete",_curPage:null,_frame:null,_logger:null,_timeoutId:0,_pages:[],_results:null,_handleTestRunnerComplete:function(A){this.fireEvent(this.TEST_PAGE_COMPLETE_EVENT,{page:this._curPage,results:A.results});this._processResults(this._curPage,A.results);this._logger.clearTestRunner();if(this._pages.length){this._timeoutId=setTimeout(function(){YAHOO.tool.T!
 estManager._run();},1000);}else{this.fireEvent(this.TEST_MANAGER_COMPLETE_EVENT,this._results);}},_processResults:function(C,A){var B=this._results;B.passed+=A.passed;B.failed+=A.failed;B.ignored+=A.ignored;B.total+=A.total;if(A.failed){B.failedPages.push(C);}else{B.passedPages.push(C);}A.name=C;A.type="page";B[C]=A;},_run:function(){this._curPage=this._pages.shift();this.fireEvent(this.TEST_PAGE_BEGIN_EVENT,this._curPage);this._frame.location.replace(this._curPage);},load:function(){if(parent.YAHOO.tool.TestManager!==this){parent.YAHOO.tool.TestManager.load();}else{if(this._frame){var A=this._frame.YAHOO.tool.TestRunner;this._logger.setTestRunner(A);A.subscribe(A.COMPLETE_EVENT,this._handleTestRunnerComplete,this,true);A.run();}}},setPages:function(A){this._pages=A;},start:function(){if(!this._initialized){this.createEvent(this.TEST_PAGE_BEGIN_EVENT);this.createEvent(this.TEST_PAGE_COMPLETE_EVENT);this.createEvent(this.TEST_MANAGER_BEGIN_EVENT);this.createEvent(this.TEST_M!
 ANAGER_COMPLETE_EVENT);if(!this._frame){var A=document.createE!
 lement("
iframe");A.style.visibility="hidden";A.style.position="absolute";document.body.appendChild(A);this._frame=A.contentWindow||A.contentDocument.ownerWindow;}if(!this._logger){this._logger=new YAHOO.tool.TestLogger();}this._initialized=true;}this._results={passed:0,failed:0,ignored:0,total:0,type:"report",name:"YUI Test Results",failedPages:[],passedPages:[]};this.fireEvent(this.TEST_MANAGER_BEGIN_EVENT,null);this._run();},stop:function(){clearTimeout(this._timeoutId);}};YAHOO.lang.augmentObject(YAHOO.tool.TestManager,YAHOO.util.EventProvider.prototype);YAHOO.namespace("tool");YAHOO.tool.TestLogger=function(B,A){YAHOO.tool.TestLogger.superclass.constructor.call(this,B,A);this.init();};YAHOO.lang.extend(YAHOO.tool.TestLogger,YAHOO.widget.LogReader,{footerEnabled:true,newestOnTop:false,formatMsg:function(B){var A=B.category;var C=this.html2Text(B.msg);return"<pre><p><span class=\""+A+"\">"+A.toUpperCase()+"</span> "+C+"</p></pre>";},init:function(){if(YAHOO.tool.TestRunner){this.s!
 etTestRunner(YAHOO.tool.TestRunner);}this.hideSource("global");this.hideSource("LogReader");this.hideCategory("warn");this.hideCategory("window");this.hideCategory("time");this.clearConsole();},clearTestRunner:function(){if(this._runner){this._runner.unsubscribeAll();this._runner=null;}},setTestRunner:function(A){if(this._runner){this.clearTestRunner();}this._runner=A;A.subscribe(A.TEST_PASS_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_FAIL_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_IGNORE_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.BEGIN_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.COMPLETE_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_SUITE_BEGIN_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_SUITE_COMPLETE_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_CASE_BEGIN_EVENT,this._handleTestRunnerEvent,this,true);
+A.subscribe(A.TEST_CASE_COMPLETE_EVENT,this._handleTestRunnerEvent,this,true);},_handleTestRunnerEvent:function(D){var A=YAHOO.tool.TestRunner;var C="";var B="";switch(D.type){case A.BEGIN_EVENT:C="Testing began at "+(new Date()).toString()+".";B="info";break;case A.COMPLETE_EVENT:C="Testing completed at "+(new Date()).toString()+".\nPassed:"+D.results.passed+" Failed:"+D.results.failed+" Total:"+D.results.total;B="info";break;case A.TEST_FAIL_EVENT:C=D.testName+": "+D.error.getMessage();B="fail";break;case A.TEST_IGNORE_EVENT:C=D.testName+": ignored.";B="ignore";break;case A.TEST_PASS_EVENT:C=D.testName+": passed.";B="pass";break;case A.TEST_SUITE_BEGIN_EVENT:C="Test suite \""+D.testSuite.name+"\" started.";B="info";break;case A.TEST_SUITE_COMPLETE_EVENT:C="Test suite \""+D.testSuite.name+"\" completed.\nPassed:"+D.results.passed+" Failed:"+D.results.failed+" Total:"+D.results.total;B="info";break;case A.TEST_CASE_BEGIN_EVENT:C="Test case \""+D.testCase.name+"\" started.";!
 B="info";break;case A.TEST_CASE_COMPLETE_EVENT:C="Test case \""+D.testCase.name+"\" completed.\nPassed:"+D.results.passed+" Failed:"+D.results.failed+" Total:"+D.results.total;B="info";break;default:C="Unexpected event "+D.type;C="info";}YAHOO.log(C,B,"TestRunner");}});YAHOO.namespace("tool.TestFormat");YAHOO.tool.TestFormat.JSON=function(A){return YAHOO.lang.JSON.stringify(A);};YAHOO.tool.TestFormat.XML=function(C){var A=YAHOO.lang;var B="<"+C.type+" name=\""+C.name.replace(/"/g,""").replace(/'/g,"'")+"\"";if(C.type=="test"){B+=" result=\""+C.result+"\" message=\""+C.message+"\">";}else{B+=" passed=\""+C.passed+"\" failed=\""+C.failed+"\" ignored=\""+C.ignored+"\" total=\""+C.total+"\">";for(var D in C){if(A.hasOwnProperty(C,D)&&A.isObject(C[D])&&!A.isArray(C[D])){B+=arguments.callee(C[D]);}}}B+="</"+C.type+">";return B;};YAHOO.namespace("tool");YAHOO.tool.TestReporter=function(A,B){this.url=A;this.format=B||YAHOO.tool.TestFormat.XML;this._fields=new Object();thi!
 s._form=null;this._iframe=null;};YAHOO.tool.TestReporter.proto!
 type={co
nstructor:YAHOO.tool.TestReporter,addField:function(A,B){this._fields[A]=B;},clearFields:function(){this._fields=new Object();},destroy:function(){if(this._form){this._form.parentNode.removeChild(this._form);this._form=null;}if(this._iframe){this._iframe.parentNode.removeChild(this._iframe);this._iframe=null;}this._fields=null;},report:function(A){if(!this._form){this._form=document.createElement("form");this._form.method="post";this._form.style.visibility="hidden";this._form.style.position="absolute";this._form.style.top=0;document.body.appendChild(this._form);if(YAHOO.env.ua.ie){this._iframe=document.createElement("<iframe name=\"yuiTestTarget\" />");}else{this._iframe=document.createElement("iframe");this._iframe.name="yuiTestTarget";}this._iframe.src="javascript:false";this._iframe.style.visibility="hidden";this._iframe.style.position="absolute";this._iframe.style.top=0;document.body.appendChild(this._iframe);this._form.target="yuiTestTarget";}this._form.action=this.url;!
 while(this._form.hasChildNodes()){this._form.removeChild(this._form.lastChild);}this._fields.results=this.format(A);this._fields.useragent=navigator.userAgent;this._fields.timestamp=(new Date()).toLocaleString();for(var B in this._fields){if(YAHOO.lang.hasOwnProperty(this._fields,B)&&typeof this._fields[B]!="function"){if(YAHOO.env.ua.ie){input=document.createElement("<input name=\""+B+"\" >");}else{input=document.createElement("input");input.name=B;}input.type="hidden";input.value=this._fields[B];this._form.appendChild(input);}}delete this._fields.results;delete this._fields.useragent;delete this._fields.timestamp;if(arguments[1]!==false){this._form.submit();}}};YAHOO.register("yuitest",YAHOO.tool.TestRunner,{version:"2.5.1",build:"984"});
\ No newline at end of file

Added: trunk/root/static/yui/yuitest/yuitest.js
===================================================================
--- trunk/root/static/yui/yuitest/yuitest.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/yuitest.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,3313 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+YAHOO.namespace("tool");
+
+//-----------------------------------------------------------------------------
+// TestCase object
+//-----------------------------------------------------------------------------
+
+/**
+ * Test case containing various tests to run.
+ * @param template An object containing any number of test methods, other methods,
+ *                 an optional name, and anything else the test case needs.
+ * @class TestCase
+ * @namespace YAHOO.tool
+ * @constructor
+ */
+YAHOO.tool.TestCase = function (template /*:Object*/) {
+    
+    /**
+     * Special rules for the test case. Possible subobjects
+     * are fail, for tests that should fail, and error, for
+     * tests that should throw an error.
+     */
+    this._should /*:Object*/ = {};
+    
+    //copy over all properties from the template to this object
+    for (var prop in template) {
+        this[prop] = template[prop];
+    }    
+    
+    //check for a valid name
+    if (!YAHOO.lang.isString(this.name)){
+        /**
+         * Name for the test case.
+         */
+        this.name /*:String*/ = YAHOO.util.Dom.generateId(null, "testCase");
+    }
+
+};
+
+
+YAHOO.tool.TestCase.prototype = {  
+
+    /**
+     * Resumes a paused test and runs the given function.
+     * @param {Function} segment (Optional) The function to run.
+     *      If omitted, the test automatically passes.
+     * @return {Void}
+     * @method resume
+     */
+    resume : function (segment /*:Function*/) /*:Void*/ {
+        YAHOO.tool.TestRunner.resume(segment);
+    },
+
+    /**
+     * Causes the test case to wait a specified amount of time and then
+     * continue executing the given code.
+     * @param {Function} segment (Optional) The function to run after the delay.
+     *      If omitted, the TestRunner will wait until resume() is called.
+     * @param {int} delay (Optional) The number of milliseconds to wait before running
+     *      the function. If omitted, defaults to zero.
+     * @return {Void}
+     * @method wait
+     */
+    wait : function (segment /*:Function*/, delay /*:int*/) /*:Void*/{
+        throw new YAHOO.tool.TestCase.Wait(segment, delay);
+    },
+
+    //-------------------------------------------------------------------------
+    // Stub Methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Function to run before each test is executed.
+     * @return {Void}
+     * @method setUp
+     */
+    setUp : function () /*:Void*/ {
+    },
+    
+    /**
+     * Function to run after each test is executed.
+     * @return {Void}
+     * @method tearDown
+     */
+    tearDown: function () /*:Void*/ {    
+    }
+};
+
+/**
+ * Represents a stoppage in test execution to wait for an amount of time before
+ * continuing.
+ * @param {Function} segment A function to run when the wait is over.
+ * @param {int} delay The number of milliseconds to wait before running the code.
+ * @class Wait
+ * @namespace YAHOO.tool.TestCase
+ * @constructor
+ *
+ */
+YAHOO.tool.TestCase.Wait = function (segment /*:Function*/, delay /*:int*/) {
+    
+    /**
+     * The segment of code to run when the wait is over.
+     * @type Function
+     * @property segment
+     */
+    this.segment /*:Function*/ = (YAHOO.lang.isFunction(segment) ? segment : null);
+
+    /**
+     * The delay before running the segment of code.
+     * @type int
+     * @property delay
+     */
+    this.delay /*:int*/ = (YAHOO.lang.isNumber(delay) ? delay : 0);
+
+};
+
+YAHOO.namespace("tool");
+
+
+//-----------------------------------------------------------------------------
+// TestSuite object
+//-----------------------------------------------------------------------------
+
+/**
+ * A test suite that can contain a collection of TestCase and TestSuite objects.
+ * @param {String||Object} data The name of the test suite or an object containing
+ *      a name property as well as setUp and tearDown methods.
+ * @namespace YAHOO.tool
+ * @class TestSuite
+ * @constructor
+ */
+YAHOO.tool.TestSuite = function (data /*:String||Object*/) {
+
+    /**
+     * The name of the test suite.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "";
+
+    /**
+     * Array of test suites and
+     * @private
+     */
+    this.items /*:Array*/ = [];
+
+    //initialize the properties
+    if (YAHOO.lang.isString(data)){
+        this.name = data;
+    } else if (YAHOO.lang.isObject(data)){
+        YAHOO.lang.augmentObject(this, data, true);
+    }
+
+    //double-check name
+    if (this.name === ""){
+        this.name = YAHOO.util.Dom.generateId(null, "testSuite");
+    }
+
+};
+
+YAHOO.tool.TestSuite.prototype = {
+    
+    /**
+     * Adds a test suite or test case to the test suite.
+     * @param {YAHOO.tool.TestSuite||YAHOO.tool.TestCase} testObject The test suite or test case to add.
+     * @return {Void}
+     * @method add
+     */
+    add : function (testObject /*:YAHOO.tool.TestSuite*/) /*:Void*/ {
+        if (testObject instanceof YAHOO.tool.TestSuite || testObject instanceof YAHOO.tool.TestCase) {
+            this.items.push(testObject);
+        }
+    },
+    
+    //-------------------------------------------------------------------------
+    // Stub Methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Function to run before each test is executed.
+     * @return {Void}
+     * @method setUp
+     */
+    setUp : function () /*:Void*/ {
+    },
+    
+    /**
+     * Function to run after each test is executed.
+     * @return {Void}
+     * @method tearDown
+     */
+    tearDown: function () /*:Void*/ {
+    }
+    
+};
+
+YAHOO.namespace("tool");
+
+/**
+ * The YUI test tool
+ * @module yuitest
+ * @namespace YAHOO.tool
+ * @requires yahoo,dom,event,logger
+ */
+
+
+//-----------------------------------------------------------------------------
+// TestRunner object
+//-----------------------------------------------------------------------------
+
+/**
+ * Runs test suites and test cases, providing events to allowing for the
+ * interpretation of test results.
+ * @namespace YAHOO.tool
+ * @class TestRunner
+ * @static
+ */
+YAHOO.tool.TestRunner = (function(){
+
+    /**
+     * A node in the test tree structure. May represent a TestSuite, TestCase, or
+     * test function.
+     * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.
+     * @class TestNode
+     * @constructor
+     * @private
+     */
+    function TestNode(testObject /*:Variant*/){
+    
+        /**
+         * The TestSuite, TestCase, or test function represented by this node.
+         * @type Variant
+         * @property testObject
+         */
+        this.testObject = testObject;
+        
+        /**
+         * Pointer to this node's first child.
+         * @type TestNode
+         * @property firstChild
+         */        
+        this.firstChild /*:TestNode*/ = null;
+        
+        /**
+         * Pointer to this node's last child.
+         * @type TestNode
+         * @property lastChild
+         */        
+        this.lastChild = null;
+        
+        /**
+         * Pointer to this node's parent.
+         * @type TestNode
+         * @property parent
+         */        
+        this.parent = null; 
+   
+        /**
+         * Pointer to this node's next sibling.
+         * @type TestNode
+         * @property next
+         */        
+        this.next = null;
+        
+        /**
+         * Test results for this test object.
+         * @type object
+         * @property results
+         */                
+        this.results /*:Object*/ = {
+            passed : 0,
+            failed : 0,
+            total : 0,
+            ignored : 0
+        };
+        
+        //initialize results
+        if (testObject instanceof YAHOO.tool.TestSuite){
+            this.results.type = "testsuite";
+            this.results.name = testObject.name;
+        } else if (testObject instanceof YAHOO.tool.TestCase){
+            this.results.type = "testcase";
+            this.results.name = testObject.name;
+        }
+       
+    }
+    
+    TestNode.prototype = {
+    
+        /**
+         * Appends a new test object (TestSuite, TestCase, or test function name) as a child
+         * of this node.
+         * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.
+         * @return {Void}
+         */
+        appendChild : function (testObject /*:Variant*/) /*:Void*/{
+            var node = new TestNode(testObject);
+            if (this.firstChild === null){
+                this.firstChild = this.lastChild = node;
+            } else {
+                this.lastChild.next = node;
+                this.lastChild = node;
+            }
+            node.parent = this;
+            return node;
+        }       
+    };
+
+    function TestRunner(){
+    
+        //inherit from EventProvider
+        TestRunner.superclass.constructor.apply(this,arguments);
+        
+        /**
+         * Suite on which to attach all TestSuites and TestCases to be run.
+         * @type YAHOO.tool.TestSuite
+         * @property masterSuite
+         * @private
+         */
+        this.masterSuite /*:YAHOO.tool.TestSuite*/ = new YAHOO.tool.TestSuite("YUI Test Results");        
+
+        /**
+         * Pointer to the current node in the test tree.
+         * @type TestNode
+         * @private
+         * @property _cur
+         */
+        this._cur = null;
+        
+        /**
+         * Pointer to the root node in the test tree.
+         * @type TestNode
+         * @private
+         * @property _root
+         */
+        this._root = null;
+        
+        //create events
+        var events /*:Array*/ = [
+            this.TEST_CASE_BEGIN_EVENT,
+            this.TEST_CASE_COMPLETE_EVENT,
+            this.TEST_SUITE_BEGIN_EVENT,
+            this.TEST_SUITE_COMPLETE_EVENT,
+            this.TEST_PASS_EVENT,
+            this.TEST_FAIL_EVENT,
+            this.TEST_IGNORE_EVENT,
+            this.COMPLETE_EVENT,
+            this.BEGIN_EVENT
+        ];
+        for (var i=0; i < events.length; i++){
+            this.createEvent(events[i], { scope: this });
+        }       
+   
+    }
+    
+    YAHOO.lang.extend(TestRunner, YAHOO.util.EventProvider, {
+    
+        //-------------------------------------------------------------------------
+        // Constants
+        //-------------------------------------------------------------------------
+         
+        /**
+         * Fires when a test case is opened but before the first 
+         * test is executed.
+         * @event testcasebegin
+         */         
+        TEST_CASE_BEGIN_EVENT /*:String*/ : "testcasebegin",
+        
+        /**
+         * Fires when all tests in a test case have been executed.
+         * @event testcasecomplete
+         */        
+        TEST_CASE_COMPLETE_EVENT /*:String*/ : "testcasecomplete",
+        
+        /**
+         * Fires when a test suite is opened but before the first 
+         * test is executed.
+         * @event testsuitebegin
+         */        
+        TEST_SUITE_BEGIN_EVENT /*:String*/ : "testsuitebegin",
+        
+        /**
+         * Fires when all test cases in a test suite have been
+         * completed.
+         * @event testsuitecomplete
+         */        
+        TEST_SUITE_COMPLETE_EVENT /*:String*/ : "testsuitecomplete",
+        
+        /**
+         * Fires when a test has passed.
+         * @event pass
+         */        
+        TEST_PASS_EVENT /*:String*/ : "pass",
+        
+        /**
+         * Fires when a test has failed.
+         * @event fail
+         */        
+        TEST_FAIL_EVENT /*:String*/ : "fail",
+        
+        /**
+         * Fires when a test has been ignored.
+         * @event ignore
+         */        
+        TEST_IGNORE_EVENT /*:String*/ : "ignore",
+        
+        /**
+         * Fires when all test suites and test cases have been completed.
+         * @event complete
+         */        
+        COMPLETE_EVENT /*:String*/ : "complete",
+        
+        /**
+         * Fires when the run() method is called.
+         * @event begin
+         */        
+        BEGIN_EVENT /*:String*/ : "begin",    
+        
+        //-------------------------------------------------------------------------
+        // Test Tree-Related Methods
+        //-------------------------------------------------------------------------
+
+        /**
+         * Adds a test case to the test tree as a child of the specified node.
+         * @param {TestNode} parentNode The node to add the test case to as a child.
+         * @param {YAHOO.tool.TestCase} testCase The test case to add.
+         * @return {Void}
+         * @static
+         * @private
+         * @method _addTestCaseToTestTree
+         */
+       _addTestCaseToTestTree : function (parentNode /*:TestNode*/, testCase /*:YAHOO.tool.TestCase*/) /*:Void*/{
+            
+            //add the test suite
+            var node = parentNode.appendChild(testCase);
+            
+            //iterate over the items in the test case
+            for (var prop in testCase){
+                if (prop.indexOf("test") === 0 && YAHOO.lang.isFunction(testCase[prop])){
+                    node.appendChild(prop);
+                }
+            }
+         
+        },
+        
+        /**
+         * Adds a test suite to the test tree as a child of the specified node.
+         * @param {TestNode} parentNode The node to add the test suite to as a child.
+         * @param {YAHOO.tool.TestSuite} testSuite The test suite to add.
+         * @return {Void}
+         * @static
+         * @private
+         * @method _addTestSuiteToTestTree
+         */
+        _addTestSuiteToTestTree : function (parentNode /*:TestNode*/, testSuite /*:YAHOO.tool.TestSuite*/) /*:Void*/ {
+            
+            //add the test suite
+            var node = parentNode.appendChild(testSuite);
+            
+            //iterate over the items in the master suite
+            for (var i=0; i < testSuite.items.length; i++){
+                if (testSuite.items[i] instanceof YAHOO.tool.TestSuite) {
+                    this._addTestSuiteToTestTree(node, testSuite.items[i]);
+                } else if (testSuite.items[i] instanceof YAHOO.tool.TestCase) {
+                    this._addTestCaseToTestTree(node, testSuite.items[i]);
+                }                   
+            }            
+        },
+        
+        /**
+         * Builds the test tree based on items in the master suite. The tree is a hierarchical
+         * representation of the test suites, test cases, and test functions. The resulting tree
+         * is stored in _root and the pointer _cur is set to the root initially.
+         * @return {Void}
+         * @static
+         * @private
+         * @method _buildTestTree
+         */
+        _buildTestTree : function () /*:Void*/ {
+        
+            this._root = new TestNode(this.masterSuite);
+            this._cur = this._root;
+            
+            //iterate over the items in the master suite
+            for (var i=0; i < this.masterSuite.items.length; i++){
+                if (this.masterSuite.items[i] instanceof YAHOO.tool.TestSuite) {
+                    this._addTestSuiteToTestTree(this._root, this.masterSuite.items[i]);
+                } else if (this.masterSuite.items[i] instanceof YAHOO.tool.TestCase) {
+                    this._addTestCaseToTestTree(this._root, this.masterSuite.items[i]);
+                }                   
+            }            
+        
+        }, 
+    
+        //-------------------------------------------------------------------------
+        // Private Methods
+        //-------------------------------------------------------------------------
+        
+        /**
+         * Handles the completion of a test object's tests. Tallies test results 
+         * from one level up to the next.
+         * @param {TestNode} node The TestNode representing the test object.
+         * @return {Void}
+         * @method _handleTestObjectComplete
+         * @private
+         */
+        _handleTestObjectComplete : function (node /*:TestNode*/) /*:Void*/ {
+            if (YAHOO.lang.isObject(node.testObject)){
+                node.parent.results.passed += node.results.passed;
+                node.parent.results.failed += node.results.failed;
+                node.parent.results.total += node.results.total;                
+                node.parent.results.ignored += node.results.ignored;                
+                node.parent.results[node.testObject.name] = node.results;
+            
+                if (node.testObject instanceof YAHOO.tool.TestSuite){
+                    node.testObject.tearDown();
+                    this.fireEvent(this.TEST_SUITE_COMPLETE_EVENT, { testSuite: node.testObject, results: node.results});
+                } else if (node.testObject instanceof YAHOO.tool.TestCase){
+                    this.fireEvent(this.TEST_CASE_COMPLETE_EVENT, { testCase: node.testObject, results: node.results});
+                }      
+            } 
+        },                
+        
+        //-------------------------------------------------------------------------
+        // Navigation Methods
+        //-------------------------------------------------------------------------
+        
+        /**
+         * Retrieves the next node in the test tree.
+         * @return {TestNode} The next node in the test tree or null if the end is reached.
+         * @private
+         * @static
+         * @method _next
+         */
+        _next : function () /*:TestNode*/ {
+        
+            if (this._cur.firstChild) {
+                this._cur = this._cur.firstChild;
+            } else if (this._cur.next) {
+                this._cur = this._cur.next;            
+            } else {
+                while (this._cur && !this._cur.next && this._cur !== this._root){
+                    this._handleTestObjectComplete(this._cur);
+                    this._cur = this._cur.parent;
+                }
+                
+                if (this._cur == this._root){
+                    this._cur.results.type = "report";
+                    this._cur.results.timestamp = (new Date()).toLocaleString();
+                    this.fireEvent(this.COMPLETE_EVENT, { results: this._cur.results});
+                    this._cur = null;
+                } else {
+                    this._handleTestObjectComplete(this._cur);               
+                    this._cur = this._cur.next;                
+                }
+            }
+        
+            return this._cur;
+        },
+        
+        /**
+         * Runs a test case or test suite, returning the results.
+         * @param {YAHOO.tool.TestCase|YAHOO.tool.TestSuite} testObject The test case or test suite to run.
+         * @return {Object} Results of the execution with properties passed, failed, and total.
+         * @private
+         * @method _run
+         * @static
+         */
+        _run : function () /*:Void*/ {
+        
+            //flag to indicate if the TestRunner should wait before continuing
+            var shouldWait /*:Boolean*/ = false;
+            
+            //get the next test node
+            var node = this._next();
+            
+            if (node !== null) {
+                var testObject = node.testObject;
+                
+                //figure out what to do
+                if (YAHOO.lang.isObject(testObject)){
+                    if (testObject instanceof YAHOO.tool.TestSuite){
+                        this.fireEvent(this.TEST_SUITE_BEGIN_EVENT, { testSuite: testObject });
+                        testObject.setUp();
+                    } else if (testObject instanceof YAHOO.tool.TestCase){
+                        this.fireEvent(this.TEST_CASE_BEGIN_EVENT, { testCase: testObject });
+                    }
+                    
+                    //some environments don't support setTimeout
+                    if (typeof setTimeout != "undefined"){                    
+                        setTimeout(function(){
+                            YAHOO.tool.TestRunner._run();
+                        }, 0);
+                    } else {
+                        this._run();
+                    }
+                } else {
+                    this._runTest(node);
+                }
+
+            }
+        },
+        
+        _resumeTest : function (segment /*:Function*/) /*:Void*/ {
+        
+            //get relevant information
+            var node /*:TestNode*/ = this._cur;
+            var testName /*:String*/ = node.testObject;
+            var testCase /*:YAHOO.tool.TestCase*/ = node.parent.testObject;
+            
+            //get the "should" test cases
+            var shouldFail /*:Object*/ = (testCase._should.fail || {})[testName];
+            var shouldError /*:Object*/ = (testCase._should.error || {})[testName];
+            
+            //variable to hold whether or not the test failed
+            var failed /*:Boolean*/ = false;
+            var error /*:Error*/ = null;
+                
+            //try the test
+            try {
+            
+                //run the test
+                segment.apply(testCase);
+                
+                //if it should fail, and it got here, then it's a fail because it didn't
+                if (shouldFail){
+                    error = new YAHOO.util.ShouldFail();
+                    failed = true;
+                } else if (shouldError){
+                    error = new YAHOO.util.ShouldError();
+                    failed = true;
+                }
+                           
+            } catch (thrown /*:Error*/){
+                if (thrown instanceof YAHOO.util.AssertionError) {
+                    if (!shouldFail){
+                        error = thrown;
+                        failed = true;
+                    }
+                } else if (thrown instanceof YAHOO.tool.TestCase.Wait){
+                
+                    if (YAHOO.lang.isFunction(thrown.segment)){
+                        if (YAHOO.lang.isNumber(thrown.delay)){
+                        
+                            //some environments don't support setTimeout
+                            if (typeof setTimeout != "undefined"){
+                                setTimeout(function(){
+                                    YAHOO.tool.TestRunner._resumeTest(thrown.segment);
+                                }, thrown.delay);
+                            } else {
+                                throw new Error("Asynchronous tests not supported in this environment.");
+                            }
+                        }
+                    }
+                    
+                    return;
+                
+                } else {
+                    //first check to see if it should error
+                    if (!shouldError) {                        
+                        error = new YAHOO.util.UnexpectedError(thrown);
+                        failed = true;
+                    } else {
+                        //check to see what type of data we have
+                        if (YAHOO.lang.isString(shouldError)){
+                            
+                            //if it's a string, check the error message
+                            if (thrown.message != shouldError){
+                                error = new YAHOO.util.UnexpectedError(thrown);
+                                failed = true;                                    
+                            }
+                        } else if (YAHOO.lang.isFunction(shouldError)){
+                        
+                            //if it's a function, see if the error is an instance of it
+                            if (!(thrown instanceof shouldError)){
+                                error = new YAHOO.util.UnexpectedError(thrown);
+                                failed = true;
+                            }
+                        
+                        } else if (YAHOO.lang.isObject(shouldError)){
+                        
+                            //if it's an object, check the instance and message
+                            if (!(thrown instanceof shouldError.constructor) || 
+                                    thrown.message != shouldError.message){
+                                error = new YAHOO.util.UnexpectedError(thrown);
+                                failed = true;                                    
+                            }
+                        
+                        }
+                    
+                    }
+                }
+                
+            }
+            
+            //fireEvent appropriate event
+            if (failed) {
+                this.fireEvent(this.TEST_FAIL_EVENT, { testCase: testCase, testName: testName, error: error });
+            } else {
+                this.fireEvent(this.TEST_PASS_EVENT, { testCase: testCase, testName: testName });
+            }
+            
+            //run the tear down
+            testCase.tearDown();
+            
+            //update results
+            node.parent.results[testName] = { 
+                result: failed ? "fail" : "pass",
+                message: error ? error.getMessage() : "Test passed",
+                type: "test",
+                name: testName
+            };
+            
+            if (failed){
+                node.parent.results.failed++;
+            } else {
+                node.parent.results.passed++;
+            }
+            node.parent.results.total++;
+
+            //set timeout not supported in all environments
+            if (typeof setTimeout != "undefined"){
+                setTimeout(function(){
+                    YAHOO.tool.TestRunner._run();
+                }, 0);
+            } else {
+                this._run();
+            }
+        
+        },
+                
+        /**
+         * Runs a single test based on the data provided in the node.
+         * @param {TestNode} node The TestNode representing the test to run.
+         * @return {Void}
+         * @static
+         * @private
+         * @name _runTest
+         */
+        _runTest : function (node /*:TestNode*/) /*:Void*/ {
+        
+            //get relevant information
+            var testName /*:String*/ = node.testObject;
+            var testCase /*:YAHOO.tool.TestCase*/ = node.parent.testObject;
+            var test /*:Function*/ = testCase[testName];
+            
+            //get the "should" test cases
+            var shouldIgnore /*:Object*/ = (testCase._should.ignore || {})[testName];
+            
+            //figure out if the test should be ignored or not
+            if (shouldIgnore){
+            
+                //update results
+                node.parent.results[testName] = { 
+                    result: "ignore",
+                    message: "Test ignored",
+                    type: "test",
+                    name: testName
+                };
+                
+                node.parent.results.ignored++;
+                node.parent.results.total++;
+            
+                this.fireEvent(this.TEST_IGNORE_EVENT, { testCase: testCase, testName: testName });
+                
+                //some environments don't support setTimeout
+                if (typeof setTimeout != "undefined"){                    
+                    setTimeout(function(){
+                        YAHOO.tool.TestRunner._run();
+                    }, 0);              
+                } else {
+                    this._run();
+                }
+
+            } else {
+            
+                //run the setup
+                testCase.setUp();
+                
+                //now call the body of the test
+                this._resumeTest(test);                
+            }
+
+        },        
+        
+        //-------------------------------------------------------------------------
+        // Protected Methods
+        //-------------------------------------------------------------------------   
+    
+        /*
+         * Fires events for the TestRunner. This overrides the default fireEvent()
+         * method from EventProvider to add the type property to the data that is
+         * passed through on each event call.
+         * @param {String} type The type of event to fire.
+         * @param {Object} data (Optional) Data for the event.
+         * @method fireEvent
+         * @static
+         * @protected
+         */
+        fireEvent : function (type /*:String*/, data /*:Object*/) /*:Void*/ {
+            data = data || {};
+            data.type = type;
+            TestRunner.superclass.fireEvent.call(this, type, data);
+        },
+        
+        //-------------------------------------------------------------------------
+        // Public Methods
+        //-------------------------------------------------------------------------   
+    
+        /**
+         * Adds a test suite or test case to the list of test objects to run.
+         * @param testObject Either a TestCase or a TestSuite that should be run.
+         * @return {Void}
+         * @method add
+         * @static
+         */
+        add : function (testObject /*:Object*/) /*:Void*/ {
+            this.masterSuite.add(testObject);
+        },
+        
+        /**
+         * Removes all test objects from the runner.
+         * @return {Void}
+         * @method clear
+         * @static
+         */
+        clear : function () /*:Void*/ {
+            this.masterSuite.items = [];
+        },
+        
+        /**
+         * Resumes the TestRunner after wait() was called.
+         * @param {Function} segment The function to run as the rest
+         *      of the haulted test.
+         * @return {Void}
+         * @method resume
+         * @static
+         */
+        resume : function (segment /*:Function*/) /*:Void*/ {
+            this._resumeTest(segment || function(){});
+        },
+    
+        /**
+         * Runs the test suite.
+         * @return {Void}
+         * @method run
+         * @static
+         */
+        run : function (testObject /*:Object*/) /*:Void*/ {
+            
+            //pointer to runner to avoid scope issues 
+            var runner = YAHOO.tool.TestRunner;
+
+            //build the test tree
+            runner._buildTestTree();
+            
+            //fire the begin event
+            runner.fireEvent(runner.BEGIN_EVENT);
+       
+            //begin the testing
+            runner._run();
+        }    
+    });
+    
+    return new TestRunner();
+    
+})();
+
+YAHOO.namespace("util");
+
+//-----------------------------------------------------------------------------
+// Assert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The Assert object provides functions to test JavaScript values against
+ * known and expected results. Whenever a comparison (assertion) fails,
+ * an error is thrown.
+ *
+ * @namespace YAHOO.util
+ * @class Assert
+ * @static
+ */
+YAHOO.util.Assert = {
+
+    //-------------------------------------------------------------------------
+    // Helper Methods
+    //-------------------------------------------------------------------------
+    
+    /**
+     * Formats a message so that it can contain the original assertion message
+     * in addition to the custom message.
+     * @param {String} customMessage The message passed in by the developer.
+     * @param {String} defaultMessage The message created by the error by default.
+     * @return {String} The final error message, containing either or both.
+     * @protected
+     * @static
+     * @method _formatMessage
+     */
+    _formatMessage : function (customMessage /*:String*/, defaultMessage /*:String*/) /*:String*/ {
+        var message = customMessage;
+        if (YAHOO.lang.isString(customMessage) && customMessage.length > 0){
+            return YAHOO.lang.substitute(customMessage, { message: defaultMessage });
+        } else {
+            return defaultMessage;
+        }        
+    },
+    
+    //-------------------------------------------------------------------------
+    // Generic Assertion Methods
+    //-------------------------------------------------------------------------
+    
+    /** 
+     * Forces an assertion error to occur.
+     * @param {String} message (Optional) The message to display with the failure.
+     * @method fail
+     * @static
+     */
+    fail : function (message /*:String*/) /*:Void*/ {
+        throw new YAHOO.util.AssertionError(this._formatMessage(message, "Test force-failed."));
+    },       
+    
+    //-------------------------------------------------------------------------
+    // Equality Assertion Methods
+    //-------------------------------------------------------------------------    
+    
+    /**
+     * Asserts that a value is equal to another. This uses the double equals sign
+     * so type cohersion may occur.
+     * @param {Object} expected The expected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areEqual
+     * @static
+     */
+    areEqual : function (expected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (expected != actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Values should be equal."), expected, actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is not equal to another. This uses the double equals sign
+     * so type cohersion may occur.
+     * @param {Object} unexpected The unexpected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areNotEqual
+     * @static
+     */
+    areNotEqual : function (unexpected /*:Object*/, actual /*:Object*/, 
+                         message /*:String*/) /*:Void*/ {
+        if (unexpected == actual) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be equal."), unexpected);
+        }
+    },
+    
+    /**
+     * Asserts that a value is not the same as another. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} unexpected The unexpected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areNotSame
+     * @static
+     */
+    areNotSame : function (unexpected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (unexpected === actual) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be the same."), unexpected);
+        }
+    },
+
+    /**
+     * Asserts that a value is the same as another. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} expected The expected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areSame
+     * @static
+     */
+    areSame : function (expected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (expected !== actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Values should be the same."), expected, actual);
+        }
+    },    
+    
+    //-------------------------------------------------------------------------
+    // Boolean Assertion Methods
+    //-------------------------------------------------------------------------    
+    
+    /**
+     * Asserts that a value is false. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isFalse
+     * @static
+     */
+    isFalse : function (actual /*:Boolean*/, message /*:String*/) {
+        if (false !== actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be false."), false, actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is true. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isTrue
+     * @static
+     */
+    isTrue : function (actual /*:Boolean*/, message /*:String*/) /*:Void*/ {
+        if (true !== actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be true."), true, actual);
+        }
+
+    },
+    
+    //-------------------------------------------------------------------------
+    // Special Value Assertion Methods
+    //-------------------------------------------------------------------------    
+    
+    /**
+     * Asserts that a value is not a number.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNaN
+     * @static
+     */
+    isNaN : function (actual /*:Object*/, message /*:String*/) /*:Void*/{
+        if (!isNaN(actual)){
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be NaN."), NaN, actual);
+        }    
+    },
+    
+    /**
+     * Asserts that a value is not the special NaN value.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotNaN
+     * @static
+     */
+    isNotNaN : function (actual /*:Object*/, message /*:String*/) /*:Void*/{
+        if (isNaN(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be NaN."), NaN);
+        }    
+    },
+    
+    /**
+     * Asserts that a value is not null. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotNull
+     * @static
+     */
+    isNotNull : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (YAHOO.lang.isNull(actual)) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be null."), null);
+        }
+    },
+
+    /**
+     * Asserts that a value is not undefined. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotUndefined
+     * @static
+     */
+    isNotUndefined : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (YAHOO.lang.isUndefined(actual)) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should not be undefined."), undefined);
+        }
+    },
+
+    /**
+     * Asserts that a value is null. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNull
+     * @static
+     */
+    isNull : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isNull(actual)) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be null."), null, actual);
+        }
+    },
+        
+    /**
+     * Asserts that a value is undefined. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isUndefined
+     * @static
+     */
+    isUndefined : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isUndefined(actual)) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be undefined."), undefined, actual);
+        }
+    },    
+    
+    //--------------------------------------------------------------------------
+    // Instance Assertion Methods
+    //--------------------------------------------------------------------------    
+   
+    /**
+     * Asserts that a value is an array.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isArray
+     * @static
+     */
+    isArray : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isArray(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be an array."), actual);
+        }    
+    },
+   
+    /**
+     * Asserts that a value is a Boolean.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isBoolean
+     * @static
+     */
+    isBoolean : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isBoolean(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a Boolean."), actual);
+        }    
+    },
+   
+    /**
+     * Asserts that a value is a function.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isFunction
+     * @static
+     */
+    isFunction : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isFunction(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a function."), actual);
+        }    
+    },
+   
+    /**
+     * Asserts that a value is an instance of a particular object. This may return
+     * incorrect results when comparing objects from one frame to constructors in
+     * another frame. For best results, don't use in a cross-frame manner.
+     * @param {Function} expected The function that the object should be an instance of.
+     * @param {Object} actual The object to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isInstanceOf
+     * @static
+     */
+    isInstanceOf : function (expected /*:Function*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!(actual instanceof expected)){
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value isn't an instance of expected type."), expected, actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is a number.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNumber
+     * @static
+     */
+    isNumber : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isNumber(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a number."), actual);
+        }    
+    },    
+    
+    /**
+     * Asserts that a value is an object.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isObject
+     * @static
+     */
+    isObject : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isObject(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be an object."), actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is a string.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isString
+     * @static
+     */
+    isString : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isString(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a string."), actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is of a particular type. 
+     * @param {String} expectedType The expected type of the variable.
+     * @param {Object} actualValue The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isTypeOf
+     * @static
+     */
+    isTypeOf : function (expectedType /*:String*/, actualValue /*:Object*/, message /*:String*/) /*:Void*/{
+        if (typeof actualValue != expectedType){
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be of type " + expected + "."), expected, typeof actual);
+        }
+    }
+};
+
+//-----------------------------------------------------------------------------
+// Assertion errors
+//-----------------------------------------------------------------------------
+
+/**
+ * AssertionError is thrown whenever an assertion fails. It provides methods
+ * to more easily get at error information and also provides a base class
+ * from which more specific assertion errors can be derived.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @namespace YAHOO.util
+ * @class AssertionError
+ * @extends Error
+ * @constructor
+ */ 
+YAHOO.util.AssertionError = function (message /*:String*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message);
+    
+    /*
+     * Error message. Must be duplicated to ensure browser receives it.
+     * @type String
+     * @property message
+     */
+    this.message /*:String*/ = message;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "AssertionError";
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.AssertionError, Error, {
+
+    /**
+     * Returns a fully formatted error for an assertion failure. This should
+     * be overridden by all subclasses to provide specific information.
+     * @method getMessage
+     * @return {String} A string describing the error.
+     */
+    getMessage : function () /*:String*/ {
+        return this.message;
+    },
+    
+    /**
+     * Returns a string representation of the error.
+     * @method toString
+     * @return {String} A string representation of the error.
+     */
+    toString : function () /*:String*/ {
+        return this.name + ": " + this.getMessage();
+    },
+    
+    /**
+     * Returns a primitive value version of the error. Same as toString().
+     * @method valueOf
+     * @return {String} A primitive value version of the error.
+     */
+    valueOf : function () /*:String*/ {
+        return this.toString();
+    }
+
+});
+
+/**
+ * ComparisonFailure is subclass of AssertionError that is thrown whenever
+ * a comparison between two values fails. It provides mechanisms to retrieve
+ * both the expected and actual value.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @param {Object} expected The expected value.
+ * @param {Object} actual The actual value that caused the assertion to fail.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class ComparisonFailure
+ * @constructor
+ */ 
+YAHOO.util.ComparisonFailure = function (message /*:String*/, expected /*:Object*/, actual /*:Object*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message);
+    
+    /**
+     * The expected value.
+     * @type Object
+     * @property expected
+     */
+    this.expected /*:Object*/ = expected;
+    
+    /**
+     * The actual value.
+     * @type Object
+     * @property actual
+     */
+    this.actual /*:Object*/ = actual;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "ComparisonFailure";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.ComparisonFailure, YAHOO.util.AssertionError, {
+
+    /**
+     * Returns a fully formatted error for an assertion failure. This message
+     * provides information about the expected and actual values.
+     * @method toString
+     * @return {String} A string describing the error.
+     */
+    getMessage : function () /*:String*/ {
+        return this.message + "\nExpected: " + this.expected + " (" + (typeof this.expected) + ")"  +
+            "\nActual:" + this.actual + " (" + (typeof this.actual) + ")";
+    }
+
+});
+
+/**
+ * UnexpectedValue is subclass of AssertionError that is thrown whenever
+ * a value was unexpected in its scope. This typically means that a test
+ * was performed to determine that a value was *not* equal to a certain
+ * value.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @param {Object} unexpected The unexpected value.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class UnexpectedValue
+ * @constructor
+ */ 
+YAHOO.util.UnexpectedValue = function (message /*:String*/, unexpected /*:Object*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message);
+    
+    /**
+     * The unexpected value.
+     * @type Object
+     * @property unexpected
+     */
+    this.unexpected /*:Object*/ = unexpected;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "UnexpectedValue";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.UnexpectedValue, YAHOO.util.AssertionError, {
+
+    /**
+     * Returns a fully formatted error for an assertion failure. The message
+     * contains information about the unexpected value that was encountered.
+     * @method getMessage
+     * @return {String} A string describing the error.
+     */
+    getMessage : function () /*:String*/ {
+        return this.message + "\nUnexpected: " + this.unexpected + " (" + (typeof this.unexpected) + ") ";
+    }
+
+});
+
+/**
+ * ShouldFail is subclass of AssertionError that is thrown whenever
+ * a test was expected to fail but did not.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class ShouldFail
+ * @constructor
+ */  
+YAHOO.util.ShouldFail = function (message /*:String*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message || "This test should fail but didn't.");
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "ShouldFail";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.ShouldFail, YAHOO.util.AssertionError);
+
+/**
+ * ShouldError is subclass of AssertionError that is thrown whenever
+ * a test is expected to throw an error but doesn't.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class ShouldError
+ * @constructor
+ */  
+YAHOO.util.ShouldError = function (message /*:String*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message || "This test should have thrown an error but didn't.");
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "ShouldError";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.ShouldError, YAHOO.util.AssertionError);
+
+/**
+ * UnexpectedError is subclass of AssertionError that is thrown whenever
+ * an error occurs within the course of a test and the test was not expected
+ * to throw an error.
+ *
+ * @param {Error} cause The unexpected error that caused this error to be 
+ *                      thrown.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class UnexpectedError
+ * @constructor
+ */  
+YAHOO.util.UnexpectedError = function (cause /*:Object*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, "Unexpected error: " + cause.message);
+    
+    /**
+     * The unexpected error that occurred.
+     * @type Error
+     * @property cause
+     */
+    this.cause /*:Error*/ = cause;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "UnexpectedError";
+    
+    /**
+     * Stack information for the error (if provided).
+     * @type String
+     * @property stack
+     */
+    this.stack /*:String*/ = cause.stack;
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.UnexpectedError, YAHOO.util.AssertionError);
+
+//-----------------------------------------------------------------------------
+// ArrayAssert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The ArrayAssert object provides functions to test JavaScript array objects
+ * for a variety of cases.
+ *
+ * @namespace YAHOO.util
+ * @class ArrayAssert
+ * @static
+ */
+ 
+YAHOO.util.ArrayAssert = {
+
+    /**
+     * Asserts that a value is present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur.
+     * @param {Object} needle The value that is expected in the array.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method contains
+     * @static
+     */
+    contains : function (needle /*:Object*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (haystack[i] === needle) {
+                found = true;
+            }
+        }
+        
+        if (!found){
+            Assert.fail(Assert._formatMessage(message, "Value " + needle + " (" + (typeof needle) + ") not found in array [" + haystack + "]."));
+        }
+    },
+
+    /**
+     * Asserts that a set of values are present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur. For this assertion to pass, all values must
+     * be found.
+     * @param {Object[]} needles An array of values that are expected in the array.
+     * @param {Array} haystack An array of values to check.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method containsItems
+     * @static
+     */
+    containsItems : function (needles /*:Object[]*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+
+        //begin checking values
+        for (var i=0; i < needles.length; i++){
+            this.contains(needles[i], haystack, message);
+        }
+    },
+
+    /**
+     * Asserts that a value matching some condition is present in an array. This uses
+     * a function to determine a match.
+     * @param {Function} matcher A function that returns true if the items matches or false if not.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method containsMatch
+     * @static
+     */
+    containsMatch : function (matcher /*:Function*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        //check for valid matcher
+        if (typeof matcher != "function"){
+            throw new TypeError("ArrayAssert.containsMatch(): First argument must be a function.");
+        }
+        
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (matcher(haystack[i])) {
+                found = true;
+            }
+        }
+        
+        if (!found){
+            Assert.fail(Assert._formatMessage(message, "No match found in array [" + haystack + "]."));
+        }
+    },
+
+    /**
+     * Asserts that a value is not present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur.
+     * @param {Object} needle The value that is expected in the array.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method doesNotContain
+     * @static
+     */
+    doesNotContain : function (needle /*:Object*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (haystack[i] === needle) {
+                found = true;
+            }
+        }
+        
+        if (found){
+            Assert.fail(Assert._formatMessage(message, "Value found in array [" + haystack + "]."));
+        }
+    },
+
+    /**
+     * Asserts that a set of values are not present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur. For this assertion to pass, all values must
+     * not be found.
+     * @param {Object[]} needles An array of values that are not expected in the array.
+     * @param {Array} haystack An array of values to check.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method doesNotContainItems
+     * @static
+     */
+    doesNotContainItems : function (needles /*:Object[]*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+
+        for (var i=0; i < needles.length; i++){
+            this.doesNotContain(needles[i], haystack, message);
+        }
+
+    },
+        
+    /**
+     * Asserts that no values matching a condition are present in an array. This uses
+     * a function to determine a match.
+     * @param {Function} matcher A function that returns true if the items matches or false if not.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method doesNotContainMatch
+     * @static
+     */
+    doesNotContainMatch : function (matcher /*:Function*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        //check for valid matcher
+        if (typeof matcher != "function"){
+            throw new TypeError("ArrayAssert.doesNotContainMatch(): First argument must be a function.");
+        }
+
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (matcher(haystack[i])) {
+                found = true;
+            }
+        }
+        
+        if (found){
+            Assert.fail(Assert._formatMessage(message, "Value found in array [" + haystack + "]."));
+        }
+    },
+        
+    /**
+     * Asserts that the given value is contained in an array at the specified index.
+     * This uses the triple equals sign so no type cohersion will occur.
+     * @param {Object} needle The value to look for.
+     * @param {Array} haystack The array to search in.
+     * @param {int} index The index at which the value should exist.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method indexOf
+     * @static
+     */
+    indexOf : function (needle /*:Object*/, haystack /*:Array*/, index /*:int*/, message /*:String*/) /*:Void*/ {
+    
+        //try to find the value in the array
+        for (var i=0; i < haystack.length; i++){
+            if (haystack[i] === needle){
+                YAHOO.util.Assert.areEqual(index, i, message || "Value exists at index " + i + " but should be at index " + index + ".");
+                return;
+            }
+        }
+        
+        var Assert = YAHOO.util.Assert;
+        
+        //if it makes it here, it wasn't found at all
+        Assert.fail(Assert._formatMessage(message, "Value doesn't exist in array [" + haystack + "]."));
+    },
+        
+    /**
+     * Asserts that the values in an array are equal, and in the same position,
+     * as values in another array. This uses the double equals sign
+     * so type cohersion may occur. Note that the array objects themselves
+     * need not be the same for this test to pass.
+     * @param {Array} expected An array of the expected values.
+     * @param {Array} actual Any array of the actual values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method itemsAreEqual
+     * @static
+     */
+    itemsAreEqual : function (expected /*:Array*/, actual /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        //one may be longer than the other, so get the maximum length
+        var len /*:int*/ = Math.max(expected.length, actual.length);
+        var Assert = YAHOO.util.Assert;
+       
+        //begin checking values
+        for (var i=0; i < len; i++){
+            Assert.areEqual(expected[i], actual[i], 
+                Assert._formatMessage(message, "Values in position " + i + " are not equal."));
+        }
+    },
+    
+    /**
+     * Asserts that the values in an array are equivalent, and in the same position,
+     * as values in another array. This uses a function to determine if the values
+     * are equivalent. Note that the array objects themselves
+     * need not be the same for this test to pass.
+     * @param {Array} expected An array of the expected values.
+     * @param {Array} actual Any array of the actual values.
+     * @param {Function} comparator A function that returns true if the values are equivalent
+     *      or false if not.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @return {Void}
+     * @method itemsAreEquivalent
+     * @static
+     */
+    itemsAreEquivalent : function (expected /*:Array*/, actual /*:Array*/, 
+                           comparator /*:Function*/, message /*:String*/) /*:Void*/ {
+        
+        //make sure the comparator is valid
+        if (typeof comparator != "function"){
+            throw new TypeError("ArrayAssert.itemsAreEquivalent(): Third argument must be a function.");
+        }
+        
+        //one may be longer than the other, so get the maximum length
+        var len /*:int*/ = Math.max(expected.length, actual.length);
+        
+        //begin checking values
+        for (var i=0; i < len; i++){
+            if (!comparator(expected[i], actual[i])){
+                throw new YAHOO.util.ComparisonFailure(YAHOO.util.Assert._formatMessage(message, "Values in position " + i + " are not equivalent."), expected[i], actual[i]);
+            }
+        }
+    },
+    
+    /**
+     * Asserts that an array is empty.
+     * @param {Array} actual The array to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isEmpty
+     * @static
+     */
+    isEmpty : function (actual /*:Array*/, message /*:String*/) /*:Void*/ {        
+        if (actual.length > 0){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Array should be empty."));
+        }
+    },    
+    
+    /**
+     * Asserts that an array is not empty.
+     * @param {Array} actual The array to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotEmpty
+     * @static
+     */
+    isNotEmpty : function (actual /*:Array*/, message /*:String*/) /*:Void*/ {        
+        if (actual.length === 0){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Array should not be empty."));
+        }
+    },    
+    
+    /**
+     * Asserts that the values in an array are the same, and in the same position,
+     * as values in another array. This uses the triple equals sign
+     * so no type cohersion will occur. Note that the array objects themselves
+     * need not be the same for this test to pass.
+     * @param {Array} expected An array of the expected values.
+     * @param {Array} actual Any array of the actual values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method itemsAreSame
+     * @static
+     */
+    itemsAreSame : function (expected /*:Array*/, actual /*:Array*/, 
+                          message /*:String*/) /*:Void*/ {
+        
+        //one may be longer than the other, so get the maximum length
+        var len /*:int*/ = Math.max(expected.length, actual.length);
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < len; i++){
+            Assert.areSame(expected[i], actual[i], 
+                Assert._formatMessage(message, "Values in position " + i + " are not the same."));
+        }
+    },
+    
+    /**
+     * Asserts that the given value is contained in an array at the specified index,
+     * starting from the back of the array.
+     * This uses the triple equals sign so no type cohersion will occur.
+     * @param {Object} needle The value to look for.
+     * @param {Array} haystack The array to search in.
+     * @param {int} index The index at which the value should exist.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method lastIndexOf
+     * @static
+     */
+    lastIndexOf : function (needle /*:Object*/, haystack /*:Array*/, index /*:int*/, message /*:String*/) /*:Void*/ {
+    
+        var Assert = YAHOO.util.Assert;
+    
+        //try to find the value in the array
+        for (var i=haystack.length; i >= 0; i--){
+            if (haystack[i] === needle){
+                Assert.areEqual(index, i, Assert._formatMessage(message, "Value exists at index " + i + " but should be at index " + index + "."));
+                return;
+            }
+        }
+        
+        //if it makes it here, it wasn't found at all
+        Assert.fail(Assert._formatMessage(message, "Value doesn't exist in array."));        
+    }
+    
+};
+
+YAHOO.namespace("util");
+
+
+//-----------------------------------------------------------------------------
+// ObjectAssert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The ObjectAssert object provides functions to test JavaScript objects
+ * for a variety of cases.
+ *
+ * @namespace YAHOO.util
+ * @class ObjectAssert
+ * @static
+ */
+YAHOO.util.ObjectAssert = {
+        
+    /**
+     * Asserts that all properties in the object exist in another object.
+     * @param {Object} expected An object with the expected properties.
+     * @param {Object} actual An object with the actual properties.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method propertiesAreEqual
+     * @static
+     */
+    propertiesAreEqual : function (expected /*:Object*/, actual /*:Object*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        var Assert = YAHOO.util.Assert;
+        
+        //get all properties in the object
+        var properties /*:Array*/ = [];        
+        for (var property in expected){
+            properties.push(property);
+        }
+        
+        //see if the properties are in the expected object
+        for (var i=0; i < properties.length; i++){
+            Assert.isNotUndefined(actual[properties[i]], 
+                Assert._formatMessage(message, "Property '" + properties[i] + "' expected."));
+        }
+
+    },
+    
+    /**
+     * Asserts that an object has a property with the given name.
+     * @param {String} propertyName The name of the property to test.
+     * @param {Object} object The object to search.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method hasProperty
+     * @static
+     */    
+    hasProperty : function (propertyName /*:String*/, object /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!(propertyName in object)){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Property '" + propertyName + "' not found on object."));
+        }    
+    },
+    
+    /**
+     * Asserts that a property with the given name exists on an object instance (not on its prototype).
+     * @param {String} propertyName The name of the property to test.
+     * @param {Object} object The object to search.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method hasProperty
+     * @static
+     */    
+    hasOwnProperty : function (propertyName /*:String*/, object /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.hasOwnProperty(object, propertyName)){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Property '" + propertyName + "' not found on object instance."));
+        }     
+    }
+};
+
+//-----------------------------------------------------------------------------
+// DateAssert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The DateAssert object provides functions to test JavaScript Date objects
+ * for a variety of cases.
+ *
+ * @namespace YAHOO.util
+ * @class DateAssert
+ * @static
+ */
+ 
+YAHOO.util.DateAssert = {
+
+    /**
+     * Asserts that a date's month, day, and year are equal to another date's.
+     * @param {Date} expected The expected date.
+     * @param {Date} actual The actual date to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method datesAreEqual
+     * @static
+     */
+    datesAreEqual : function (expected /*:Date*/, actual /*:Date*/, message /*:String*/){
+        if (expected instanceof Date && actual instanceof Date){
+            var Assert = YAHOO.util.Assert;
+            Assert.areEqual(expected.getFullYear(), actual.getFullYear(), Assert._formatMessage(message, "Years should be equal."));
+            Assert.areEqual(expected.getMonth(), actual.getMonth(), Assert._formatMessage(message, "Months should be equal."));
+            Assert.areEqual(expected.getDate(), actual.getDate(), Assert._formatMessage(message, "Day of month should be equal."));
+        } else {
+            throw new TypeError("DateAssert.datesAreEqual(): Expected and actual values must be Date objects.");
+        }
+    },
+
+    /**
+     * Asserts that a date's hour, minutes, and seconds are equal to another date's.
+     * @param {Date} expected The expected date.
+     * @param {Date} actual The actual date to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method timesAreEqual
+     * @static
+     */
+    timesAreEqual : function (expected /*:Date*/, actual /*:Date*/, message /*:String*/){
+        if (expected instanceof Date && actual instanceof Date){
+            var Assert = YAHOO.util.Assert;
+            Assert.areEqual(expected.getHours(), actual.getHours(), Assert._formatMessage(message, "Hours should be equal."));
+            Assert.areEqual(expected.getMinutes(), actual.getMinutes(), Assert._formatMessage(message, "Minutes should be equal."));
+            Assert.areEqual(expected.getSeconds(), actual.getSeconds(), Assert._formatMessage(message, "Seconds should be equal."));
+        } else {
+            throw new TypeError("DateAssert.timesAreEqual(): Expected and actual values must be Date objects.");
+        }
+    }
+    
+};
+
+YAHOO.namespace("util");
+
+/**
+ * The UserAction object provides functions that simulate events occurring in
+ * the browser. Since these are simulated events, they do not behave exactly
+ * as regular, user-initiated events do, but can be used to test simple
+ * user interactions safely.
+ *
+ * @namespace YAHOO.util
+ * @class UserAction
+ * @static
+ */
+YAHOO.util.UserAction = {
+
+    //--------------------------------------------------------------------------
+    // Generic event methods
+    //--------------------------------------------------------------------------
+
+    /**
+     * Simulates a key event using the given event information to populate
+     * the generated event object. This method does browser-equalizing
+     * calculations to account for differences in the DOM and IE event models
+     * as well as different browser quirks. Note: keydown causes Safari 2.x to
+     * crash.
+     * @method simulateKeyEvent
+     * @private
+     * @static
+     * @param {HTMLElement} target The target of the given event.
+     * @param {String} type The type of event to fire. This can be any one of
+     *      the following: keyup, keydown, and keypress.
+     * @param {Boolean} bubbles (Optional) Indicates if the event can be
+     *      bubbled up. DOM Level 3 specifies that all key events bubble by
+     *      default. The default is true.
+     * @param {Boolean} cancelable (Optional) Indicates if the event can be
+     *      canceled using preventDefault(). DOM Level 3 specifies that all
+     *      key events can be cancelled. The default 
+     *      is true.
+     * @param {Window} view (Optional) The view containing the target. This is
+     *      typically the window object. The default is window.
+     * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {int} keyCode (Optional) The code for the key that is in use. 
+     *      The default is 0.
+     * @param {int} charCode (Optional) The Unicode code for the character
+     *      associated with the key being used. The default is 0.
+     */
+    simulateKeyEvent : function (target /*:HTMLElement*/, type /*:String*/, 
+                                 bubbles /*:Boolean*/,  cancelable /*:Boolean*/,    
+                                 view /*:Window*/,
+                                 ctrlKey /*:Boolean*/,    altKey /*:Boolean*/, 
+                                 shiftKey /*:Boolean*/,   metaKey /*:Boolean*/, 
+                                 keyCode /*:int*/,        charCode /*:int*/) /*:Void*/                             
+    {
+        //check target
+        target = YAHOO.util.Dom.get(target);        
+        if (!target){
+            throw new Error("simulateKeyEvent(): Invalid target.");
+        }
+        
+        //check event type
+        if (YAHOO.lang.isString(type)){
+            type = type.toLowerCase();
+            switch(type){
+                case "keyup":
+                case "keydown":
+                case "keypress":
+                    break;
+                case "textevent": //DOM Level 3
+                    type = "keypress";
+                    break;
+                    // @TODO was the fallthrough intentional, if so throw error
+                default:
+                    throw new Error("simulateKeyEvent(): Event type '" + type + "' not supported.");
+            }
+        } else {
+            throw new Error("simulateKeyEvent(): Event type must be a string.");
+        }
+        
+        //setup default values
+        if (!YAHOO.lang.isBoolean(bubbles)){
+            bubbles = true; //all key events bubble
+        }
+        if (!YAHOO.lang.isBoolean(cancelable)){
+            cancelable = true; //all key events can be cancelled
+        }
+        if (!YAHOO.lang.isObject(view)){
+            view = window; //view is typically window
+        }
+        if (!YAHOO.lang.isBoolean(ctrlKey)){
+            ctrlKey = false;
+        }
+        if (!YAHOO.lang.isBoolean(altKey)){
+            altKey = false;
+        }
+        if (!YAHOO.lang.isBoolean(shiftKey)){
+            shiftKey = false;
+        }
+        if (!YAHOO.lang.isBoolean(metaKey)){
+            metaKey = false;
+        }
+        if (!YAHOO.lang.isNumber(keyCode)){
+            keyCode = 0;
+        }
+        if (!YAHOO.lang.isNumber(charCode)){
+            charCode = 0; 
+        }
+
+        //try to create a mouse event
+        var customEvent /*:MouseEvent*/ = null;
+            
+        //check for DOM-compliant browsers first
+        if (YAHOO.lang.isFunction(document.createEvent)){
+        
+            try {
+                
+                //try to create key event
+                customEvent = document.createEvent("KeyEvents");
+                
+                /*
+                 * Interesting problem: Firefox implemented a non-standard
+                 * version of initKeyEvent() based on DOM Level 2 specs.
+                 * Key event was removed from DOM Level 2 and re-introduced
+                 * in DOM Level 3 with a different interface. Firefox is the
+                 * only browser with any implementation of Key Events, so for
+                 * now, assume it's Firefox if the above line doesn't error.
+                 */
+                //TODO: Decipher between Firefox's implementation and a correct one.
+                customEvent.initKeyEvent(type, bubbles, cancelable, view, ctrlKey,
+                    altKey, shiftKey, metaKey, keyCode, charCode);       
+                
+            } catch (ex /*:Error*/){
+
+                /*
+                 * If it got here, that means key events aren't officially supported. 
+                 * Safari/WebKit is a real problem now. WebKit 522 won't let you
+                 * set keyCode, charCode, or other properties if you use a
+                 * UIEvent, so we first must try to create a generic event. The
+                 * fun part is that this will throw an error on Safari 2.x. The
+                 * end result is that we need another try...catch statement just to
+                 * deal with this mess.
+                 */
+                try {
+
+                    //try to create generic event - will fail in Safari 2.x
+                    customEvent = document.createEvent("Events");
+
+                } catch (uierror /*:Error*/){
+
+                    //the above failed, so create a UIEvent for Safari 2.x
+                    customEvent = document.createEvent("UIEvents");
+
+                } finally {
+
+                    customEvent.initEvent(type, bubbles, cancelable);
+    
+                    //initialize
+                    customEvent.view = view;
+                    customEvent.altKey = altKey;
+                    customEvent.ctrlKey = ctrlKey;
+                    customEvent.shiftKey = shiftKey;
+                    customEvent.metaKey = metaKey;
+                    customEvent.keyCode = keyCode;
+                    customEvent.charCode = charCode;
+          
+                }          
+             
+            }
+            
+            //fire the event
+            target.dispatchEvent(customEvent);
+
+        } else if (YAHOO.lang.isObject(document.createEventObject)){ //IE
+        
+            //create an IE event object
+            customEvent = document.createEventObject();
+            
+            //assign available properties
+            customEvent.bubbles = bubbles;
+            customEvent.cancelable = cancelable;
+            customEvent.view = view;
+            customEvent.ctrlKey = ctrlKey;
+            customEvent.altKey = altKey;
+            customEvent.shiftKey = shiftKey;
+            customEvent.metaKey = metaKey;
+            
+            /*
+             * IE doesn't support charCode explicitly. CharCode should
+             * take precedence over any keyCode value for accurate
+             * representation.
+             */
+            customEvent.keyCode = (charCode > 0) ? charCode : keyCode;
+            
+            //fire the event
+            target.fireEvent("on" + type, customEvent);  
+                    
+        } else {
+            throw new Error("simulateKeyEvent(): No event simulation framework present.");
+        }
+    },
+
+    /**
+     * Simulates a mouse event using the given event information to populate
+     * the generated event object. This method does browser-equalizing
+     * calculations to account for differences in the DOM and IE event models
+     * as well as different browser quirks.
+     * @method simulateMouseEvent
+     * @private
+     * @static
+     * @param {HTMLElement} target The target of the given event.
+     * @param {String} type The type of event to fire. This can be any one of
+     *      the following: click, dblclick, mousedown, mouseup, mouseout,
+     *      mouseover, and mousemove.
+     * @param {Boolean} bubbles (Optional) Indicates if the event can be
+     *      bubbled up. DOM Level 2 specifies that all mouse events bubble by
+     *      default. The default is true.
+     * @param {Boolean} cancelable (Optional) Indicates if the event can be
+     *      canceled using preventDefault(). DOM Level 2 specifies that all
+     *      mouse events except mousemove can be cancelled. The default 
+     *      is true for all events except mousemove, for which the default 
+     *      is false.
+     * @param {Window} view (Optional) The view containing the target. This is
+     *      typically the window object. The default is window.
+     * @param {int} detail (Optional) The number of times the mouse button has
+     *      been used. The default value is 1.
+     * @param {int} screenX (Optional) The x-coordinate on the screen at which
+     *      point the event occured. The default is 0.
+     * @param {int} screenY (Optional) The y-coordinate on the screen at which
+     *      point the event occured. The default is 0.
+     * @param {int} clientX (Optional) The x-coordinate on the client at which
+     *      point the event occured. The default is 0.
+     * @param {int} clientY (Optional) The y-coordinate on the client at which
+     *      point the event occured. The default is 0.
+     * @param {Boolean} ctrlKey (Optional) Indicates if one of the CTRL keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {Boolean} altKey (Optional) Indicates if one of the ALT keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {Boolean} shiftKey (Optional) Indicates if one of the SHIFT keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {Boolean} metaKey (Optional) Indicates if one of the META keys
+     *      is pressed while the event is firing. The default is false.
+     * @param {int} button (Optional) The button being pressed while the event
+     *      is executing. The value should be 0 for the primary mouse button
+     *      (typically the left button), 1 for the terciary mouse button
+     *      (typically the middle button), and 2 for the secondary mouse button
+     *      (typically the right button). The default is 0.
+     * @param {HTMLElement} relatedTarget (Optional) For mouseout events,
+     *      this is the element that the mouse has moved to. For mouseover
+     *      events, this is the element that the mouse has moved from. This
+     *      argument is ignored for all other events. The default is null.
+     */
+    simulateMouseEvent : function (target /*:HTMLElement*/, type /*:String*/, 
+                                   bubbles /*:Boolean*/,  cancelable /*:Boolean*/,    
+                                   view /*:Window*/,        detail /*:int*/, 
+                                   screenX /*:int*/,        screenY /*:int*/, 
+                                   clientX /*:int*/,        clientY /*:int*/,       
+                                   ctrlKey /*:Boolean*/,    altKey /*:Boolean*/, 
+                                   shiftKey /*:Boolean*/,   metaKey /*:Boolean*/, 
+                                   button /*:int*/,         relatedTarget /*:HTMLElement*/) /*:Void*/
+    {
+        
+        //check target
+        target = YAHOO.util.Dom.get(target);        
+        if (!target){
+            throw new Error("simulateMouseEvent(): Invalid target.");
+        }
+        
+        //check event type
+        if (YAHOO.lang.isString(type)){
+            type = type.toLowerCase();
+            switch(type){
+                case "mouseover":
+                case "mouseout":
+                case "mousedown":
+                case "mouseup":
+                case "click":
+                case "dblclick":
+                case "mousemove":
+                    break;
+                default:
+                    throw new Error("simulateMouseEvent(): Event type '" + type + "' not supported.");
+            }
+        } else {
+            throw new Error("simulateMouseEvent(): Event type must be a string.");
+        }
+        
+        //setup default values
+        if (!YAHOO.lang.isBoolean(bubbles)){
+            bubbles = true; //all mouse events bubble
+        }
+        if (!YAHOO.lang.isBoolean(cancelable)){
+            cancelable = (type != "mousemove"); //mousemove is the only one that can't be cancelled
+        }
+        if (!YAHOO.lang.isObject(view)){
+            view = window; //view is typically window
+        }
+        if (!YAHOO.lang.isNumber(detail)){
+            detail = 1;  //number of mouse clicks must be at least one
+        }
+        if (!YAHOO.lang.isNumber(screenX)){
+            screenX = 0; 
+        }
+        if (!YAHOO.lang.isNumber(screenY)){
+            screenY = 0; 
+        }
+        if (!YAHOO.lang.isNumber(clientX)){
+            clientX = 0; 
+        }
+        if (!YAHOO.lang.isNumber(clientY)){
+            clientY = 0; 
+        }
+        if (!YAHOO.lang.isBoolean(ctrlKey)){
+            ctrlKey = false;
+        }
+        if (!YAHOO.lang.isBoolean(altKey)){
+            altKey = false;
+        }
+        if (!YAHOO.lang.isBoolean(shiftKey)){
+            shiftKey = false;
+        }
+        if (!YAHOO.lang.isBoolean(metaKey)){
+            metaKey = false;
+        }
+        if (!YAHOO.lang.isNumber(button)){
+            button = 0; 
+        }
+
+        //try to create a mouse event
+        var customEvent /*:MouseEvent*/ = null;
+            
+        //check for DOM-compliant browsers first
+        if (YAHOO.lang.isFunction(document.createEvent)){
+        
+            customEvent = document.createEvent("MouseEvents");
+        
+            //Safari 2.x (WebKit 418) still doesn't implement initMouseEvent()
+            if (customEvent.initMouseEvent){
+                customEvent.initMouseEvent(type, bubbles, cancelable, view, detail,
+                                     screenX, screenY, clientX, clientY, 
+                                     ctrlKey, altKey, shiftKey, metaKey, 
+                                     button, relatedTarget);
+            } else { //Safari
+            
+                //the closest thing available in Safari 2.x is UIEvents
+                customEvent = document.createEvent("UIEvents");
+                customEvent.initEvent(type, bubbles, cancelable);
+                customEvent.view = view;
+                customEvent.detail = detail;
+                customEvent.screenX = screenX;
+                customEvent.screenY = screenY;
+                customEvent.clientX = clientX;
+                customEvent.clientY = clientY;
+                customEvent.ctrlKey = ctrlKey;
+                customEvent.altKey = altKey;
+                customEvent.metaKey = metaKey;
+                customEvent.shiftKey = shiftKey;
+                customEvent.button = button;
+                customEvent.relatedTarget = relatedTarget;
+            }
+            
+            /*
+             * Check to see if relatedTarget has been assigned. Firefox
+             * versions less than 2.0 don't allow it to be assigned via
+             * initMouseEvent() and the property is readonly after event
+             * creation, so in order to keep YAHOO.util.getRelatedTarget()
+             * working, assign to the IE proprietary toElement property
+             * for mouseout event and fromElement property for mouseover
+             * event.
+             */
+            if (relatedTarget && !customEvent.relatedTarget){
+                if (type == "mouseout"){
+                    customEvent.toElement = relatedTarget;
+                } else if (type == "mouseover"){
+                    customEvent.fromElement = relatedTarget;
+                }
+            }
+            
+            //fire the event
+            target.dispatchEvent(customEvent);
+
+        } else if (YAHOO.lang.isObject(document.createEventObject)){ //IE
+        
+            //create an IE event object
+            customEvent = document.createEventObject();
+            
+            //assign available properties
+            customEvent.bubbles = bubbles;
+            customEvent.cancelable = cancelable;
+            customEvent.view = view;
+            customEvent.detail = detail;
+            customEvent.screenX = screenX;
+            customEvent.screenY = screenY;
+            customEvent.clientX = clientX;
+            customEvent.clientY = clientY;
+            customEvent.ctrlKey = ctrlKey;
+            customEvent.altKey = altKey;
+            customEvent.metaKey = metaKey;
+            customEvent.shiftKey = shiftKey;
+
+            //fix button property for IE's wacky implementation
+            switch(button){
+                case 0:
+                    customEvent.button = 1;
+                    break;
+                case 1:
+                    customEvent.button = 4;
+                    break;
+                case 2:
+                    //leave as is
+                    break;
+                default:
+                    customEvent.button = 0;                    
+            }    
+
+            /*
+             * Have to use relatedTarget because IE won't allow assignment
+             * to toElement or fromElement on generic events. This keeps
+             * YAHOO.util.customEvent.getRelatedTarget() functional.
+             */
+            customEvent.relatedTarget = relatedTarget;
+            
+            //fire the event
+            target.fireEvent("on" + type, customEvent);
+                    
+        } else {
+            throw new Error("simulateMouseEvent(): No event simulation framework present.");
+        }
+    },
+   
+    //--------------------------------------------------------------------------
+    // Mouse events
+    //--------------------------------------------------------------------------
+
+    /**
+     * Simulates a mouse event on a particular element.
+     * @param {HTMLElement} target The element to click on.
+     * @param {String} type The type of event to fire. This can be any one of
+     *      the following: click, dblclick, mousedown, mouseup, mouseout,
+     *      mouseover, and mousemove.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method mouseEvent
+     * @static
+     */
+    fireMouseEvent : function (target /*:HTMLElement*/, type /*:String*/, 
+                           options /*:Object*/) /*:Void*/
+    {
+        options = options || {};
+        this.simulateMouseEvent(target, type, options.bubbles,
+            options.cancelable, options.view, options.detail, options.screenX,        
+            options.screenY, options.clientX, options.clientY, options.ctrlKey,
+            options.altKey, options.shiftKey, options.metaKey, options.button,         
+            options.relatedTarget);        
+    },
+
+    /**
+     * Simulates a click on a particular element.
+     * @param {HTMLElement} target The element to click on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method click
+     * @static     
+     */
+    click : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
+        this.fireMouseEvent(target, "click", options);
+    },
+    
+    /**
+     * Simulates a double click on a particular element.
+     * @param {HTMLElement} target The element to double click on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method dblclick
+     * @static
+     */
+    dblclick : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
+        this.fireMouseEvent( target, "dblclick", options);
+    },
+    
+    /**
+     * Simulates a mousedown on a particular element.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method mousedown
+     * @static
+     */
+    mousedown : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
+        this.fireMouseEvent(target, "mousedown", options);
+    },
+    
+    /**
+     * Simulates a mousemove on a particular element.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method mousemove
+     * @static
+     */
+    mousemove : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
+        this.fireMouseEvent(target, "mousemove", options);
+    },
+    
+    /**
+     * Simulates a mouseout event on a particular element. Use "relatedTarget"
+     * on the options object to specify where the mouse moved to.
+     * Quirks: Firefox less than 2.0 doesn't set relatedTarget properly, so
+     * toElement is assigned in its place. IE doesn't allow toElement to be
+     * be assigned, so relatedTarget is assigned in its place. Both of these
+     * concessions allow YAHOO.util.Event.getRelatedTarget() to work correctly
+     * in both browsers.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method mouseout
+     * @static
+     */
+    mouseout : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
+        this.fireMouseEvent(target, "mouseout", options);
+    },
+    
+    /**
+     * Simulates a mouseover event on a particular element. Use "relatedTarget"
+     * on the options object to specify where the mouse moved from.
+     * Quirks: Firefox less than 2.0 doesn't set relatedTarget properly, so
+     * fromElement is assigned in its place. IE doesn't allow fromElement to be
+     * be assigned, so relatedTarget is assigned in its place. Both of these
+     * concessions allow YAHOO.util.Event.getRelatedTarget() to work correctly
+     * in both browsers.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method mouseover
+     * @static
+     */
+    mouseover : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
+        this.fireMouseEvent(target, "mouseover", options);
+    },
+    
+    /**
+     * Simulates a mouseup on a particular element.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method mouseup
+     * @static
+     */
+    mouseup : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
+        this.fireMouseEvent(target, "mouseup", options);
+    },
+    
+    //--------------------------------------------------------------------------
+    // Key events
+    //--------------------------------------------------------------------------
+
+    /**
+     * Fires an event that normally would be fired by the keyboard (keyup,
+     * keydown, keypress). Make sure to specify either keyCode or charCode as
+     * an option.
+     * @private
+     * @param {String} type The type of event ("keyup", "keydown" or "keypress").
+     * @param {HTMLElement} target The target of the event.
+     * @param {Object} options Options for the event. Either keyCode or charCode
+     *                         are required.
+     * @method fireKeyEvent
+     * @static
+     */     
+    fireKeyEvent : function (type /*:String*/, target /*:HTMLElement*/,
+                             options /*:Object*/) /*:Void*/ 
+    {
+        options = options || {};
+        this.simulateKeyEvent(target, type, options.bubbles,
+            options.cancelable, options.view, options.ctrlKey,
+            options.altKey, options.shiftKey, options.metaKey, 
+            options.keyCode, options.charCode);    
+    },
+    
+    /**
+     * Simulates a keydown event on a particular element.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method keydown
+     * @static
+     */
+    keydown : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
+        this.fireKeyEvent("keydown", target, options);
+    },
+    
+    /**
+     * Simulates a keypress on a particular element.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method keypress
+     * @static
+     */
+    keypress : function (target /*:HTMLElement*/, options /*:Object*/) /*:Void*/ {
+        this.fireKeyEvent("keypress", target, options);
+    },
+    
+    /**
+     * Simulates a keyup event on a particular element.
+     * @param {HTMLElement} target The element to act on.
+     * @param {Object} options Additional event options (use DOM standard names).
+     * @method keyup
+     * @static
+     */
+    keyup : function (target /*:HTMLElement*/, options /*Object*/) /*:Void*/ {
+        this.fireKeyEvent("keyup", target, options);
+    }
+    
+
+};
+
+YAHOO.namespace("tool");
+
+//-----------------------------------------------------------------------------
+// TestManager object
+//-----------------------------------------------------------------------------
+
+/**
+ * Runs pages containing test suite definitions.
+ * @namespace YAHOO.tool
+ * @class TestManager
+ * @static
+ */
+YAHOO.tool.TestManager = {
+
+    /**
+     * Constant for the testpagebegin custom event
+     * @property TEST_PAGE_BEGIN_EVENT
+     * @static
+     * @type string
+     * @final
+     */
+    TEST_PAGE_BEGIN_EVENT /*:String*/ : "testpagebegin",
+
+    /**
+     * Constant for the testpagecomplete custom event
+     * @property TEST_PAGE_COMPLETE_EVENT
+     * @static
+     * @type string
+     * @final
+     */
+    TEST_PAGE_COMPLETE_EVENT /*:String*/ : "testpagecomplete",
+
+    /**
+     * Constant for the testmanagerbegin custom event
+     * @property TEST_MANAGER_BEGIN_EVENT
+     * @static
+     * @type string
+     * @final
+     */
+    TEST_MANAGER_BEGIN_EVENT /*:String*/ : "testmanagerbegin",
+
+    /**
+     * Constant for the testmanagercomplete custom event
+     * @property TEST_MANAGER_COMPLETE_EVENT
+     * @static
+     * @type string
+     * @final
+     */
+    TEST_MANAGER_COMPLETE_EVENT /*:String*/ : "testmanagercomplete",
+
+    //-------------------------------------------------------------------------
+    // Private Properties
+    //-------------------------------------------------------------------------
+    
+    
+    /**
+     * The URL of the page currently being executed.
+     * @type String
+     * @private
+     * @property _curPage
+     * @static
+     */
+    _curPage /*:String*/ : null,
+    
+    /**
+     * The frame used to load and run tests.
+     * @type Window
+     * @private
+     * @property _frame
+     * @static
+     */
+    _frame /*:Window*/ : null,
+    
+    /**
+     * The logger used to output results from the various tests.
+     * @type YAHOO.tool.TestLogger
+     * @private
+     * @property _logger
+     * @static
+     */
+    _logger : null,
+    
+    /**
+     * The timeout ID for the next iteration through the tests.
+     * @type int
+     * @private
+     * @property _timeoutId
+     * @static
+     */
+    _timeoutId /*:int*/ : 0,
+    
+    /**
+     * Array of pages to load.
+     * @type String[]
+     * @private
+     * @property _pages
+     * @static
+     */
+    _pages /*:String[]*/ : [],
+    
+    /**
+     * Aggregated results
+     * @type Object
+     * @private
+     * @property _results
+     * @static
+     */
+    _results: null,
+    
+    //-------------------------------------------------------------------------
+    // Private Methods
+    //-------------------------------------------------------------------------
+    
+    /**
+     * Handles TestRunner.COMPLETE_EVENT, storing the results and beginning
+     * the loop again.
+     * @param {Object} data Data about the event.
+     * @return {Void}
+     * @private
+     * @static
+     */
+    _handleTestRunnerComplete : function (data /*:Object*/) /*:Void*/ {
+
+        this.fireEvent(this.TEST_PAGE_COMPLETE_EVENT, {
+                page: this._curPage,
+                results: data.results
+            });
+    
+        //save results
+        //this._results[this.curPage] = data.results;
+        
+        //process 'em
+        this._processResults(this._curPage, data.results);
+        
+        this._logger.clearTestRunner();
+    
+        //if there's more to do, set a timeout to begin again
+        if (this._pages.length){
+            this._timeoutId = setTimeout(function(){
+                YAHOO.tool.TestManager._run();
+            }, 1000);
+        } else {
+            this.fireEvent(this.TEST_MANAGER_COMPLETE_EVENT, this._results);
+        }
+    },
+    
+    /**
+     * Processes the results of a test page run, outputting log messages
+     * for failed tests.
+     * @return {Void}
+     * @private
+     * @static
+     */
+    _processResults : function (page /*:String*/, results /*:Object*/) /*:Void*/ {
+
+        var r = this._results;
+        
+        r.passed += results.passed;
+        r.failed += results.failed;
+        r.ignored += results.ignored;
+        r.total += results.total;
+        
+        if (results.failed){
+            r.failedPages.push(page);
+        } else {
+            r.passedPages.push(page);
+        }
+        
+        results.name = page;
+        results.type = "page";
+        
+        r[page] = results;
+    },
+    
+    /**
+     * Loads the next test page into the iframe.
+     * @return {Void}
+     * @static
+     * @private
+     */
+    _run : function () /*:Void*/ {
+    
+        //set the current page
+        this._curPage = this._pages.shift();
+
+        this.fireEvent(this.TEST_PAGE_BEGIN_EVENT, this._curPage);
+        
+        //load the frame - destroy history in case there are other iframes that
+        //need testing
+        this._frame.location.replace(this._curPage);
+    
+    },
+        
+    //-------------------------------------------------------------------------
+    // Public Methods
+    //-------------------------------------------------------------------------
+    
+    /**
+     * Signals that a test page has been loaded. This should be called from
+     * within the test page itself to notify the TestManager that it is ready.
+     * @return {Void}
+     * @static
+     */
+    load : function () /*:Void*/ {
+        if (parent.YAHOO.tool.TestManager !== this){
+            parent.YAHOO.tool.TestManager.load();
+        } else {
+            
+            if (this._frame) {
+                //assign event handling
+                var TestRunner = this._frame.YAHOO.tool.TestRunner;
+
+                this._logger.setTestRunner(TestRunner);
+                TestRunner.subscribe(TestRunner.COMPLETE_EVENT, this._handleTestRunnerComplete, this, true);
+                
+                //run it
+                TestRunner.run();
+            }
+        }
+    },
+    
+    /**
+     * Sets the pages to be loaded.
+     * @param {String[]} pages An array of URLs to load.
+     * @return {Void}
+     * @static
+     */
+    setPages : function (pages /*:String[]*/) /*:Void*/ {
+        this._pages = pages;
+    },
+    
+    /**
+     * Begins the process of running the tests.
+     * @return {Void}
+     * @static
+     */
+    start : function () /*:Void*/ {
+
+        if (!this._initialized) {
+
+            /**
+             * Fires when loading a test page
+             * @event testpagebegin
+             * @param curPage {string} the page being loaded
+             * @static
+             */
+            this.createEvent(this.TEST_PAGE_BEGIN_EVENT);
+
+            /**
+             * Fires when a test page is complete
+             * @event testpagecomplete
+             * @param obj {page: string, results: object} the name of the
+             * page that was loaded, and the test suite results
+             * @static
+             */
+            this.createEvent(this.TEST_PAGE_COMPLETE_EVENT);
+
+            /**
+             * Fires when the test manager starts running all test pages
+             * @event testmanagerbegin
+             * @static
+             */
+            this.createEvent(this.TEST_MANAGER_BEGIN_EVENT);
+
+            /**
+             * Fires when the test manager finishes running all test pages.  External
+             * test runners should subscribe to this event in order to get the
+             * aggregated test results.
+             * @event testmanagercomplete
+             * @param obj { pages_passed: int, pages_failed: int, tests_passed: int
+             *              tests_failed: int, passed: string[], failed: string[],
+             *              page_results: {} }
+             * @static
+             */
+            this.createEvent(this.TEST_MANAGER_COMPLETE_EVENT);
+
+            //create iframe if not already available
+            if (!this._frame){
+                var frame /*:HTMLElement*/ = document.createElement("iframe");
+                frame.style.visibility = "hidden";
+                frame.style.position = "absolute";
+                document.body.appendChild(frame);
+                this._frame = frame.contentWindow || frame.contentDocument.ownerWindow;
+            }
+            
+            //create test logger if not already available
+            if (!this._logger){
+                this._logger = new YAHOO.tool.TestLogger();
+            }
+
+            this._initialized = true;
+        }
+
+
+        // reset the results cache
+        this._results = {
+        
+            passed: 0,
+            failed: 0,
+            ignored: 0,
+            total: 0,
+            type: "report",
+            name: "YUI Test Results",
+            failedPages:[],
+            passedPages:[]
+            /*
+            // number of pages that pass
+            pages_passed: 0,
+            // number of pages that fail
+            pages_failed: 0,
+            // total number of tests passed
+            tests_passed: 0,
+            // total number of tests failed
+            tests_failed: 0,
+            // array of pages that passed
+            passed: [],
+            // array of pages that failed
+            failed: [],
+            // map of full results for each page
+            page_results: {}*/
+        };
+
+        this.fireEvent(this.TEST_MANAGER_BEGIN_EVENT, null);
+        this._run();
+    
+    },
+
+    /**
+     * Stops the execution of tests.
+     * @return {Void}
+     * @static
+     */
+    stop : function () /*:Void*/ {
+        clearTimeout(this._timeoutId);
+    }
+
+};
+
+YAHOO.lang.augmentObject(YAHOO.tool.TestManager, YAHOO.util.EventProvider.prototype);
+
+
+YAHOO.namespace("tool");
+
+//-----------------------------------------------------------------------------
+// TestLogger object
+//-----------------------------------------------------------------------------
+
+/**
+ * Displays test execution progress and results, providing filters based on
+ * different key events.
+ * @namespace YAHOO.tool
+ * @class TestLogger
+ * @constructor
+ * @param {HTMLElement} element (Optional) The element to create the logger in.
+ * @param {Object} config (Optional) Configuration options for the logger.
+ */
+YAHOO.tool.TestLogger = function (element, config) {
+    YAHOO.tool.TestLogger.superclass.constructor.call(this, element, config);
+    this.init();
+};
+
+YAHOO.lang.extend(YAHOO.tool.TestLogger, YAHOO.widget.LogReader, {
+
+    footerEnabled : true,
+    newestOnTop : false,
+
+    /**
+     * Formats message string to HTML for output to console.
+     * @private
+     * @method formatMsg
+     * @param oLogMsg {Object} Log message object.
+     * @return {String} HTML-formatted message for output to console.
+     */
+    formatMsg : function(message /*:Object*/) {
+    
+        var category /*:String*/ = message.category;        
+        var text /*:String*/ = this.html2Text(message.msg);
+        
+        return "<pre><p><span class=\"" + category + "\">" + category.toUpperCase() + "</span> " + text + "</p></pre>";
+    
+    },
+    
+    //-------------------------------------------------------------------------
+    // Private Methods
+    //-------------------------------------------------------------------------
+    
+    /*
+     * Initializes the logger.
+     * @private
+     */
+    init : function () {
+    
+        //attach to any available TestRunner
+        if (YAHOO.tool.TestRunner){
+            this.setTestRunner(YAHOO.tool.TestRunner);
+        }
+        
+        //hide useless sources
+        this.hideSource("global");
+        this.hideSource("LogReader");
+        
+        //hide useless message categories
+        this.hideCategory("warn");
+        this.hideCategory("window");
+        this.hideCategory("time");
+        
+        //reset the logger
+        this.clearConsole();
+    },
+    
+    /**
+     * Clears the reference to the TestRunner from previous operations. This 
+     * unsubscribes all events and removes the object reference.
+     * @return {Void}
+     * @static
+     */
+    clearTestRunner : function () /*:Void*/ {
+        if (this._runner){
+            this._runner.unsubscribeAll();
+            this._runner = null;
+        }
+    },
+    
+    /**
+     * Sets the source test runner that the logger should monitor.
+     * @param {YAHOO.tool.TestRunner} testRunner The TestRunner to observe.
+     * @return {Void}
+     * @static
+     */
+    setTestRunner : function (testRunner /*:YAHOO.tool.TestRunner*/) /*:Void*/ {
+    
+        if (this._runner){
+            this.clearTestRunner();
+        }
+        
+        this._runner = testRunner;
+        
+        //setup event _handlers
+        testRunner.subscribe(testRunner.TEST_PASS_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.TEST_FAIL_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.TEST_IGNORE_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.BEGIN_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.COMPLETE_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.TEST_SUITE_BEGIN_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.TEST_SUITE_COMPLETE_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.TEST_CASE_BEGIN_EVENT, this._handleTestRunnerEvent, this, true);
+        testRunner.subscribe(testRunner.TEST_CASE_COMPLETE_EVENT, this._handleTestRunnerEvent, this, true);    
+    },
+    
+    //-------------------------------------------------------------------------
+    // Event Handlers
+    //-------------------------------------------------------------------------
+    
+    /**
+     * Handles all TestRunner events, outputting appropriate data into the console.
+     * @param {Object} data The event data object.
+     * @return {Void}
+     * @private
+     */
+    _handleTestRunnerEvent : function (data /*:Object*/) /*:Void*/ {
+    
+        //shortcut variables
+        var TestRunner /*:Object*/ = YAHOO.tool.TestRunner;
+    
+        //data variables
+        var message /*:String*/ = "";
+        var messageType /*:String*/ = "";
+        
+        switch(data.type){
+            case TestRunner.BEGIN_EVENT:
+                message = "Testing began at " + (new Date()).toString() + ".";
+                messageType = "info";
+                break;
+                
+            case TestRunner.COMPLETE_EVENT:
+                message = "Testing completed at " + (new Date()).toString() + ".\nPassed:" + 
+                    data.results.passed + " Failed:" + data.results.failed + " Total:" + data.results.total;
+                messageType = "info";
+                break;
+                
+            case TestRunner.TEST_FAIL_EVENT:
+                message = data.testName + ": " + data.error.getMessage();
+                messageType = "fail";
+                break;
+                
+            case TestRunner.TEST_IGNORE_EVENT:
+                message = data.testName + ": ignored.";
+                messageType = "ignore";
+                break;
+                
+            case TestRunner.TEST_PASS_EVENT:
+                message = data.testName + ": passed.";
+                messageType = "pass";
+                break;
+                
+            case TestRunner.TEST_SUITE_BEGIN_EVENT:
+                message = "Test suite \"" + data.testSuite.name + "\" started.";
+                messageType = "info";
+                break;
+                
+            case TestRunner.TEST_SUITE_COMPLETE_EVENT:
+                message = "Test suite \"" + data.testSuite.name + "\" completed.\nPassed:" + 
+                    data.results.passed + " Failed:" + data.results.failed + " Total:" + data.results.total;
+                messageType = "info";
+                break;
+                
+            case TestRunner.TEST_CASE_BEGIN_EVENT:
+                message = "Test case \"" + data.testCase.name + "\" started.";
+                messageType = "info";
+                break;
+                
+            case TestRunner.TEST_CASE_COMPLETE_EVENT:
+                message = "Test case \"" + data.testCase.name + "\" completed.\nPassed:" + 
+                    data.results.passed + " Failed:" + data.results.failed + " Total:" + data.results.total;
+                messageType = "info";
+                break;
+            default:
+                message = "Unexpected event " + data.type;
+                message = "info";
+        }
+    
+        YAHOO.log(message, messageType, "TestRunner");    
+    }
+    
+});
+
+YAHOO.namespace("tool.TestFormat");
+
+/**
+ * Returns test results formatted as a JSON string. Requires JSON utility.
+ * @param {Object} result The results object created by TestRunner.
+ * @return {String} An XML-formatted string of results.
+ * @namespace YAHOO.tool.TestFormat
+ * @method JSON
+ * @static
+ */
+YAHOO.tool.TestFormat.JSON = function(results /*:Object*/) /*:String*/ {
+    return YAHOO.lang.JSON.stringify(results);
+};
+
+/**
+ * Returns test results formatted as an XML string.
+ * @param {Object} result The results object created by TestRunner.
+ * @return {String} An XML-formatted string of results.
+ * @namespace YAHOO.tool.TestFormat
+ * @method XML
+ * @static
+ */
+YAHOO.tool.TestFormat.XML = function(results /*:Object*/) /*:String*/ {
+
+    var l = YAHOO.lang;
+    var xml /*:String*/ = "<" + results.type + " name=\"" + results.name.replace(/"/g, """).replace(/'/g, "'") + "\"";
+    
+    if (results.type == "test"){
+        xml += " result=\"" + results.result + "\" message=\"" + results.message + "\">";
+    } else {
+        xml += " passed=\"" + results.passed + "\" failed=\"" + results.failed + "\" ignored=\"" + results.ignored + "\" total=\"" + results.total + "\">";
+        for (var prop in results) {
+            if (l.hasOwnProperty(results, prop) && l.isObject(results[prop]) && !l.isArray(results[prop])){
+                xml += arguments.callee(results[prop]);
+            }
+        }        
+    }
+
+    xml += "</" + results.type + ">";
+    
+    return xml;
+
+};
+
+YAHOO.namespace("tool");
+
+/**
+ * An object capable of sending test results to a server.
+ * @param {String} url The URL to submit the results to.
+ * @param {Function} format (Optiona) A function that outputs the results in a specific format.
+ *      Default is YAHOO.tool.TestFormat.XML.
+ * @constructor
+ * @namespace YAHOO.tool
+ * @class TestReporter
+ */
+YAHOO.tool.TestReporter = function(url /*:String*/, format /*:Function*/) {
+
+    /**
+     * The URL to submit the data to.
+     * @type String
+     * @property url
+     */
+    this.url /*:String*/ = url;
+
+    /**
+     * The formatting function to call when submitting the data.
+     * @type Function
+     * @property format
+     */
+    this.format /*:Function*/ = format || YAHOO.tool.TestFormat.XML;
+
+    /**
+     * Extra fields to submit with the request.
+     * @type Object
+     * @property _fields
+     * @private
+     */
+    this._fields /*:Object*/ = new Object();
+    
+    /**
+     * The form element used to submit the results.
+     * @type HTMLFormElement
+     * @property _form
+     * @private
+     */
+    this._form /*:HTMLElement*/ = null;
+
+    /**
+     * Iframe used as a target for form submission.
+     * @type HTMLIFrameElement
+     * @property _iframe
+     * @private
+     */
+    this._iframe /*:HTMLElement*/ = null;
+};
+
+YAHOO.tool.TestReporter.prototype = {
+
+    //restore missing constructor
+    constructor: YAHOO.tool.TestReporter,
+
+    /**
+     * Adds a field to the form that submits the results.
+     * @param {String} name The name of the field.
+     * @param {Variant} value The value of the field.
+     * @return {Void}
+     * @method addField
+     */
+    addField : function (name /*:String*/, value /*:Variant*/) /*:Void*/{
+        this._fields[name] = value;    
+    },
+    
+    /**
+     * Removes all previous defined fields.
+     * @return {Void}
+     * @method addField
+     */
+    clearFields : function() /*:Void*/{
+        this._fields = new Object();
+    },
+
+    /**
+     * Cleans up the memory associated with the TestReporter, removing DOM elements
+     * that were created.
+     * @return {Void}
+     * @method destroy
+     */
+    destroy : function() /*:Void*/ {
+        if (this._form){
+            this._form.parentNode.removeChild(this._form);
+            this._form = null;
+        }        
+        if (this._iframe){
+            this._iframe.parentNode.removeChild(this._iframe);
+            this._iframe = null;
+        }
+        this._fields = null;
+    },
+
+    /**
+     * Sends the report to the server.
+     * @param {Object} results The results object created by TestRunner.
+     * @return {Void}
+     * @method report
+     */
+    report : function(results /*:Object*/) /*:Void*/{
+    
+        //if the form hasn't been created yet, create it
+        if (!this._form){
+            this._form = document.createElement("form");
+            this._form.method = "post";
+            this._form.style.visibility = "hidden";
+            this._form.style.position = "absolute";
+            this._form.style.top = 0;
+            document.body.appendChild(this._form);
+        
+            //IE won't let you assign a name using the DOM, must do it the hacky way
+            if (YAHOO.env.ua.ie){
+                this._iframe = document.createElement("<iframe name=\"yuiTestTarget\" />");
+            } else {
+                this._iframe = document.createElement("iframe");
+                this._iframe.name = "yuiTestTarget";
+            }
+
+            this._iframe.src = "javascript:false";
+            this._iframe.style.visibility = "hidden";
+            this._iframe.style.position = "absolute";
+            this._iframe.style.top = 0;
+            document.body.appendChild(this._iframe);
+
+            this._form.target = "yuiTestTarget";
+        }
+
+        //set the form's action
+        this._form.action = this.url;
+    
+        //remove any existing fields
+        while(this._form.hasChildNodes()){
+            this._form.removeChild(this._form.lastChild);
+        }
+        
+        //create default fields
+        this._fields.results = this.format(results);
+        this._fields.useragent = navigator.userAgent;
+        this._fields.timestamp = (new Date()).toLocaleString();
+
+        //add fields to the form
+        for (var prop in this._fields){
+            if (YAHOO.lang.hasOwnProperty(this._fields, prop) && typeof this._fields[prop] != "function"){
+                if (YAHOO.env.ua.ie){
+                    input = document.createElement("<input name=\"" + prop + "\" >");
+                } else {
+                    input = document.createElement("input");
+                    input.name = prop;
+                }
+                input.type = "hidden";
+                input.value = this._fields[prop];
+                this._form.appendChild(input);
+            }
+        }
+
+        //remove default fields
+        delete this._fields.results;
+        delete this._fields.useragent;
+        delete this._fields.timestamp;
+        
+        if (arguments[1] !== false){
+            this._form.submit();
+        }
+    
+    }
+
+};
+
+YAHOO.register("yuitest", YAHOO.tool.TestRunner, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/yuitest/yuitest_core-debug.js
===================================================================
--- trunk/root/static/yui/yuitest/yuitest_core-debug.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/yuitest_core-debug.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,1963 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+YAHOO.namespace("tool");
+
+//-----------------------------------------------------------------------------
+// TestCase object
+//-----------------------------------------------------------------------------
+
+/**
+ * Test case containing various tests to run.
+ * @param template An object containing any number of test methods, other methods,
+ *                 an optional name, and anything else the test case needs.
+ * @class TestCase
+ * @namespace YAHOO.tool
+ * @constructor
+ */
+YAHOO.tool.TestCase = function (template /*:Object*/) {
+    
+    /**
+     * Special rules for the test case. Possible subobjects
+     * are fail, for tests that should fail, and error, for
+     * tests that should throw an error.
+     */
+    this._should /*:Object*/ = {};
+    
+    //copy over all properties from the template to this object
+    for (var prop in template) {
+        this[prop] = template[prop];
+    }    
+    
+    //check for a valid name
+    if (!YAHOO.lang.isString(this.name)){
+        /**
+         * Name for the test case.
+         */
+        this.name /*:String*/ = YAHOO.util.Dom.generateId(null, "testCase");
+    }
+
+};
+
+
+YAHOO.tool.TestCase.prototype = {  
+
+    /**
+     * Resumes a paused test and runs the given function.
+     * @param {Function} segment (Optional) The function to run.
+     *      If omitted, the test automatically passes.
+     * @return {Void}
+     * @method resume
+     */
+    resume : function (segment /*:Function*/) /*:Void*/ {
+        YAHOO.tool.TestRunner.resume(segment);
+    },
+
+    /**
+     * Causes the test case to wait a specified amount of time and then
+     * continue executing the given code.
+     * @param {Function} segment (Optional) The function to run after the delay.
+     *      If omitted, the TestRunner will wait until resume() is called.
+     * @param {int} delay (Optional) The number of milliseconds to wait before running
+     *      the function. If omitted, defaults to zero.
+     * @return {Void}
+     * @method wait
+     */
+    wait : function (segment /*:Function*/, delay /*:int*/) /*:Void*/{
+        throw new YAHOO.tool.TestCase.Wait(segment, delay);
+    },
+
+    //-------------------------------------------------------------------------
+    // Stub Methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Function to run before each test is executed.
+     * @return {Void}
+     * @method setUp
+     */
+    setUp : function () /*:Void*/ {
+    },
+    
+    /**
+     * Function to run after each test is executed.
+     * @return {Void}
+     * @method tearDown
+     */
+    tearDown: function () /*:Void*/ {    
+    }
+};
+
+/**
+ * Represents a stoppage in test execution to wait for an amount of time before
+ * continuing.
+ * @param {Function} segment A function to run when the wait is over.
+ * @param {int} delay The number of milliseconds to wait before running the code.
+ * @class Wait
+ * @namespace YAHOO.tool.TestCase
+ * @constructor
+ *
+ */
+YAHOO.tool.TestCase.Wait = function (segment /*:Function*/, delay /*:int*/) {
+    
+    /**
+     * The segment of code to run when the wait is over.
+     * @type Function
+     * @property segment
+     */
+    this.segment /*:Function*/ = (YAHOO.lang.isFunction(segment) ? segment : null);
+
+    /**
+     * The delay before running the segment of code.
+     * @type int
+     * @property delay
+     */
+    this.delay /*:int*/ = (YAHOO.lang.isNumber(delay) ? delay : 0);
+
+};
+
+YAHOO.namespace("tool");
+
+
+//-----------------------------------------------------------------------------
+// TestSuite object
+//-----------------------------------------------------------------------------
+
+/**
+ * A test suite that can contain a collection of TestCase and TestSuite objects.
+ * @param {String||Object} data The name of the test suite or an object containing
+ *      a name property as well as setUp and tearDown methods.
+ * @namespace YAHOO.tool
+ * @class TestSuite
+ * @constructor
+ */
+YAHOO.tool.TestSuite = function (data /*:String||Object*/) {
+
+    /**
+     * The name of the test suite.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "";
+
+    /**
+     * Array of test suites and
+     * @private
+     */
+    this.items /*:Array*/ = [];
+
+    //initialize the properties
+    if (YAHOO.lang.isString(data)){
+        this.name = data;
+    } else if (YAHOO.lang.isObject(data)){
+        YAHOO.lang.augmentObject(this, data, true);
+    }
+
+    //double-check name
+    if (this.name === ""){
+        this.name = YAHOO.util.Dom.generateId(null, "testSuite");
+    }
+
+};
+
+YAHOO.tool.TestSuite.prototype = {
+    
+    /**
+     * Adds a test suite or test case to the test suite.
+     * @param {YAHOO.tool.TestSuite||YAHOO.tool.TestCase} testObject The test suite or test case to add.
+     * @return {Void}
+     * @method add
+     */
+    add : function (testObject /*:YAHOO.tool.TestSuite*/) /*:Void*/ {
+        if (testObject instanceof YAHOO.tool.TestSuite || testObject instanceof YAHOO.tool.TestCase) {
+            this.items.push(testObject);
+        }
+    },
+    
+    //-------------------------------------------------------------------------
+    // Stub Methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Function to run before each test is executed.
+     * @return {Void}
+     * @method setUp
+     */
+    setUp : function () /*:Void*/ {
+    },
+    
+    /**
+     * Function to run after each test is executed.
+     * @return {Void}
+     * @method tearDown
+     */
+    tearDown: function () /*:Void*/ {
+    }
+    
+};
+
+YAHOO.namespace("tool");
+
+/**
+ * The YUI test tool
+ * @module yuitest
+ * @namespace YAHOO.tool
+ * @requires yahoo,dom,event,logger
+ */
+
+
+//-----------------------------------------------------------------------------
+// TestRunner object
+//-----------------------------------------------------------------------------
+
+/**
+ * Runs test suites and test cases, providing events to allowing for the
+ * interpretation of test results.
+ * @namespace YAHOO.tool
+ * @class TestRunner
+ * @static
+ */
+YAHOO.tool.TestRunner = (function(){
+
+    /**
+     * A node in the test tree structure. May represent a TestSuite, TestCase, or
+     * test function.
+     * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.
+     * @class TestNode
+     * @constructor
+     * @private
+     */
+    function TestNode(testObject /*:Variant*/){
+    
+        /**
+         * The TestSuite, TestCase, or test function represented by this node.
+         * @type Variant
+         * @property testObject
+         */
+        this.testObject = testObject;
+        
+        /**
+         * Pointer to this node's first child.
+         * @type TestNode
+         * @property firstChild
+         */        
+        this.firstChild /*:TestNode*/ = null;
+        
+        /**
+         * Pointer to this node's last child.
+         * @type TestNode
+         * @property lastChild
+         */        
+        this.lastChild = null;
+        
+        /**
+         * Pointer to this node's parent.
+         * @type TestNode
+         * @property parent
+         */        
+        this.parent = null; 
+   
+        /**
+         * Pointer to this node's next sibling.
+         * @type TestNode
+         * @property next
+         */        
+        this.next = null;
+        
+        /**
+         * Test results for this test object.
+         * @type object
+         * @property results
+         */                
+        this.results /*:Object*/ = {
+            passed : 0,
+            failed : 0,
+            total : 0,
+            ignored : 0
+        };
+        
+        //initialize results
+        if (testObject instanceof YAHOO.tool.TestSuite){
+            this.results.type = "testsuite";
+            this.results.name = testObject.name;
+        } else if (testObject instanceof YAHOO.tool.TestCase){
+            this.results.type = "testcase";
+            this.results.name = testObject.name;
+        }
+       
+    }
+    
+    TestNode.prototype = {
+    
+        /**
+         * Appends a new test object (TestSuite, TestCase, or test function name) as a child
+         * of this node.
+         * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.
+         * @return {Void}
+         */
+        appendChild : function (testObject /*:Variant*/) /*:Void*/{
+            var node = new TestNode(testObject);
+            if (this.firstChild === null){
+                this.firstChild = this.lastChild = node;
+            } else {
+                this.lastChild.next = node;
+                this.lastChild = node;
+            }
+            node.parent = this;
+            return node;
+        }       
+    };
+
+    function TestRunner(){
+    
+        //inherit from EventProvider
+        TestRunner.superclass.constructor.apply(this,arguments);
+        
+        /**
+         * Suite on which to attach all TestSuites and TestCases to be run.
+         * @type YAHOO.tool.TestSuite
+         * @property masterSuite
+         * @private
+         */
+        this.masterSuite /*:YAHOO.tool.TestSuite*/ = new YAHOO.tool.TestSuite("YUI Test Results");        
+
+        /**
+         * Pointer to the current node in the test tree.
+         * @type TestNode
+         * @private
+         * @property _cur
+         */
+        this._cur = null;
+        
+        /**
+         * Pointer to the root node in the test tree.
+         * @type TestNode
+         * @private
+         * @property _root
+         */
+        this._root = null;
+        
+        //create events
+        var events /*:Array*/ = [
+            this.TEST_CASE_BEGIN_EVENT,
+            this.TEST_CASE_COMPLETE_EVENT,
+            this.TEST_SUITE_BEGIN_EVENT,
+            this.TEST_SUITE_COMPLETE_EVENT,
+            this.TEST_PASS_EVENT,
+            this.TEST_FAIL_EVENT,
+            this.TEST_IGNORE_EVENT,
+            this.COMPLETE_EVENT,
+            this.BEGIN_EVENT
+        ];
+        for (var i=0; i < events.length; i++){
+            this.createEvent(events[i], { scope: this });
+        }       
+   
+    }
+    
+    YAHOO.lang.extend(TestRunner, YAHOO.util.EventProvider, {
+    
+        //-------------------------------------------------------------------------
+        // Constants
+        //-------------------------------------------------------------------------
+         
+        /**
+         * Fires when a test case is opened but before the first 
+         * test is executed.
+         * @event testcasebegin
+         */         
+        TEST_CASE_BEGIN_EVENT /*:String*/ : "testcasebegin",
+        
+        /**
+         * Fires when all tests in a test case have been executed.
+         * @event testcasecomplete
+         */        
+        TEST_CASE_COMPLETE_EVENT /*:String*/ : "testcasecomplete",
+        
+        /**
+         * Fires when a test suite is opened but before the first 
+         * test is executed.
+         * @event testsuitebegin
+         */        
+        TEST_SUITE_BEGIN_EVENT /*:String*/ : "testsuitebegin",
+        
+        /**
+         * Fires when all test cases in a test suite have been
+         * completed.
+         * @event testsuitecomplete
+         */        
+        TEST_SUITE_COMPLETE_EVENT /*:String*/ : "testsuitecomplete",
+        
+        /**
+         * Fires when a test has passed.
+         * @event pass
+         */        
+        TEST_PASS_EVENT /*:String*/ : "pass",
+        
+        /**
+         * Fires when a test has failed.
+         * @event fail
+         */        
+        TEST_FAIL_EVENT /*:String*/ : "fail",
+        
+        /**
+         * Fires when a test has been ignored.
+         * @event ignore
+         */        
+        TEST_IGNORE_EVENT /*:String*/ : "ignore",
+        
+        /**
+         * Fires when all test suites and test cases have been completed.
+         * @event complete
+         */        
+        COMPLETE_EVENT /*:String*/ : "complete",
+        
+        /**
+         * Fires when the run() method is called.
+         * @event begin
+         */        
+        BEGIN_EVENT /*:String*/ : "begin",    
+        
+        //-------------------------------------------------------------------------
+        // Test Tree-Related Methods
+        //-------------------------------------------------------------------------
+
+        /**
+         * Adds a test case to the test tree as a child of the specified node.
+         * @param {TestNode} parentNode The node to add the test case to as a child.
+         * @param {YAHOO.tool.TestCase} testCase The test case to add.
+         * @return {Void}
+         * @static
+         * @private
+         * @method _addTestCaseToTestTree
+         */
+       _addTestCaseToTestTree : function (parentNode /*:TestNode*/, testCase /*:YAHOO.tool.TestCase*/) /*:Void*/{
+            
+            //add the test suite
+            var node = parentNode.appendChild(testCase);
+            
+            //iterate over the items in the test case
+            for (var prop in testCase){
+                if (prop.indexOf("test") === 0 && YAHOO.lang.isFunction(testCase[prop])){
+                    node.appendChild(prop);
+                }
+            }
+         
+        },
+        
+        /**
+         * Adds a test suite to the test tree as a child of the specified node.
+         * @param {TestNode} parentNode The node to add the test suite to as a child.
+         * @param {YAHOO.tool.TestSuite} testSuite The test suite to add.
+         * @return {Void}
+         * @static
+         * @private
+         * @method _addTestSuiteToTestTree
+         */
+        _addTestSuiteToTestTree : function (parentNode /*:TestNode*/, testSuite /*:YAHOO.tool.TestSuite*/) /*:Void*/ {
+            
+            //add the test suite
+            var node = parentNode.appendChild(testSuite);
+            
+            //iterate over the items in the master suite
+            for (var i=0; i < testSuite.items.length; i++){
+                if (testSuite.items[i] instanceof YAHOO.tool.TestSuite) {
+                    this._addTestSuiteToTestTree(node, testSuite.items[i]);
+                } else if (testSuite.items[i] instanceof YAHOO.tool.TestCase) {
+                    this._addTestCaseToTestTree(node, testSuite.items[i]);
+                }                   
+            }            
+        },
+        
+        /**
+         * Builds the test tree based on items in the master suite. The tree is a hierarchical
+         * representation of the test suites, test cases, and test functions. The resulting tree
+         * is stored in _root and the pointer _cur is set to the root initially.
+         * @return {Void}
+         * @static
+         * @private
+         * @method _buildTestTree
+         */
+        _buildTestTree : function () /*:Void*/ {
+        
+            this._root = new TestNode(this.masterSuite);
+            this._cur = this._root;
+            
+            //iterate over the items in the master suite
+            for (var i=0; i < this.masterSuite.items.length; i++){
+                if (this.masterSuite.items[i] instanceof YAHOO.tool.TestSuite) {
+                    this._addTestSuiteToTestTree(this._root, this.masterSuite.items[i]);
+                } else if (this.masterSuite.items[i] instanceof YAHOO.tool.TestCase) {
+                    this._addTestCaseToTestTree(this._root, this.masterSuite.items[i]);
+                }                   
+            }            
+        
+        }, 
+    
+        //-------------------------------------------------------------------------
+        // Private Methods
+        //-------------------------------------------------------------------------
+        
+        /**
+         * Handles the completion of a test object's tests. Tallies test results 
+         * from one level up to the next.
+         * @param {TestNode} node The TestNode representing the test object.
+         * @return {Void}
+         * @method _handleTestObjectComplete
+         * @private
+         */
+        _handleTestObjectComplete : function (node /*:TestNode*/) /*:Void*/ {
+            if (YAHOO.lang.isObject(node.testObject)){
+                node.parent.results.passed += node.results.passed;
+                node.parent.results.failed += node.results.failed;
+                node.parent.results.total += node.results.total;                
+                node.parent.results.ignored += node.results.ignored;                
+                node.parent.results[node.testObject.name] = node.results;
+            
+                if (node.testObject instanceof YAHOO.tool.TestSuite){
+                    node.testObject.tearDown();
+                    this.fireEvent(this.TEST_SUITE_COMPLETE_EVENT, { testSuite: node.testObject, results: node.results});
+                } else if (node.testObject instanceof YAHOO.tool.TestCase){
+                    this.fireEvent(this.TEST_CASE_COMPLETE_EVENT, { testCase: node.testObject, results: node.results});
+                }      
+            } 
+        },                
+        
+        //-------------------------------------------------------------------------
+        // Navigation Methods
+        //-------------------------------------------------------------------------
+        
+        /**
+         * Retrieves the next node in the test tree.
+         * @return {TestNode} The next node in the test tree or null if the end is reached.
+         * @private
+         * @static
+         * @method _next
+         */
+        _next : function () /*:TestNode*/ {
+        
+            if (this._cur.firstChild) {
+                this._cur = this._cur.firstChild;
+            } else if (this._cur.next) {
+                this._cur = this._cur.next;            
+            } else {
+                while (this._cur && !this._cur.next && this._cur !== this._root){
+                    this._handleTestObjectComplete(this._cur);
+                    this._cur = this._cur.parent;
+                }
+                
+                if (this._cur == this._root){
+                    this._cur.results.type = "report";
+                    this._cur.results.timestamp = (new Date()).toLocaleString();
+                    this.fireEvent(this.COMPLETE_EVENT, { results: this._cur.results});
+                    this._cur = null;
+                } else {
+                    this._handleTestObjectComplete(this._cur);               
+                    this._cur = this._cur.next;                
+                }
+            }
+        
+            return this._cur;
+        },
+        
+        /**
+         * Runs a test case or test suite, returning the results.
+         * @param {YAHOO.tool.TestCase|YAHOO.tool.TestSuite} testObject The test case or test suite to run.
+         * @return {Object} Results of the execution with properties passed, failed, and total.
+         * @private
+         * @method _run
+         * @static
+         */
+        _run : function () /*:Void*/ {
+        
+            //flag to indicate if the TestRunner should wait before continuing
+            var shouldWait /*:Boolean*/ = false;
+            
+            //get the next test node
+            var node = this._next();
+            
+            if (node !== null) {
+                var testObject = node.testObject;
+                
+                //figure out what to do
+                if (YAHOO.lang.isObject(testObject)){
+                    if (testObject instanceof YAHOO.tool.TestSuite){
+                        this.fireEvent(this.TEST_SUITE_BEGIN_EVENT, { testSuite: testObject });
+                        testObject.setUp();
+                    } else if (testObject instanceof YAHOO.tool.TestCase){
+                        this.fireEvent(this.TEST_CASE_BEGIN_EVENT, { testCase: testObject });
+                    }
+                    
+                    //some environments don't support setTimeout
+                    if (typeof setTimeout != "undefined"){                    
+                        setTimeout(function(){
+                            YAHOO.tool.TestRunner._run();
+                        }, 0);
+                    } else {
+                        this._run();
+                    }
+                } else {
+                    this._runTest(node);
+                }
+
+            }
+        },
+        
+        _resumeTest : function (segment /*:Function*/) /*:Void*/ {
+        
+            //get relevant information
+            var node /*:TestNode*/ = this._cur;
+            var testName /*:String*/ = node.testObject;
+            var testCase /*:YAHOO.tool.TestCase*/ = node.parent.testObject;
+            
+            //get the "should" test cases
+            var shouldFail /*:Object*/ = (testCase._should.fail || {})[testName];
+            var shouldError /*:Object*/ = (testCase._should.error || {})[testName];
+            
+            //variable to hold whether or not the test failed
+            var failed /*:Boolean*/ = false;
+            var error /*:Error*/ = null;
+                
+            //try the test
+            try {
+            
+                //run the test
+                segment.apply(testCase);
+                
+                //if it should fail, and it got here, then it's a fail because it didn't
+                if (shouldFail){
+                    error = new YAHOO.util.ShouldFail();
+                    failed = true;
+                } else if (shouldError){
+                    error = new YAHOO.util.ShouldError();
+                    failed = true;
+                }
+                           
+            } catch (thrown /*:Error*/){
+                if (thrown instanceof YAHOO.util.AssertionError) {
+                    if (!shouldFail){
+                        error = thrown;
+                        failed = true;
+                    }
+                } else if (thrown instanceof YAHOO.tool.TestCase.Wait){
+                
+                    if (YAHOO.lang.isFunction(thrown.segment)){
+                        if (YAHOO.lang.isNumber(thrown.delay)){
+                        
+                            //some environments don't support setTimeout
+                            if (typeof setTimeout != "undefined"){
+                                setTimeout(function(){
+                                    YAHOO.tool.TestRunner._resumeTest(thrown.segment);
+                                }, thrown.delay);
+                            } else {
+                                throw new Error("Asynchronous tests not supported in this environment.");
+                            }
+                        }
+                    }
+                    
+                    return;
+                
+                } else {
+                    //first check to see if it should error
+                    if (!shouldError) {                        
+                        error = new YAHOO.util.UnexpectedError(thrown);
+                        failed = true;
+                    } else {
+                        //check to see what type of data we have
+                        if (YAHOO.lang.isString(shouldError)){
+                            
+                            //if it's a string, check the error message
+                            if (thrown.message != shouldError){
+                                error = new YAHOO.util.UnexpectedError(thrown);
+                                failed = true;                                    
+                            }
+                        } else if (YAHOO.lang.isFunction(shouldError)){
+                        
+                            //if it's a function, see if the error is an instance of it
+                            if (!(thrown instanceof shouldError)){
+                                error = new YAHOO.util.UnexpectedError(thrown);
+                                failed = true;
+                            }
+                        
+                        } else if (YAHOO.lang.isObject(shouldError)){
+                        
+                            //if it's an object, check the instance and message
+                            if (!(thrown instanceof shouldError.constructor) || 
+                                    thrown.message != shouldError.message){
+                                error = new YAHOO.util.UnexpectedError(thrown);
+                                failed = true;                                    
+                            }
+                        
+                        }
+                    
+                    }
+                }
+                
+            }
+            
+            //fireEvent appropriate event
+            if (failed) {
+                this.fireEvent(this.TEST_FAIL_EVENT, { testCase: testCase, testName: testName, error: error });
+            } else {
+                this.fireEvent(this.TEST_PASS_EVENT, { testCase: testCase, testName: testName });
+            }
+            
+            //run the tear down
+            testCase.tearDown();
+            
+            //update results
+            node.parent.results[testName] = { 
+                result: failed ? "fail" : "pass",
+                message: error ? error.getMessage() : "Test passed",
+                type: "test",
+                name: testName
+            };
+            
+            if (failed){
+                node.parent.results.failed++;
+            } else {
+                node.parent.results.passed++;
+            }
+            node.parent.results.total++;
+
+            //set timeout not supported in all environments
+            if (typeof setTimeout != "undefined"){
+                setTimeout(function(){
+                    YAHOO.tool.TestRunner._run();
+                }, 0);
+            } else {
+                this._run();
+            }
+        
+        },
+                
+        /**
+         * Runs a single test based on the data provided in the node.
+         * @param {TestNode} node The TestNode representing the test to run.
+         * @return {Void}
+         * @static
+         * @private
+         * @name _runTest
+         */
+        _runTest : function (node /*:TestNode*/) /*:Void*/ {
+        
+            //get relevant information
+            var testName /*:String*/ = node.testObject;
+            var testCase /*:YAHOO.tool.TestCase*/ = node.parent.testObject;
+            var test /*:Function*/ = testCase[testName];
+            
+            //get the "should" test cases
+            var shouldIgnore /*:Object*/ = (testCase._should.ignore || {})[testName];
+            
+            //figure out if the test should be ignored or not
+            if (shouldIgnore){
+            
+                //update results
+                node.parent.results[testName] = { 
+                    result: "ignore",
+                    message: "Test ignored",
+                    type: "test",
+                    name: testName
+                };
+                
+                node.parent.results.ignored++;
+                node.parent.results.total++;
+            
+                this.fireEvent(this.TEST_IGNORE_EVENT, { testCase: testCase, testName: testName });
+                
+                //some environments don't support setTimeout
+                if (typeof setTimeout != "undefined"){                    
+                    setTimeout(function(){
+                        YAHOO.tool.TestRunner._run();
+                    }, 0);              
+                } else {
+                    this._run();
+                }
+
+            } else {
+            
+                //run the setup
+                testCase.setUp();
+                
+                //now call the body of the test
+                this._resumeTest(test);                
+            }
+
+        },        
+        
+        //-------------------------------------------------------------------------
+        // Protected Methods
+        //-------------------------------------------------------------------------   
+    
+        /*
+         * Fires events for the TestRunner. This overrides the default fireEvent()
+         * method from EventProvider to add the type property to the data that is
+         * passed through on each event call.
+         * @param {String} type The type of event to fire.
+         * @param {Object} data (Optional) Data for the event.
+         * @method fireEvent
+         * @static
+         * @protected
+         */
+        fireEvent : function (type /*:String*/, data /*:Object*/) /*:Void*/ {
+            data = data || {};
+            data.type = type;
+            TestRunner.superclass.fireEvent.call(this, type, data);
+        },
+        
+        //-------------------------------------------------------------------------
+        // Public Methods
+        //-------------------------------------------------------------------------   
+    
+        /**
+         * Adds a test suite or test case to the list of test objects to run.
+         * @param testObject Either a TestCase or a TestSuite that should be run.
+         * @return {Void}
+         * @method add
+         * @static
+         */
+        add : function (testObject /*:Object*/) /*:Void*/ {
+            this.masterSuite.add(testObject);
+        },
+        
+        /**
+         * Removes all test objects from the runner.
+         * @return {Void}
+         * @method clear
+         * @static
+         */
+        clear : function () /*:Void*/ {
+            this.masterSuite.items = [];
+        },
+        
+        /**
+         * Resumes the TestRunner after wait() was called.
+         * @param {Function} segment The function to run as the rest
+         *      of the haulted test.
+         * @return {Void}
+         * @method resume
+         * @static
+         */
+        resume : function (segment /*:Function*/) /*:Void*/ {
+            this._resumeTest(segment || function(){});
+        },
+    
+        /**
+         * Runs the test suite.
+         * @return {Void}
+         * @method run
+         * @static
+         */
+        run : function (testObject /*:Object*/) /*:Void*/ {
+            
+            //pointer to runner to avoid scope issues 
+            var runner = YAHOO.tool.TestRunner;
+
+            //build the test tree
+            runner._buildTestTree();
+            
+            //fire the begin event
+            runner.fireEvent(runner.BEGIN_EVENT);
+       
+            //begin the testing
+            runner._run();
+        }    
+    });
+    
+    return new TestRunner();
+    
+})();
+
+YAHOO.namespace("util");
+
+//-----------------------------------------------------------------------------
+// Assert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The Assert object provides functions to test JavaScript values against
+ * known and expected results. Whenever a comparison (assertion) fails,
+ * an error is thrown.
+ *
+ * @namespace YAHOO.util
+ * @class Assert
+ * @static
+ */
+YAHOO.util.Assert = {
+
+    //-------------------------------------------------------------------------
+    // Helper Methods
+    //-------------------------------------------------------------------------
+    
+    /**
+     * Formats a message so that it can contain the original assertion message
+     * in addition to the custom message.
+     * @param {String} customMessage The message passed in by the developer.
+     * @param {String} defaultMessage The message created by the error by default.
+     * @return {String} The final error message, containing either or both.
+     * @protected
+     * @static
+     * @method _formatMessage
+     */
+    _formatMessage : function (customMessage /*:String*/, defaultMessage /*:String*/) /*:String*/ {
+        var message = customMessage;
+        if (YAHOO.lang.isString(customMessage) && customMessage.length > 0){
+            return YAHOO.lang.substitute(customMessage, { message: defaultMessage });
+        } else {
+            return defaultMessage;
+        }        
+    },
+    
+    //-------------------------------------------------------------------------
+    // Generic Assertion Methods
+    //-------------------------------------------------------------------------
+    
+    /** 
+     * Forces an assertion error to occur.
+     * @param {String} message (Optional) The message to display with the failure.
+     * @method fail
+     * @static
+     */
+    fail : function (message /*:String*/) /*:Void*/ {
+        throw new YAHOO.util.AssertionError(this._formatMessage(message, "Test force-failed."));
+    },       
+    
+    //-------------------------------------------------------------------------
+    // Equality Assertion Methods
+    //-------------------------------------------------------------------------    
+    
+    /**
+     * Asserts that a value is equal to another. This uses the double equals sign
+     * so type cohersion may occur.
+     * @param {Object} expected The expected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areEqual
+     * @static
+     */
+    areEqual : function (expected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (expected != actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Values should be equal."), expected, actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is not equal to another. This uses the double equals sign
+     * so type cohersion may occur.
+     * @param {Object} unexpected The unexpected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areNotEqual
+     * @static
+     */
+    areNotEqual : function (unexpected /*:Object*/, actual /*:Object*/, 
+                         message /*:String*/) /*:Void*/ {
+        if (unexpected == actual) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be equal."), unexpected);
+        }
+    },
+    
+    /**
+     * Asserts that a value is not the same as another. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} unexpected The unexpected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areNotSame
+     * @static
+     */
+    areNotSame : function (unexpected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (unexpected === actual) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be the same."), unexpected);
+        }
+    },
+
+    /**
+     * Asserts that a value is the same as another. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} expected The expected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areSame
+     * @static
+     */
+    areSame : function (expected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (expected !== actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Values should be the same."), expected, actual);
+        }
+    },    
+    
+    //-------------------------------------------------------------------------
+    // Boolean Assertion Methods
+    //-------------------------------------------------------------------------    
+    
+    /**
+     * Asserts that a value is false. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isFalse
+     * @static
+     */
+    isFalse : function (actual /*:Boolean*/, message /*:String*/) {
+        if (false !== actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be false."), false, actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is true. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isTrue
+     * @static
+     */
+    isTrue : function (actual /*:Boolean*/, message /*:String*/) /*:Void*/ {
+        if (true !== actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be true."), true, actual);
+        }
+
+    },
+    
+    //-------------------------------------------------------------------------
+    // Special Value Assertion Methods
+    //-------------------------------------------------------------------------    
+    
+    /**
+     * Asserts that a value is not a number.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNaN
+     * @static
+     */
+    isNaN : function (actual /*:Object*/, message /*:String*/) /*:Void*/{
+        if (!isNaN(actual)){
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be NaN."), NaN, actual);
+        }    
+    },
+    
+    /**
+     * Asserts that a value is not the special NaN value.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotNaN
+     * @static
+     */
+    isNotNaN : function (actual /*:Object*/, message /*:String*/) /*:Void*/{
+        if (isNaN(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be NaN."), NaN);
+        }    
+    },
+    
+    /**
+     * Asserts that a value is not null. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotNull
+     * @static
+     */
+    isNotNull : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (YAHOO.lang.isNull(actual)) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be null."), null);
+        }
+    },
+
+    /**
+     * Asserts that a value is not undefined. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotUndefined
+     * @static
+     */
+    isNotUndefined : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (YAHOO.lang.isUndefined(actual)) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should not be undefined."), undefined);
+        }
+    },
+
+    /**
+     * Asserts that a value is null. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNull
+     * @static
+     */
+    isNull : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isNull(actual)) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be null."), null, actual);
+        }
+    },
+        
+    /**
+     * Asserts that a value is undefined. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isUndefined
+     * @static
+     */
+    isUndefined : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isUndefined(actual)) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be undefined."), undefined, actual);
+        }
+    },    
+    
+    //--------------------------------------------------------------------------
+    // Instance Assertion Methods
+    //--------------------------------------------------------------------------    
+   
+    /**
+     * Asserts that a value is an array.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isArray
+     * @static
+     */
+    isArray : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isArray(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be an array."), actual);
+        }    
+    },
+   
+    /**
+     * Asserts that a value is a Boolean.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isBoolean
+     * @static
+     */
+    isBoolean : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isBoolean(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a Boolean."), actual);
+        }    
+    },
+   
+    /**
+     * Asserts that a value is a function.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isFunction
+     * @static
+     */
+    isFunction : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isFunction(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a function."), actual);
+        }    
+    },
+   
+    /**
+     * Asserts that a value is an instance of a particular object. This may return
+     * incorrect results when comparing objects from one frame to constructors in
+     * another frame. For best results, don't use in a cross-frame manner.
+     * @param {Function} expected The function that the object should be an instance of.
+     * @param {Object} actual The object to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isInstanceOf
+     * @static
+     */
+    isInstanceOf : function (expected /*:Function*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!(actual instanceof expected)){
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value isn't an instance of expected type."), expected, actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is a number.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNumber
+     * @static
+     */
+    isNumber : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isNumber(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a number."), actual);
+        }    
+    },    
+    
+    /**
+     * Asserts that a value is an object.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isObject
+     * @static
+     */
+    isObject : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isObject(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be an object."), actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is a string.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isString
+     * @static
+     */
+    isString : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isString(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a string."), actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is of a particular type. 
+     * @param {String} expectedType The expected type of the variable.
+     * @param {Object} actualValue The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isTypeOf
+     * @static
+     */
+    isTypeOf : function (expectedType /*:String*/, actualValue /*:Object*/, message /*:String*/) /*:Void*/{
+        if (typeof actualValue != expectedType){
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be of type " + expected + "."), expected, typeof actual);
+        }
+    }
+};
+
+//-----------------------------------------------------------------------------
+// Assertion errors
+//-----------------------------------------------------------------------------
+
+/**
+ * AssertionError is thrown whenever an assertion fails. It provides methods
+ * to more easily get at error information and also provides a base class
+ * from which more specific assertion errors can be derived.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @namespace YAHOO.util
+ * @class AssertionError
+ * @extends Error
+ * @constructor
+ */ 
+YAHOO.util.AssertionError = function (message /*:String*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message);
+    
+    /*
+     * Error message. Must be duplicated to ensure browser receives it.
+     * @type String
+     * @property message
+     */
+    this.message /*:String*/ = message;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "AssertionError";
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.AssertionError, Error, {
+
+    /**
+     * Returns a fully formatted error for an assertion failure. This should
+     * be overridden by all subclasses to provide specific information.
+     * @method getMessage
+     * @return {String} A string describing the error.
+     */
+    getMessage : function () /*:String*/ {
+        return this.message;
+    },
+    
+    /**
+     * Returns a string representation of the error.
+     * @method toString
+     * @return {String} A string representation of the error.
+     */
+    toString : function () /*:String*/ {
+        return this.name + ": " + this.getMessage();
+    },
+    
+    /**
+     * Returns a primitive value version of the error. Same as toString().
+     * @method valueOf
+     * @return {String} A primitive value version of the error.
+     */
+    valueOf : function () /*:String*/ {
+        return this.toString();
+    }
+
+});
+
+/**
+ * ComparisonFailure is subclass of AssertionError that is thrown whenever
+ * a comparison between two values fails. It provides mechanisms to retrieve
+ * both the expected and actual value.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @param {Object} expected The expected value.
+ * @param {Object} actual The actual value that caused the assertion to fail.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class ComparisonFailure
+ * @constructor
+ */ 
+YAHOO.util.ComparisonFailure = function (message /*:String*/, expected /*:Object*/, actual /*:Object*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message);
+    
+    /**
+     * The expected value.
+     * @type Object
+     * @property expected
+     */
+    this.expected /*:Object*/ = expected;
+    
+    /**
+     * The actual value.
+     * @type Object
+     * @property actual
+     */
+    this.actual /*:Object*/ = actual;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "ComparisonFailure";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.ComparisonFailure, YAHOO.util.AssertionError, {
+
+    /**
+     * Returns a fully formatted error for an assertion failure. This message
+     * provides information about the expected and actual values.
+     * @method toString
+     * @return {String} A string describing the error.
+     */
+    getMessage : function () /*:String*/ {
+        return this.message + "\nExpected: " + this.expected + " (" + (typeof this.expected) + ")"  +
+            "\nActual:" + this.actual + " (" + (typeof this.actual) + ")";
+    }
+
+});
+
+/**
+ * UnexpectedValue is subclass of AssertionError that is thrown whenever
+ * a value was unexpected in its scope. This typically means that a test
+ * was performed to determine that a value was *not* equal to a certain
+ * value.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @param {Object} unexpected The unexpected value.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class UnexpectedValue
+ * @constructor
+ */ 
+YAHOO.util.UnexpectedValue = function (message /*:String*/, unexpected /*:Object*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message);
+    
+    /**
+     * The unexpected value.
+     * @type Object
+     * @property unexpected
+     */
+    this.unexpected /*:Object*/ = unexpected;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "UnexpectedValue";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.UnexpectedValue, YAHOO.util.AssertionError, {
+
+    /**
+     * Returns a fully formatted error for an assertion failure. The message
+     * contains information about the unexpected value that was encountered.
+     * @method getMessage
+     * @return {String} A string describing the error.
+     */
+    getMessage : function () /*:String*/ {
+        return this.message + "\nUnexpected: " + this.unexpected + " (" + (typeof this.unexpected) + ") ";
+    }
+
+});
+
+/**
+ * ShouldFail is subclass of AssertionError that is thrown whenever
+ * a test was expected to fail but did not.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class ShouldFail
+ * @constructor
+ */  
+YAHOO.util.ShouldFail = function (message /*:String*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message || "This test should fail but didn't.");
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "ShouldFail";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.ShouldFail, YAHOO.util.AssertionError);
+
+/**
+ * ShouldError is subclass of AssertionError that is thrown whenever
+ * a test is expected to throw an error but doesn't.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class ShouldError
+ * @constructor
+ */  
+YAHOO.util.ShouldError = function (message /*:String*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message || "This test should have thrown an error but didn't.");
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "ShouldError";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.ShouldError, YAHOO.util.AssertionError);
+
+/**
+ * UnexpectedError is subclass of AssertionError that is thrown whenever
+ * an error occurs within the course of a test and the test was not expected
+ * to throw an error.
+ *
+ * @param {Error} cause The unexpected error that caused this error to be 
+ *                      thrown.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class UnexpectedError
+ * @constructor
+ */  
+YAHOO.util.UnexpectedError = function (cause /*:Object*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, "Unexpected error: " + cause.message);
+    
+    /**
+     * The unexpected error that occurred.
+     * @type Error
+     * @property cause
+     */
+    this.cause /*:Error*/ = cause;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "UnexpectedError";
+    
+    /**
+     * Stack information for the error (if provided).
+     * @type String
+     * @property stack
+     */
+    this.stack /*:String*/ = cause.stack;
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.UnexpectedError, YAHOO.util.AssertionError);
+
+//-----------------------------------------------------------------------------
+// ArrayAssert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The ArrayAssert object provides functions to test JavaScript array objects
+ * for a variety of cases.
+ *
+ * @namespace YAHOO.util
+ * @class ArrayAssert
+ * @static
+ */
+ 
+YAHOO.util.ArrayAssert = {
+
+    /**
+     * Asserts that a value is present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur.
+     * @param {Object} needle The value that is expected in the array.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method contains
+     * @static
+     */
+    contains : function (needle /*:Object*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (haystack[i] === needle) {
+                found = true;
+            }
+        }
+        
+        if (!found){
+            Assert.fail(Assert._formatMessage(message, "Value " + needle + " (" + (typeof needle) + ") not found in array [" + haystack + "]."));
+        }
+    },
+
+    /**
+     * Asserts that a set of values are present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur. For this assertion to pass, all values must
+     * be found.
+     * @param {Object[]} needles An array of values that are expected in the array.
+     * @param {Array} haystack An array of values to check.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method containsItems
+     * @static
+     */
+    containsItems : function (needles /*:Object[]*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+
+        //begin checking values
+        for (var i=0; i < needles.length; i++){
+            this.contains(needles[i], haystack, message);
+        }
+    },
+
+    /**
+     * Asserts that a value matching some condition is present in an array. This uses
+     * a function to determine a match.
+     * @param {Function} matcher A function that returns true if the items matches or false if not.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method containsMatch
+     * @static
+     */
+    containsMatch : function (matcher /*:Function*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        //check for valid matcher
+        if (typeof matcher != "function"){
+            throw new TypeError("ArrayAssert.containsMatch(): First argument must be a function.");
+        }
+        
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (matcher(haystack[i])) {
+                found = true;
+            }
+        }
+        
+        if (!found){
+            Assert.fail(Assert._formatMessage(message, "No match found in array [" + haystack + "]."));
+        }
+    },
+
+    /**
+     * Asserts that a value is not present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur.
+     * @param {Object} needle The value that is expected in the array.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method doesNotContain
+     * @static
+     */
+    doesNotContain : function (needle /*:Object*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (haystack[i] === needle) {
+                found = true;
+            }
+        }
+        
+        if (found){
+            Assert.fail(Assert._formatMessage(message, "Value found in array [" + haystack + "]."));
+        }
+    },
+
+    /**
+     * Asserts that a set of values are not present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur. For this assertion to pass, all values must
+     * not be found.
+     * @param {Object[]} needles An array of values that are not expected in the array.
+     * @param {Array} haystack An array of values to check.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method doesNotContainItems
+     * @static
+     */
+    doesNotContainItems : function (needles /*:Object[]*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+
+        for (var i=0; i < needles.length; i++){
+            this.doesNotContain(needles[i], haystack, message);
+        }
+
+    },
+        
+    /**
+     * Asserts that no values matching a condition are present in an array. This uses
+     * a function to determine a match.
+     * @param {Function} matcher A function that returns true if the items matches or false if not.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method doesNotContainMatch
+     * @static
+     */
+    doesNotContainMatch : function (matcher /*:Function*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        //check for valid matcher
+        if (typeof matcher != "function"){
+            throw new TypeError("ArrayAssert.doesNotContainMatch(): First argument must be a function.");
+        }
+
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (matcher(haystack[i])) {
+                found = true;
+            }
+        }
+        
+        if (found){
+            Assert.fail(Assert._formatMessage(message, "Value found in array [" + haystack + "]."));
+        }
+    },
+        
+    /**
+     * Asserts that the given value is contained in an array at the specified index.
+     * This uses the triple equals sign so no type cohersion will occur.
+     * @param {Object} needle The value to look for.
+     * @param {Array} haystack The array to search in.
+     * @param {int} index The index at which the value should exist.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method indexOf
+     * @static
+     */
+    indexOf : function (needle /*:Object*/, haystack /*:Array*/, index /*:int*/, message /*:String*/) /*:Void*/ {
+    
+        //try to find the value in the array
+        for (var i=0; i < haystack.length; i++){
+            if (haystack[i] === needle){
+                YAHOO.util.Assert.areEqual(index, i, message || "Value exists at index " + i + " but should be at index " + index + ".");
+                return;
+            }
+        }
+        
+        var Assert = YAHOO.util.Assert;
+        
+        //if it makes it here, it wasn't found at all
+        Assert.fail(Assert._formatMessage(message, "Value doesn't exist in array [" + haystack + "]."));
+    },
+        
+    /**
+     * Asserts that the values in an array are equal, and in the same position,
+     * as values in another array. This uses the double equals sign
+     * so type cohersion may occur. Note that the array objects themselves
+     * need not be the same for this test to pass.
+     * @param {Array} expected An array of the expected values.
+     * @param {Array} actual Any array of the actual values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method itemsAreEqual
+     * @static
+     */
+    itemsAreEqual : function (expected /*:Array*/, actual /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        //one may be longer than the other, so get the maximum length
+        var len /*:int*/ = Math.max(expected.length, actual.length);
+        var Assert = YAHOO.util.Assert;
+       
+        //begin checking values
+        for (var i=0; i < len; i++){
+            Assert.areEqual(expected[i], actual[i], 
+                Assert._formatMessage(message, "Values in position " + i + " are not equal."));
+        }
+    },
+    
+    /**
+     * Asserts that the values in an array are equivalent, and in the same position,
+     * as values in another array. This uses a function to determine if the values
+     * are equivalent. Note that the array objects themselves
+     * need not be the same for this test to pass.
+     * @param {Array} expected An array of the expected values.
+     * @param {Array} actual Any array of the actual values.
+     * @param {Function} comparator A function that returns true if the values are equivalent
+     *      or false if not.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @return {Void}
+     * @method itemsAreEquivalent
+     * @static
+     */
+    itemsAreEquivalent : function (expected /*:Array*/, actual /*:Array*/, 
+                           comparator /*:Function*/, message /*:String*/) /*:Void*/ {
+        
+        //make sure the comparator is valid
+        if (typeof comparator != "function"){
+            throw new TypeError("ArrayAssert.itemsAreEquivalent(): Third argument must be a function.");
+        }
+        
+        //one may be longer than the other, so get the maximum length
+        var len /*:int*/ = Math.max(expected.length, actual.length);
+        
+        //begin checking values
+        for (var i=0; i < len; i++){
+            if (!comparator(expected[i], actual[i])){
+                throw new YAHOO.util.ComparisonFailure(YAHOO.util.Assert._formatMessage(message, "Values in position " + i + " are not equivalent."), expected[i], actual[i]);
+            }
+        }
+    },
+    
+    /**
+     * Asserts that an array is empty.
+     * @param {Array} actual The array to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isEmpty
+     * @static
+     */
+    isEmpty : function (actual /*:Array*/, message /*:String*/) /*:Void*/ {        
+        if (actual.length > 0){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Array should be empty."));
+        }
+    },    
+    
+    /**
+     * Asserts that an array is not empty.
+     * @param {Array} actual The array to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotEmpty
+     * @static
+     */
+    isNotEmpty : function (actual /*:Array*/, message /*:String*/) /*:Void*/ {        
+        if (actual.length === 0){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Array should not be empty."));
+        }
+    },    
+    
+    /**
+     * Asserts that the values in an array are the same, and in the same position,
+     * as values in another array. This uses the triple equals sign
+     * so no type cohersion will occur. Note that the array objects themselves
+     * need not be the same for this test to pass.
+     * @param {Array} expected An array of the expected values.
+     * @param {Array} actual Any array of the actual values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method itemsAreSame
+     * @static
+     */
+    itemsAreSame : function (expected /*:Array*/, actual /*:Array*/, 
+                          message /*:String*/) /*:Void*/ {
+        
+        //one may be longer than the other, so get the maximum length
+        var len /*:int*/ = Math.max(expected.length, actual.length);
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < len; i++){
+            Assert.areSame(expected[i], actual[i], 
+                Assert._formatMessage(message, "Values in position " + i + " are not the same."));
+        }
+    },
+    
+    /**
+     * Asserts that the given value is contained in an array at the specified index,
+     * starting from the back of the array.
+     * This uses the triple equals sign so no type cohersion will occur.
+     * @param {Object} needle The value to look for.
+     * @param {Array} haystack The array to search in.
+     * @param {int} index The index at which the value should exist.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method lastIndexOf
+     * @static
+     */
+    lastIndexOf : function (needle /*:Object*/, haystack /*:Array*/, index /*:int*/, message /*:String*/) /*:Void*/ {
+    
+        var Assert = YAHOO.util.Assert;
+    
+        //try to find the value in the array
+        for (var i=haystack.length; i >= 0; i--){
+            if (haystack[i] === needle){
+                Assert.areEqual(index, i, Assert._formatMessage(message, "Value exists at index " + i + " but should be at index " + index + "."));
+                return;
+            }
+        }
+        
+        //if it makes it here, it wasn't found at all
+        Assert.fail(Assert._formatMessage(message, "Value doesn't exist in array."));        
+    }
+    
+};
+
+YAHOO.namespace("util");
+
+
+//-----------------------------------------------------------------------------
+// ObjectAssert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The ObjectAssert object provides functions to test JavaScript objects
+ * for a variety of cases.
+ *
+ * @namespace YAHOO.util
+ * @class ObjectAssert
+ * @static
+ */
+YAHOO.util.ObjectAssert = {
+        
+    /**
+     * Asserts that all properties in the object exist in another object.
+     * @param {Object} expected An object with the expected properties.
+     * @param {Object} actual An object with the actual properties.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method propertiesAreEqual
+     * @static
+     */
+    propertiesAreEqual : function (expected /*:Object*/, actual /*:Object*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        var Assert = YAHOO.util.Assert;
+        
+        //get all properties in the object
+        var properties /*:Array*/ = [];        
+        for (var property in expected){
+            properties.push(property);
+        }
+        
+        //see if the properties are in the expected object
+        for (var i=0; i < properties.length; i++){
+            Assert.isNotUndefined(actual[properties[i]], 
+                Assert._formatMessage(message, "Property '" + properties[i] + "' expected."));
+        }
+
+    },
+    
+    /**
+     * Asserts that an object has a property with the given name.
+     * @param {String} propertyName The name of the property to test.
+     * @param {Object} object The object to search.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method hasProperty
+     * @static
+     */    
+    hasProperty : function (propertyName /*:String*/, object /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!(propertyName in object)){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Property '" + propertyName + "' not found on object."));
+        }    
+    },
+    
+    /**
+     * Asserts that a property with the given name exists on an object instance (not on its prototype).
+     * @param {String} propertyName The name of the property to test.
+     * @param {Object} object The object to search.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method hasProperty
+     * @static
+     */    
+    hasOwnProperty : function (propertyName /*:String*/, object /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.hasOwnProperty(object, propertyName)){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Property '" + propertyName + "' not found on object instance."));
+        }     
+    }
+};
+
+//-----------------------------------------------------------------------------
+// DateAssert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The DateAssert object provides functions to test JavaScript Date objects
+ * for a variety of cases.
+ *
+ * @namespace YAHOO.util
+ * @class DateAssert
+ * @static
+ */
+ 
+YAHOO.util.DateAssert = {
+
+    /**
+     * Asserts that a date's month, day, and year are equal to another date's.
+     * @param {Date} expected The expected date.
+     * @param {Date} actual The actual date to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method datesAreEqual
+     * @static
+     */
+    datesAreEqual : function (expected /*:Date*/, actual /*:Date*/, message /*:String*/){
+        if (expected instanceof Date && actual instanceof Date){
+            var Assert = YAHOO.util.Assert;
+            Assert.areEqual(expected.getFullYear(), actual.getFullYear(), Assert._formatMessage(message, "Years should be equal."));
+            Assert.areEqual(expected.getMonth(), actual.getMonth(), Assert._formatMessage(message, "Months should be equal."));
+            Assert.areEqual(expected.getDate(), actual.getDate(), Assert._formatMessage(message, "Day of month should be equal."));
+        } else {
+            throw new TypeError("DateAssert.datesAreEqual(): Expected and actual values must be Date objects.");
+        }
+    },
+
+    /**
+     * Asserts that a date's hour, minutes, and seconds are equal to another date's.
+     * @param {Date} expected The expected date.
+     * @param {Date} actual The actual date to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method timesAreEqual
+     * @static
+     */
+    timesAreEqual : function (expected /*:Date*/, actual /*:Date*/, message /*:String*/){
+        if (expected instanceof Date && actual instanceof Date){
+            var Assert = YAHOO.util.Assert;
+            Assert.areEqual(expected.getHours(), actual.getHours(), Assert._formatMessage(message, "Hours should be equal."));
+            Assert.areEqual(expected.getMinutes(), actual.getMinutes(), Assert._formatMessage(message, "Minutes should be equal."));
+            Assert.areEqual(expected.getSeconds(), actual.getSeconds(), Assert._formatMessage(message, "Seconds should be equal."));
+        } else {
+            throw new TypeError("DateAssert.timesAreEqual(): Expected and actual values must be Date objects.");
+        }
+    }
+    
+};
+
+YAHOO.register("yuitest_core", YAHOO.tool.TestRunner, {version: "2.5.1", build: "984"});

Added: trunk/root/static/yui/yuitest/yuitest_core-min.js
===================================================================
--- trunk/root/static/yui/yuitest/yuitest_core-min.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/yuitest_core-min.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,9 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+YAHOO.namespace("tool");YAHOO.tool.TestCase=function(A){this._should={};for(var B in A){this[B]=A[B];}if(!YAHOO.lang.isString(this.name)){this.name=YAHOO.util.Dom.generateId(null,"testCase");}};YAHOO.tool.TestCase.prototype={resume:function(A){YAHOO.tool.TestRunner.resume(A);},wait:function(B,A){throw new YAHOO.tool.TestCase.Wait(B,A);},setUp:function(){},tearDown:function(){}};YAHOO.tool.TestCase.Wait=function(B,A){this.segment=(YAHOO.lang.isFunction(B)?B:null);this.delay=(YAHOO.lang.isNumber(A)?A:0);};YAHOO.namespace("tool");YAHOO.tool.TestSuite=function(A){this.name="";this.items=[];if(YAHOO.lang.isString(A)){this.name=A;}else{if(YAHOO.lang.isObject(A)){YAHOO.lang.augmentObject(this,A,true);}}if(this.name===""){this.name=YAHOO.util.Dom.generateId(null,"testSuite");}};YAHOO.tool.TestSuite.prototype={add:function(A){if(A instanceof YAHOO.tool.TestSuite||A instanceof YAHOO.tool.TestCase){this.items.push(A);}},setUp:function(){},tearDown:function(){}};YAHOO.namespace("tool")!
 ;YAHOO.tool.TestRunner=(function(){function B(C){this.testObject=C;this.firstChild=null;this.lastChild=null;this.parent=null;this.next=null;this.results={passed:0,failed:0,total:0,ignored:0};if(C instanceof YAHOO.tool.TestSuite){this.results.type="testsuite";this.results.name=C.name;}else{if(C instanceof YAHOO.tool.TestCase){this.results.type="testcase";this.results.name=C.name;}}}B.prototype={appendChild:function(C){var D=new B(C);if(this.firstChild===null){this.firstChild=this.lastChild=D;}else{this.lastChild.next=D;this.lastChild=D;}D.parent=this;return D;}};function A(){A.superclass.constructor.apply(this,arguments);this.masterSuite=new YAHOO.tool.TestSuite("YUI Test Results");this._cur=null;this._root=null;var D=[this.TEST_CASE_BEGIN_EVENT,this.TEST_CASE_COMPLETE_EVENT,this.TEST_SUITE_BEGIN_EVENT,this.TEST_SUITE_COMPLETE_EVENT,this.TEST_PASS_EVENT,this.TEST_FAIL_EVENT,this.TEST_IGNORE_EVENT,this.COMPLETE_EVENT,this.BEGIN_EVENT];for(var C=0;C<D.length;C++){this.createEv!
 ent(D[C],{scope:this});}}YAHOO.lang.extend(A,YAHOO.util.EventP!
 rovider,
{TEST_CASE_BEGIN_EVENT:"testcasebegin",TEST_CASE_COMPLETE_EVENT:"testcasecomplete",TEST_SUITE_BEGIN_EVENT:"testsuitebegin",TEST_SUITE_COMPLETE_EVENT:"testsuitecomplete",TEST_PASS_EVENT:"pass",TEST_FAIL_EVENT:"fail",TEST_IGNORE_EVENT:"ignore",COMPLETE_EVENT:"complete",BEGIN_EVENT:"begin",_addTestCaseToTestTree:function(C,D){var E=C.appendChild(D);for(var F in D){if(F.indexOf("test")===0&&YAHOO.lang.isFunction(D[F])){E.appendChild(F);}}},_addTestSuiteToTestTree:function(C,F){var E=C.appendChild(F);for(var D=0;D<F.items.length;D++){if(F.items[D] instanceof YAHOO.tool.TestSuite){this._addTestSuiteToTestTree(E,F.items[D]);}else{if(F.items[D] instanceof YAHOO.tool.TestCase){this._addTestCaseToTestTree(E,F.items[D]);}}}},_buildTestTree:function(){this._root=new B(this.masterSuite);this._cur=this._root;for(var C=0;C<this.masterSuite.items.length;C++){if(this.masterSuite.items[C] instanceof YAHOO.tool.TestSuite){this._addTestSuiteToTestTree(this._root,this.masterSuite.items[C]);}else!
 {if(this.masterSuite.items[C] instanceof YAHOO.tool.TestCase){this._addTestCaseToTestTree(this._root,this.masterSuite.items[C]);}}}},_handleTestObjectComplete:function(C){if(YAHOO.lang.isObject(C.testObject)){C.parent.results.passed+=C.results.passed;C.parent.results.failed+=C.results.failed;C.parent.results.total+=C.results.total;C.parent.results.ignored+=C.results.ignored;C.parent.results[C.testObject.name]=C.results;if(C.testObject instanceof YAHOO.tool.TestSuite){C.testObject.tearDown();this.fireEvent(this.TEST_SUITE_COMPLETE_EVENT,{testSuite:C.testObject,results:C.results});}else{if(C.testObject instanceof YAHOO.tool.TestCase){this.fireEvent(this.TEST_CASE_COMPLETE_EVENT,{testCase:C.testObject,results:C.results});}}}},_next:function(){if(this._cur.firstChild){this._cur=this._cur.firstChild;}else{if(this._cur.next){this._cur=this._cur.next;}else{while(this._cur&&!this._cur.next&&this._cur!==this._root){this._handleTestObjectComplete(this._cur);this._cur=this._cur.parent!
 ;}if(this._cur==this._root){this._cur.results.type="report";th!
 is._cur.
results.timestamp=(new Date()).toLocaleString();this.fireEvent(this.COMPLETE_EVENT,{results:this._cur.results});this._cur=null;}else{this._handleTestObjectComplete(this._cur);this._cur=this._cur.next;}}}return this._cur;},_run:function(){var E=false;var D=this._next();if(D!==null){var C=D.testObject;if(YAHOO.lang.isObject(C)){if(C instanceof YAHOO.tool.TestSuite){this.fireEvent(this.TEST_SUITE_BEGIN_EVENT,{testSuite:C});C.setUp();}else{if(C instanceof YAHOO.tool.TestCase){this.fireEvent(this.TEST_CASE_BEGIN_EVENT,{testCase:C});}}if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._run();},0);}else{this._run();}}else{this._runTest(D);}}},_resumeTest:function(G){var C=this._cur;var H=C.testObject;var E=C.parent.testObject;var K=(E._should.fail||{})[H];var D=(E._should.error||{})[H];var F=false;var I=null;try{G.apply(E);if(K){I=new YAHOO.util.ShouldFail();F=true;}else{if(D){I=new YAHOO.util.ShouldError();F=true;}}}catch(J){if(J instanceof YAHOO.util.A!
 ssertionError){if(!K){I=J;F=true;}}else{if(J instanceof YAHOO.tool.TestCase.Wait){if(YAHOO.lang.isFunction(J.segment)){if(YAHOO.lang.isNumber(J.delay)){if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._resumeTest(J.segment);},J.delay);}else{throw new Error("Asynchronous tests not supported in this environment.");}}}return ;}else{if(!D){I=new YAHOO.util.UnexpectedError(J);F=true;}else{if(YAHOO.lang.isString(D)){if(J.message!=D){I=new YAHOO.util.UnexpectedError(J);F=true;}}else{if(YAHOO.lang.isFunction(D)){if(!(J instanceof D)){I=new YAHOO.util.UnexpectedError(J);F=true;}}else{if(YAHOO.lang.isObject(D)){if(!(J instanceof D.constructor)||J.message!=D.message){I=new YAHOO.util.UnexpectedError(J);F=true;}}}}}}}}if(F){this.fireEvent(this.TEST_FAIL_EVENT,{testCase:E,testName:H,error:I});}else{this.fireEvent(this.TEST_PASS_EVENT,{testCase:E,testName:H});}E.tearDown();C.parent.results[H]={result:F?"fail":"pass",message:I?I.getMessage():"Test passed",typ!
 e:"test",name:H};
+if(F){C.parent.results.failed++;}else{C.parent.results.passed++;}C.parent.results.total++;if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._run();},0);}else{this._run();}},_runTest:function(F){var C=F.testObject;var D=F.parent.testObject;var G=D[C];var E=(D._should.ignore||{})[C];if(E){F.parent.results[C]={result:"ignore",message:"Test ignored",type:"test",name:C};F.parent.results.ignored++;F.parent.results.total++;this.fireEvent(this.TEST_IGNORE_EVENT,{testCase:D,testName:C});if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._run();},0);}else{this._run();}}else{D.setUp();this._resumeTest(G);}},fireEvent:function(C,D){D=D||{};D.type=C;A.superclass.fireEvent.call(this,C,D);},add:function(C){this.masterSuite.add(C);},clear:function(){this.masterSuite.items=[];},resume:function(C){this._resumeTest(C||function(){});},run:function(C){var D=YAHOO.tool.TestRunner;D._buildTestTree();D.fireEvent(D.BEGIN_EVENT);D._run();}});r!
 eturn new A();})();YAHOO.namespace("util");YAHOO.util.Assert={_formatMessage:function(B,A){var C=B;if(YAHOO.lang.isString(B)&&B.length>0){return YAHOO.lang.substitute(B,{message:A});}else{return A;}},fail:function(A){throw new YAHOO.util.AssertionError(this._formatMessage(A,"Test force-failed."));},areEqual:function(B,C,A){if(B!=C){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Values should be equal."),B,C);}},areNotEqual:function(A,C,B){if(A==C){throw new YAHOO.util.UnexpectedValue(this._formatMessage(B,"Values should not be equal."),A);}},areNotSame:function(A,C,B){if(A===C){throw new YAHOO.util.UnexpectedValue(this._formatMessage(B,"Values should not be the same."),A);}},areSame:function(B,C,A){if(B!==C){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Values should be the same."),B,C);}},isFalse:function(B,A){if(false!==B){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value should be false."),false,B);}},isTrue:function(B,A){!
 if(true!==B){throw new YAHOO.util.ComparisonFailure(this._form!
 atMessag
e(A,"Value should be true."),true,B);}},isNaN:function(B,A){if(!isNaN(B)){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value should be NaN."),NaN,B);}},isNotNaN:function(B,A){if(isNaN(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Values should not be NaN."),NaN);}},isNotNull:function(B,A){if(YAHOO.lang.isNull(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Values should not be null."),null);}},isNotUndefined:function(B,A){if(YAHOO.lang.isUndefined(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should not be undefined."),undefined);}},isNull:function(B,A){if(!YAHOO.lang.isNull(B)){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value should be null."),null,B);}},isUndefined:function(B,A){if(!YAHOO.lang.isUndefined(B)){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value should be undefined."),undefined,B);}},isArray:function(B,A){if(!YAHOO.lang.isArray(B)){throw new YAHOO.ut!
 il.UnexpectedValue(this._formatMessage(A,"Value should be an array."),B);}},isBoolean:function(B,A){if(!YAHOO.lang.isBoolean(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be a Boolean."),B);}},isFunction:function(B,A){if(!YAHOO.lang.isFunction(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be a function."),B);}},isInstanceOf:function(B,C,A){if(!(C instanceof B)){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value isn't an instance of expected type."),B,C);}},isNumber:function(B,A){if(!YAHOO.lang.isNumber(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be a number."),B);}},isObject:function(B,A){if(!YAHOO.lang.isObject(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be an object."),B);}},isString:function(B,A){if(!YAHOO.lang.isString(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be a string."),B);}},isTypeOf:fun!
 ction(A,C,B){if(typeof C!=A){throw new YAHOO.util.ComparisonFa!
 ilure(th
is._formatMessage(B,"Value should be of type "+expected+"."),expected,typeof actual);}}};YAHOO.util.AssertionError=function(A){arguments.callee.superclass.constructor.call(this,A);this.message=A;this.name="AssertionError";};YAHOO.lang.extend(YAHOO.util.AssertionError,Error,{getMessage:function(){return this.message;},toString:function(){return this.name+": "+this.getMessage();},valueOf:function(){return this.toString();}});YAHOO.util.ComparisonFailure=function(B,A,C){arguments.callee.superclass.constructor.call(this,B);this.expected=A;this.actual=C;this.name="ComparisonFailure";};YAHOO.lang.extend(YAHOO.util.ComparisonFailure,YAHOO.util.AssertionError,{getMessage:function(){return this.message+"\nExpected: "+this.expected+" ("+(typeof this.expected)+")\nActual:"+this.actual+" ("+(typeof this.actual)+")";}});YAHOO.util.UnexpectedValue=function(B,A){arguments.callee.superclass.constructor.call(this,B);this.unexpected=A;this.name="UnexpectedValue";};YAHOO.lang.extend(YAHOO.util!
 .UnexpectedValue,YAHOO.util.AssertionError,{getMessage:function(){return this.message+"\nUnexpected: "+this.unexpected+" ("+(typeof this.unexpected)+") ";}});YAHOO.util.ShouldFail=function(A){arguments.callee.superclass.constructor.call(this,A||"This test should fail but didn't.");this.name="ShouldFail";};YAHOO.lang.extend(YAHOO.util.ShouldFail,YAHOO.util.AssertionError);YAHOO.util.ShouldError=function(A){arguments.callee.superclass.constructor.call(this,A||"This test should have thrown an error but didn't.");this.name="ShouldError";};YAHOO.lang.extend(YAHOO.util.ShouldError,YAHOO.util.AssertionError);YAHOO.util.UnexpectedError=function(A){arguments.callee.superclass.constructor.call(this,"Unexpected error: "+A.message);this.cause=A;this.name="UnexpectedError";this.stack=A.stack;};YAHOO.lang.extend(YAHOO.util.UnexpectedError,YAHOO.util.AssertionError);YAHOO.util.ArrayAssert={contains:function(E,D,B){var C=false;
+var F=YAHOO.util.Assert;for(var A=0;A<D.length&&!C;A++){if(D[A]===E){C=true;}}if(!C){F.fail(F._formatMessage(B,"Value "+E+" ("+(typeof E)+") not found in array ["+D+"]."));}},containsItems:function(C,D,B){for(var A=0;A<C.length;A++){this.contains(C[A],D,B);}},containsMatch:function(E,D,B){if(typeof E!="function"){throw new TypeError("ArrayAssert.containsMatch(): First argument must be a function.");}var C=false;var F=YAHOO.util.Assert;for(var A=0;A<D.length&&!C;A++){if(E(D[A])){C=true;}}if(!C){F.fail(F._formatMessage(B,"No match found in array ["+D+"]."));}},doesNotContain:function(E,D,B){var C=false;var F=YAHOO.util.Assert;for(var A=0;A<D.length&&!C;A++){if(D[A]===E){C=true;}}if(C){F.fail(F._formatMessage(B,"Value found in array ["+D+"]."));}},doesNotContainItems:function(C,D,B){for(var A=0;A<C.length;A++){this.doesNotContain(C[A],D,B);}},doesNotContainMatch:function(E,D,B){if(typeof E!="function"){throw new TypeError("ArrayAssert.doesNotContainMatch(): First argument must!
  be a function.");}var C=false;var F=YAHOO.util.Assert;for(var A=0;A<D.length&&!C;A++){if(E(D[A])){C=true;}}if(C){F.fail(F._formatMessage(B,"Value found in array ["+D+"]."));}},indexOf:function(E,D,A,C){for(var B=0;B<D.length;B++){if(D[B]===E){YAHOO.util.Assert.areEqual(A,B,C||"Value exists at index "+B+" but should be at index "+A+".");return ;}}var F=YAHOO.util.Assert;F.fail(F._formatMessage(C,"Value doesn't exist in array ["+D+"]."));},itemsAreEqual:function(D,F,C){var A=Math.max(D.length,F.length);var E=YAHOO.util.Assert;for(var B=0;B<A;B++){E.areEqual(D[B],F[B],E._formatMessage(C,"Values in position "+B+" are not equal."));}},itemsAreEquivalent:function(E,F,B,D){if(typeof B!="function"){throw new TypeError("ArrayAssert.itemsAreEquivalent(): Third argument must be a function.");}var A=Math.max(E.length,F.length);for(var C=0;C<A;C++){if(!B(E[C],F[C])){throw new YAHOO.util.ComparisonFailure(YAHOO.util.Assert._formatMessage(D,"Values in position "+C+" are not equivalent.")!
 ,E[C],F[C]);}}},isEmpty:function(C,A){if(C.length>0){var B=YAH!
 OO.util.
Assert;B.fail(B._formatMessage(A,"Array should be empty."));}},isNotEmpty:function(C,A){if(C.length===0){var B=YAHOO.util.Assert;B.fail(B._formatMessage(A,"Array should not be empty."));}},itemsAreSame:function(D,F,C){var A=Math.max(D.length,F.length);var E=YAHOO.util.Assert;for(var B=0;B<A;B++){E.areSame(D[B],F[B],E._formatMessage(C,"Values in position "+B+" are not the same."));}},lastIndexOf:function(E,D,A,C){var F=YAHOO.util.Assert;for(var B=D.length;B>=0;B--){if(D[B]===E){F.areEqual(A,B,F._formatMessage(C,"Value exists at index "+B+" but should be at index "+A+"."));return ;}}F.fail(F._formatMessage(C,"Value doesn't exist in array."));}};YAHOO.namespace("util");YAHOO.util.ObjectAssert={propertiesAreEqual:function(D,G,C){var F=YAHOO.util.Assert;var B=[];for(var E in D){B.push(E);}for(var A=0;A<B.length;A++){F.isNotUndefined(G[B[A]],F._formatMessage(C,"Property '"+B[A]+"' expected."));}},hasProperty:function(A,B,C){if(!(A in B)){var D=YAHOO.util.Assert;D.fail(D._formatMes!
 sage(C,"Property '"+A+"' not found on object."));}},hasOwnProperty:function(A,B,C){if(!YAHOO.lang.hasOwnProperty(B,A)){var D=YAHOO.util.Assert;D.fail(D._formatMessage(C,"Property '"+A+"' not found on object instance."));}}};YAHOO.util.DateAssert={datesAreEqual:function(B,D,A){if(B instanceof Date&&D instanceof Date){var C=YAHOO.util.Assert;C.areEqual(B.getFullYear(),D.getFullYear(),C._formatMessage(A,"Years should be equal."));C.areEqual(B.getMonth(),D.getMonth(),C._formatMessage(A,"Months should be equal."));C.areEqual(B.getDate(),D.getDate(),C._formatMessage(A,"Day of month should be equal."));}else{throw new TypeError("DateAssert.datesAreEqual(): Expected and actual values must be Date objects.");}},timesAreEqual:function(B,D,A){if(B instanceof Date&&D instanceof Date){var C=YAHOO.util.Assert;C.areEqual(B.getHours(),D.getHours(),C._formatMessage(A,"Hours should be equal."));C.areEqual(B.getMinutes(),D.getMinutes(),C._formatMessage(A,"Minutes should be equal."));C.areEqua!
 l(B.getSeconds(),D.getSeconds(),C._formatMessage(A,"Seconds sh!
 ould be 
equal."));}else{throw new TypeError("DateAssert.timesAreEqual(): Expected and actual values must be Date objects.");}}};YAHOO.register("yuitest_core",YAHOO.tool.TestRunner,{version:"2.5.1",build:"984"});
\ No newline at end of file

Added: trunk/root/static/yui/yuitest/yuitest_core.js
===================================================================
--- trunk/root/static/yui/yuitest/yuitest_core.js	2008-04-11 09:58:49 UTC (rev 872)
+++ trunk/root/static/yui/yuitest/yuitest_core.js	2008-04-11 09:58:56 UTC (rev 873)
@@ -0,0 +1,1963 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+YAHOO.namespace("tool");
+
+//-----------------------------------------------------------------------------
+// TestCase object
+//-----------------------------------------------------------------------------
+
+/**
+ * Test case containing various tests to run.
+ * @param template An object containing any number of test methods, other methods,
+ *                 an optional name, and anything else the test case needs.
+ * @class TestCase
+ * @namespace YAHOO.tool
+ * @constructor
+ */
+YAHOO.tool.TestCase = function (template /*:Object*/) {
+    
+    /**
+     * Special rules for the test case. Possible subobjects
+     * are fail, for tests that should fail, and error, for
+     * tests that should throw an error.
+     */
+    this._should /*:Object*/ = {};
+    
+    //copy over all properties from the template to this object
+    for (var prop in template) {
+        this[prop] = template[prop];
+    }    
+    
+    //check for a valid name
+    if (!YAHOO.lang.isString(this.name)){
+        /**
+         * Name for the test case.
+         */
+        this.name /*:String*/ = YAHOO.util.Dom.generateId(null, "testCase");
+    }
+
+};
+
+
+YAHOO.tool.TestCase.prototype = {  
+
+    /**
+     * Resumes a paused test and runs the given function.
+     * @param {Function} segment (Optional) The function to run.
+     *      If omitted, the test automatically passes.
+     * @return {Void}
+     * @method resume
+     */
+    resume : function (segment /*:Function*/) /*:Void*/ {
+        YAHOO.tool.TestRunner.resume(segment);
+    },
+
+    /**
+     * Causes the test case to wait a specified amount of time and then
+     * continue executing the given code.
+     * @param {Function} segment (Optional) The function to run after the delay.
+     *      If omitted, the TestRunner will wait until resume() is called.
+     * @param {int} delay (Optional) The number of milliseconds to wait before running
+     *      the function. If omitted, defaults to zero.
+     * @return {Void}
+     * @method wait
+     */
+    wait : function (segment /*:Function*/, delay /*:int*/) /*:Void*/{
+        throw new YAHOO.tool.TestCase.Wait(segment, delay);
+    },
+
+    //-------------------------------------------------------------------------
+    // Stub Methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Function to run before each test is executed.
+     * @return {Void}
+     * @method setUp
+     */
+    setUp : function () /*:Void*/ {
+    },
+    
+    /**
+     * Function to run after each test is executed.
+     * @return {Void}
+     * @method tearDown
+     */
+    tearDown: function () /*:Void*/ {    
+    }
+};
+
+/**
+ * Represents a stoppage in test execution to wait for an amount of time before
+ * continuing.
+ * @param {Function} segment A function to run when the wait is over.
+ * @param {int} delay The number of milliseconds to wait before running the code.
+ * @class Wait
+ * @namespace YAHOO.tool.TestCase
+ * @constructor
+ *
+ */
+YAHOO.tool.TestCase.Wait = function (segment /*:Function*/, delay /*:int*/) {
+    
+    /**
+     * The segment of code to run when the wait is over.
+     * @type Function
+     * @property segment
+     */
+    this.segment /*:Function*/ = (YAHOO.lang.isFunction(segment) ? segment : null);
+
+    /**
+     * The delay before running the segment of code.
+     * @type int
+     * @property delay
+     */
+    this.delay /*:int*/ = (YAHOO.lang.isNumber(delay) ? delay : 0);
+
+};
+
+YAHOO.namespace("tool");
+
+
+//-----------------------------------------------------------------------------
+// TestSuite object
+//-----------------------------------------------------------------------------
+
+/**
+ * A test suite that can contain a collection of TestCase and TestSuite objects.
+ * @param {String||Object} data The name of the test suite or an object containing
+ *      a name property as well as setUp and tearDown methods.
+ * @namespace YAHOO.tool
+ * @class TestSuite
+ * @constructor
+ */
+YAHOO.tool.TestSuite = function (data /*:String||Object*/) {
+
+    /**
+     * The name of the test suite.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "";
+
+    /**
+     * Array of test suites and
+     * @private
+     */
+    this.items /*:Array*/ = [];
+
+    //initialize the properties
+    if (YAHOO.lang.isString(data)){
+        this.name = data;
+    } else if (YAHOO.lang.isObject(data)){
+        YAHOO.lang.augmentObject(this, data, true);
+    }
+
+    //double-check name
+    if (this.name === ""){
+        this.name = YAHOO.util.Dom.generateId(null, "testSuite");
+    }
+
+};
+
+YAHOO.tool.TestSuite.prototype = {
+    
+    /**
+     * Adds a test suite or test case to the test suite.
+     * @param {YAHOO.tool.TestSuite||YAHOO.tool.TestCase} testObject The test suite or test case to add.
+     * @return {Void}
+     * @method add
+     */
+    add : function (testObject /*:YAHOO.tool.TestSuite*/) /*:Void*/ {
+        if (testObject instanceof YAHOO.tool.TestSuite || testObject instanceof YAHOO.tool.TestCase) {
+            this.items.push(testObject);
+        }
+    },
+    
+    //-------------------------------------------------------------------------
+    // Stub Methods
+    //-------------------------------------------------------------------------
+
+    /**
+     * Function to run before each test is executed.
+     * @return {Void}
+     * @method setUp
+     */
+    setUp : function () /*:Void*/ {
+    },
+    
+    /**
+     * Function to run after each test is executed.
+     * @return {Void}
+     * @method tearDown
+     */
+    tearDown: function () /*:Void*/ {
+    }
+    
+};
+
+YAHOO.namespace("tool");
+
+/**
+ * The YUI test tool
+ * @module yuitest
+ * @namespace YAHOO.tool
+ * @requires yahoo,dom,event,logger
+ */
+
+
+//-----------------------------------------------------------------------------
+// TestRunner object
+//-----------------------------------------------------------------------------
+
+/**
+ * Runs test suites and test cases, providing events to allowing for the
+ * interpretation of test results.
+ * @namespace YAHOO.tool
+ * @class TestRunner
+ * @static
+ */
+YAHOO.tool.TestRunner = (function(){
+
+    /**
+     * A node in the test tree structure. May represent a TestSuite, TestCase, or
+     * test function.
+     * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.
+     * @class TestNode
+     * @constructor
+     * @private
+     */
+    function TestNode(testObject /*:Variant*/){
+    
+        /**
+         * The TestSuite, TestCase, or test function represented by this node.
+         * @type Variant
+         * @property testObject
+         */
+        this.testObject = testObject;
+        
+        /**
+         * Pointer to this node's first child.
+         * @type TestNode
+         * @property firstChild
+         */        
+        this.firstChild /*:TestNode*/ = null;
+        
+        /**
+         * Pointer to this node's last child.
+         * @type TestNode
+         * @property lastChild
+         */        
+        this.lastChild = null;
+        
+        /**
+         * Pointer to this node's parent.
+         * @type TestNode
+         * @property parent
+         */        
+        this.parent = null; 
+   
+        /**
+         * Pointer to this node's next sibling.
+         * @type TestNode
+         * @property next
+         */        
+        this.next = null;
+        
+        /**
+         * Test results for this test object.
+         * @type object
+         * @property results
+         */                
+        this.results /*:Object*/ = {
+            passed : 0,
+            failed : 0,
+            total : 0,
+            ignored : 0
+        };
+        
+        //initialize results
+        if (testObject instanceof YAHOO.tool.TestSuite){
+            this.results.type = "testsuite";
+            this.results.name = testObject.name;
+        } else if (testObject instanceof YAHOO.tool.TestCase){
+            this.results.type = "testcase";
+            this.results.name = testObject.name;
+        }
+       
+    }
+    
+    TestNode.prototype = {
+    
+        /**
+         * Appends a new test object (TestSuite, TestCase, or test function name) as a child
+         * of this node.
+         * @param {Variant} testObject A TestSuite, TestCase, or the name of a test function.
+         * @return {Void}
+         */
+        appendChild : function (testObject /*:Variant*/) /*:Void*/{
+            var node = new TestNode(testObject);
+            if (this.firstChild === null){
+                this.firstChild = this.lastChild = node;
+            } else {
+                this.lastChild.next = node;
+                this.lastChild = node;
+            }
+            node.parent = this;
+            return node;
+        }       
+    };
+
+    function TestRunner(){
+    
+        //inherit from EventProvider
+        TestRunner.superclass.constructor.apply(this,arguments);
+        
+        /**
+         * Suite on which to attach all TestSuites and TestCases to be run.
+         * @type YAHOO.tool.TestSuite
+         * @property masterSuite
+         * @private
+         */
+        this.masterSuite /*:YAHOO.tool.TestSuite*/ = new YAHOO.tool.TestSuite("YUI Test Results");        
+
+        /**
+         * Pointer to the current node in the test tree.
+         * @type TestNode
+         * @private
+         * @property _cur
+         */
+        this._cur = null;
+        
+        /**
+         * Pointer to the root node in the test tree.
+         * @type TestNode
+         * @private
+         * @property _root
+         */
+        this._root = null;
+        
+        //create events
+        var events /*:Array*/ = [
+            this.TEST_CASE_BEGIN_EVENT,
+            this.TEST_CASE_COMPLETE_EVENT,
+            this.TEST_SUITE_BEGIN_EVENT,
+            this.TEST_SUITE_COMPLETE_EVENT,
+            this.TEST_PASS_EVENT,
+            this.TEST_FAIL_EVENT,
+            this.TEST_IGNORE_EVENT,
+            this.COMPLETE_EVENT,
+            this.BEGIN_EVENT
+        ];
+        for (var i=0; i < events.length; i++){
+            this.createEvent(events[i], { scope: this });
+        }       
+   
+    }
+    
+    YAHOO.lang.extend(TestRunner, YAHOO.util.EventProvider, {
+    
+        //-------------------------------------------------------------------------
+        // Constants
+        //-------------------------------------------------------------------------
+         
+        /**
+         * Fires when a test case is opened but before the first 
+         * test is executed.
+         * @event testcasebegin
+         */         
+        TEST_CASE_BEGIN_EVENT /*:String*/ : "testcasebegin",
+        
+        /**
+         * Fires when all tests in a test case have been executed.
+         * @event testcasecomplete
+         */        
+        TEST_CASE_COMPLETE_EVENT /*:String*/ : "testcasecomplete",
+        
+        /**
+         * Fires when a test suite is opened but before the first 
+         * test is executed.
+         * @event testsuitebegin
+         */        
+        TEST_SUITE_BEGIN_EVENT /*:String*/ : "testsuitebegin",
+        
+        /**
+         * Fires when all test cases in a test suite have been
+         * completed.
+         * @event testsuitecomplete
+         */        
+        TEST_SUITE_COMPLETE_EVENT /*:String*/ : "testsuitecomplete",
+        
+        /**
+         * Fires when a test has passed.
+         * @event pass
+         */        
+        TEST_PASS_EVENT /*:String*/ : "pass",
+        
+        /**
+         * Fires when a test has failed.
+         * @event fail
+         */        
+        TEST_FAIL_EVENT /*:String*/ : "fail",
+        
+        /**
+         * Fires when a test has been ignored.
+         * @event ignore
+         */        
+        TEST_IGNORE_EVENT /*:String*/ : "ignore",
+        
+        /**
+         * Fires when all test suites and test cases have been completed.
+         * @event complete
+         */        
+        COMPLETE_EVENT /*:String*/ : "complete",
+        
+        /**
+         * Fires when the run() method is called.
+         * @event begin
+         */        
+        BEGIN_EVENT /*:String*/ : "begin",    
+        
+        //-------------------------------------------------------------------------
+        // Test Tree-Related Methods
+        //-------------------------------------------------------------------------
+
+        /**
+         * Adds a test case to the test tree as a child of the specified node.
+         * @param {TestNode} parentNode The node to add the test case to as a child.
+         * @param {YAHOO.tool.TestCase} testCase The test case to add.
+         * @return {Void}
+         * @static
+         * @private
+         * @method _addTestCaseToTestTree
+         */
+       _addTestCaseToTestTree : function (parentNode /*:TestNode*/, testCase /*:YAHOO.tool.TestCase*/) /*:Void*/{
+            
+            //add the test suite
+            var node = parentNode.appendChild(testCase);
+            
+            //iterate over the items in the test case
+            for (var prop in testCase){
+                if (prop.indexOf("test") === 0 && YAHOO.lang.isFunction(testCase[prop])){
+                    node.appendChild(prop);
+                }
+            }
+         
+        },
+        
+        /**
+         * Adds a test suite to the test tree as a child of the specified node.
+         * @param {TestNode} parentNode The node to add the test suite to as a child.
+         * @param {YAHOO.tool.TestSuite} testSuite The test suite to add.
+         * @return {Void}
+         * @static
+         * @private
+         * @method _addTestSuiteToTestTree
+         */
+        _addTestSuiteToTestTree : function (parentNode /*:TestNode*/, testSuite /*:YAHOO.tool.TestSuite*/) /*:Void*/ {
+            
+            //add the test suite
+            var node = parentNode.appendChild(testSuite);
+            
+            //iterate over the items in the master suite
+            for (var i=0; i < testSuite.items.length; i++){
+                if (testSuite.items[i] instanceof YAHOO.tool.TestSuite) {
+                    this._addTestSuiteToTestTree(node, testSuite.items[i]);
+                } else if (testSuite.items[i] instanceof YAHOO.tool.TestCase) {
+                    this._addTestCaseToTestTree(node, testSuite.items[i]);
+                }                   
+            }            
+        },
+        
+        /**
+         * Builds the test tree based on items in the master suite. The tree is a hierarchical
+         * representation of the test suites, test cases, and test functions. The resulting tree
+         * is stored in _root and the pointer _cur is set to the root initially.
+         * @return {Void}
+         * @static
+         * @private
+         * @method _buildTestTree
+         */
+        _buildTestTree : function () /*:Void*/ {
+        
+            this._root = new TestNode(this.masterSuite);
+            this._cur = this._root;
+            
+            //iterate over the items in the master suite
+            for (var i=0; i < this.masterSuite.items.length; i++){
+                if (this.masterSuite.items[i] instanceof YAHOO.tool.TestSuite) {
+                    this._addTestSuiteToTestTree(this._root, this.masterSuite.items[i]);
+                } else if (this.masterSuite.items[i] instanceof YAHOO.tool.TestCase) {
+                    this._addTestCaseToTestTree(this._root, this.masterSuite.items[i]);
+                }                   
+            }            
+        
+        }, 
+    
+        //-------------------------------------------------------------------------
+        // Private Methods
+        //-------------------------------------------------------------------------
+        
+        /**
+         * Handles the completion of a test object's tests. Tallies test results 
+         * from one level up to the next.
+         * @param {TestNode} node The TestNode representing the test object.
+         * @return {Void}
+         * @method _handleTestObjectComplete
+         * @private
+         */
+        _handleTestObjectComplete : function (node /*:TestNode*/) /*:Void*/ {
+            if (YAHOO.lang.isObject(node.testObject)){
+                node.parent.results.passed += node.results.passed;
+                node.parent.results.failed += node.results.failed;
+                node.parent.results.total += node.results.total;                
+                node.parent.results.ignored += node.results.ignored;                
+                node.parent.results[node.testObject.name] = node.results;
+            
+                if (node.testObject instanceof YAHOO.tool.TestSuite){
+                    node.testObject.tearDown();
+                    this.fireEvent(this.TEST_SUITE_COMPLETE_EVENT, { testSuite: node.testObject, results: node.results});
+                } else if (node.testObject instanceof YAHOO.tool.TestCase){
+                    this.fireEvent(this.TEST_CASE_COMPLETE_EVENT, { testCase: node.testObject, results: node.results});
+                }      
+            } 
+        },                
+        
+        //-------------------------------------------------------------------------
+        // Navigation Methods
+        //-------------------------------------------------------------------------
+        
+        /**
+         * Retrieves the next node in the test tree.
+         * @return {TestNode} The next node in the test tree or null if the end is reached.
+         * @private
+         * @static
+         * @method _next
+         */
+        _next : function () /*:TestNode*/ {
+        
+            if (this._cur.firstChild) {
+                this._cur = this._cur.firstChild;
+            } else if (this._cur.next) {
+                this._cur = this._cur.next;            
+            } else {
+                while (this._cur && !this._cur.next && this._cur !== this._root){
+                    this._handleTestObjectComplete(this._cur);
+                    this._cur = this._cur.parent;
+                }
+                
+                if (this._cur == this._root){
+                    this._cur.results.type = "report";
+                    this._cur.results.timestamp = (new Date()).toLocaleString();
+                    this.fireEvent(this.COMPLETE_EVENT, { results: this._cur.results});
+                    this._cur = null;
+                } else {
+                    this._handleTestObjectComplete(this._cur);               
+                    this._cur = this._cur.next;                
+                }
+            }
+        
+            return this._cur;
+        },
+        
+        /**
+         * Runs a test case or test suite, returning the results.
+         * @param {YAHOO.tool.TestCase|YAHOO.tool.TestSuite} testObject The test case or test suite to run.
+         * @return {Object} Results of the execution with properties passed, failed, and total.
+         * @private
+         * @method _run
+         * @static
+         */
+        _run : function () /*:Void*/ {
+        
+            //flag to indicate if the TestRunner should wait before continuing
+            var shouldWait /*:Boolean*/ = false;
+            
+            //get the next test node
+            var node = this._next();
+            
+            if (node !== null) {
+                var testObject = node.testObject;
+                
+                //figure out what to do
+                if (YAHOO.lang.isObject(testObject)){
+                    if (testObject instanceof YAHOO.tool.TestSuite){
+                        this.fireEvent(this.TEST_SUITE_BEGIN_EVENT, { testSuite: testObject });
+                        testObject.setUp();
+                    } else if (testObject instanceof YAHOO.tool.TestCase){
+                        this.fireEvent(this.TEST_CASE_BEGIN_EVENT, { testCase: testObject });
+                    }
+                    
+                    //some environments don't support setTimeout
+                    if (typeof setTimeout != "undefined"){                    
+                        setTimeout(function(){
+                            YAHOO.tool.TestRunner._run();
+                        }, 0);
+                    } else {
+                        this._run();
+                    }
+                } else {
+                    this._runTest(node);
+                }
+
+            }
+        },
+        
+        _resumeTest : function (segment /*:Function*/) /*:Void*/ {
+        
+            //get relevant information
+            var node /*:TestNode*/ = this._cur;
+            var testName /*:String*/ = node.testObject;
+            var testCase /*:YAHOO.tool.TestCase*/ = node.parent.testObject;
+            
+            //get the "should" test cases
+            var shouldFail /*:Object*/ = (testCase._should.fail || {})[testName];
+            var shouldError /*:Object*/ = (testCase._should.error || {})[testName];
+            
+            //variable to hold whether or not the test failed
+            var failed /*:Boolean*/ = false;
+            var error /*:Error*/ = null;
+                
+            //try the test
+            try {
+            
+                //run the test
+                segment.apply(testCase);
+                
+                //if it should fail, and it got here, then it's a fail because it didn't
+                if (shouldFail){
+                    error = new YAHOO.util.ShouldFail();
+                    failed = true;
+                } else if (shouldError){
+                    error = new YAHOO.util.ShouldError();
+                    failed = true;
+                }
+                           
+            } catch (thrown /*:Error*/){
+                if (thrown instanceof YAHOO.util.AssertionError) {
+                    if (!shouldFail){
+                        error = thrown;
+                        failed = true;
+                    }
+                } else if (thrown instanceof YAHOO.tool.TestCase.Wait){
+                
+                    if (YAHOO.lang.isFunction(thrown.segment)){
+                        if (YAHOO.lang.isNumber(thrown.delay)){
+                        
+                            //some environments don't support setTimeout
+                            if (typeof setTimeout != "undefined"){
+                                setTimeout(function(){
+                                    YAHOO.tool.TestRunner._resumeTest(thrown.segment);
+                                }, thrown.delay);
+                            } else {
+                                throw new Error("Asynchronous tests not supported in this environment.");
+                            }
+                        }
+                    }
+                    
+                    return;
+                
+                } else {
+                    //first check to see if it should error
+                    if (!shouldError) {                        
+                        error = new YAHOO.util.UnexpectedError(thrown);
+                        failed = true;
+                    } else {
+                        //check to see what type of data we have
+                        if (YAHOO.lang.isString(shouldError)){
+                            
+                            //if it's a string, check the error message
+                            if (thrown.message != shouldError){
+                                error = new YAHOO.util.UnexpectedError(thrown);
+                                failed = true;                                    
+                            }
+                        } else if (YAHOO.lang.isFunction(shouldError)){
+                        
+                            //if it's a function, see if the error is an instance of it
+                            if (!(thrown instanceof shouldError)){
+                                error = new YAHOO.util.UnexpectedError(thrown);
+                                failed = true;
+                            }
+                        
+                        } else if (YAHOO.lang.isObject(shouldError)){
+                        
+                            //if it's an object, check the instance and message
+                            if (!(thrown instanceof shouldError.constructor) || 
+                                    thrown.message != shouldError.message){
+                                error = new YAHOO.util.UnexpectedError(thrown);
+                                failed = true;                                    
+                            }
+                        
+                        }
+                    
+                    }
+                }
+                
+            }
+            
+            //fireEvent appropriate event
+            if (failed) {
+                this.fireEvent(this.TEST_FAIL_EVENT, { testCase: testCase, testName: testName, error: error });
+            } else {
+                this.fireEvent(this.TEST_PASS_EVENT, { testCase: testCase, testName: testName });
+            }
+            
+            //run the tear down
+            testCase.tearDown();
+            
+            //update results
+            node.parent.results[testName] = { 
+                result: failed ? "fail" : "pass",
+                message: error ? error.getMessage() : "Test passed",
+                type: "test",
+                name: testName
+            };
+            
+            if (failed){
+                node.parent.results.failed++;
+            } else {
+                node.parent.results.passed++;
+            }
+            node.parent.results.total++;
+
+            //set timeout not supported in all environments
+            if (typeof setTimeout != "undefined"){
+                setTimeout(function(){
+                    YAHOO.tool.TestRunner._run();
+                }, 0);
+            } else {
+                this._run();
+            }
+        
+        },
+                
+        /**
+         * Runs a single test based on the data provided in the node.
+         * @param {TestNode} node The TestNode representing the test to run.
+         * @return {Void}
+         * @static
+         * @private
+         * @name _runTest
+         */
+        _runTest : function (node /*:TestNode*/) /*:Void*/ {
+        
+            //get relevant information
+            var testName /*:String*/ = node.testObject;
+            var testCase /*:YAHOO.tool.TestCase*/ = node.parent.testObject;
+            var test /*:Function*/ = testCase[testName];
+            
+            //get the "should" test cases
+            var shouldIgnore /*:Object*/ = (testCase._should.ignore || {})[testName];
+            
+            //figure out if the test should be ignored or not
+            if (shouldIgnore){
+            
+                //update results
+                node.parent.results[testName] = { 
+                    result: "ignore",
+                    message: "Test ignored",
+                    type: "test",
+                    name: testName
+                };
+                
+                node.parent.results.ignored++;
+                node.parent.results.total++;
+            
+                this.fireEvent(this.TEST_IGNORE_EVENT, { testCase: testCase, testName: testName });
+                
+                //some environments don't support setTimeout
+                if (typeof setTimeout != "undefined"){                    
+                    setTimeout(function(){
+                        YAHOO.tool.TestRunner._run();
+                    }, 0);              
+                } else {
+                    this._run();
+                }
+
+            } else {
+            
+                //run the setup
+                testCase.setUp();
+                
+                //now call the body of the test
+                this._resumeTest(test);                
+            }
+
+        },        
+        
+        //-------------------------------------------------------------------------
+        // Protected Methods
+        //-------------------------------------------------------------------------   
+    
+        /*
+         * Fires events for the TestRunner. This overrides the default fireEvent()
+         * method from EventProvider to add the type property to the data that is
+         * passed through on each event call.
+         * @param {String} type The type of event to fire.
+         * @param {Object} data (Optional) Data for the event.
+         * @method fireEvent
+         * @static
+         * @protected
+         */
+        fireEvent : function (type /*:String*/, data /*:Object*/) /*:Void*/ {
+            data = data || {};
+            data.type = type;
+            TestRunner.superclass.fireEvent.call(this, type, data);
+        },
+        
+        //-------------------------------------------------------------------------
+        // Public Methods
+        //-------------------------------------------------------------------------   
+    
+        /**
+         * Adds a test suite or test case to the list of test objects to run.
+         * @param testObject Either a TestCase or a TestSuite that should be run.
+         * @return {Void}
+         * @method add
+         * @static
+         */
+        add : function (testObject /*:Object*/) /*:Void*/ {
+            this.masterSuite.add(testObject);
+        },
+        
+        /**
+         * Removes all test objects from the runner.
+         * @return {Void}
+         * @method clear
+         * @static
+         */
+        clear : function () /*:Void*/ {
+            this.masterSuite.items = [];
+        },
+        
+        /**
+         * Resumes the TestRunner after wait() was called.
+         * @param {Function} segment The function to run as the rest
+         *      of the haulted test.
+         * @return {Void}
+         * @method resume
+         * @static
+         */
+        resume : function (segment /*:Function*/) /*:Void*/ {
+            this._resumeTest(segment || function(){});
+        },
+    
+        /**
+         * Runs the test suite.
+         * @return {Void}
+         * @method run
+         * @static
+         */
+        run : function (testObject /*:Object*/) /*:Void*/ {
+            
+            //pointer to runner to avoid scope issues 
+            var runner = YAHOO.tool.TestRunner;
+
+            //build the test tree
+            runner._buildTestTree();
+            
+            //fire the begin event
+            runner.fireEvent(runner.BEGIN_EVENT);
+       
+            //begin the testing
+            runner._run();
+        }    
+    });
+    
+    return new TestRunner();
+    
+})();
+
+YAHOO.namespace("util");
+
+//-----------------------------------------------------------------------------
+// Assert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The Assert object provides functions to test JavaScript values against
+ * known and expected results. Whenever a comparison (assertion) fails,
+ * an error is thrown.
+ *
+ * @namespace YAHOO.util
+ * @class Assert
+ * @static
+ */
+YAHOO.util.Assert = {
+
+    //-------------------------------------------------------------------------
+    // Helper Methods
+    //-------------------------------------------------------------------------
+    
+    /**
+     * Formats a message so that it can contain the original assertion message
+     * in addition to the custom message.
+     * @param {String} customMessage The message passed in by the developer.
+     * @param {String} defaultMessage The message created by the error by default.
+     * @return {String} The final error message, containing either or both.
+     * @protected
+     * @static
+     * @method _formatMessage
+     */
+    _formatMessage : function (customMessage /*:String*/, defaultMessage /*:String*/) /*:String*/ {
+        var message = customMessage;
+        if (YAHOO.lang.isString(customMessage) && customMessage.length > 0){
+            return YAHOO.lang.substitute(customMessage, { message: defaultMessage });
+        } else {
+            return defaultMessage;
+        }        
+    },
+    
+    //-------------------------------------------------------------------------
+    // Generic Assertion Methods
+    //-------------------------------------------------------------------------
+    
+    /** 
+     * Forces an assertion error to occur.
+     * @param {String} message (Optional) The message to display with the failure.
+     * @method fail
+     * @static
+     */
+    fail : function (message /*:String*/) /*:Void*/ {
+        throw new YAHOO.util.AssertionError(this._formatMessage(message, "Test force-failed."));
+    },       
+    
+    //-------------------------------------------------------------------------
+    // Equality Assertion Methods
+    //-------------------------------------------------------------------------    
+    
+    /**
+     * Asserts that a value is equal to another. This uses the double equals sign
+     * so type cohersion may occur.
+     * @param {Object} expected The expected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areEqual
+     * @static
+     */
+    areEqual : function (expected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (expected != actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Values should be equal."), expected, actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is not equal to another. This uses the double equals sign
+     * so type cohersion may occur.
+     * @param {Object} unexpected The unexpected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areNotEqual
+     * @static
+     */
+    areNotEqual : function (unexpected /*:Object*/, actual /*:Object*/, 
+                         message /*:String*/) /*:Void*/ {
+        if (unexpected == actual) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be equal."), unexpected);
+        }
+    },
+    
+    /**
+     * Asserts that a value is not the same as another. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} unexpected The unexpected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areNotSame
+     * @static
+     */
+    areNotSame : function (unexpected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (unexpected === actual) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be the same."), unexpected);
+        }
+    },
+
+    /**
+     * Asserts that a value is the same as another. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} expected The expected value.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method areSame
+     * @static
+     */
+    areSame : function (expected /*:Object*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (expected !== actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Values should be the same."), expected, actual);
+        }
+    },    
+    
+    //-------------------------------------------------------------------------
+    // Boolean Assertion Methods
+    //-------------------------------------------------------------------------    
+    
+    /**
+     * Asserts that a value is false. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isFalse
+     * @static
+     */
+    isFalse : function (actual /*:Boolean*/, message /*:String*/) {
+        if (false !== actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be false."), false, actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is true. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isTrue
+     * @static
+     */
+    isTrue : function (actual /*:Boolean*/, message /*:String*/) /*:Void*/ {
+        if (true !== actual) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be true."), true, actual);
+        }
+
+    },
+    
+    //-------------------------------------------------------------------------
+    // Special Value Assertion Methods
+    //-------------------------------------------------------------------------    
+    
+    /**
+     * Asserts that a value is not a number.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNaN
+     * @static
+     */
+    isNaN : function (actual /*:Object*/, message /*:String*/) /*:Void*/{
+        if (!isNaN(actual)){
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be NaN."), NaN, actual);
+        }    
+    },
+    
+    /**
+     * Asserts that a value is not the special NaN value.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotNaN
+     * @static
+     */
+    isNotNaN : function (actual /*:Object*/, message /*:String*/) /*:Void*/{
+        if (isNaN(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be NaN."), NaN);
+        }    
+    },
+    
+    /**
+     * Asserts that a value is not null. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotNull
+     * @static
+     */
+    isNotNull : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (YAHOO.lang.isNull(actual)) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Values should not be null."), null);
+        }
+    },
+
+    /**
+     * Asserts that a value is not undefined. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotUndefined
+     * @static
+     */
+    isNotUndefined : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (YAHOO.lang.isUndefined(actual)) {
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should not be undefined."), undefined);
+        }
+    },
+
+    /**
+     * Asserts that a value is null. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNull
+     * @static
+     */
+    isNull : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isNull(actual)) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be null."), null, actual);
+        }
+    },
+        
+    /**
+     * Asserts that a value is undefined. This uses the triple equals sign
+     * so no type cohersion may occur.
+     * @param {Object} actual The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isUndefined
+     * @static
+     */
+    isUndefined : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isUndefined(actual)) {
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be undefined."), undefined, actual);
+        }
+    },    
+    
+    //--------------------------------------------------------------------------
+    // Instance Assertion Methods
+    //--------------------------------------------------------------------------    
+   
+    /**
+     * Asserts that a value is an array.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isArray
+     * @static
+     */
+    isArray : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isArray(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be an array."), actual);
+        }    
+    },
+   
+    /**
+     * Asserts that a value is a Boolean.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isBoolean
+     * @static
+     */
+    isBoolean : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isBoolean(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a Boolean."), actual);
+        }    
+    },
+   
+    /**
+     * Asserts that a value is a function.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isFunction
+     * @static
+     */
+    isFunction : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isFunction(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a function."), actual);
+        }    
+    },
+   
+    /**
+     * Asserts that a value is an instance of a particular object. This may return
+     * incorrect results when comparing objects from one frame to constructors in
+     * another frame. For best results, don't use in a cross-frame manner.
+     * @param {Function} expected The function that the object should be an instance of.
+     * @param {Object} actual The object to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isInstanceOf
+     * @static
+     */
+    isInstanceOf : function (expected /*:Function*/, actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!(actual instanceof expected)){
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value isn't an instance of expected type."), expected, actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is a number.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNumber
+     * @static
+     */
+    isNumber : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isNumber(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a number."), actual);
+        }    
+    },    
+    
+    /**
+     * Asserts that a value is an object.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isObject
+     * @static
+     */
+    isObject : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isObject(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be an object."), actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is a string.
+     * @param {Object} actual The value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isString
+     * @static
+     */
+    isString : function (actual /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.isString(actual)){
+            throw new YAHOO.util.UnexpectedValue(this._formatMessage(message, "Value should be a string."), actual);
+        }
+    },
+    
+    /**
+     * Asserts that a value is of a particular type. 
+     * @param {String} expectedType The expected type of the variable.
+     * @param {Object} actualValue The actual value to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isTypeOf
+     * @static
+     */
+    isTypeOf : function (expectedType /*:String*/, actualValue /*:Object*/, message /*:String*/) /*:Void*/{
+        if (typeof actualValue != expectedType){
+            throw new YAHOO.util.ComparisonFailure(this._formatMessage(message, "Value should be of type " + expected + "."), expected, typeof actual);
+        }
+    }
+};
+
+//-----------------------------------------------------------------------------
+// Assertion errors
+//-----------------------------------------------------------------------------
+
+/**
+ * AssertionError is thrown whenever an assertion fails. It provides methods
+ * to more easily get at error information and also provides a base class
+ * from which more specific assertion errors can be derived.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @namespace YAHOO.util
+ * @class AssertionError
+ * @extends Error
+ * @constructor
+ */ 
+YAHOO.util.AssertionError = function (message /*:String*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message);
+    
+    /*
+     * Error message. Must be duplicated to ensure browser receives it.
+     * @type String
+     * @property message
+     */
+    this.message /*:String*/ = message;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "AssertionError";
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.AssertionError, Error, {
+
+    /**
+     * Returns a fully formatted error for an assertion failure. This should
+     * be overridden by all subclasses to provide specific information.
+     * @method getMessage
+     * @return {String} A string describing the error.
+     */
+    getMessage : function () /*:String*/ {
+        return this.message;
+    },
+    
+    /**
+     * Returns a string representation of the error.
+     * @method toString
+     * @return {String} A string representation of the error.
+     */
+    toString : function () /*:String*/ {
+        return this.name + ": " + this.getMessage();
+    },
+    
+    /**
+     * Returns a primitive value version of the error. Same as toString().
+     * @method valueOf
+     * @return {String} A primitive value version of the error.
+     */
+    valueOf : function () /*:String*/ {
+        return this.toString();
+    }
+
+});
+
+/**
+ * ComparisonFailure is subclass of AssertionError that is thrown whenever
+ * a comparison between two values fails. It provides mechanisms to retrieve
+ * both the expected and actual value.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @param {Object} expected The expected value.
+ * @param {Object} actual The actual value that caused the assertion to fail.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class ComparisonFailure
+ * @constructor
+ */ 
+YAHOO.util.ComparisonFailure = function (message /*:String*/, expected /*:Object*/, actual /*:Object*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message);
+    
+    /**
+     * The expected value.
+     * @type Object
+     * @property expected
+     */
+    this.expected /*:Object*/ = expected;
+    
+    /**
+     * The actual value.
+     * @type Object
+     * @property actual
+     */
+    this.actual /*:Object*/ = actual;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "ComparisonFailure";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.ComparisonFailure, YAHOO.util.AssertionError, {
+
+    /**
+     * Returns a fully formatted error for an assertion failure. This message
+     * provides information about the expected and actual values.
+     * @method toString
+     * @return {String} A string describing the error.
+     */
+    getMessage : function () /*:String*/ {
+        return this.message + "\nExpected: " + this.expected + " (" + (typeof this.expected) + ")"  +
+            "\nActual:" + this.actual + " (" + (typeof this.actual) + ")";
+    }
+
+});
+
+/**
+ * UnexpectedValue is subclass of AssertionError that is thrown whenever
+ * a value was unexpected in its scope. This typically means that a test
+ * was performed to determine that a value was *not* equal to a certain
+ * value.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @param {Object} unexpected The unexpected value.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class UnexpectedValue
+ * @constructor
+ */ 
+YAHOO.util.UnexpectedValue = function (message /*:String*/, unexpected /*:Object*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message);
+    
+    /**
+     * The unexpected value.
+     * @type Object
+     * @property unexpected
+     */
+    this.unexpected /*:Object*/ = unexpected;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "UnexpectedValue";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.UnexpectedValue, YAHOO.util.AssertionError, {
+
+    /**
+     * Returns a fully formatted error for an assertion failure. The message
+     * contains information about the unexpected value that was encountered.
+     * @method getMessage
+     * @return {String} A string describing the error.
+     */
+    getMessage : function () /*:String*/ {
+        return this.message + "\nUnexpected: " + this.unexpected + " (" + (typeof this.unexpected) + ") ";
+    }
+
+});
+
+/**
+ * ShouldFail is subclass of AssertionError that is thrown whenever
+ * a test was expected to fail but did not.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class ShouldFail
+ * @constructor
+ */  
+YAHOO.util.ShouldFail = function (message /*:String*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message || "This test should fail but didn't.");
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "ShouldFail";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.ShouldFail, YAHOO.util.AssertionError);
+
+/**
+ * ShouldError is subclass of AssertionError that is thrown whenever
+ * a test is expected to throw an error but doesn't.
+ *
+ * @param {String} message The message to display when the error occurs.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class ShouldError
+ * @constructor
+ */  
+YAHOO.util.ShouldError = function (message /*:String*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, message || "This test should have thrown an error but didn't.");
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "ShouldError";
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.ShouldError, YAHOO.util.AssertionError);
+
+/**
+ * UnexpectedError is subclass of AssertionError that is thrown whenever
+ * an error occurs within the course of a test and the test was not expected
+ * to throw an error.
+ *
+ * @param {Error} cause The unexpected error that caused this error to be 
+ *                      thrown.
+ * @namespace YAHOO.util
+ * @extends YAHOO.util.AssertionError
+ * @class UnexpectedError
+ * @constructor
+ */  
+YAHOO.util.UnexpectedError = function (cause /*:Object*/){
+
+    //call superclass
+    arguments.callee.superclass.constructor.call(this, "Unexpected error: " + cause.message);
+    
+    /**
+     * The unexpected error that occurred.
+     * @type Error
+     * @property cause
+     */
+    this.cause /*:Error*/ = cause;
+    
+    /**
+     * The name of the error that occurred.
+     * @type String
+     * @property name
+     */
+    this.name /*:String*/ = "UnexpectedError";
+    
+    /**
+     * Stack information for the error (if provided).
+     * @type String
+     * @property stack
+     */
+    this.stack /*:String*/ = cause.stack;
+    
+};
+
+//inherit methods
+YAHOO.lang.extend(YAHOO.util.UnexpectedError, YAHOO.util.AssertionError);
+
+//-----------------------------------------------------------------------------
+// ArrayAssert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The ArrayAssert object provides functions to test JavaScript array objects
+ * for a variety of cases.
+ *
+ * @namespace YAHOO.util
+ * @class ArrayAssert
+ * @static
+ */
+ 
+YAHOO.util.ArrayAssert = {
+
+    /**
+     * Asserts that a value is present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur.
+     * @param {Object} needle The value that is expected in the array.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method contains
+     * @static
+     */
+    contains : function (needle /*:Object*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (haystack[i] === needle) {
+                found = true;
+            }
+        }
+        
+        if (!found){
+            Assert.fail(Assert._formatMessage(message, "Value " + needle + " (" + (typeof needle) + ") not found in array [" + haystack + "]."));
+        }
+    },
+
+    /**
+     * Asserts that a set of values are present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur. For this assertion to pass, all values must
+     * be found.
+     * @param {Object[]} needles An array of values that are expected in the array.
+     * @param {Array} haystack An array of values to check.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method containsItems
+     * @static
+     */
+    containsItems : function (needles /*:Object[]*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+
+        //begin checking values
+        for (var i=0; i < needles.length; i++){
+            this.contains(needles[i], haystack, message);
+        }
+    },
+
+    /**
+     * Asserts that a value matching some condition is present in an array. This uses
+     * a function to determine a match.
+     * @param {Function} matcher A function that returns true if the items matches or false if not.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method containsMatch
+     * @static
+     */
+    containsMatch : function (matcher /*:Function*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        //check for valid matcher
+        if (typeof matcher != "function"){
+            throw new TypeError("ArrayAssert.containsMatch(): First argument must be a function.");
+        }
+        
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (matcher(haystack[i])) {
+                found = true;
+            }
+        }
+        
+        if (!found){
+            Assert.fail(Assert._formatMessage(message, "No match found in array [" + haystack + "]."));
+        }
+    },
+
+    /**
+     * Asserts that a value is not present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur.
+     * @param {Object} needle The value that is expected in the array.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method doesNotContain
+     * @static
+     */
+    doesNotContain : function (needle /*:Object*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (haystack[i] === needle) {
+                found = true;
+            }
+        }
+        
+        if (found){
+            Assert.fail(Assert._formatMessage(message, "Value found in array [" + haystack + "]."));
+        }
+    },
+
+    /**
+     * Asserts that a set of values are not present in an array. This uses the triple equals 
+     * sign so no type cohersion may occur. For this assertion to pass, all values must
+     * not be found.
+     * @param {Object[]} needles An array of values that are not expected in the array.
+     * @param {Array} haystack An array of values to check.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method doesNotContainItems
+     * @static
+     */
+    doesNotContainItems : function (needles /*:Object[]*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+
+        for (var i=0; i < needles.length; i++){
+            this.doesNotContain(needles[i], haystack, message);
+        }
+
+    },
+        
+    /**
+     * Asserts that no values matching a condition are present in an array. This uses
+     * a function to determine a match.
+     * @param {Function} matcher A function that returns true if the items matches or false if not.
+     * @param {Array} haystack An array of values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method doesNotContainMatch
+     * @static
+     */
+    doesNotContainMatch : function (matcher /*:Function*/, haystack /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        //check for valid matcher
+        if (typeof matcher != "function"){
+            throw new TypeError("ArrayAssert.doesNotContainMatch(): First argument must be a function.");
+        }
+
+        var found /*:Boolean*/ = false;
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < haystack.length && !found; i++){
+            if (matcher(haystack[i])) {
+                found = true;
+            }
+        }
+        
+        if (found){
+            Assert.fail(Assert._formatMessage(message, "Value found in array [" + haystack + "]."));
+        }
+    },
+        
+    /**
+     * Asserts that the given value is contained in an array at the specified index.
+     * This uses the triple equals sign so no type cohersion will occur.
+     * @param {Object} needle The value to look for.
+     * @param {Array} haystack The array to search in.
+     * @param {int} index The index at which the value should exist.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method indexOf
+     * @static
+     */
+    indexOf : function (needle /*:Object*/, haystack /*:Array*/, index /*:int*/, message /*:String*/) /*:Void*/ {
+    
+        //try to find the value in the array
+        for (var i=0; i < haystack.length; i++){
+            if (haystack[i] === needle){
+                YAHOO.util.Assert.areEqual(index, i, message || "Value exists at index " + i + " but should be at index " + index + ".");
+                return;
+            }
+        }
+        
+        var Assert = YAHOO.util.Assert;
+        
+        //if it makes it here, it wasn't found at all
+        Assert.fail(Assert._formatMessage(message, "Value doesn't exist in array [" + haystack + "]."));
+    },
+        
+    /**
+     * Asserts that the values in an array are equal, and in the same position,
+     * as values in another array. This uses the double equals sign
+     * so type cohersion may occur. Note that the array objects themselves
+     * need not be the same for this test to pass.
+     * @param {Array} expected An array of the expected values.
+     * @param {Array} actual Any array of the actual values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method itemsAreEqual
+     * @static
+     */
+    itemsAreEqual : function (expected /*:Array*/, actual /*:Array*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        //one may be longer than the other, so get the maximum length
+        var len /*:int*/ = Math.max(expected.length, actual.length);
+        var Assert = YAHOO.util.Assert;
+       
+        //begin checking values
+        for (var i=0; i < len; i++){
+            Assert.areEqual(expected[i], actual[i], 
+                Assert._formatMessage(message, "Values in position " + i + " are not equal."));
+        }
+    },
+    
+    /**
+     * Asserts that the values in an array are equivalent, and in the same position,
+     * as values in another array. This uses a function to determine if the values
+     * are equivalent. Note that the array objects themselves
+     * need not be the same for this test to pass.
+     * @param {Array} expected An array of the expected values.
+     * @param {Array} actual Any array of the actual values.
+     * @param {Function} comparator A function that returns true if the values are equivalent
+     *      or false if not.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @return {Void}
+     * @method itemsAreEquivalent
+     * @static
+     */
+    itemsAreEquivalent : function (expected /*:Array*/, actual /*:Array*/, 
+                           comparator /*:Function*/, message /*:String*/) /*:Void*/ {
+        
+        //make sure the comparator is valid
+        if (typeof comparator != "function"){
+            throw new TypeError("ArrayAssert.itemsAreEquivalent(): Third argument must be a function.");
+        }
+        
+        //one may be longer than the other, so get the maximum length
+        var len /*:int*/ = Math.max(expected.length, actual.length);
+        
+        //begin checking values
+        for (var i=0; i < len; i++){
+            if (!comparator(expected[i], actual[i])){
+                throw new YAHOO.util.ComparisonFailure(YAHOO.util.Assert._formatMessage(message, "Values in position " + i + " are not equivalent."), expected[i], actual[i]);
+            }
+        }
+    },
+    
+    /**
+     * Asserts that an array is empty.
+     * @param {Array} actual The array to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isEmpty
+     * @static
+     */
+    isEmpty : function (actual /*:Array*/, message /*:String*/) /*:Void*/ {        
+        if (actual.length > 0){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Array should be empty."));
+        }
+    },    
+    
+    /**
+     * Asserts that an array is not empty.
+     * @param {Array} actual The array to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method isNotEmpty
+     * @static
+     */
+    isNotEmpty : function (actual /*:Array*/, message /*:String*/) /*:Void*/ {        
+        if (actual.length === 0){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Array should not be empty."));
+        }
+    },    
+    
+    /**
+     * Asserts that the values in an array are the same, and in the same position,
+     * as values in another array. This uses the triple equals sign
+     * so no type cohersion will occur. Note that the array objects themselves
+     * need not be the same for this test to pass.
+     * @param {Array} expected An array of the expected values.
+     * @param {Array} actual Any array of the actual values.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method itemsAreSame
+     * @static
+     */
+    itemsAreSame : function (expected /*:Array*/, actual /*:Array*/, 
+                          message /*:String*/) /*:Void*/ {
+        
+        //one may be longer than the other, so get the maximum length
+        var len /*:int*/ = Math.max(expected.length, actual.length);
+        var Assert = YAHOO.util.Assert;
+        
+        //begin checking values
+        for (var i=0; i < len; i++){
+            Assert.areSame(expected[i], actual[i], 
+                Assert._formatMessage(message, "Values in position " + i + " are not the same."));
+        }
+    },
+    
+    /**
+     * Asserts that the given value is contained in an array at the specified index,
+     * starting from the back of the array.
+     * This uses the triple equals sign so no type cohersion will occur.
+     * @param {Object} needle The value to look for.
+     * @param {Array} haystack The array to search in.
+     * @param {int} index The index at which the value should exist.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method lastIndexOf
+     * @static
+     */
+    lastIndexOf : function (needle /*:Object*/, haystack /*:Array*/, index /*:int*/, message /*:String*/) /*:Void*/ {
+    
+        var Assert = YAHOO.util.Assert;
+    
+        //try to find the value in the array
+        for (var i=haystack.length; i >= 0; i--){
+            if (haystack[i] === needle){
+                Assert.areEqual(index, i, Assert._formatMessage(message, "Value exists at index " + i + " but should be at index " + index + "."));
+                return;
+            }
+        }
+        
+        //if it makes it here, it wasn't found at all
+        Assert.fail(Assert._formatMessage(message, "Value doesn't exist in array."));        
+    }
+    
+};
+
+YAHOO.namespace("util");
+
+
+//-----------------------------------------------------------------------------
+// ObjectAssert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The ObjectAssert object provides functions to test JavaScript objects
+ * for a variety of cases.
+ *
+ * @namespace YAHOO.util
+ * @class ObjectAssert
+ * @static
+ */
+YAHOO.util.ObjectAssert = {
+        
+    /**
+     * Asserts that all properties in the object exist in another object.
+     * @param {Object} expected An object with the expected properties.
+     * @param {Object} actual An object with the actual properties.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method propertiesAreEqual
+     * @static
+     */
+    propertiesAreEqual : function (expected /*:Object*/, actual /*:Object*/, 
+                           message /*:String*/) /*:Void*/ {
+        
+        var Assert = YAHOO.util.Assert;
+        
+        //get all properties in the object
+        var properties /*:Array*/ = [];        
+        for (var property in expected){
+            properties.push(property);
+        }
+        
+        //see if the properties are in the expected object
+        for (var i=0; i < properties.length; i++){
+            Assert.isNotUndefined(actual[properties[i]], 
+                Assert._formatMessage(message, "Property '" + properties[i] + "' expected."));
+        }
+
+    },
+    
+    /**
+     * Asserts that an object has a property with the given name.
+     * @param {String} propertyName The name of the property to test.
+     * @param {Object} object The object to search.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method hasProperty
+     * @static
+     */    
+    hasProperty : function (propertyName /*:String*/, object /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!(propertyName in object)){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Property '" + propertyName + "' not found on object."));
+        }    
+    },
+    
+    /**
+     * Asserts that a property with the given name exists on an object instance (not on its prototype).
+     * @param {String} propertyName The name of the property to test.
+     * @param {Object} object The object to search.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method hasProperty
+     * @static
+     */    
+    hasOwnProperty : function (propertyName /*:String*/, object /*:Object*/, message /*:String*/) /*:Void*/ {
+        if (!YAHOO.lang.hasOwnProperty(object, propertyName)){
+            var Assert = YAHOO.util.Assert;
+            Assert.fail(Assert._formatMessage(message, "Property '" + propertyName + "' not found on object instance."));
+        }     
+    }
+};
+
+//-----------------------------------------------------------------------------
+// DateAssert object
+//-----------------------------------------------------------------------------
+
+/**
+ * The DateAssert object provides functions to test JavaScript Date objects
+ * for a variety of cases.
+ *
+ * @namespace YAHOO.util
+ * @class DateAssert
+ * @static
+ */
+ 
+YAHOO.util.DateAssert = {
+
+    /**
+     * Asserts that a date's month, day, and year are equal to another date's.
+     * @param {Date} expected The expected date.
+     * @param {Date} actual The actual date to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method datesAreEqual
+     * @static
+     */
+    datesAreEqual : function (expected /*:Date*/, actual /*:Date*/, message /*:String*/){
+        if (expected instanceof Date && actual instanceof Date){
+            var Assert = YAHOO.util.Assert;
+            Assert.areEqual(expected.getFullYear(), actual.getFullYear(), Assert._formatMessage(message, "Years should be equal."));
+            Assert.areEqual(expected.getMonth(), actual.getMonth(), Assert._formatMessage(message, "Months should be equal."));
+            Assert.areEqual(expected.getDate(), actual.getDate(), Assert._formatMessage(message, "Day of month should be equal."));
+        } else {
+            throw new TypeError("DateAssert.datesAreEqual(): Expected and actual values must be Date objects.");
+        }
+    },
+
+    /**
+     * Asserts that a date's hour, minutes, and seconds are equal to another date's.
+     * @param {Date} expected The expected date.
+     * @param {Date} actual The actual date to test.
+     * @param {String} message (Optional) The message to display if the assertion fails.
+     * @method timesAreEqual
+     * @static
+     */
+    timesAreEqual : function (expected /*:Date*/, actual /*:Date*/, message /*:String*/){
+        if (expected instanceof Date && actual instanceof Date){
+            var Assert = YAHOO.util.Assert;
+            Assert.areEqual(expected.getHours(), actual.getHours(), Assert._formatMessage(message, "Hours should be equal."));
+            Assert.areEqual(expected.getMinutes(), actual.getMinutes(), Assert._formatMessage(message, "Minutes should be equal."));
+            Assert.areEqual(expected.getSeconds(), actual.getSeconds(), Assert._formatMessage(message, "Seconds should be equal."));
+        } else {
+            throw new TypeError("DateAssert.timesAreEqual(): Expected and actual values must be Date objects.");
+        }
+    }
+    
+};
+
+YAHOO.register("yuitest_core", YAHOO.tool.TestRunner, {version: "2.5.1", build: "984"});




More information about the Parley-svn mailing list